update to 11.2.3 (5335)

This commit is contained in:
dkaraush 2024-10-18 00:04:16 +04:00
parent 1e89182699
commit 9b78d437de
188 changed files with 14155 additions and 4829 deletions

View file

@ -116,7 +116,7 @@ android {
minifyEnabled false
shrinkResources false
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
@ -129,7 +129,7 @@ android {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\""
@ -142,7 +142,7 @@ android {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\""
@ -155,7 +155,7 @@ android {
jniDebuggable false
minifyEnabled true
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro', '../TMessagesProj/proguard-rules-beta.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""

View file

@ -100,7 +100,7 @@ jint getTimeDifference(JNIEnv *env, jclass c, jint instanceNum) {
void sendRequest(JNIEnv *env, jclass c, jint instanceNum, jlong object, jint flags, jint datacenterId, jint connectionType, jboolean immediate, jint token) {
TL_api_request *request = new TL_api_request();
request->request = (NativeByteBuffer *) (intptr_t) object;
ConnectionsManager::getInstance(instanceNum).sendRequest(request, ([instanceNum, token](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(instanceNum).sendRequest(request, ([instanceNum, token](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
TL_api_response *resp = (TL_api_response *) response;
jlong ptr = 0;
jint errorCode = 0;
@ -117,7 +117,7 @@ void sendRequest(JNIEnv *env, jclass c, jint instanceNum, jlong object, jint fla
errorText = jniEnv[instanceNum]->NewStringUTF("UTF-8 ERROR");
}
}
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onRequestComplete, instanceNum, token, ptr, errorCode, errorText, networkType, responseTime, msgId);
jniEnv[instanceNum]->CallStaticVoidMethod(jclass_ConnectionsManager, jclass_ConnectionsManager_onRequestComplete, instanceNum, token, ptr, errorCode, errorText, networkType, responseTime, msgId, dcId);
if (errorText != nullptr) {
jniEnv[instanceNum]->DeleteLocalRef(errorText);
}
@ -561,7 +561,7 @@ extern "C" int registerNativeTgNetFunctions(JavaVM *vm, JNIEnv *env) {
if (jclass_ConnectionsManager_onRequestClear == 0) {
return JNI_FALSE;
}
jclass_ConnectionsManager_onRequestComplete = env->GetStaticMethodID(jclass_ConnectionsManager, "onRequestComplete", "(IIJILjava/lang/String;IJJ)V");
jclass_ConnectionsManager_onRequestComplete = env->GetStaticMethodID(jclass_ConnectionsManager, "onRequestComplete", "(IIJILjava/lang/String;IJJI)V");
if (jclass_ConnectionsManager_onRequestComplete == 0) {
return JNI_FALSE;
}

View file

@ -624,7 +624,8 @@ void ConnectionsManager::cleanUp(bool resetKeys, int32_t datacenterId) {
auto error = new TL_error();
error->code = -1000;
error->text = "";
request->onComplete(nullptr, error, 0, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, 0, 0, request->messageId, dcId);
delete error;
}
iter = requestsQueue.erase(iter);
@ -646,7 +647,8 @@ void ConnectionsManager::cleanUp(bool resetKeys, int32_t datacenterId) {
auto error = new TL_error();
error->code = -1000;
error->text = "";
request->onComplete(nullptr, error, 0, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, 0, 0, request->messageId, dcId);
delete error;
}
DEBUG_D("1) erase request %d 0x%" PRIx64, request->requestToken, request->messageId);
@ -1205,7 +1207,8 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
for (auto iter = runningRequests.begin(); iter != runningRequests.end(); iter++) {
Request *request = iter->get();
if (request->respondsToMessageId(requestMid)) {
request->onComplete(response, nullptr, connection->currentNetworkType, timeMessage, requestMid);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(response, nullptr, connection->currentNetworkType, timeMessage, requestMid, dcId);
request->completed = true;
DEBUG_D("4) erase request %d 0x%" PRIx64, request->requestToken, request->messageId);
runningRequests.erase(iter);
@ -1450,12 +1453,13 @@ void ConnectionsManager::processServerResponse(TLObject *message, int64_t messag
}
if (!discardResponse) {
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
if (implicitError != nullptr || error2 != nullptr) {
isError = true;
request->onComplete(nullptr, implicitError != nullptr ? implicitError : error2, connection->currentNetworkType, timeMessage, request->messageId);
request->onComplete(nullptr, implicitError != nullptr ? implicitError : error2, connection->currentNetworkType, timeMessage, request->messageId, dcId);
delete error2;
} else {
request->onComplete(response->result.get(), nullptr, connection->currentNetworkType, timeMessage, request->messageId);
request->onComplete(response->result.get(), nullptr, connection->currentNetworkType, timeMessage, request->messageId, dcId);
}
}
@ -2104,7 +2108,7 @@ bool ConnectionsManager::cancelRequestInternal(int32_t token, int64_t messageId,
auto dropAnswer = new TL_rpc_drop_answer();
dropAnswer->req_msg_id = request->messageId;
if (onCancelled != nullptr) {
sendRequest(dropAnswer, ([onCancelled](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) -> void {
sendRequest(dropAnswer, ([onCancelled](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) -> void {
if (onCancelled != nullptr) {
onCancelled();
}
@ -2161,7 +2165,8 @@ void ConnectionsManager::failNotRunningRequest(int32_t token) {
auto error = new TL_error();
error->code = -2000;
error->text = "CANCELLED_REQUEST";
request->onComplete(nullptr, error, 0, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, 0, 0, request->messageId, dcId);
request->cancelled = true;
if (LOGS_ENABLED) DEBUG_D("cancelled queued rpc request %p - %s", request->rawRequest, typeid(*request->rawRequest).name());
@ -2304,7 +2309,7 @@ void ConnectionsManager::requestSaltsForDatacenter(Datacenter *datacenter, bool
requestingSaltsForDc.push_back(id);
auto request = new TL_get_future_salts();
request->num = 32;
sendRequest(request, [&, datacenter, id, media](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&, datacenter, id, media](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
auto iter = std::find(requestingSaltsForDc.begin(), requestingSaltsForDc.end(), id);
if (iter != requestingSaltsForDc.end()) {
requestingSaltsForDc.erase(iter);
@ -2339,7 +2344,7 @@ void ConnectionsManager::registerForInternalPushUpdates() {
request->token_type = 7;
request->token = to_string_uint64((uint64_t) pushSessionId);
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error == nullptr) {
registeredForInternalPush = true;
if (LOGS_ENABLED) DEBUG_D("registered for internal push");
@ -2562,7 +2567,8 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
auto error = new TL_error();
error->code = -123;
error->text = "RETRY_LIMIT";
request->onComplete(nullptr, error, connection->currentNetworkType, 0, request->messageId);
int32_t dcId = request->datacenterId != DEFAULT_DATACENTER_ID ? request->datacenterId : currentDatacenterId;
request->onComplete(nullptr, error, connection->currentNetworkType, 0, request->messageId, dcId);
delete error;
DEBUG_D("12) erase request %d 0x%" PRIx64, request->requestToken, request->messageId);
iter = runningRequests.erase(iter);
@ -3273,7 +3279,7 @@ void ConnectionsManager::updateDcSettings(uint32_t dcNum, bool workaround, bool
}
auto request = new TL_help_getConfig();
sendRequest(request, [&, workaround](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&, workaround](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if ((!workaround && !updatingDcSettings) || (workaround && !updatingDcSettingsWorkaround)) {
return;
}
@ -3422,7 +3428,7 @@ void ConnectionsManager::authorizeOnMovingDatacenter() {
auto request = new TL_auth_importAuthorization();
request->id = currentUserId;
request->bytes = std::move(movingAuthorization);
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error == nullptr) {
authorizedOnMovingDatacenter();
} else {

View file

@ -1447,14 +1447,14 @@ void Datacenter::exportAuthorization() {
auto request = new TL_auth_exportAuthorization();
request->dc_id = datacenterId;
if (LOGS_ENABLED) DEBUG_D("dc%u begin export authorization", datacenterId);
ConnectionsManager::getInstance(instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error == nullptr) {
auto res = (TL_auth_exportedAuthorization *) response;
auto request2 = new TL_auth_importAuthorization();
request2->bytes = std::move(res->bytes);
request2->id = res->id;
if (LOGS_ENABLED) DEBUG_D("dc%u begin import authorization", datacenterId);
ConnectionsManager::getInstance(instanceNum).sendRequest(request2, [&](TLObject *response2, TL_error *error2, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(instanceNum).sendRequest(request2, [&](TLObject *response2, TL_error *error2, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (error2 == nullptr) {
authorized = true;
ConnectionsManager::getInstance(instanceNum).onDatacenterExportAuthorizationComplete(this);

View file

@ -47,7 +47,7 @@ class NativeByteBuffer;
class Handshake;
class ConnectionSocket;
typedef std::function<void(TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId)> onCompleteFunc;
typedef std::function<void(TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId)> onCompleteFunc;
typedef std::function<void()> onQuickAckFunc;
typedef std::function<void()> onWriteToSocketFunc;
typedef std::function<void()> onRequestClearFunc;

View file

@ -873,7 +873,7 @@ void Handshake::processHandshakeResponse_serverDHParamsAnswer(TLObject *message,
request->encrypted_message = currentDatacenter->createRequestsData(array, nullptr, connection, true);
};
authKeyPendingRequestId = ConnectionsManager::getInstance(currentDatacenter->instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
authKeyPendingRequestId = ConnectionsManager::getInstance(currentDatacenter->instanceNum).sendRequest(request, [&](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
authKeyPendingMessageId = 0;
authKeyPendingRequestId = 0;
if (response != nullptr && typeid(*response) == typeid(TL_boolTrue)) {
@ -989,7 +989,7 @@ void Handshake::loadCdnConfig(Datacenter *datacenter) {
loadingCdnKeys = true;
auto request = new TL_help_getCdnConfig();
ConnectionsManager::getInstance(datacenter->instanceNum).sendRequest(request, [&, datacenter](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId) {
ConnectionsManager::getInstance(datacenter->instanceNum).sendRequest(request, [&, datacenter](TLObject *response, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msgId, int32_t dcId) {
if (response != nullptr) {
auto config = (TL_cdnConfig *) response;
size_t count = config->public_keys.size();

View file

@ -52,10 +52,10 @@ void Request::clear(bool time) {
}
}
void Request::onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t requestMsgId) {
void Request::onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t requestMsgId, int32_t dcId) {
if (onCompleteRequestCallback != nullptr && (result != nullptr || error != nullptr)) {
completedSent = true;
onCompleteRequestCallback(result, error, networkType, responseTime, requestMsgId);
onCompleteRequestCallback(result, error, networkType, responseTime, requestMsgId, dcId);
}
}

View file

@ -66,7 +66,7 @@ public:
void addRespondMessageId(int64_t id);
bool respondsToMessageId(int64_t id);
void clear(bool time);
void onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msg_id);
void onComplete(TLObject *result, TL_error *error, int32_t networkType, int64_t responseTime, int64_t msg_id, int32_t dcId);
void onQuickAck();
void onWriteToSocket();
bool isMediaRequest();

View file

@ -401,6 +401,14 @@
</intent-filter>
</receiver>
<receiver
android:name=".CopyCodeReceiver"
android:exported="false">
<intent-filter>
<action android:name="org.telegram.messenger.ACTION_COPY_CODE"/>
</intent-filter>
</receiver>
<receiver
android:name=".NotificationsDisabledReceiver"
android:exported="false">

View file

@ -446,3 +446,4 @@ iv_backgroundGray=-14737633
iv_navigationBackground=-16777216
table_background=177390847
table_border=436207615
dialogCardShadow=1073741824

View file

@ -471,3 +471,4 @@ iv_backgroundGray=-14737633
iv_navigationBackground=-16777216
table_background=177390847
table_border=436207615
dialogCardShadow=1073741824

View file

@ -16,12 +16,16 @@
package androidx.recyclerview.widget;
import android.text.TextUtils;
import android.util.Log;
import androidx.core.util.Pools;
import org.telegram.messenger.BuildVars;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
@ -68,6 +72,29 @@ class AdapterHelper implements OpReorderer.Callback {
private int mExistingUpdateTypes = 0;
private final ArrayList<String> lastNotifies = BuildVars.DEBUG_VERSION ? new ArrayList<String>() : null;
private void logNotify(String name) {
if (lastNotifies == null) return;
while (lastNotifies.size() > 5) lastNotifies.remove(0);
final StringBuilder sb = new StringBuilder();
sb.append(new Date().toString()).append(" ").append(name).append("\n");
final StackTraceElement[] trace = new Exception().getStackTrace();
for (int i = 0, j = 0; i < trace.length && j < 5; ++i) {
final String traceElement = trace[i].toString();
if (traceElement.startsWith("androidx.recyclerview.widget.") && j == 0) {
continue;
}
sb.append("\n").append(traceElement).append("\n");
j++;
}
lastNotifies.add(sb.toString());
}
public String getLastNotifies() {
if (lastNotifies == null) return null;
return TextUtils.join("\n\n", lastNotifies);
}
AdapterHelper(Callback callback) {
this(callback, false);
}
@ -504,6 +531,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount < 1) {
return false;
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeChanged(" + positionStart + ", " + itemCount + ", " + payload + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.UPDATE, positionStart, itemCount, payload));
mExistingUpdateTypes |= UpdateOp.UPDATE;
return mPendingUpdates.size() == 1;
@ -516,6 +546,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount < 1) {
return false;
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeInserted(" + positionStart + ", " + itemCount + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.ADD, positionStart, itemCount, null));
mExistingUpdateTypes |= UpdateOp.ADD;
return mPendingUpdates.size() == 1;
@ -528,6 +561,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount < 1) {
return false;
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeRemoved(" + positionStart + ", " + itemCount + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.REMOVE, positionStart, itemCount, null));
mExistingUpdateTypes |= UpdateOp.REMOVE;
return mPendingUpdates.size() == 1;
@ -543,6 +579,9 @@ class AdapterHelper implements OpReorderer.Callback {
if (itemCount != 1) {
throw new IllegalArgumentException("Moving more than 1 item is not supported yet");
}
if (BuildVars.DEBUG_VERSION) {
logNotify("onItemRangeMoved(" + from + ", " + to + ", " + itemCount + ")");
}
mPendingUpdates.add(obtainUpdateOp(UpdateOp.MOVE, from, to, null));
mExistingUpdateTypes |= UpdateOp.MOVE;
return mPendingUpdates.size() == 1;

View file

@ -63,6 +63,11 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
ArrayList<RecyclerView.ViewHolder> mChangeAnimations = new ArrayList<>();
protected boolean delayAnimations = true;
private long delayIncrement = 0;
public void setDelayIncrement(long increment) {
this.delayIncrement = increment;
}
protected static class MoveInfo {
public RecyclerView.ViewHolder holder;
@ -121,6 +126,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
animateRemoveImpl(holder);
}
final long[] delay = new long[] { 0 };
mPendingRemovals.clear();
// Next, move stuff
if (movesPending) {
@ -179,8 +185,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
Runnable adder = new Runnable() {
@Override
public void run() {
for (RecyclerView.ViewHolder holder : additions) {
animateAddImpl(holder);
for (int i = additions.size() - 1; i >= 0; --i) {
// for (int i = 0; i < additions.size(); ++i) {
final RecyclerView.ViewHolder holder = additions.get(i);
animateAddImpl(holder, delay[0] += delayIncrement);
}
additions.clear();
mAdditionsList.remove(additions);
@ -224,6 +232,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
animateRemoveImpl(holder, 0);
}
public void animateRemoveImpl(final RecyclerView.ViewHolder holder, long delay) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mRemoveAnimations.add(holder);
@ -233,7 +245,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
animation
.setDuration(getRemoveDuration())
.setStartDelay(getRemoveDelay())
.setStartDelay(getRemoveDelay() + delay)
.setInterpolator(getRemoveInterpolator())
.alpha(0)
.scaleX(1f - animateByScale(view))
@ -280,6 +292,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
public void animateAddImpl(final RecyclerView.ViewHolder holder) {
animateAddImpl(holder, 0);
}
public void animateAddImpl(final RecyclerView.ViewHolder holder, long delay) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mAddAnimations.add(holder);
@ -288,7 +304,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
.scaleX(1f)
.scaleY(1f)
.setDuration(getAddDuration())
.setStartDelay(getAddDelay())
.setStartDelay(getAddDelay() + delay)
.setInterpolator(getAddInterpolator());
if (Build.VERSION.SDK_INT >= 19) {
animation.setUpdateListener(animation1 -> onAddAnimationUpdate(holder));
@ -376,6 +392,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void animateMoveImpl(final RecyclerView.ViewHolder holder, MoveInfo moveInfo) {
animateMoveImpl(holder, moveInfo, 0);
}
public void animateMoveImpl(final RecyclerView.ViewHolder holder, MoveInfo moveInfo, long delay) {
int fromX = moveInfo.fromX;
int fromY = moveInfo.fromY;
int toX = moveInfo.toX;
@ -405,7 +425,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
beforeAnimateMoveImpl(holder);
animation
.setDuration(getMoveDuration())
.setStartDelay(getMoveDelay())
.setStartDelay(getMoveDelay() + delay)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
@ -470,6 +490,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
public void animateChangeImpl(final ChangeInfo changeInfo) {
animateChangeImpl(changeInfo, 0);
}
public void animateChangeImpl(final ChangeInfo changeInfo, long delay) {
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
@ -491,6 +515,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
oldViewAnim.setUpdateListener(animation1 -> onChangeAnimationUpdate(changeInfo.oldHolder));
}
oldViewAnim
.setStartDelay(delay)
.setInterpolator(getChangeInterpolator())
.setListener(new AnimatorListenerAdapter() {
@Override
@ -520,7 +545,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
newViewAnimation
.translationX(0).translationY(0)
.setDuration(getChangeAddDuration())
.setStartDelay(getChangeDelay() + (getChangeDuration() - getChangeAddDuration()))
.setStartDelay(getChangeDelay() + (getChangeDuration() - getChangeAddDuration()) + delay)
.setInterpolator(getChangeInterpolator())
.alpha(1);
if (animateByScale(newView) > 0) {

View file

@ -774,10 +774,16 @@ public class RecyclerView extends ViewGroup implements ScrollingView,
* hitting an exception.
*/
String exceptionLabel() {
return " " + super.toString()
+ ", adapter:" + mAdapter
+ ", layout:" + mLayout
+ ", context:" + getContext();
final StringBuilder sb = new StringBuilder();
sb.append(" ").append(super.toString())
.append(", adapter:").append(mAdapter)
.append(", layout:").append(mLayout)
.append(", context:").append(getContext());
final String lastNotifies = mAdapterHelper.getLastNotifies();
if (lastNotifies != null) {
sb.append(", last notifies:\n").append(lastNotifies);
}
return sb.toString();
}
/**

View file

@ -634,7 +634,7 @@ public final class MediaCodecUtil {
* The result of {@link android.media.MediaCodecInfo#isHardwareAccelerated()} for API levels 29+,
* or a best-effort approximation for lower levels.
*/
private static boolean isHardwareAccelerated(
public static boolean isHardwareAccelerated(
android.media.MediaCodecInfo codecInfo, String mimeType) {
if (Util.SDK_INT >= 29) {
return isHardwareAcceleratedV29(codecInfo);

View file

@ -427,7 +427,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
initDataSource,
initDataSpec,
initSegmentEncrypted,
/* initializeTimestampAdjuster= */ false);
/* initializeTimestampAdjuster= */ true);
nextLoadPosition = 0;
initDataLoadRequired = false;
}

View file

@ -25,6 +25,8 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.PlaybackException;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

View file

@ -19,6 +19,9 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.util.Log;
import java.util.ArrayList;
/**

View file

@ -319,7 +319,7 @@ public final class DataSpec {
}
/** A {@link Uri} from which data belonging to the resource can be read. */
public final Uri uri;
public Uri uri;
/**
* The offset of the data located at {@link #uri} within the resource.

View file

@ -53,7 +53,7 @@ public final class DefaultHttpDataSourceFactory extends BaseFactory {
*/
public DefaultHttpDataSourceFactory(String userAgent, @Nullable TransferListener listener) {
this(userAgent, listener, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, false);
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true);
}
/**

View file

@ -500,6 +500,17 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static Activity getActivity() {
return getActivity(null);
}
public static Activity getActivity(Context context) {
Activity activity = findActivity(context);
if (activity == null || activity.isFinishing()) activity = LaunchActivity.instance;
if (activity == null || activity.isFinishing()) activity = findActivity(ApplicationLoader.applicationContext);
return activity;
}
public static Activity findActivity(Context context) {
if (context instanceof Activity) {
return (Activity) context;
@ -533,7 +544,7 @@ public class AndroidUtilities {
index = startIndex;
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
if (index >= 0) {
if (runnable != null && index >= 0) {
if (type == REPLACING_TAG_TYPE_LINK_NBSP) {
spannableStringBuilder.replace(index, index + len, AndroidUtilities.replaceMultipleCharSequence(" ", spannableStringBuilder.subSequence(index, index + len), " "));
}
@ -574,6 +585,43 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static SpannableStringBuilder makeClickable(String str, int type, Runnable runnable, Theme.ResourcesProvider resourcesProvider) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
if (type == REPLACING_TAG_TYPE_LINK || type == REPLACING_TAG_TYPE_LINK_NBSP || type == REPLACING_TAG_TYPE_LINKBOLD || type == REPLACING_TAG_TYPE_UNDERLINE) {
spannableStringBuilder.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(type == REPLACING_TAG_TYPE_UNDERLINE);
if (type == REPLACING_TAG_TYPE_LINKBOLD) {
ds.setTypeface(AndroidUtilities.bold());
}
}
@Override
public void onClick(@NonNull View view) {
if (runnable != null) {
runnable.run();
}
}
}, 0, spannableStringBuilder.length(), 0);
} else {
spannableStringBuilder.setSpan(new CharacterStyle() {
@Override
public void updateDrawState(TextPaint textPaint) {
textPaint.setTypeface(AndroidUtilities.bold());
int wasAlpha = textPaint.getAlpha();
textPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText, resourcesProvider));
textPaint.setAlpha(wasAlpha);
}
}, 0, spannableStringBuilder.length(), 0);
}
return spannableStringBuilder;
}
public static SpannableStringBuilder makeClickable(String str, Runnable runnable) {
return makeClickable(str, 0, runnable, null);
}
public static SpannableStringBuilder replaceMultipleTags(String str, Runnable ...runnables) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);

View file

@ -50,6 +50,7 @@ import org.telegram.ui.LauncherIconController;
import java.io.File;
import java.util.ArrayList;
import java.util.Locale;
public class ApplicationLoader extends Application {
@ -267,7 +268,23 @@ public class ApplicationLoader extends Application {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("app start time = " + (startTime = SystemClock.elapsedRealtime()));
try {
FileLog.d("buildVersion = " + ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0).versionCode);
final PackageInfo info = ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0);
final String abi;
switch (info.versionCode % 10) {
case 1:
case 2:
abi = "store bundled " + Build.CPU_ABI + " " + Build.CPU_ABI2;
break;
default:
case 9:
if (ApplicationLoader.isStandaloneBuild()) {
abi = "direct " + Build.CPU_ABI + " " + Build.CPU_ABI2;
} else {
abi = "universal " + Build.CPU_ABI + " " + Build.CPU_ABI2;
}
break;
}
FileLog.d("buildVersion = " + String.format(Locale.US, "v%s (%d[%d]) %s", info.versionName, info.versionCode / 10, info.versionCode % 10, abi));
} catch (Exception e) {
FileLog.e(e);
}

View file

@ -43,6 +43,11 @@ public class BuildVars {
if (ApplicationLoader.applicationContext != null) {
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("systemConfig", Context.MODE_PRIVATE);
LOGS_ENABLED = DEBUG_VERSION || sharedPreferences.getBoolean("logsEnabled", DEBUG_VERSION);
if (LOGS_ENABLED) {
Thread.setDefaultUncaughtExceptionHandler((thread, exception) -> {
FileLog.fatal(exception, true);
});
}
}
}

View file

@ -1801,6 +1801,15 @@ public class ChatObject {
return isChannel(chat) && !isMegagroup(chat);
}
public static boolean isDiscussionGroup(int currentAccount, long chatId) {
final MessagesController messagesController = MessagesController.getInstance(currentAccount);
return isDiscussionGroup(messagesController.getChat(chatId), messagesController.getChatFull(chatId));
}
public static boolean isDiscussionGroup(TLRPC.Chat chat, TLRPC.ChatFull chatFull) {
return isMegagroup(chat) && chatFull != null && chatFull.linked_chat_id != 0;
}
public static boolean isBoostSupported(TLRPC.Chat chat) {
return isChannelAndNotMegaGroup(chat) || isMegagroup(chat);
}
@ -1906,6 +1915,9 @@ public class ChatObject {
}
public static boolean canSendMessages(TLRPC.Chat chat) {
if (isNotInChat(chat) && chat != null && chat.join_to_send) {
return false;
}
if (isIgnoredChatRestrictionsForBoosters(chat)) {
return true;
}

View file

@ -0,0 +1,15 @@
package org.telegram.messenger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class CopyCodeReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String text = intent.getStringExtra("text");
AndroidUtilities.addToClipboard(text);
}
}

View file

@ -1522,6 +1522,19 @@ public class DatabaseMigrationHelper {
version = 156;
}
if (version == 156 || version == 157) {
database.executeFast("CREATE TABLE star_gifts2(id INTEGER PRIMARY KEY, data BLOB, hash INTEGER, time INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 158").stepThis().dispose();
version = 158;
}
if (version == 158) {
database.executeFast("DELETE FROM star_gifts2").stepThis().dispose();
database.executeFast("ALTER TABLE star_gifts2 ADD COLUMN pos INTEGER default 0;").stepThis().dispose();
database.executeFast("PRAGMA user_version = 159").stepThis().dispose();
version = 159;
}
return version;
}

View file

@ -169,6 +169,9 @@ public class DialogObject {
}
public static long getEmojiStatusDocumentId(TLRPC.EmojiStatus emojiStatus) {
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked()) {
return 0;
}
if (emojiStatus instanceof TLRPC.TL_emojiStatus) {
return ((TLRPC.TL_emojiStatus) emojiStatus).document_id;
} else if (emojiStatus instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) emojiStatus).until > (int) (System.currentTimeMillis() / 1000)) {

View file

@ -397,14 +397,14 @@ public class FactCheckController {
menu.removeItem(android.R.id.shareText);
}
int order = 6;
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getString("Bold", R.string.Bold));
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getString(R.string.Bold));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_bold, order++, stringBuilder);
stringBuilder = new SpannableStringBuilder(getString("Italic", R.string.Italic));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/ritalic.ttf")), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder = new SpannableStringBuilder(getString(R.string.Italic));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM_ITALIC)), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_italic, order++, stringBuilder);
menu.add(R.id.menu_groupbolditalic, R.id.menu_link, order++, getString("CreateLink", R.string.CreateLink));
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, order++, getString("Regular", R.string.Regular));
menu.add(R.id.menu_groupbolditalic, R.id.menu_link, order++, getString(R.string.CreateLink));
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, order++, getString(R.string.Regular));
}
@Override

View file

@ -8,8 +8,6 @@
package org.telegram.messenger;
import android.util.Log;
import org.telegram.messenger.utils.ImmutableByteArrayOutputStream;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer;
@ -51,7 +49,7 @@ public class FileLoadOperation {
public volatile boolean caughtPremiumFloodWait;
public void setStream(FileLoadOperationStream stream, boolean streamPriority, long streamOffset) {
FileLog.e("FileLoadOperation " + getFileName() + " setStream(" + stream + ")");
// FileLog.e("FileLoadOperation " + getFileName() + " setStream(" + stream + ")");
this.stream = stream;
this.streamOffset = streamOffset;
this.streamPriority = streamPriority;
@ -240,6 +238,7 @@ public class FileLoadOperation {
private byte[] cdnCheckBytes;
private boolean requestingCdnOffsets;
public final ArrayList<Integer> uiRequestTokens = new ArrayList<>();
public ArrayList<RequestInfo> requestInfos;
private ArrayList<RequestInfo> cancelledRequestInfos;
private ArrayList<RequestInfo> delayedRequestInfos;
@ -249,6 +248,7 @@ public class FileLoadOperation {
private File cacheFileFinal;
private File cacheIvTemp;
private File cacheFileParts;
private boolean cacheFileFinalReady;
private String ext;
private RandomAccessFile fileOutputStream;
@ -686,7 +686,7 @@ public class FileLoadOperation {
}
protected File getCurrentFileFast() {
if (state == stateFinished && !preloadFinished) {
if (state == stateFinished && !preloadFinished && cacheFileFinalReady) {
return cacheFileFinal;
} else {
return cacheFileTemp;
@ -836,7 +836,9 @@ public class FileLoadOperation {
if (streamPriority) {
long offset = (streamOffset / (long) currentDownloadChunkSize) * (long) currentDownloadChunkSize;
if (priorityRequestInfo != null && priorityRequestInfo.offset != offset) {
final int requestToken = priorityRequestInfo.requestToken;
requestInfos.remove(priorityRequestInfo);
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.remove((Integer) requestToken));
requestedBytesCount -= currentDownloadChunkSize;
removePart(notRequestedBytesRanges, priorityRequestInfo.offset, priorityRequestInfo.offset + currentDownloadChunkSize);
if (priorityRequestInfo.requestToken != 0) {
@ -978,7 +980,7 @@ public class FileLoadOperation {
cacheFileFinal = new File(storePath, fileNameFinal);
}
}
boolean finalFileExist = cacheFileFinal.exists();
boolean finalFileExist = cacheFileFinalReady = cacheFileFinal.exists();
if (finalFileExist && (parentObject instanceof TLRPC.TL_theme || (totalBytesCount != 0 && !ungzip && totalBytesCount != cacheFileFinal.length())) && !delegate.isLocallyCreatedFile(cacheFileFinal.toString())) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("debug_loading: delete existing file cause file size mismatch " + cacheFileFinal.getName() + " totalSize=" + totalBytesCount + " existingFileSize=" + cacheFileFinal.length());
@ -1626,7 +1628,9 @@ public class FileLoadOperation {
return;
}
cacheFileFinal = cacheFileTempLocal;
cacheFileFinalReady = false;
} else {
cacheFileFinalReady = true;
if (pathSaveData != null && cacheFileFinal.exists()) {
delegate.saveFilePath(pathSaveData, cacheFileFinal);
}
@ -1779,7 +1783,9 @@ public class FileLoadOperation {
}
return false;
}
final int requestToken = requestInfo.requestToken;
requestInfos.remove(requestInfo);
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.remove((Integer) requestToken));
if (error == null) {
try {
if (notLoadedBytesRanges == null && downloadedBytes != requestInfo.offset) {
@ -2149,6 +2155,7 @@ public class FileLoadOperation {
}
}
requestInfos.clear();
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.clear());
for (int a = 0; a < delayedRequestInfos.size(); a++) {
RequestInfo info = delayedRequestInfos.get(a);
if (isPreloadVideoOperation) {
@ -2406,7 +2413,7 @@ public class FileLoadOperation {
}
flags |= ConnectionsManager.RequestFlagListenAfterCancel;
int datacenterId = isCdn ? cdnDatacenterId : this.datacenterId;
requestInfo.requestToken = ConnectionsManager.getInstance(currentAccount).sendRequestSync(request, (response, error) -> {
final int requestToken = requestInfo.requestToken = ConnectionsManager.getInstance(currentAccount).sendRequestSync(request, (response, error) -> {
if (requestInfo.cancelled) {
FileLog.e("received chunk but definitely cancelled offset=" + requestInfo.offset + " size=" + requestInfo.chunkSize + " token=" + requestInfo.requestToken);
return;
@ -2573,6 +2580,7 @@ public class FileLoadOperation {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("debug_loading: " + cacheFileFinal.getName() + " dc=" + datacenterId + " send reqId " + requestInfo.requestToken + " offset=" + requestInfo.offset + " conType=" + connectionType + " priority=" + priority);
}
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.add(requestToken));
requestsCount++;
}
}

View file

@ -682,11 +682,8 @@ public class FileLoader extends BaseController {
public FileUploadOperation findUploadOperationByRequestToken(final int requestToken) {
for (FileUploadOperation operation : uploadOperationPaths.values()) {
if (operation == null) continue;
for (int i = 0; i < operation.requestTokens.size(); ++i) {
if (operation.requestTokens.valueAt(i) == requestToken) {
return operation;
}
if (operation != null && operation.uiRequestTokens.contains(requestToken)) {
return operation;
}
}
return null;
@ -704,11 +701,8 @@ public class FileLoader extends BaseController {
public FileLoadOperation findLoadOperationByRequestToken(final int requestToken) {
for (FileLoadOperation operation : loadOperationPaths.values()) {
if (operation == null || operation.requestInfos == null) continue;
for (FileLoadOperation.RequestInfo requestInfo : operation.requestInfos) {
if (requestInfo != null && requestInfo.requestToken == requestToken) {
return operation;
}
if (operation != null && operation.uiRequestTokens.contains(requestToken)) {
return operation;
}
}
return null;
@ -821,7 +815,7 @@ public class FileLoader extends BaseController {
if (priorityChanged) {
operation.getQueue().checkLoadingOperations();
}
FileLog.d("load operation update position fileName=" + finalFileName + " position in queue " + operation.getPositionInQueue() + " preloadFinish " + operation.isPreloadFinished() + " priority=" + operation.getPriority());
// FileLog.d("load operation update position fileName=" + finalFileName + " position in queue " + operation.getPositionInQueue() + " preloadFinish " + operation.isPreloadFinished() + " priority=" + operation.getPriority());
return operation;
}

View file

@ -83,7 +83,7 @@ public class FileLog {
private static HashSet<String> excludeRequests;
public static void dumpResponseAndRequest(int account, TLObject request, TLObject response, TLRPC.TL_error error, long requestMsgId, long startRequestTimeInMillis, int requestToken) {
if (false && (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || request == null)) {
if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || request == null) {
return;
}
String requestSimpleName = request.getClass().getSimpleName();
@ -127,7 +127,7 @@ public class FileLog {
}
public static void dumpUnparsedMessage(TLObject message, long messageId, int account) {
if (false && (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || message == null)) {
if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || message == null) {
return;
}
try {
@ -330,6 +330,10 @@ public class FileLog {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + message + "\n");
getInstance().streamWriter.write(exception.toString());
StackTraceElement[] stack = exception.getStackTrace();
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: \tat " + stack[a] + "\n");
}
getInstance().streamWriter.flush();
} catch (Exception e) {
e.printStackTrace();
@ -386,12 +390,19 @@ public class FileLog {
e.printStackTrace();
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + e + "\n");
StackTraceElement[] stack = e.getStackTrace();
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + stack[a] + "\n");
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: \tat " + stack[a] + "\n");
}
Throwable cause = e.getCause();
if (cause != null) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: Caused by " + cause + "\n");
stack = cause.getStackTrace();
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: \tat " + stack[a] + "\n");
}
}
getInstance().streamWriter.flush();
} catch (Exception e1) {
@ -411,7 +422,7 @@ public class FileLog {
if (!BuildVars.LOGS_ENABLED) {
return;
}
if (BuildVars.DEBUG_VERSION && needSent(e) && logToAppCenter) {
if (logToAppCenter && BuildVars.DEBUG_VERSION && needSent(e)) {
AndroidUtilities.appCenterLog(e);
}
ensureInitied();
@ -419,10 +430,18 @@ public class FileLog {
if (getInstance().streamWriter != null) {
getInstance().logQueue.postRunnable(() -> {
try {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + e + "\n");
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " FATAL/tmessages: " + e + "\n");
StackTraceElement[] stack = e.getStackTrace();
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: " + stack[a] + "\n");
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " FATAL/tmessages: \tat " + stack[a] + "\n");
}
Throwable cause = e.getCause();
if (cause != null) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: Caused by " + cause + "\n");
stack = cause.getStackTrace();
for (int a = 0; a < stack.length; a++) {
getInstance().streamWriter.write(getInstance().dateFormat.format(System.currentTimeMillis()) + " E/tmessages: \tat " + stack[a] + "\n");
}
}
getInstance().streamWriter.flush();
} catch (Exception e1) {

View file

@ -951,7 +951,7 @@ public class FileRefController extends BaseController {
if (response instanceof StoriesController.BotPreview) {
StoriesController.BotPreview newStoryItem = (StoriesController.BotPreview) response;
if (newStoryItem.media.document != null) {
result = getFileReference(newStoryItem.media.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(newStoryItem.media.document, newStoryItem.media.alt_documents, requester.location, needReplacement, locationReplacement);
} else if (newStoryItem.media.photo != null) {
result = getFileReference(newStoryItem.media.photo, requester.location, needReplacement, locationReplacement);
}
@ -968,9 +968,9 @@ public class FileRefController extends BaseController {
TLRPC.MessageMedia media = ((TLRPC.TL_messageExtendedMedia) extendedMedia).media;
if (media != null) {
if (media.document != null) {
result = getFileReference(media.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(media.document, media.alt_documents, requester.location, needReplacement, locationReplacement);
} else if (media.game != null) {
result = getFileReference(media.game.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(media.game.document, null, requester.location, needReplacement, locationReplacement);
if (result == null) {
result = getFileReference(media.game.photo, requester.location, needReplacement, locationReplacement);
}
@ -987,9 +987,9 @@ public class FileRefController extends BaseController {
}
} else if (message.media != null) {
if (message.media.document != null) {
result = getFileReference(message.media.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(message.media.document, message.media.alt_documents, requester.location, needReplacement, locationReplacement);
} else if (message.media.game != null) {
result = getFileReference(message.media.game.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(message.media.game.document, null, requester.location, needReplacement, locationReplacement);
if (result == null) {
result = getFileReference(message.media.game.photo, requester.location, needReplacement, locationReplacement);
}
@ -1022,7 +1022,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_help_premiumPromo) {
TLRPC.TL_help_premiumPromo premiumPromo = (TLRPC.TL_help_premiumPromo) response;
for (TLRPC.Document document : premiumPromo.videos) {
result = getFileReference(document, requester.location, needReplacement, locationReplacement);
result = getFileReference(document, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1032,31 +1032,31 @@ public class FileRefController extends BaseController {
getMediaDataController().processLoadedReactions(availableReactions.reactions, availableReactions.hash, (int) (System.currentTimeMillis() / 1000), false);
for (TLRPC.TL_availableReaction reaction : availableReactions.reactions) {
result = getFileReference(reaction.static_icon, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.static_icon, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
result = getFileReference(reaction.appear_animation, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.appear_animation, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
result = getFileReference(reaction.select_animation, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.select_animation, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
result = getFileReference(reaction.activate_animation, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.activate_animation, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
result = getFileReference(reaction.effect_animation, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.effect_animation, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
result = getFileReference(reaction.around_animation, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.around_animation, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
result = getFileReference(reaction.center_icon, requester.location, needReplacement, locationReplacement);
result = getFileReference(reaction.center_icon, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1070,7 +1070,7 @@ public class FileRefController extends BaseController {
if (botInfo != null) {
getMessagesStorage().updateUserInfo(userFull, true);
result = getFileReference(botInfo.description_document, requester.location, needReplacement, locationReplacement);
result = getFileReference(botInfo.description_document, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
continue;
@ -1081,7 +1081,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_attachMenuBotsBot) {
TLRPC.TL_attachMenuBot bot = ((TLRPC.TL_attachMenuBotsBot) response).bot;
for (TLRPC.TL_attachMenuBotIcon icon : bot.icons) {
result = getFileReference(icon.icon, requester.location, needReplacement, locationReplacement);
result = getFileReference(icon.icon, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1128,10 +1128,10 @@ public class FileRefController extends BaseController {
FileLog.e(e);
}
if (result == null) {
result = getFileReference(appUpdate.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(appUpdate.document, null, requester.location, needReplacement, locationReplacement);
}
if (result == null) {
result = getFileReference(appUpdate.sticker, requester.location, needReplacement, locationReplacement);
result = getFileReference(appUpdate.sticker, null, requester.location, needReplacement, locationReplacement);
}
} else if (response instanceof TLRPC.TL_messages_webPage) {
TLRPC.TL_messages_webPage res = (TLRPC.TL_messages_webPage) response;
@ -1143,7 +1143,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_account_wallPapers) {
TLRPC.TL_account_wallPapers accountWallPapers = (TLRPC.TL_account_wallPapers) response;
for (int i = 0, size10 = accountWallPapers.wallpapers.size(); i < size10; i++) {
result = getFileReference(((TLRPC.WallPaper) accountWallPapers.wallpapers.get(i)).document, requester.location, needReplacement, locationReplacement);
result = getFileReference(((TLRPC.WallPaper) accountWallPapers.wallpapers.get(i)).document, null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1153,7 +1153,7 @@ public class FileRefController extends BaseController {
}
} else if (response instanceof TLRPC.TL_wallPaper) {
TLRPC.TL_wallPaper wallPaper = (TLRPC.TL_wallPaper) response;
result = getFileReference(wallPaper.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(wallPaper.document, null, requester.location, needReplacement, locationReplacement);
if (result != null && cache) {
ArrayList<TLRPC.WallPaper> wallpapers = new ArrayList<>();
wallpapers.add(wallPaper);
@ -1161,7 +1161,7 @@ public class FileRefController extends BaseController {
}
} else if (response instanceof TLRPC.TL_theme) {
TLRPC.TL_theme theme = (TLRPC.TL_theme) response;
result = getFileReference(theme.document, requester.location, needReplacement, locationReplacement);
result = getFileReference(theme.document, null, requester.location, needReplacement, locationReplacement);
if (result != null && cache) {
AndroidUtilities.runOnUIThread(() -> Theme.setThemeFileReference(theme));
}
@ -1214,7 +1214,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_messages_savedGifs) {
TLRPC.TL_messages_savedGifs savedGifs = (TLRPC.TL_messages_savedGifs) response;
for (int b = 0, size2 = savedGifs.gifs.size(); b < size2; b++) {
result = getFileReference(savedGifs.gifs.get(b), requester.location, needReplacement, locationReplacement);
result = getFileReference(savedGifs.gifs.get(b), null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1226,7 +1226,7 @@ public class FileRefController extends BaseController {
TLRPC.TL_messages_stickerSet stickerSet = (TLRPC.TL_messages_stickerSet) response;
if (result == null) {
for (int b = 0, size2 = stickerSet.documents.size(); b < size2; b++) {
result = getFileReference(stickerSet.documents.get(b), requester.location, needReplacement, locationReplacement);
result = getFileReference(stickerSet.documents.get(b), null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1238,7 +1238,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_messages_recentStickers) {
TLRPC.TL_messages_recentStickers recentStickers = (TLRPC.TL_messages_recentStickers) response;
for (int b = 0, size2 = recentStickers.stickers.size(); b < size2; b++) {
result = getFileReference(recentStickers.stickers.get(b), requester.location, needReplacement, locationReplacement);
result = getFileReference(recentStickers.stickers.get(b), null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1249,7 +1249,7 @@ public class FileRefController extends BaseController {
} else if (response instanceof TLRPC.TL_messages_favedStickers) {
TLRPC.TL_messages_favedStickers favedStickers = (TLRPC.TL_messages_favedStickers) response;
for (int b = 0, size2 = favedStickers.stickers.size(); b < size2; b++) {
result = getFileReference(favedStickers.stickers.get(b), requester.location, needReplacement, locationReplacement);
result = getFileReference(favedStickers.stickers.get(b), null, requester.location, needReplacement, locationReplacement);
if (result != null) {
break;
}
@ -1276,10 +1276,7 @@ public class FileRefController extends BaseController {
result = getFileReference(storyItem.media.photo, requester.location, needReplacement, locationReplacement);
}
if (result == null && storyItem.media.document != null) {
result = getFileReference(storyItem.media.document, requester.location, needReplacement, locationReplacement);
}
if (result == null && storyItem.media.alt_document != null) {
result = getFileReference(storyItem.media.alt_document, requester.location, needReplacement, locationReplacement);
result = getFileReference(storyItem.media.document, storyItem.media.alt_documents, requester.location, needReplacement, locationReplacement);
}
}
}
@ -1370,7 +1367,7 @@ public class FileRefController extends BaseController {
}
}
private byte[] getFileReference(TLRPC.Document document, TLRPC.InputFileLocation location, boolean[] needReplacement, TLRPC.InputFileLocation[] replacement) {
private byte[] getFileReference(TLRPC.Document document, ArrayList<TLRPC.Document> alt_documents, TLRPC.InputFileLocation location, boolean[] needReplacement, TLRPC.InputFileLocation[] replacement) {
if (document == null || location == null) {
return null;
}
@ -1397,6 +1394,14 @@ public class FileRefController extends BaseController {
}
}
}
if (alt_documents != null) {
byte[] result = null;
for (int i = 0; i < alt_documents.size(); ++i) {
if ((result = getFileReference(alt_documents.get(i), null, location, needReplacement, replacement)) != null) {
return result;
}
}
}
return null;
}
@ -1525,7 +1530,7 @@ public class FileRefController extends BaseController {
}
private byte[] getFileReference(TLRPC.WebPage webpage, TLRPC.InputFileLocation location, boolean[] needReplacement, TLRPC.InputFileLocation[] replacement) {
byte[] result = getFileReference(webpage.document, location, needReplacement, replacement);
byte[] result = getFileReference(webpage.document, null, location, needReplacement, replacement);
if (result != null) {
return result;
}
@ -1541,7 +1546,7 @@ public class FileRefController extends BaseController {
}
TLRPC.TL_webPageAttributeTheme attribute = (TLRPC.TL_webPageAttributeTheme) attribute_;
for (int b = 0, size2 = attribute.documents.size(); b < size2; b++) {
result = getFileReference(attribute.documents.get(b), location, needReplacement, replacement);
result = getFileReference(attribute.documents.get(b), null, location, needReplacement, replacement);
if (result != null) {
return result;
}
@ -1550,7 +1555,7 @@ public class FileRefController extends BaseController {
}
if (webpage.cached_page != null) {
for (int b = 0, size2 = webpage.cached_page.documents.size(); b < size2; b++) {
result = getFileReference(webpage.cached_page.documents.get(b), location, needReplacement, replacement);
result = getFileReference(webpage.cached_page.documents.get(b), null, location, needReplacement, replacement);
if (result != null) {
return result;
}

View file

@ -38,6 +38,8 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
private Uri uri;
private long bytesRemaining;
private long bytesTransferred;
private long requestedLength;
private boolean opened;
private long currentOffset;
private CountDownLatch countDownLatch;
@ -94,10 +96,13 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
document.attributes.add(new TLRPC.TL_documentAttributeAudio());
}
allStreams.put(document.id, this);
loadOperation = FileLoader.getInstance(currentAccount).loadStreamFile(this, document, null, parentObject, currentOffset = dataSpec.position, false, getCurrentPriority());
bytesRemaining = dataSpec.length == C.LENGTH_UNSET ? document.size - dataSpec.position : dataSpec.length;
if (bytesRemaining < 0) {
throw new EOFException();
currentOffset = dataSpec.position;
requestedLength = dataSpec.length;
loadOperation = FileLoader.getInstance(currentAccount).loadStreamFile(this, document, null, parentObject, currentOffset, false, getCurrentPriority());
bytesTransferred = 0;
bytesRemaining = document.size - dataSpec.position;
if (requestedLength != C.LENGTH_UNSET) {
bytesRemaining = Math.min(bytesRemaining, requestedLength - bytesTransferred);
}
opened = true;
transferStarted(dataSpec);
@ -109,6 +114,9 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
file.seek(currentOffset);
if (loadOperation.isFinished()) {
bytesRemaining = currentFile.length() - currentOffset;
if (requestedLength != C.LENGTH_UNSET) {
bytesRemaining = Math.min(bytesRemaining, requestedLength - bytesTransferred);
}
}
} catch (Throwable e) {
}
@ -178,6 +186,9 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
file.seek(currentOffset);
if (loadOperation.isFinished()) {
bytesRemaining = currentFile.length() - currentOffset;
if (requestedLength != C.LENGTH_UNSET) {
bytesRemaining = Math.min(bytesRemaining, requestedLength - bytesTransferred);
}
}
} catch (Throwable e) {
@ -195,6 +206,7 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
if (bytesRead > 0) {
currentOffset += bytesRead;
bytesRemaining -= bytesRead;
bytesTransferred += bytesRead;
bytesTransferred(bytesRead);
}
} catch (Exception e) {
@ -239,9 +251,10 @@ public class FileStreamLoadOperation extends BaseDataSource implements FileLoadO
@Override
public void newDataAvailable() {
// FileLog.e("FileStreamLoadOperation " + document.id + " newDataAvailable me=" + this);
if (countDownLatch != null) {
countDownLatch.countDown();
countDownLatch = null;
CountDownLatch latch = countDownLatch;
countDownLatch = null;
if (latch != null) {
latch.countDown();
}
}

View file

@ -54,6 +54,7 @@ public class FileUploadOperation {
private byte[] readBuffer;
private FileUploadOperationDelegate delegate;
public final SparseIntArray requestTokens = new SparseIntArray();
public final ArrayList<Integer> uiRequestTokens = new ArrayList<>();
private int currentPartNum;
private long currentFileId;
private long totalFileSize;
@ -162,6 +163,7 @@ public class FileUploadOperation {
}
}
});
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.clear());
}
public void cancel() {
@ -570,6 +572,7 @@ public class FileUploadOperation {
freeRequestIvs.add(currentRequestIv);
}
requestTokens.delete(requestNumFinal);
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.remove((Integer) requestToken[0]));
if (response instanceof TLRPC.TL_boolTrue) {
if (state != 1) {
return;
@ -676,5 +679,6 @@ public class FileUploadOperation {
FileLog.d("debug_uploading: " + " send reqId " + requestToken[0] + " " + uploadingFilePath + " file_part=" + currentRequestPartNum + " isBig=" + isBigFile + " file_id=" + currentFileId);
}
requestTokens.put(requestNumFinal, requestToken[0]);
AndroidUtilities.runOnUIThread(() -> uiRequestTokens.add(requestToken[0]));
}
}

View file

@ -2047,12 +2047,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
manualAlphaAnimator = value;
}
@Keep
public float getCurrentAlpha() {
return currentAlpha;
}
@Keep
public void setCurrentAlpha(float value) {
currentAlpha = value;
}
@ -2602,6 +2600,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
public int getAutoRepeat() {
return autoRepeat;
}
public void setAutoRepeatCount(int count) {
autoRepeatCount = count;
if (getLottieAnimation() != null) {

View file

@ -89,6 +89,7 @@ import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.VideoPlayer;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.Stories.DarkThemeResourceProvider;
import java.io.File;
import java.io.FileDescriptor;
@ -727,12 +728,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public VideoEditedInfo videoEditedInfo;
public int currentAccount;
public boolean foreground;
public boolean foregroundConversion;
public VideoConvertMessage(MessageObject object, VideoEditedInfo info, boolean foreground) {
public VideoConvertMessage(MessageObject object, VideoEditedInfo info, boolean foreground, boolean conversion) {
messageObject = object;
currentAccount = messageObject.currentAccount;
videoEditedInfo = info;
this.foreground = foreground;
this.foregroundConversion = conversion;
}
}
@ -4372,11 +4375,14 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileLoaded);
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileLoadProgressChanged);
currentAccount.getNotificationCenter().addObserver(this, NotificationCenter.fileLoadFailed);
progressDialog = new AlertDialog(context, AlertDialog.ALERT_TYPE_LOADING);
final Theme.ResourcesProvider resourcesProvider = PhotoViewer.getInstance().isVisible() ? new DarkThemeResourceProvider() : null;
progressDialog = new AlertDialog(context, AlertDialog.ALERT_TYPE_LOADING, resourcesProvider);
progressDialog.setMessage(LocaleController.getString(R.string.Loading));
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(d -> cancelled = true);
progressDialog.setCancelDialog(true);
progressDialog.setOnCancelListener(d -> {
cancelled = true;
});
}
public void start() {
@ -4392,7 +4398,12 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
for (int b = 0, N = messageObjects.size(); b < N; b++) {
MessageObject message = messageObjects.get(b);
String path = message.messageOwner.attachPath;
String name = message.getDocumentName();
TLRPC.Document document = message.getDocument();
if (message.qualityToSave != null) {
document = message.qualityToSave;
path = null;
}
String name = FileLoader.getDocumentFileName(document);
if (path != null && path.length() > 0) {
File temp = new File(path);
if (!temp.exists()) {
@ -4400,18 +4411,21 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
if (TextUtils.isEmpty(path)) {
// path = null;
// TLRPC.Document document = message.getDocument();
// if (!TextUtils.isEmpty(FileLoader.getDocumentFileName(document)) && !(message.messageOwner instanceof TLRPC.TL_message_secret) && FileLoader.canSaveAsFile(message)) {
// String filename = FileLoader.getDocumentFileName(document);
// File newDir = FileLoader.getDirectory(FileLoader.MEDIA_DIR_FILES);
// if (newDir != null) {
// path = new File(newDir, filename).getAbsolutePath();
// }
// }
// if (path == null) {
path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner).toString();
// }
final FileLoader fileLoader = FileLoader.getInstance(currentAccount.getCurrentAccount());
final TLRPC.MessageMedia media = MessageObject.getMedia(message);
File file = null;
if (message.qualityToSave != null) {
file = fileLoader.getPathToAttach(message.qualityToSave, null, false, true);
} else {
file = fileLoader.getPathToMessage(message.messageOwner, true);
if (media instanceof TLRPC.TL_messageMediaDocument) {
final TLRPC.TL_messageMediaDocument mediaDocument = (TLRPC.TL_messageMediaDocument) media;
if (!mediaDocument.alt_documents.isEmpty()) {
file = fileLoader.getPathToAttach(mediaDocument.alt_documents.get(0), null, false, true);
}
}
}
path = file.toString();
}
File sourceFile = new File(path);
if (!sourceFile.exists()) {
@ -4441,7 +4455,11 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
dir.mkdir();
for (int b = 0, N = messageObjects.size(); b < N; b++) {
MessageObject message = messageObjects.get(b);
String name = message.getDocumentName();
TLRPC.Document document = message.getDocument();
if (message.qualityToSave != null) {
document = message.qualityToSave;
}
String name = FileLoader.getDocumentFileName(document);
File destFile = new File(dir, name);
if (destFile.exists()) {
int idx = name.lastIndexOf('.');
@ -4462,16 +4480,24 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
destFile.createNewFile();
}
String path = message.messageOwner.attachPath;
if (message.qualityToSave != null) {
path = null;
}
if (path != null && path.length() > 0) {
File temp = new File(path);
if (!temp.exists()) {
path = null;
}
}
if (path == null || path.length() == 0) {
path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner).toString();
File sourceFile;
if (message.qualityToSave != null) {
sourceFile = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToAttach(message.qualityToSave, null, false, true);
} else {
if (path == null || path.length() == 0) {
path = FileLoader.getInstance(currentAccount.getCurrentAccount()).getPathToMessage(message.messageOwner).toString();
}
sourceFile = new File(path);
}
File sourceFile = new File(path);
if (!sourceFile.exists()) {
waitingForFile = new CountDownLatch(1);
addMessageToLoad(message);
@ -4517,6 +4543,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private void addMessageToLoad(MessageObject messageObject) {
AndroidUtilities.runOnUIThread(() -> {
TLRPC.Document document = messageObject.getDocument();
if (messageObject.qualityToSave != null) {
document = messageObject.qualityToSave;
}
if (document == null) {
return;
}
@ -5364,10 +5393,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
public void scheduleVideoConvert(MessageObject messageObject) {
scheduleVideoConvert(messageObject, false, true);
scheduleVideoConvert(messageObject, false, true, false);
}
public boolean scheduleVideoConvert(MessageObject messageObject, boolean isEmpty, boolean withForeground) {
public boolean scheduleVideoConvert(MessageObject messageObject, boolean isEmpty, boolean withForeground, boolean forConversion) {
if (messageObject == null || messageObject.videoEditedInfo == null) {
return false;
}
@ -5376,7 +5405,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} else if (isEmpty) {
new File(messageObject.messageOwner.attachPath).delete();
}
VideoConvertMessage videoConvertMessage = new VideoConvertMessage(messageObject, messageObject.videoEditedInfo, withForeground);
VideoConvertMessage videoConvertMessage = new VideoConvertMessage(messageObject, messageObject.videoEditedInfo, withForeground, forConversion);
videoConvertQueue.add(videoConvertMessage);
if (videoConvertMessage.foreground) {
foregroundConvertingMessages.add(videoConvertMessage);

View file

@ -428,7 +428,7 @@ public class MediaDataController extends BaseController {
}
public void checkPremiumPromo() {
if (!isLoadingPremiumPromo && Math.abs(System.currentTimeMillis() / 1000 - premiumPromoUpdateDate) >= 60 * 60) {
if (!isLoadingPremiumPromo && (premiumPromo == null || Math.abs(System.currentTimeMillis() / 1000 - premiumPromoUpdateDate) >= 60 * 60)) {
loadPremiumPromo(true);
}
}
@ -654,9 +654,7 @@ public class MediaDataController extends BaseController {
c.dispose();
}
}
if (premiumPromo != null) {
processLoadedPremiumPromo(premiumPromo, date, true);
}
processLoadedPremiumPromo(premiumPromo, date, true);
});
} else {
TLRPC.TL_help_getPremiumPromo req = new TLRPC.TL_help_getPremiumPromo();
@ -671,15 +669,24 @@ public class MediaDataController extends BaseController {
}
public void processLoadedPremiumPromo(TLRPC.TL_help_premiumPromo premiumPromo, int date, boolean cache) {
this.premiumPromo = premiumPromo;
premiumPromoUpdateDate = date;
getMessagesController().putUsers(premiumPromo.users, cache);
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.premiumPromoUpdated));
if (premiumPromo != null) {
this.premiumPromo = premiumPromo;
premiumPromoUpdateDate = date;
getMessagesController().putUsers(premiumPromo.users, cache);
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.premiumPromoUpdated));
}
if (!cache) {
putPremiumPromoToCache(premiumPromo, date);
} else if (Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60 * 24 || BuildVars.DEBUG_PRIVATE_VERSION) {
loadPremiumPromo(false);
if (premiumPromo != null) {
putPremiumPromoToCache(premiumPromo, date);
}
isLoadingPremiumPromo = false;
} else {
if (premiumPromo == null || Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60 * 24) {
loadPremiumPromo(false);
} else {
isLoadingPremiumPromo = false;
}
}
}
@ -793,7 +800,7 @@ public class MediaDataController extends BaseController {
isLoadingReactions = false;
if (!cache) {
putReactionsToCache(reactions, hash, date);
} else if (Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60) {
} else if (Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60 || true) {
loadReactions(false, hash);
}
}
@ -841,7 +848,7 @@ public class MediaDataController extends BaseController {
getMessagesStorage().getDatabase().executeFast("DELETE FROM reactions").stepThis().dispose();
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO reactions VALUES(?, ?, ?)");
state.requery();
int size = 4; // Integer.BYTES
int size = 4;
for (int a = 0; a < reactionsFinal.size(); a++) {
size += reactionsFinal.get(a).getObjectSize();
}
@ -8778,8 +8785,10 @@ public class MediaDataController extends BaseController {
String emoticon = MessageObject.findAnimatedEmojiEmoticon(document, null);
if (document != null &&
emoticon != null && emoticon.contains(emoji) &&
(isPremium || MessageObject.isFreeEmoji(document))
(isPremium || MessageObject.isFreeEmoji(document)) &&
!foundEmojis.contains(document.id)
) {
foundEmojis.add(document.id);
animatedEmoji.add(document);
}
} catch (Exception ignore) {

View file

@ -36,7 +36,6 @@ import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray;
@ -75,6 +74,7 @@ import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.URLSpanNoUnderlineBold;
import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.URLSpanUserMention;
import org.telegram.ui.Components.VideoPlayer;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PeerColorActivity;
import org.telegram.ui.Stars.StarsController;
@ -96,7 +96,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
@ -2957,14 +2956,26 @@ public class MessageObject {
messageText = replaceWithLink(messageText, "un2", createTopic.topic);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionEditTopic) {
TLRPC.TL_channelAdminLogEventActionEditTopic editTopic = (TLRPC.TL_channelAdminLogEventActionEditTopic) event.action;
if (editTopic.prev_topic instanceof TLRPC.TL_forumTopic && editTopic.new_topic instanceof TLRPC.TL_forumTopic &&
((TLRPC.TL_forumTopic) editTopic.prev_topic).hidden != ((TLRPC.TL_forumTopic) editTopic.new_topic).hidden) {
if (
editTopic.prev_topic instanceof TLRPC.TL_forumTopic && editTopic.new_topic instanceof TLRPC.TL_forumTopic &&
((TLRPC.TL_forumTopic) editTopic.prev_topic).hidden != ((TLRPC.TL_forumTopic) editTopic.new_topic).hidden
) {
String text = ((TLRPC.TL_forumTopic) editTopic.new_topic).hidden ? getString(R.string.TopicHidden2) : getString(R.string.TopicShown2);
messageText = replaceWithLink(text, "%s", fromUser);
} else if (
editTopic.prev_topic instanceof TLRPC.TL_forumTopic && editTopic.new_topic instanceof TLRPC.TL_forumTopic &&
((TLRPC.TL_forumTopic) editTopic.prev_topic).closed != ((TLRPC.TL_forumTopic) editTopic.new_topic).closed
) {
if (((TLRPC.TL_forumTopic) editTopic.new_topic).closed) {
messageText = replaceWithLink(getString(R.string.EventLogClosedTopic), "%s", fromUser);
} else {
messageText = replaceWithLink(getString(R.string.EventLogReopenedTopic), "%s", fromUser);
}
messageText = replaceWithLink(messageText, "un2", editTopic.new_topic);
} else {
messageText = replaceWithLink(
getString(R.string.EventLogEditTopic),
"un1", fromUser
getString(R.string.EventLogEditTopic),
"un1", fromUser
);
messageText = replaceWithLink(messageText, "un2", editTopic.prev_topic);
messageText = replaceWithLink(messageText, "un3", editTopic.new_topic);
@ -3267,9 +3278,9 @@ public class MessageObject {
private boolean spoiledLoginCode = false;
private static Pattern loginCodePattern;
public void spoilLoginCode() { // spoil login code from +42777
if (!spoiledLoginCode && messageText != null && messageOwner != null && messageOwner.entities != null && messageOwner.from_id instanceof TLRPC.TL_peerUser && messageOwner.from_id.user_id == 777000) {
if (!spoiledLoginCode && messageText != null && messageOwner != null && messageOwner.entities != null && messageOwner.from_id instanceof TLRPC.TL_peerUser && (messageOwner.from_id.user_id == 777000 || messageOwner.from_id.user_id == UserObject.VERIFY)) {
if (loginCodePattern == null) {
loginCodePattern = Pattern.compile("[\\d\\-]{5,7}");
loginCodePattern = Pattern.compile("[\\d\\-]{5,8}");
}
try {
Matcher matcher = loginCodePattern.matcher(messageText);
@ -3373,7 +3384,7 @@ public class MessageObject {
public boolean translated = false;
public boolean updateTranslation(boolean force) {
boolean replyUpdated = replyMessageObject != null && replyMessageObject.updateTranslation(force);
boolean replyUpdated = replyMessageObject != null && replyMessageObject != this && replyMessageObject.updateTranslation(force);
TranslateController translateController = MessagesController.getInstance(currentAccount).getTranslateController();
if (
TranslateController.isTranslatable(this) &&
@ -4014,6 +4025,10 @@ public class MessageObject {
return chat;
}
public void updateMessageText() {
updateMessageText(MessagesController.getInstance(currentAccount).getUsers(), MessagesController.getInstance(currentAccount).getChats(), null, null);
}
private void updateMessageText(AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, LongSparseArray<TLRPC.User> sUsers, LongSparseArray<TLRPC.Chat> sChats) {
TLRPC.User fromUser = null;
TLRPC.Chat fromChat = null;
@ -4345,6 +4360,25 @@ public class MessageObject {
final long chatId = -DialogObject.getPeerDialogId(action.boost_peer);
final TLRPC.Chat chat = getChat(chats, sChats, chatId);
messageText = replaceWithLink(AndroidUtilities.replaceTags(LocaleController.formatPluralStringComma("ActionStarGiveawayPrize", (int) action.stars)), "un1", chat);
} else if (messageOwner.action instanceof TLRPC.TL_messageActionStarGift) {
TLRPC.TL_messageActionStarGift action = (TLRPC.TL_messageActionStarGift) messageOwner.action;
if (fromObject instanceof TLRPC.User && ((TLRPC.User) fromObject).self && !action.forceIn) {
TLRPC.User user = getUser(users, sUsers, messageOwner.peer_id.user_id);
messageText = replaceWithLink(AndroidUtilities.replaceTags(getString(R.string.ActionGiftOutbound)), "un1", user);
} else if (fromObject instanceof TLRPC.User && UserObject.isService(((TLRPC.User) fromObject).id)) {
messageText = TextUtils.replace(AndroidUtilities.replaceTags(getString(R.string.ActionGiftInbound)), new String[] {"un1"}, new CharSequence[]{ getString(R.string.StarsTransactionUnknown) });
} else {
messageText = replaceWithLink(AndroidUtilities.replaceTags(getString(R.string.ActionGiftInbound)), "un1", fromObject);
}
int stars = 0;
if (action.gift != null) {
stars = (int) action.gift.stars;
}
int i = messageText.toString().indexOf("un2");
if (i != -1) {
SpannableStringBuilder sb = SpannableStringBuilder.valueOf(messageText);
messageText = sb.replace(i, i + 3, LocaleController.formatPluralStringComma("Gift2StarsCount", (int) stars));
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftStars) {
if (fromObject instanceof TLRPC.User && ((TLRPC.User) fromObject).self) {
TLRPC.User user = getUser(users, sUsers, messageOwner.peer_id.user_id);
@ -5313,7 +5347,7 @@ public class MessageObject {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium || messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
contentType = 1;
type = TYPE_GIFT_PREMIUM;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftStars || messageOwner.action instanceof TLRPC.TL_messageActionPrizeStars) {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftStars || messageOwner.action instanceof TLRPC.TL_messageActionStarGift || messageOwner.action instanceof TLRPC.TL_messageActionPrizeStars) {
contentType = 1;
type = TYPE_GIFT_STARS;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
@ -5814,7 +5848,7 @@ public class MessageObject {
public static String getFileName(TLRPC.Message messageOwner) {
if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument) {
return FileLoader.getAttachFileName(getDocument(messageOwner));
return getFileName(getDocument(messageOwner));
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaPhoto) {
ArrayList<TLRPC.PhotoSize> sizes = getMedia(messageOwner).photo.sizes;
if (sizes.size() > 0) {
@ -5824,11 +5858,15 @@ public class MessageObject {
}
}
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaWebPage && getMedia(messageOwner).webpage != null) {
return FileLoader.getAttachFileName(getMedia(messageOwner).webpage.document);
return getFileName(getMedia(messageOwner).webpage.document);
}
return "";
}
public static String getFileName(TLRPC.Document document) {
return FileLoader.getAttachFileName(document);
}
public static String getFileName(TLRPC.MessageMedia media) {
if (media instanceof TLRPC.TL_messageMediaDocument) {
return FileLoader.getAttachFileName(media.document);
@ -6723,6 +6761,9 @@ public class MessageObject {
if (isRepostPreview) {
return false;
}
if (getDialogId() == UserObject.VERIFY) {
return false;
}
if (isSaved) {
long selfId = UserConfig.getInstance(currentAccount).clientUserId;
long dialogId = MessageObject.getSavedDialogId(selfId, messageOwner);
@ -7868,6 +7909,8 @@ public class MessageObject {
if (getDialogId() < 0) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-getDialogId());
channelSignatureProfiles = (chat != null && chat.signature_profiles);
} else {
channelSignatureProfiles = getDialogId() == UserObject.VERIFY;
}
return !isSponsored() && (isFromUser() || isFromGroup() || channelSignatureProfiles || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
}
@ -7889,6 +7932,8 @@ public class MessageObject {
if (getDialogId() < 0) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-getDialogId());
channelSignatureProfiles = (chat != null && chat.signature_profiles);
} else {
channelSignatureProfiles = getDialogId() == UserObject.VERIFY;
}
return !isSponsored() && (isFromChat() && isFromUser() || isFromGroup() || channelSignatureProfiles || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
}
@ -8151,6 +8196,9 @@ public class MessageObject {
} else {
document = media != null ? media.document : null;
}
if (media != null && !media.alt_documents.isEmpty()) {
document = VideoPlayer.getDocumentForThumb(UserConfig.selectedAccount, media);
}
if (document != null) {
return document.size;
}
@ -9478,6 +9526,9 @@ public class MessageObject {
if (type == MessageObject.TYPE_STORY && !isExpiredStory()) {
return true;
}
if (getDialogId() == UserObject.VERIFY) {
return false;
}
if (isSaved) {
if (messageOwner == null || messageOwner.fwd_from == null) return false;
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
@ -9733,6 +9784,13 @@ public class MessageObject {
return null;
}
public Long getForwardedFromId() {
if (messageOwner == null) return null;
if (messageOwner.fwd_from == null) return null;
if (messageOwner.fwd_from.from_id == null) return null;
return DialogObject.getPeerDialogId(messageOwner.fwd_from.from_id);
}
public int getReplyMsgId() {
return messageOwner.reply_to != null ? messageOwner.reply_to.reply_to_msg_id : 0;
}
@ -10400,7 +10458,7 @@ public class MessageObject {
for (int a = 0; a < getDocument().attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = getDocument().attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeAudio) {
if (attribute.duration < 60) {
if (attribute.duration < 5) {
return true;
}
}
@ -10972,4 +11030,21 @@ public class MessageObject {
return 0f;
}
private Boolean videoQualitiesCached;
public TLRPC.Document qualityToSave;
public boolean hasVideoQualities() {
if (videoQualitiesCached == null) {
try {
videoQualitiesCached = messageOwner != null && VideoPlayer.hasQualities(currentAccount, messageOwner.media);
} catch (Exception e) {
FileLog.e(e);
videoQualitiesCached = false;
}
}
return videoQualitiesCached;
}
public boolean isStarGiftAction() {
return messageOwner != null && messageOwner.action instanceof TLRPC.TL_messageActionStarGift;
}
}

View file

@ -35,7 +35,6 @@ import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
@ -70,7 +69,6 @@ import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Business.QuickRepliesController;
import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.ChannelMonetizationLayout;
import org.telegram.ui.ChatActivity;
@ -635,6 +633,7 @@ public class MessagesController extends BaseController implements NotificationCe
public String weatherSearchUsername;
public boolean storyWeatherPreload;
public boolean starsGiftsEnabled;
public boolean stargiftsBlocked;
public long starsPaidReactionAmountMax;
public long starsSubscriptionAmountMax;
public float starsUsdSellRate1000;
@ -695,6 +694,9 @@ public class MessagesController extends BaseController implements NotificationCe
public int chatlistJoinedLimitPremium;
public String storiesPosting;
public String storiesEntities;
public int stargiftsMessageLengthMax;
public int stargiftsConvertPeriodMax;
public boolean videoIgnoreAltDocuments;
public int checkResetLangpack;
public boolean folderTags;
@ -819,7 +821,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
public boolean isPremiumUser(TLRPC.User currentUser) {
return !premiumFeaturesBlocked() && currentUser.premium;
return !premiumFeaturesBlocked() && currentUser.premium && !isSupportUser(currentUser);
}
public boolean didPressTranscribeButtonEnough() {
@ -963,6 +965,7 @@ public class MessagesController extends BaseController implements NotificationCe
public Integer posts_between;
public long loadTime;
public boolean loading;
public boolean faked;
}
private class SendAsPeersInfo {
@ -1547,6 +1550,9 @@ public class MessagesController extends BaseController implements NotificationCe
chatlistInvitesLimitPremium = mainPreferences.getInt("chatlistInvitesLimitPremium", isTest ? 5 : 20);
chatlistJoinedLimitDefault = mainPreferences.getInt("chatlistJoinedLimitDefault", 2);
chatlistJoinedLimitPremium = mainPreferences.getInt("chatlistJoinedLimitPremium", isTest ? 5 : 20);
stargiftsMessageLengthMax = mainPreferences.getInt("stargiftsMessageLengthMax", 255);
stargiftsConvertPeriodMax = mainPreferences.getInt("stargiftsConvertPeriodMax", isTest ? 300 : 90 * 86400);
videoIgnoreAltDocuments = mainPreferences.getBoolean("videoIgnoreAltDocuments", false);
storiesPosting = mainPreferences.getString("storiesPosting", "enabled");
storiesEntities = mainPreferences.getString("storiesEntities", "premium");
storiesExportNopublicLink = mainPreferences.getBoolean("storiesExportNopublicLink", false);
@ -1592,6 +1598,7 @@ public class MessagesController extends BaseController implements NotificationCe
weatherSearchUsername = mainPreferences.getString("weatherSearchUsername", "izweatherbot");
storyWeatherPreload = mainPreferences.getBoolean("storyWeatherPreload", true);
starsGiftsEnabled = mainPreferences.getBoolean("starsGiftsEnabled", true);
stargiftsBlocked = mainPreferences.getBoolean("stargiftsBlocked", true); // !BuildVars.DEBUG_VERSION);
starsPaidReactionAmountMax = mainPreferences.getLong("starsPaidReactionAmountMax", 10_000L);
starsSubscriptionAmountMax = mainPreferences.getLong("starsSubscriptionAmountMax", 2500L);
starsUsdSellRate1000 = mainPreferences.getFloat("starsUsdSellRate1000", 2000);
@ -3698,6 +3705,39 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "stargifts_message_length_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != stargiftsMessageLengthMax) {
stargiftsMessageLengthMax = (int) num.value;
editor.putInt("stargiftsMessageLengthMax", stargiftsMessageLengthMax);
changed = true;
}
}
break;
}
case "stargifts_convert_period_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != stargiftsConvertPeriodMax) {
stargiftsConvertPeriodMax = (int) num.value;
editor.putInt("stargiftsConvertPeriodMax", stargiftsConvertPeriodMax);
changed = true;
}
}
break;
}
case "video_ignore_alt_documents": {
if (value.value instanceof TLRPC.TL_jsonBool) {
TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value;
if (bool.value != videoIgnoreAltDocuments) {
videoIgnoreAltDocuments = bool.value;
editor.putBoolean("videoIgnoreAltDocuments", videoIgnoreAltDocuments);
changed = true;
}
}
break;
}
case "stories_posting": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
@ -4269,6 +4309,17 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "stargifts_blocked": {
if (value.value instanceof TLRPC.TL_jsonBool) {
TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value;
if (bool.value != stargiftsBlocked) {
stargiftsBlocked = bool.value;
editor.putBoolean("stargiftsBlocked", stargiftsBlocked);
changed = true;
}
}
break;
}
case "stars_paid_reaction_amount_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
@ -6814,6 +6865,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
fullUsers.put(user.id, userFull);
getTranslateController().updateDialogFull(user.id);
StarsController.getInstance(currentAccount).invalidateProfileGifts(userFull);
loadingFullUsers.remove(user.id);
loadedFullUsers.put(user.id, System.currentTimeMillis());
String names = user.first_name + user.last_name + UserObject.getPublicUsername(user);
@ -7964,8 +8016,10 @@ public class MessagesController extends BaseController implements NotificationCe
}
TLRPC.UserFull userFull = getUserFull(dialogId);
userFull.profile_photo = photos_photo.photo;
getMessagesStorage().updateUserInfo(userFull, false);
if (userFull != null) {
userFull.profile_photo = photos_photo.photo;
getMessagesStorage().updateUserInfo(userFull, false);
}
getUserConfig().getCurrentUser().photo = user1.photo;
putUser(user1, false);
@ -9161,6 +9215,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (fullUsers.get(user.id) == null) {
fullUsers.put(user.id, info);
getTranslateController().updateDialogFull(user.id);
StarsController.getInstance(currentAccount).invalidateProfileGifts(info);
int index = blockePeers.indexOfKey(user.id);
if (info.blocked) {
@ -17997,6 +18052,8 @@ public class MessagesController extends BaseController implements NotificationCe
message.localType = 1;
if (user != null && !UserObject.isDeleted(user)) {
message.localUserName = UserObject.getFirstName(user);
} else {
message.localUserName = LocaleController.getString(R.string.PushReactStoryHiddenSender);
}
messageObjects.add(message);
getNotificationsController().processNewMessages(messageObjects, true, false, null);
@ -19258,6 +19315,22 @@ public class MessagesController extends BaseController implements NotificationCe
}
public SponsoredMessagesInfo getSponsoredMessages(long dialogId) {
// for (int i = 0; i < sponsoredMessages.size(); ++i) {
// if (sponsoredMessages.valueAt(i).messages != null && !sponsoredMessages.valueAt(i).messages.isEmpty()) {
// SponsoredMessagesInfo info = sponsoredMessages.valueAt(i);
// if (info.faked) {
// return info;
// }
// info.loading = true;
// info.faked = true;
// AndroidUtilities.runOnUIThread(() -> {
// info.loading = false;
// getNotificationCenter().postNotificationName(NotificationCenter.didLoadSponsoredMessages, dialogId, info.messages);
// AndroidUtilities.runOnUIThread(() -> { info.faked = false; }, 500);
// }, 1500);
// return null;
// }
// }
SponsoredMessagesInfo info = sponsoredMessages.get(dialogId);
if (info != null && (info.loading || Math.abs(SystemClock.elapsedRealtime() - info.loadTime) <= 5 * 60 * 1000)) {
return info;
@ -19937,7 +20010,7 @@ public class MessagesController extends BaseController implements NotificationCe
dialogsGroupsOnly.add(d);
} else if (d.id != selfId) {
dialogsUsersOnly.add(d);
if (!UserObject.isReplyUser(d.id)) {
if (!UserObject.isReplyUser(d.id) && d.id != UserObject.VERIFY) {
dialogsForBlock.add(d);
}
}
@ -21842,9 +21915,9 @@ public class MessagesController extends BaseController implements NotificationCe
}
public void openApp(TLRPC.User bot, int classGuid) {
openApp(null, bot, classGuid, null);
openApp(null, bot, null, classGuid, null);
}
public void openApp(BaseFragment _fragment, TLRPC.User bot, int classGuid, Browser.Progress progress) {
public void openApp(BaseFragment _fragment, TLRPC.User bot, String param, int classGuid, Browser.Progress progress) {
if (bot == null) return;
boolean[] cancelled = new boolean[] { false };
@ -21866,7 +21939,7 @@ public class MessagesController extends BaseController implements NotificationCe
fragment = ((ActionBarLayout) fragment.getParentLayout()).getSheetFragment();
}
AndroidUtilities.hideKeyboard(fragment.getFragmentView());
WebViewRequestProps props = WebViewRequestProps.of(currentAccount, bot.id, bot.id, null, null, BotWebViewAttachedSheet.TYPE_WEB_VIEW_BOT_MAIN, 0, false, null, false, null, bot, 0, false);
WebViewRequestProps props = WebViewRequestProps.of(currentAccount, bot.id, bot.id, null, null, BotWebViewAttachedSheet.TYPE_WEB_VIEW_BOT_MAIN, 0, false, null, false, param, bot, 0, false);
if (LaunchActivity.instance != null && LaunchActivity.instance.getBottomSheetTabs() != null && LaunchActivity.instance.getBottomSheetTabs().tryReopenTab(props) != null) {
return;
}
@ -21891,7 +21964,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
TL_bots.TL_botMenuButton btn = (TL_bots.TL_botMenuButton) botInfo[0].menu_button;
AndroidUtilities.hideKeyboard(fragment.getFragmentView());
WebViewRequestProps props = WebViewRequestProps.of(currentAccount, bot.id, bot.id, btn.text, btn.url, BotWebViewAttachedSheet.TYPE_BOT_MENU_BUTTON, 0, false, null, false, null, bot, 0, false);
WebViewRequestProps props = WebViewRequestProps.of(currentAccount, bot.id, bot.id, btn.text, btn.url, BotWebViewAttachedSheet.TYPE_BOT_MENU_BUTTON, 0, false, null, false, param, bot, 0, false);
if (LaunchActivity.instance != null && LaunchActivity.instance.getBottomSheetTabs() != null && LaunchActivity.instance.getBottomSheetTabs().tryReopenTab(props) != null) {
return;
}

View file

@ -105,7 +105,7 @@ public class MessagesStorage extends BaseController {
}
}
public final static int LAST_DB_VERSION = 156;
public final static int LAST_DB_VERSION = 159;
private boolean databaseMigrationInProgress;
public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -726,6 +726,8 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE fact_checks(hash INTEGER PRIMARY KEY, data BLOB, expires INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE popular_bots(uid INTEGER PRIMARY KEY, time INTEGER, offset TEXT);").stepThis().dispose();
database.executeFast("CREATE TABLE star_gifts2(id INTEGER PRIMARY KEY, data BLOB, hash INTEGER, time INTEGER, pos INTEGER);").stepThis().dispose();
database.executeFast("PRAGMA user_version = " + MessagesStorage.LAST_DB_VERSION).stepThis().dispose();
}
@ -1407,6 +1409,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM quick_replies_messages").stepThis().dispose();
database.executeFast("DELETE FROM effects").stepThis().dispose();
database.executeFast("DELETE FROM app_config").stepThis().dispose();
database.executeFast("DELETE FROM star_gifts2").stepThis().dispose();
cursor = database.queryFinalized("SELECT did FROM dialogs WHERE 1");

View file

@ -264,6 +264,9 @@ public class NotificationCenter {
public static final int channelStarsUpdated = totalEvents++;
public static final int webViewResolved = totalEvents++;
public static final int updateAllMessages = totalEvents++;
public static final int starGiftsLoaded = totalEvents++;
public static final int starUserGiftsLoaded = totalEvents++;
public static final int starGiftSoldOut = totalEvents++;
//global
public static final int pushMessagesUpdated = totalEvents++;
@ -543,7 +546,7 @@ public class NotificationCenter {
AndroidUtilities.runOnUIThread(() -> postNotificationName(id, args));
}
public void postNotificationName(int id, Object... args) {
public void postNotificationName(final int id, Object... args) {
boolean allowDuringAnimation = id == startAllHeavyOperations || id == stopAllHeavyOperations || id == didReplacedPhotoInMemCache || id == closeChats || id == invalidateMotionBackground || id == needCheckSystemBarColors;
ArrayList<Integer> expiredIndices = null;
if (!allowDuringAnimation && allowedNotifications.size() > 0) {
@ -592,20 +595,20 @@ public class NotificationCenter {
}
}
SparseArray<Runnable> alreadyPostedRannubles = new SparseArray<>();
SparseArray<Runnable> alreadyPostedRunnubles = new SparseArray<>();
private void postNotificationDebounced(int id, Object[] args) {
int hash = id + (Arrays.hashCode(args) << 16);
if (alreadyPostedRannubles.indexOfKey(hash) >= 0) {
if (alreadyPostedRunnubles.indexOfKey(hash) >= 0) {
//skip
} else {
Runnable runnable = () -> {
postNotificationNameInternal(id, false, args);
alreadyPostedRannubles.remove(hash);
};
alreadyPostedRannubles.put(hash, runnable);
AndroidUtilities.runOnUIThread(runnable, 250);
return;
}
final Runnable runnable = () -> {
postNotificationNameInternal(id, false, args);
alreadyPostedRunnubles.remove(hash);
};
alreadyPostedRunnubles.put(hash, runnable);
AndroidUtilities.runOnUIThread(runnable, 250);
}
private boolean shouldDebounce(int id, Object[] args) {

View file

@ -152,6 +152,7 @@ public class PushListenerController {
buffer.readBytes(strBytes, true);
jsonString = new String(strBytes);
JSONObject json = new JSONObject(jsonString);
// FileLog.d("FCM DATA: " + jsonString);
if (ApplicationLoader.applicationLoaderInstance != null && ApplicationLoader.applicationLoaderInstance.consumePush(currentAccount, json)) {
countDownLatch.countDown();
@ -501,6 +502,12 @@ public class PushListenerController {
message1 = args[1];
break;
}
case "MESSAGE_STARGIFT": {
userName = args[0];
messageText = LocaleController.formatPluralStringComma("NotificationMessageStarGift", Integer.parseInt(args[1]), args[0]);
message1 = LocaleController.formatPluralStringComma("Gift2Notification", Integer.parseInt(args[1]));
break;
}
case "MESSAGE_PAID_MEDIA": {
int stars = Integer.parseInt(args[1]);
messageText = LocaleController.formatPluralString("NotificationMessagePaidMedia", stars, args[0]);

View file

@ -7052,8 +7052,17 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipfile))) {
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) {
if (zipEntry.getName().endsWith(".txt")) {
File newFile = MediaController.createFileInCache(zipEntry.getName(), "txt");
String name = zipEntry.getName();
if (name == null) {
zipEntry = zis.getNextEntry();
continue;
}
int idx = name.lastIndexOf("/");
if (idx >= 0) {
name = name.substring(idx + 1);
}
if (name.endsWith(".txt")) {
File newFile = MediaController.createFileInCache(name, "txt");
path = newFile.getAbsolutePath();
FileOutputStream fos = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];

View file

@ -305,6 +305,7 @@ public class SharedConfig {
public static boolean playOrderReversed;
public static boolean hasCameraCache;
public static boolean showNotificationsForAllAccounts = true;
public static boolean debugVideoQualities = false;
public static int repeatMode;
public static boolean allowBigEmoji;
public static boolean useSystemEmoji;
@ -318,7 +319,6 @@ public class SharedConfig {
public static int emojiInteractionsHintCount;
public static int dayNightThemeSwitchHintCount;
public static int callEncryptionHintDisplayedCount;
public static boolean botTabs3DEffect;
public static TLRPC.TL_help_appUpdate pendingAppUpdate;
public static int pendingAppUpdateBuildVersion;
@ -662,7 +662,7 @@ public class SharedConfig {
photoViewerBlur = preferences.getBoolean("photoViewerBlur", true);
multipleReactionsPromoShowed = preferences.getBoolean("multipleReactionsPromoShowed", false);
callEncryptionHintDisplayedCount = preferences.getInt("callEncryptionHintDisplayedCount", 0);
botTabs3DEffect = preferences.getBoolean("botTabs3DEffect", true);
debugVideoQualities = preferences.getBoolean("debugVideoQualities", false);
loadDebugConfig(preferences);
@ -1092,13 +1092,6 @@ public class SharedConfig {
editor.apply();
}
public static void setBotTabs3DEffect(boolean value) {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("botTabs3DEffect", botTabs3DEffect = value);
editor.apply();
}
public static void toggleLoopStickers() {
LiteMode.toggleFlag(LiteMode.FLAG_ANIMATED_STICKERS_CHAT);
}
@ -1265,6 +1258,14 @@ public class SharedConfig {
editor.apply();
}
public static void toggleDebugVideoQualities() {
debugVideoQualities = !debugVideoQualities;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("debugVideoQualities", debugVideoQualities);
editor.apply();
}
public static void toggleLocalInstantView() {
onlyLocalInstantView = !onlyLocalInstantView;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();

View file

@ -266,7 +266,7 @@ public class UserConfig extends BaseController {
}
private void checkPremiumSelf(TLRPC.User oldUser, TLRPC.User newUser) {
if (oldUser == null || (newUser != null && oldUser.premium != newUser.premium)) {
if (oldUser != null && newUser != null && oldUser.premium != newUser.premium) {
AndroidUtilities.runOnUIThread(() -> {
getMessagesController().updatePremium(newUser.premium);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.currentUserPremiumStatusChanged);
@ -276,6 +276,12 @@ public class UserConfig extends BaseController {
getMediaDataController().loadReactions(false, null);
getMessagesController().getStoriesController().invalidateStoryLimit();
});
} else if (oldUser == null) {
AndroidUtilities.runOnUIThread(() -> {
getMessagesController().updatePremium(newUser.premium);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.currentUserPremiumStatusChanged);
getMediaDataController().loadPremiumPromo(true);
});
}
}
@ -553,10 +559,11 @@ public class UserConfig extends BaseController {
}
public boolean isPremium() {
if (currentUser == null) {
TLRPC.User user = currentUser;
if (user == null) {
return false;
}
return currentUser.premium;
return user.premium;
}
public Long getEmojiStatus() {

View file

@ -19,6 +19,7 @@ public class UserObject {
public static final long REPLY_BOT = 1271266957L;
public static final long ANONYMOUS = 2666000L;
public static final long VERIFY = 489000L;
public static boolean isDeleted(TLRPC.User user) {
return user == null || user instanceof TLRPC.TL_userDeleted_old2 || user instanceof TLRPC.TL_userEmpty || user.deleted;
@ -151,6 +152,9 @@ public class UserObject {
if (emojiStatus == null) {
return null;
}
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked()) {
return null;
}
if (emojiStatus instanceof TLRPC.TL_emojiStatus)
return ((TLRPC.TL_emojiStatus) emojiStatus).document_id;
if (emojiStatus instanceof TLRPC.TL_emojiStatusUntil) {

View file

@ -151,7 +151,10 @@ public class VideoEncodingService extends Service implements NotificationCenter.
return;
}
boolean isGif = videoConvertMessage.messageObject != null && MessageObject.isGifMessage(videoConvertMessage.messageObject.messageOwner);
if (isGif) {
if (videoConvertMessage.foregroundConversion) {
builder.setTicker(LocaleController.getString(R.string.ConvertingVideo));
builder.setContentText(LocaleController.getString(R.string.ConvertingVideo));
} else if (isGif) {
builder.setTicker(LocaleController.getString(R.string.SendingGif));
builder.setContentText(LocaleController.getString(R.string.SendingGif));
} else {

View file

@ -10,6 +10,8 @@ package org.telegram.messenger.secretmedia;
import android.content.Context;
import android.net.Uri;
import android.util.LongSparseArray;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.upstream.AssetDataSource;
@ -94,13 +96,15 @@ public final class ExtendedDefaultDataSource implements DataSource {
int readTimeoutMillis,
boolean allowCrossProtocolRedirects) {
this(
context,
new DefaultHttpDataSource(
userAgent,
connectTimeoutMillis,
readTimeoutMillis,
allowCrossProtocolRedirects,
/* defaultRequestProperties= */ null));
context,
new DefaultHttpDataSource(
userAgent,
connectTimeoutMillis,
readTimeoutMillis,
allowCrossProtocolRedirects,
/* defaultRequestProperties= */ null),
null
);
}
/**
@ -111,68 +115,14 @@ public final class ExtendedDefaultDataSource implements DataSource {
* @param baseDataSource A {@link DataSource} to use for URI schemes other than file, asset and
* content. This {@link DataSource} should normally support at least http(s).
*/
public ExtendedDefaultDataSource(Context context, DataSource baseDataSource) {
public ExtendedDefaultDataSource(Context context, DataSource baseDataSource, LongSparseArray<Uri> mtprotoUris) {
this.context = context.getApplicationContext();
this.baseDataSource = Assertions.checkNotNull(baseDataSource);
transferListeners = new ArrayList<>();
this.mtprotoUris = mtprotoUris;
}
/**
* Constructs a new instance, optionally configured to follow cross-protocol redirects.
*
* @param context A context.
* @param listener An optional listener.
* @param userAgent The User-Agent to use when requesting remote data.
* @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
* to HTTPS and vice versa) are enabled when fetching remote data.
* @deprecated Use {@link #DefaultDataSource(Context, String, boolean)} and {@link
* #addTransferListener(TransferListener)}.
*/
@Deprecated
@SuppressWarnings("deprecation")
public ExtendedDefaultDataSource(
Context context,
@Nullable TransferListener listener,
String userAgent,
boolean allowCrossProtocolRedirects) {
this(context, listener, userAgent, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, allowCrossProtocolRedirects);
}
/**
* Constructs a new instance, optionally configured to follow cross-protocol redirects.
*
* @param context A context.
* @param listener An optional listener.
* @param userAgent The User-Agent to use when requesting remote data.
* @param connectTimeoutMillis The connection timeout that should be used when requesting remote
* data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
* @param readTimeoutMillis The read timeout that should be used when requesting remote data, in
* milliseconds. A timeout of zero is interpreted as an infinite timeout.
* @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
* to HTTPS and vice versa) are enabled when fetching remote data.
* @deprecated Use {@link #DefaultDataSource(Context, String, int, int, boolean)} and {@link
* #addTransferListener(TransferListener)}.
*/
@Deprecated
@SuppressWarnings("deprecation")
public ExtendedDefaultDataSource(
Context context,
@Nullable TransferListener listener,
String userAgent,
int connectTimeoutMillis,
int readTimeoutMillis,
boolean allowCrossProtocolRedirects) {
this(
context,
listener,
new DefaultHttpDataSource(
userAgent,
connectTimeoutMillis,
readTimeoutMillis,
allowCrossProtocolRedirects,
/* defaultRequestProperties= */ null));
}
private final LongSparseArray<Uri> mtprotoUris;
/**
* Constructs a new instance that delegates to a provided {@link DataSource} for URI schemes other
@ -187,8 +137,8 @@ public final class ExtendedDefaultDataSource implements DataSource {
*/
@Deprecated
public ExtendedDefaultDataSource(
Context context, @Nullable TransferListener listener, DataSource baseDataSource) {
this(context, baseDataSource);
Context context, @Nullable TransferListener listener, DataSource baseDataSource, LongSparseArray<Uri> mtprotoUris) {
this(context, baseDataSource, mtprotoUris);
if (listener != null) {
transferListeners.add(listener);
baseDataSource.addTransferListener(listener);
@ -210,14 +160,19 @@ public final class ExtendedDefaultDataSource implements DataSource {
@Override
public long open(DataSpec dataSpec) throws IOException {
Assertions.checkState(dataSource == null);
Uri uri = dataSpec.uri;
if ("mtproto".equals(uri.getScheme())) {
final long docId = Long.parseLong(dataSpec.uri.toString().substring("mtproto:".length()));
dataSpec.uri = uri = mtprotoUris.get(docId);
}
// Choose the correct source for the scheme.
String scheme = dataSpec.uri.getScheme();
if (Util.isLocalFileUri(dataSpec.uri)) {
String uriPath = dataSpec.uri.getPath();
String scheme = uri.getScheme();
if (Util.isLocalFileUri(uri)) {
String uriPath = uri.getPath();
if (uriPath != null && uriPath.startsWith("/android_asset/")) {
dataSource = getAssetDataSource();
} else {
if (dataSpec.uri.getPath().endsWith(".enc")) {
if (uri.getPath().endsWith(".enc")) {
dataSource = getEncryptedFileDataSource();
} else {
dataSource = getFileDataSource();

View file

@ -9,6 +9,8 @@
package org.telegram.messenger.secretmedia;
import android.content.Context;
import android.net.Uri;
import android.util.LongSparseArray;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSource;
@ -53,8 +55,15 @@ public final class ExtendedDefaultDataSourceFactory implements DataSource.Factor
this.baseDataSourceFactory = baseDataSourceFactory;
}
private final LongSparseArray<Uri> mtprotoUris = new LongSparseArray<>();
@Override
public ExtendedDefaultDataSource createDataSource() {
return new ExtendedDefaultDataSource(context, listener, baseDataSourceFactory.createDataSource());
return new ExtendedDefaultDataSource(context, listener, baseDataSourceFactory.createDataSource(), mtprotoUris);
}
public void putDocumentUri(long docId, Uri uri) {
mtprotoUris.put(docId, uri);
}
}

View file

@ -267,6 +267,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
private int scheduleDate;
private TLRPC.InputPeer groupCallPeer;
public boolean hasFewPeers;
public boolean isRtmpStream;
private String joinHash;
private int remoteVideoState = Instance.VIDEO_STATE_INACTIVE;
@ -714,6 +715,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
long chatID = intent.getLongExtra("chat_id", 0);
createGroupCall = intent.getBooleanExtra("createGroupCall", false);
hasFewPeers = intent.getBooleanExtra("hasFewPeers", false);
isRtmpStream = intent.getBooleanExtra("isRtmpStream", false);
joinHash = intent.getStringExtra("hash");
long peerChannelId = intent.getLongExtra("peerChannelId", 0);
long peerChatId = intent.getLongExtra("peerChatId", 0);
@ -1766,6 +1768,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
groupCall.call.version = 1;
groupCall.call.can_start_video = true;
groupCall.call.can_change_join_muted = true;
groupCall.call.rtmp_stream = isRtmpStream;
groupCall.chatId = chat.id;
groupCall.currentAccount = AccountInstance.getInstance(currentAccount);
groupCall.setSelfPeer(groupCallPeer);
@ -1779,6 +1782,9 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
req.schedule_date = scheduleDate;
req.flags |= 2;
}
if (isRtmpStream) {
req.flags |= 4;
}
groupCallBottomSheetLatch = new CountDownLatch(1);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
if (response != null) {

View file

@ -7,14 +7,9 @@ import android.content.pm.PackageInfo;
import android.os.AsyncTask;
import android.os.Build;
import android.os.SystemClock;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Base64;
import android.util.LongSparseArray;
import android.util.SparseIntArray;
import com.google.android.exoplayer2.util.Log;
import com.google.android.gms.tasks.Task;
import com.google.android.play.core.integrity.IntegrityManager;
import com.google.android.play.core.integrity.IntegrityManagerFactory;
@ -39,20 +34,11 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.PushListenerController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.StatsController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.LoginActivity;
import org.telegram.ui.PremiumPreviewFragment;
import java.io.ByteArrayOutputStream;
import java.io.File;
@ -364,14 +350,15 @@ public class ConnectionsManager extends BaseController {
startRequestTime = System.currentTimeMillis();
}
long finalStartRequestTime = startRequestTime;
listen(requestToken, (response, errorCode, errorText, networkType, timestamp, requestMsgId) -> {
listen(requestToken, (response, errorCode, errorText, networkType, timestamp, requestMsgId, dcId) -> {
try {
TLObject resp = null;
TLRPC.TL_error error = null;
int responseSize = 0;
if (response != 0) {
NativeByteBuffer buff = NativeByteBuffer.wrap(response);
buff.reused = true;
responseSize = buff.limit();
int magic = buff.readInt32(true);
try {
resp = object.deserializeResponse(buff, magic, true);
@ -475,14 +462,14 @@ public class ConnectionsManager extends BaseController {
}
}
public static void onRequestComplete(int currentAccount, int requestToken, long response, int errorCode, String errorText, int networkType, long timestamp, long requestMsgId) {
public static void onRequestComplete(int currentAccount, int requestToken, long response, int errorCode, String errorText, int networkType, long timestamp, long requestMsgId, int dcId) {
ConnectionsManager connectionsManager = getInstance(currentAccount);
if (connectionsManager == null) return;
RequestCallbacks callbacks = connectionsManager.requestCallbacks.get(requestToken);
connectionsManager.requestCallbacks.remove(requestToken);
if (callbacks != null) {
if (callbacks.onComplete != null) {
callbacks.onComplete.run(response, errorCode, errorText, networkType, timestamp, requestMsgId);
callbacks.onComplete.run(response, errorCode, errorText, networkType, timestamp, requestMsgId, dcId);
}
FileLog.d("{rc} onRequestComplete(" + currentAccount + ", " + requestToken + "): found request " + requestToken + ", " + connectionsManager.requestCallbacks.size() + " requests' callbacks");
} else {
@ -1477,7 +1464,7 @@ public class ConnectionsManager extends BaseController {
if (UserConfig.selectedAccount != currentAccount) {
return;
}
FileLoader.getInstance(currentAccount).getFileLoaderQueue().postRunnable(() -> {
AndroidUtilities.runOnUIThread(() -> {
boolean updated = false;
if (isUpload) {
FileUploadOperation operation = FileLoader.getInstance(currentAccount).findUploadOperationByRequestToken(requestToken);
@ -1493,11 +1480,9 @@ public class ConnectionsManager extends BaseController {
}
}
final boolean finalUpdated = updated;
AndroidUtilities.runOnUIThread(() -> {
if (finalUpdated) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.premiumFloodWaitReceived);
}
});
if (finalUpdated) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.premiumFloodWaitReceived);
}
});
});
}

View file

@ -1,5 +1,5 @@
package org.telegram.tgnet;
public interface RequestDelegateInternal {
void run(long response, int errorCode, String errorText, int networkType, long timestamp, long requestMsgId);
void run(long response, int errorCode, String errorText, int networkType, long timestamp, long requestMsgId, int dcId);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1468,15 +1468,15 @@ public class TL_stories {
}
public static class TL_stories_report extends TLObject {
public static final int constructor = 0x1923fa8c;
public static final int constructor = 0x19d8eb45;
public TLRPC.InputPeer peer;
public ArrayList<Integer> id = new ArrayList<>();
public TLRPC.ReportReason reason;
public byte[] option;
public String message;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
return TLRPC.ReportResult.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
@ -1488,7 +1488,7 @@ public class TL_stories {
for (int a = 0; a < count; a++) {
stream.writeInt32(id.get(a));
}
reason.serializeToStream(stream);
stream.writeByteArray(option);
stream.writeString(message);
}
}

View file

@ -644,20 +644,6 @@ public class ActionBar extends FrameLayout {
return actionMode;
}
public void onDrawCrossfadeBackground(Canvas canvas) {
if (blurredBackground && actionBarColor != Color.TRANSPARENT) {
rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
blurScrimPaint.setColor(actionBarColor);
contentView.drawBlurRect(canvas, getY(), rectTmp, blurScrimPaint, true);
} else {
Drawable drawable = getBackground();
if (drawable != null) {
drawable.setBounds(0, 0, getWidth(), getHeight());
drawable.draw(canvas);
}
}
}
public void onDrawCrossfadeContent(Canvas canvas, boolean front, boolean hideBackDrawable, float progress) {
for (int i = 0; i < getChildCount(); i++) {
View ch = getChildAt(i);

View file

@ -619,7 +619,7 @@ public class ActionBarMenuItem extends FrameLayout {
return cell;
}
public ActionBarMenuSubItem addSwipeBackItem(int icon, Drawable iconDrawable, String text, View viewToSwipeBack) {
public ActionBarMenuSubItem addSwipeBackItem(int icon, Drawable iconDrawable, String text, View viewToSwipeBack) {
createPopupLayout();
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(getContext(), false, false, false, resourcesProvider);
@ -2536,11 +2536,11 @@ public class ActionBarMenuItem extends FrameLayout {
lazyList.clear();
}
public static ActionBarMenuSubItem addItem(ActionBarPopupWindow.ActionBarPopupWindowLayout windowLayout, int icon, CharSequence text, boolean needCheck, Theme.ResourcesProvider resourcesProvider) {
public static ActionBarMenuSubItem addItem(ViewGroup windowLayout, int icon, CharSequence text, boolean needCheck, Theme.ResourcesProvider resourcesProvider) {
return addItem(false, false, windowLayout, icon, text, needCheck, resourcesProvider);
}
public static ActionBarMenuSubItem addItem(boolean first, boolean last, ActionBarPopupWindow.ActionBarPopupWindowLayout windowLayout, int icon, CharSequence text, boolean needCheck, Theme.ResourcesProvider resourcesProvider) {
public static ActionBarMenuSubItem addItem(boolean first, boolean last, ViewGroup windowLayout, int icon, CharSequence text, boolean needCheck, Theme.ResourcesProvider resourcesProvider) {
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(windowLayout.getContext(), needCheck, first, last, resourcesProvider);
cell.setTextAndIcon(text, icon);
cell.setMinimumWidth(AndroidUtilities.dp(196));

View file

@ -156,7 +156,12 @@ public class ActionBarMenuSubItem extends FrameLayout {
}
textView.setLayoutParams(layoutParams);
setPadding(dp(LocaleController.isRTL ? 8 : 18), 0, dp(LocaleController.isRTL ? 18 : 8), 0);
rightIcon.setImageResource(icon);
if (icon == 0) {
rightIcon.setVisibility(View.GONE);
} else {
rightIcon.setVisibility(View.VISIBLE);
rightIcon.setImageResource(icon);
}
}
public void setTextAndIcon(CharSequence text, int icon) {

View file

@ -43,6 +43,7 @@ import org.telegram.messenger.AnimationNotificationsLocker;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.PopupSwipeBackLayout;

View file

@ -102,6 +102,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
private boolean[] shadowVisibility = new boolean[2];
private AnimatorSet[] shadowAnimation = new AnimatorSet[2];
private int customViewOffset = 12;
private boolean withCancelDialog;
private int dialogButtonColorKey = Theme.key_dialogButton;
@ -290,6 +291,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
shadowDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY));
shadowDrawable.getPadding(backgroundPaddings);
}
withCancelDialog = progressViewStyle == ALERT_TYPE_SPINNER;
progressViewStyle = progressStyle;
}
@ -313,6 +315,10 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
shownAt = System.currentTimeMillis();
}
public void setCancelDialog(boolean enable) {
withCancelDialog = enable;
}
public class AlertDialogView extends LinearLayout {
public AlertDialogView(Context context) {
super(context);
@ -322,7 +328,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override
public boolean onTouchEvent(MotionEvent event) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
if (withCancelDialog) {
showCancelAlert();
return false;
}
@ -331,7 +337,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
if (withCancelDialog) {
showCancelAlert();
return false;
}
@ -1218,7 +1224,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
}
private void showCancelAlert() {
public void showCancelAlert() {
if (!canCacnel || cancelDialog != null) {
return;
}

View file

@ -1434,7 +1434,7 @@ public class BottomSheet extends Dialog implements BaseFragment.AttachedSheet {
}
backDrawable.setAlpha(0);
layoutCount = 2;
containerView.setTranslationY((Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight * (1f - hideSystemVerticalInsetsProgress) : 0) + containerView.getMeasuredHeight() + (scrollNavBar ? getBottomInset() : 0));
containerView.setTranslationY((Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight * (1f - hideSystemVerticalInsetsProgress) : 0) + containerView.getMeasuredHeight() + (scrollNavBar ? Math.max(0, Math.min(AndroidUtilities.navigationBarHeight, getBottomInset())) : 0));
long delay = openNoDelay ? 0 : 150;
if (waitingKeyboard) {
delay = 500;
@ -1565,7 +1565,7 @@ public class BottomSheet extends Dialog implements BaseFragment.AttachedSheet {
containerView.setAlpha(0);
containerView.setTranslationY(0);
} else {
containerView.setTranslationY(getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? getBottomInset() : 0));
containerView.setTranslationY(getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? Math.max(0, Math.min(AndroidUtilities.navigationBarHeight, getBottomInset())) : 0));
}
currentSheetAnimationType = 1;
if (navigationBarAnimation != null) {
@ -1709,7 +1709,7 @@ public class BottomSheet extends Dialog implements BaseFragment.AttachedSheet {
currentSheetAnimationType = 2;
currentSheetAnimation = new AnimatorSet();
currentSheetAnimation.playTogether(
ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? getBottomInset() : 0)),
ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? Math.max(0, Math.min(AndroidUtilities.navigationBarHeight, getBottomInset())) : 0)),
ObjectAnimator.ofInt(backDrawable, AnimationProperties.COLOR_DRAWABLE_ALPHA, 0)
);
currentSheetAnimation.setDuration(cellType == Builder.CELL_TYPE_CALL ? 330 : 180);
@ -1849,7 +1849,7 @@ public class BottomSheet extends Dialog implements BaseFragment.AttachedSheet {
animators.add(ObjectAnimator.ofFloat(containerView, View.TRANSLATION_X, AndroidUtilities.dp(48)));
animators.add(ObjectAnimator.ofFloat(containerView, View.ALPHA, 0));
} else {
animators.add(ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, getContainerViewHeight() + (forceKeyboardOnDismiss ? lastKeyboardHeight : keyboardHeight) + AndroidUtilities.dp(10) + (scrollNavBar ? getBottomInset() : 0)));
animators.add(ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, getContainerViewHeight() + (forceKeyboardOnDismiss ? lastKeyboardHeight : keyboardHeight) + AndroidUtilities.dp(10) + (scrollNavBar ? Math.max(0, Math.min(AndroidUtilities.navigationBarHeight, getBottomInset())) : 0)));
}
}
animators.add(ObjectAnimator.ofInt(backDrawable, AnimationProperties.COLOR_DRAWABLE_ALPHA, 0));
@ -1942,7 +1942,7 @@ public class BottomSheet extends Dialog implements BaseFragment.AttachedSheet {
} else if (transitionFromRight) {
t = containerView.getAlpha();
} else {
final float fullHeight = getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? getBottomInset() : 0);
final float fullHeight = getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? Math.max(0, Math.min(AndroidUtilities.navigationBarHeight, getBottomInset())) : 0);
t = Utilities.clamp01(1f - containerView.getTranslationY() / fullHeight);
}
return ColorUtils.blendARGB(color, navBarColor, t);

View file

@ -19,6 +19,7 @@ import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.LaunchActivity;
@ -139,14 +140,22 @@ public class BottomSheetTabDialog extends Dialog {
public void attach() {
if (attached) return;
attached = true;
super.show();
try {
super.show();
} catch (Exception e) {
FileLog.e(e);
}
}
public void detach() {
sheet.setDialog(null);
if (!attached) return;
attached = false;
super.dismiss();
try {
super.dismiss();
} catch (Exception e) {
FileLog.e(e);
}
}
@Override

View file

@ -382,11 +382,11 @@ public class BottomSheetTabsOverlay extends FrameLayout {
}
public float getScrollWindow() {
return Math.min(SharedConfig.botTabs3DEffect ? 3 : 6, getScrollRange());
return Math.min(3, getScrollRange());
}
public float getScrollWindow(boolean animated) {
return Math.min(SharedConfig.botTabs3DEffect ? 3 : 6, getScrollRange(animated));
return Math.min(3, getScrollRange(animated));
}
public float getScrollMin() {
@ -522,11 +522,17 @@ public class BottomSheetTabsOverlay extends FrameLayout {
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
sheet.getWindowView().setDrawingFromOverlay(false);
View view = tab.webView != null ? tab.webView : tab.view2;
if (view != null && tab.previewBitmap == null && tab.viewWidth > 0 && tab.viewHeight > 0) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
renderHardwareViewToBitmap(view, -tab.viewScroll, b -> tab.previewBitmap = b);
renderHardwareViewToBitmap(view, -tab.viewScroll, b -> {
tab.previewBitmap = b;
sheet.getWindowView().setDrawingFromOverlay(false);
sheet.release();
});
dismissingSheet = null;
invalidate();
return;
} else {
tab.previewBitmap = Bitmap.createBitmap(tab.viewWidth, tab.viewHeight, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tab.previewBitmap);
@ -534,6 +540,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
view.draw(canvas);
}
}
sheet.getWindowView().setDrawingFromOverlay(false);
sheet.release();
dismissingSheet = null;
invalidate();
@ -796,17 +803,10 @@ public class BottomSheetTabsOverlay extends FrameLayout {
float alpha = 1f;
float top, bottom, y;
if (SharedConfig.botTabs3DEffect) {
top = paddingTop + dp(6) * Math.min(5, position);
bottom = thisHeight - paddingBottom - height * .26f;// - dp(6) * Math.min(5, count - position);
y = top + (bottom - top) * scroll;
alpha = 1f; // Utilities.clamp(oscrollT * 4f + 1f, 1f, 0f);
} else {
top = paddingTop + dp(20) * ((float) Math.pow(1.1f, position) - 1f);
bottom = thisHeight - paddingBottom - height * .26f;
y = top + (bottom - top) * (float) (Math.pow(scrollT, 2));
y = Math.min(y, thisHeight);
}
top = paddingTop + dp(6) * Math.min(5, position);
bottom = thisHeight - paddingBottom - height * .26f;// - dp(6) * Math.min(5, count - position);
y = top + (bottom - top) * scroll;
alpha = 1f; // Utilities.clamp(oscrollT * 4f + 1f, 1f, 0f);
if (alpha <= 0) continue;
@ -831,65 +831,49 @@ public class BottomSheetTabsOverlay extends FrameLayout {
canvas.save();
tab.clickBounds.set(rect2);
if (SharedConfig.botTabs3DEffect) {
Canvas tabCanvas = canvas;
tab.matrix.reset();
final int p = 0;
final float Sh = 1f;
tab.src[0] = rect2.left;
tab.src[1] = rect2.top;
tab.src[2] = rect2.right;
tab.src[3] = rect2.top;
tab.src[4] = rect2.right;
tab.src[5] = rect2.top + rect2.height() * Sh;
tab.src[6] = rect2.left;
tab.src[7] = rect2.top + rect2.height() * Sh;
Canvas tabCanvas = canvas;
tab.matrix.reset();
tab.dst[0] = rect2.left;
tab.dst[1] = rect2.top - dp(p);
tab.dst[2] = rect2.right;
tab.dst[3] = rect2.top - dp(p);
final float s1 = .83f, s2 = .6f;
tab.dst[4] = rect2.centerX() + rect2.width() / 2f * lerp(1f, s1, tabOpen * (1f - opening));
tab.dst[5] = rect2.top - dp(p) + (rect2.height() * Sh + dp(p + p)) * lerp(1f, s2, tabOpen * (1f - opening));
tab.dst[6] = rect2.centerX() - rect2.width() / 2f * lerp(1f, s1, tabOpen * (1f - opening));
tab.dst[7] = rect2.top - dp(p) + (rect2.height() * Sh + dp(p + p)) * lerp(1f, s2, tabOpen * (1f - opening));
final int p = 0;
final float Sh = 1f;
tab.src[0] = rect2.left;
tab.src[1] = rect2.top;
tab.src[2] = rect2.right;
tab.src[3] = rect2.top;
tab.src[4] = rect2.right;
tab.src[5] = rect2.top + rect2.height() * Sh;
tab.src[6] = rect2.left;
tab.src[7] = rect2.top + rect2.height() * Sh;
tab.matrix.setPolyToPoly(tab.src, 0, tab.dst, 0, 4);
tabCanvas.concat(tab.matrix);
tab.dst[0] = rect2.left;
tab.dst[1] = rect2.top - dp(p);
tab.dst[2] = rect2.right;
tab.dst[3] = rect2.top - dp(p);
final float s1 = .83f, s2 = .6f;
tab.dst[4] = rect2.centerX() + rect2.width() / 2f * lerp(1f, s1, tabOpen * (1f - opening));
tab.dst[5] = rect2.top - dp(p) + (rect2.height() * Sh + dp(p + p)) * lerp(1f, s2, tabOpen * (1f - opening));
tab.dst[6] = rect2.centerX() - rect2.width() / 2f * lerp(1f, s1, tabOpen * (1f - opening));
tab.dst[7] = rect2.top - dp(p) + (rect2.height() * Sh + dp(p + p)) * lerp(1f, s2, tabOpen * (1f - opening));
tab.draw(
tabCanvas,
rect2,
drawSimple,
tab.tabDrawable == openingTab ? 1f : lerp(tab.tabDrawable.getAlpha(), alpha, openProgress),
tab.tabDrawable == openingTab ? 1f : tabOpen * (1f - opening),
opening,
lerp(clamp01(position - count + 2),1f, clamp01((tabOpen - .1f) / .8f))
);
tab.matrix.setPolyToPoly(tab.src, 0, tab.dst, 0, 4);
tabCanvas.concat(tab.matrix);
if (openingSheet != null && tab.tabDrawable == openingTab) {
openingSheet.getWindowView().drawInto(canvas, rect2, 1f, rect2, opening, true);
}
tab.draw(
tabCanvas,
rect2,
drawSimple,
tab.tabDrawable == openingTab ? 1f : lerp(tab.tabDrawable.getAlpha(), alpha, openProgress),
tab.tabDrawable == openingTab ? 1f : tabOpen * (1f - opening),
opening,
lerp(clamp01(position - count + 2),1f, clamp01((tabOpen - .1f) / .8f))
);
canvas.restore();
} else {
final float s = lerp(
1f,
lerp(
lerp(1f, 1f - Utilities.clamp(count * .1f, .5f, .25f), 1f - scrollT),
Math.min(1, (float) Math.pow(0.7f, 1f - oscrollT)),
Utilities.clamp(count - 3, 1, 0)
),
openProgress
);
canvas.scale(s, s, rect2.centerX(), rect2.top);
scaleRect(tab.clickBounds, s, rect.centerX(), rect2.top);
tab.draw(canvas, rect2, drawSimple, lerp(tab.tabDrawable.getAlpha(), 1f, openProgress), open, 0f, lerp(clamp01(position - count + 2), 1f, clamp01((open - .1f) / .8f)));
canvas.restore();
if (openingSheet != null && tab.tabDrawable == openingTab) {
openingSheet.getWindowView().drawInto(canvas, rect2, 1f, rect2, opening, true);
}
canvas.restore();
}
canvas.save();
if (gradientClip == null) {
@ -1019,10 +1003,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
if (alpha <= 0)
return;
float tabScaleY = 1f;
if (SharedConfig.botTabs3DEffect) {
tabScaleY = lerp(1f, 1.3f, expandProgress * (1f - openingProgress));
}
float tabScaleY = lerp(1f, 1.3f, expandProgress * (1f - openingProgress));
final float tabTranslateY = openingProgress * (AndroidUtilities.statusBarHeight + ActionBar.getCurrentActionBarHeight() - dp(50));
canvas.save();

View file

@ -89,7 +89,7 @@ public class DrawerLayoutContainer extends FrameLayout {
private float drawerPosition;
private boolean drawerOpened;
private boolean allowDrawContent = true;
public boolean allowDrawContent = true;
private boolean firstLayout = true;

View file

@ -3404,6 +3404,9 @@ public class Theme {
public static final int key_dialogEmptyText = colorsCount++;
public static final int key_dialogSwipeRemove = colorsCount++;
public static final int key_dialogReactionMentionBackground = colorsCount++;
public static final int key_dialogCardShadow = colorsCount++;
public static final int key_dialogGiftsBackground = colorsCount++;
public static final int key_dialogGiftsTabText = colorsCount++;
public static final int key_windowBackgroundWhite = colorsCount++;
public static final int key_windowBackgroundUnchecked = colorsCount++;
@ -3950,6 +3953,7 @@ public class Theme {
public static final int key_voipgroup_unmuteButton = colorsCount++;
public static final int key_voipgroup_unmuteButton2 = colorsCount++;
public static final int key_voipgroup_disabledButton = colorsCount++;
public static final int key_voipgroup_rtmpButton = colorsCount++;
public static final int key_voipgroup_disabledButtonActive = colorsCount++;
public static final int key_voipgroup_disabledButtonActiveScrolled = colorsCount++;
public static final int key_voipgroup_connectingProgress = colorsCount++;
@ -4259,6 +4263,8 @@ public class Theme {
fallbackKeys.put(key_iv_backgroundGray, key_windowBackgroundGray);
fallbackKeys.put(key_iv_navigationBackground, key_windowBackgroundGray);
fallbackKeys.put(key_iv_ab_progress, key_featuredStickers_addButton);
fallbackKeys.put(key_dialogGiftsBackground, key_windowBackgroundGray);
fallbackKeys.put(key_dialogGiftsTabText, key_windowBackgroundWhiteGrayText2);
fallbackKeys.put(key_chat_inQuote, key_featuredStickers_addButtonPressed);
fallbackKeys.put(key_chat_outQuote, key_chat_outReplyLine);
fallbackKeys.put(key_chat_outReplyLine2, key_chat_outReplyLine);
@ -4473,6 +4479,7 @@ public class Theme {
themeAccentExclusionKeys.add(key_voipgroup_leaveButtonScrolled);
themeAccentExclusionKeys.add(key_voipgroup_connectingProgress);
themeAccentExclusionKeys.add(key_voipgroup_disabledButton);
themeAccentExclusionKeys.add(key_voipgroup_rtmpButton);
themeAccentExclusionKeys.add(key_voipgroup_disabledButtonActive);
themeAccentExclusionKeys.add(key_voipgroup_disabledButtonActiveScrolled);
themeAccentExclusionKeys.add(key_voipgroup_unmuteButton);

View file

@ -63,6 +63,9 @@ public class ThemeColors {
defaultColors[key_dialogEmptyText] = 0xff8c9094;
defaultColors[key_dialogSwipeRemove] = 0xffe56555;
defaultColors[key_dialogReactionMentionBackground] = 0xffF05459;
defaultColors[key_dialogCardShadow] = 0x30999999;
defaultColors[key_dialogGiftsBackground] = 0xffF5F6F7;
defaultColors[key_dialogGiftsTabText] = 0xFF56595C;
defaultColors[key_windowBackgroundWhite] = 0xffffffff;
defaultColors[key_windowBackgroundUnchecked] = 0xff9da7b1;
@ -696,6 +699,7 @@ public class ThemeColors {
defaultColors[key_voipgroup_leaveButtonScrolled] = 0x82D14D54;
defaultColors[key_voipgroup_connectingProgress] = 0xff28BAFF;
defaultColors[key_voipgroup_disabledButton] = 0xff1C2229;
defaultColors[key_voipgroup_rtmpButton] = 0xff2a3853;
defaultColors[key_voipgroup_disabledButtonActive] = 0xff2C3A45;
defaultColors[key_voipgroup_disabledButtonActiveScrolled] = 0x8277A1FC;
defaultColors[key_voipgroup_unmuteButton] = 0xff539EF8;
@ -1365,6 +1369,7 @@ public class ThemeColors {
colorKeysMap.put(key_voipgroup_unmuteButton, "voipgroup_unmuteButton");
colorKeysMap.put(key_voipgroup_unmuteButton2, "voipgroup_unmuteButton2");
colorKeysMap.put(key_voipgroup_disabledButton, "voipgroup_disabledButton");
colorKeysMap.put(key_voipgroup_rtmpButton, "voipgroup_rtmpButton");
colorKeysMap.put(key_voipgroup_disabledButtonActive, "voipgroup_disabledButtonActive");
colorKeysMap.put(key_voipgroup_disabledButtonActiveScrolled, "voipgroup_disabledButtonActiveScrolled");
colorKeysMap.put(key_voipgroup_connectingProgress, "voipgroup_connectingProgress");
@ -1550,6 +1555,9 @@ public class ThemeColors {
colorKeysMap.put(key_iv_navigationBackground, "iv_navigationBackground");
colorKeysMap.put(key_iv_ab_progress, "iv_ab_progress");
colorKeysMap.put(key_reactionStarSelector, "reactionStarSelector");
colorKeysMap.put(key_dialogCardShadow, "dialogCardShadow");
colorKeysMap.put(key_dialogGiftsBackground, "dialogGiftsBackground");
colorKeysMap.put(key_dialogGiftsTabText, "dialogGiftsTabText");
return colorKeysMap;
}

View file

@ -66,7 +66,7 @@ public class ContactsAdapter extends RecyclerListView.SectionsAdapter {
private int sortType;
private boolean isChannel;
private boolean disableSections;
private boolean isEmpty;
public boolean isEmpty;
public boolean hasStories;
public ArrayList<TL_stories.PeerStories> userStories = new ArrayList<>();

View file

@ -1778,9 +1778,11 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
int type = holder.getItemViewType();
if (type == 4) {
StickerCell stickerCell = (StickerCell) holder.itemView;
StickerResult result = stickers.get(position);
stickerCell.setSticker(result.sticker, result.parent);
stickerCell.setClearsInputField(true);
if (position >= 0 && position < stickers.size()) {
StickerResult result = stickers.get(position);
stickerCell.setSticker(result.sticker, result.parent);
stickerCell.setClearsInputField(true);
}
} else if (type == 3) {
TextView textView = (TextView) holder.itemView;
TLRPC.Chat chat = parentFragment.getCurrentChat();
@ -1808,7 +1810,9 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
if (hasTop) {
position--;
}
((ContextLinkCell) holder.itemView).setLink(searchResultBotContext.get(position), foundContextBot, contextMedia, position != searchResultBotContext.size() - 1, hasTop && position == 0, "gif".equals(searchingContextUsername));
if (position >= 0 && position < searchResultBotContext.size()) {
((ContextLinkCell) holder.itemView).setLink(searchResultBotContext.get(position), foundContextBot, contextMedia, position != searchResultBotContext.size() - 1, hasTop && position == 0, "gif".equals(searchingContextUsername));
}
}
} else {
MentionCell cell = (MentionCell) holder.itemView;
@ -1819,12 +1823,14 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
} else if (object instanceof TLRPC.Chat) {
cell.setChat((TLRPC.Chat) object);
}
} else if (searchResultHashtags != null) {
} else if (searchResultHashtags != null && position >= 0 && position < searchResultHashtags.size()) {
cell.setText(searchResultHashtags.get(position));
} else if (searchResultSuggestions != null) {
} else if (searchResultSuggestions != null && position >= 0 && position < searchResultSuggestions.size()) {
cell.setEmojiSuggestion(searchResultSuggestions.get(position));
} else if (searchResultCommands != null) {
cell.setBotCommand(searchResultCommands.get(position), searchResultCommandsHelp.get(position), searchResultCommandsUsers != null ? searchResultCommandsUsers.get(position) : null);
} else if (searchResultCommands != null && position >= 0 && position < searchResultCommands.size()) {
final String help = searchResultCommandsHelp != null && position >= 0 && position < searchResultCommandsHelp.size() ? searchResultCommandsHelp.get(position) : null;
final TLRPC.User user = searchResultCommandsUsers != null && position >= 0 && position < searchResultCommandsUsers.size() ? searchResultCommandsUsers.get(position) : null;
cell.setBotCommand(searchResultCommands.get(position), help, user);
}
cell.setDivider(USE_DIVIDERS && (isReversed ? position > 0 : position < getItemCount() - 1));
}

View file

@ -174,7 +174,7 @@ public class BusinessIntroActivity extends UniversalFragment implements Notifica
previewContainer.addView(previewBackground, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
previewContainer.addView(greetingsView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 42, 18, 42, 18));
titleEdit = new EditTextCell(context, getString(R.string.BusinessIntroTitleHint), false, getMessagesController().introTitleLengthLimit, resourceProvider) {
titleEdit = new EditTextCell(context, getString(R.string.BusinessIntroTitleHint), false, false, getMessagesController().introTitleLengthLimit, resourceProvider) {
@Override
protected void onTextChanged(CharSequence newText) {
greetingsView.setPreview(titleEdit.getText().toString(), messageEdit.getText().toString());
@ -193,7 +193,7 @@ public class BusinessIntroActivity extends UniversalFragment implements Notifica
titleEdit.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
titleEdit.setDivider(true);
titleEdit.hideKeyboardOnEnter();
messageEdit = new EditTextCell(context, getString(R.string.BusinessIntroMessageHint), true, getMessagesController().introDescriptionLengthLimit, resourceProvider) {
messageEdit = new EditTextCell(context, getString(R.string.BusinessIntroMessageHint), true, false, getMessagesController().introDescriptionLengthLimit, resourceProvider) {
@Override
protected void onTextChanged(CharSequence newText) {
greetingsView.setPreview(titleEdit.getText().toString(), messageEdit.getText().toString());

View file

@ -10,6 +10,7 @@ package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.dpf2;
import static org.telegram.messenger.AndroidUtilities.lerp;
import static org.telegram.messenger.LocaleController.getString;
import android.animation.Animator;
@ -186,6 +187,7 @@ import org.telegram.ui.Components.URLSpanMono;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import org.telegram.ui.Components.VideoForwardDrawable;
import org.telegram.ui.Components.VideoPlayer;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.Components.spoilers.SpoilerEffect2;
import org.telegram.ui.GradientClip;
@ -734,12 +736,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private final static int DOCUMENT_ATTACH_TYPE_STORY = 10;
private class BotButton {
private int x;
private float x;
private int y;
private int width;
private float width;
private int height;
private int positionFlags;
private StaticLayout title;
private Text title;
private TLRPC.KeyboardButton button;
private TLRPC.TL_reactionCount reaction;
private int angle;
@ -2537,6 +2539,22 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (drawPhotoImage && currentMessageObject.sponsoredMedia != null && photoImage.isInsideImage(x, y) || drawPhotoImage && drawImageButton && buttonState != -1 && (!checkOnlyButtonPressed && photoImage.isInsideImage(x, y) || x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE)) {
buttonPressed = 1;
invalidate();
if (currentMessageObject.sponsoredMedia != null && (MessageObject.isGifDocument(currentMessageObject.sponsoredMedia.document) || currentMessageObject.sponsoredMedia.photo != null)) {
if (Build.VERSION.SDK_INT >= 21) {
if (selectorDrawable[0] != null && selectorDrawable[0].getBounds().contains(x, y)) {
selectorDrawable[0].setHotspot(x, y);
selectorDrawable[0].setState(pressedState);
}
if (linkPreviewSelector != null && linkPreviewSelector.getBounds().contains(x, y)) {
linkPreviewSelector.setHotspot(x, y);
linkPreviewSelector.setState(pressedState);
}
setInstantButtonPressed(true);
}
if (linkPreviewBounce != null) {
linkPreviewBounce.setPressed(true);
}
}
return true;
} else {
instantPressed = true;
@ -3788,6 +3806,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
boolean result = false;
if (event.getAction() == MotionEvent.ACTION_DOWN) {
final int widthForButtons = getWidthForButtons();
int addX;
if (currentMessageObject.isOutOwner()) {
addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
@ -3797,14 +3816,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
for (int a = 0; a < botButtons.size(); a++) {
BotButton button = botButtons.get(a);
int y2 = button.y + layoutHeight - AndroidUtilities.dp(2);
if (x >= button.x + addX && x <= button.x + addX + button.width && y >= y2 && y <= y2 + button.height) {
if (x >= button.x * widthForButtons + addX && x <= button.x * widthForButtons + addX + button.width * widthForButtons && y >= y2 && y <= y2 + button.height) {
pressedBotButton = a;
invalidateOutbounds();
result = true;
if (button.selectorDrawable == null) {
button.selectorDrawable = Theme.createRadSelectorDrawable(getThemedColor(Theme.key_chat_serviceBackgroundSelector), 6, 6);
button.selectorDrawable.setCallback(this);
button.selectorDrawable.setBounds(button.x + addX, y2, button.x + addX + button.width, y2 + button.height);
button.selectorDrawable.setBounds((int) (button.x * widthForButtons) + addX, y2, (int) (button.x * widthForButtons) + addX + (int) (button.width * widthForButtons), y2 + button.height);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
button.selectorDrawable.setHotspot(x, y);
@ -5418,7 +5437,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (messageObject != null && !messageObject.mediaExists) {
int canDownload = DownloadController.getInstance(currentAccount).canDownloadMediaType(messageObject);
TLRPC.Document document = messageObject.getDocument();
boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document);
boolean loadDocumentFromImageReceiver = MessageObject.isStickerDocument(document) || MessageObject.isAnimatedStickerDocument(document, true) || MessageObject.isGifDocument(document) || MessageObject.isRoundVideoDocument(document) || messageObject.hasVideoQualities();
if (!loadDocumentFromImageReceiver && !isSmallImage) {
TLRPC.PhotoSize photo = document == null ? FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize()) : null;
if (canDownload == 2 || canDownload == 1 && messageObject.isVideo()) {
@ -8877,7 +8896,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
w -= AndroidUtilities.dp(9);
}
if (((isChat || m.isRepostPreview) && !isThreadPost && !m.isOutOwner() || m.forceAvatar) && m.needDrawAvatar() && (rowPosition == null || rowPosition.edge)) {
if (((isChat || m.isRepostPreview) && !isThreadPost && !m.isOutOwner() || m.forceAvatar || m.getDialogId() == UserObject.VERIFY) && m.needDrawAvatar() && (rowPosition == null || rowPosition.edge)) {
w -= AndroidUtilities.dp(48);
}
w += getAdditionalWidthForPosition(rowPosition);
@ -9123,11 +9142,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setAllowStartAnimation(true);
photoImage.startAnimation();
TLRPC.Document document = messageObject.getDocument();
if (messageObject.hasVideoQualities()) {
document = VideoPlayer.getDocumentForThumb(currentAccount, MessageObject.getMedia(messageObject));
}
if (currentMessageObject.videoEditedInfo != null && currentMessageObject.videoEditedInfo.canAutoPlaySourceVideo() && messageObject.getDocument() != null) {
photoImage.setImage(ImageLocation.getForPath(currentMessageObject.videoEditedInfo.originalPath), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, messageObject.getDocument().size, null, messageObject, 0);
if (currentMessageObject.videoEditedInfo != null && currentMessageObject.videoEditedInfo.canAutoPlaySourceVideo() && document != null) {
photoImage.setImage(ImageLocation.getForPath(currentMessageObject.videoEditedInfo.originalPath), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForDocument(currentPhotoObjectThumb, document), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, document.size, null, messageObject, 0);
photoImage.setMediaStartEndTime(currentMessageObject.videoEditedInfo.startTime / 1000, currentMessageObject.videoEditedInfo.endTime / 1000);
} else if (messageObject.getDocument() != null) {
} else if (document != null) {
if (!messageIdChanged && !dataChanged) {
photoImage.setCrossfadeWithOldImage(true);
}
@ -9558,9 +9580,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
botButtonsByData.put(key, botButton);
botButtonsByPosition.put(position, botButton);
botButton.x = column * (buttonWidth + AndroidUtilities.dp(5));
botButton.x = (float) column * (buttonWidth + AndroidUtilities.dp(5)) / widthForButtons;
botButton.y = row * AndroidUtilities.dp(44 + 4) + AndroidUtilities.dp(2.5f);
botButton.width = buttonWidth;
botButton.width = (float) buttonWidth / widthForButtons;
botButton.height = AndroidUtilities.dp(44);
if (column == 0) {
botButton.positionFlags |= MessageObject.POSITION_FLAG_LEFT;
@ -9584,12 +9606,21 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (botButton.button instanceof TLRPC.TL_keyboardButtonBuy && MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaInvoice) {
buttonText = StarsIntroActivity.replaceStars(buttonText);
}
if (botButton.button instanceof TLRPC.TL_keyboardButtonCopy) {
buttonText = new SpannableStringBuilder("c ").append(buttonText);
final ColoredImageSpan span = new ColoredImageSpan(R.drawable.menu_copy_s);
span.setScale(.9f, .9f);
((SpannableStringBuilder) buttonText).setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
buttonText = Emoji.replaceEmoji(buttonText, botButtonPaint.getFontMetricsInt(), AndroidUtilities.dp(15), false);
buttonText = TextUtils.ellipsize(buttonText, botButtonPaint, buttonWidth - AndroidUtilities.dp(10), TextUtils.TruncateAt.END);
botButton.title = new StaticLayout(buttonText, botButtonPaint, buttonWidth - AndroidUtilities.dp(10), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
if (oldButton != null && oldButton.title != null && TextUtils.equals(oldButton.title.getText(), buttonText)) {
botButton.title = oldButton.title;
} else {
botButton.title = new Text(buttonText, botButtonPaint);
}
botButtons.add(botButton);
if (column == buttonRow.buttons.size() - 1) {
maxButtonsWidth = Math.max(maxButtonsWidth, botButton.x + botButton.width);
maxButtonsWidth = Math.max(maxButtonsWidth, (int) (botButton.x * widthForButtons) + (int) (botButton.width * widthForButtons));
}
if (messageObject.isFromUser() && botButton.button instanceof TLRPC.TL_keyboardButtonUrl) {
try {
@ -11537,7 +11568,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(6);
}
} else {
if ((isChat || currentMessageObject != null && currentMessageObject.forceAvatar) && isAvatarVisible && (!isPlayingRound || currentMessageObject.isVoiceTranscriptionOpen())) {
if ((isChat || currentMessageObject != null && currentMessageObject.forceAvatar || currentMessageObject.getDialogId() == UserObject.VERIFY) && isAvatarVisible && (!isPlayingRound || currentMessageObject.isVoiceTranscriptionOpen())) {
x = AndroidUtilities.dp(63);
} else {
x = AndroidUtilities.dp(15);
@ -13954,6 +13985,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (SizeNotifierFrameLayout.drawingBlur) {
return;
}
final int widthForButtons = getWidthForButtons();
int addX;
if (currentMessageObject != null && currentMessageObject.isOutOwner()) {
addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
@ -13981,7 +14013,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
float y = button.y + layoutHeight - AndroidUtilities.dp(2) + transitionParams.deltaBottom;
float s = button.getPressScale();
rect.set(button.x + addX, y, button.x + addX + button.width, y + button.height);
rect.set(button.x * widthForButtons + addX, y, button.x * widthForButtons + addX + button.width * widthForButtons, y + button.height);
canvas.save();
if (s != 1) {
canvas.scale(s, s, rect.centerX(), rect.centerY());
@ -14039,19 +14071,19 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (button.selectorDrawable != null) {
button.selectorDrawable.setBounds(button.x + addX, (int) y, button.x + addX + button.width, (int) y + button.height);
button.selectorDrawable.setBounds((int) (button.x * widthForButtons) + addX, (int) y, (int) (button.x * widthForButtons) + addX + (int) (button.width * widthForButtons), (int) y + button.height);
button.selectorDrawable.setAlpha(0xFF);
button.selectorDrawable.draw(canvas);
}
canvas.restore();
canvas.save();
canvas.translate(button.x + addX + AndroidUtilities.dp(5), y + (AndroidUtilities.dp(44) - button.title.getLineBottom(button.title.getLineCount() - 1)) / 2);
button.title.draw(canvas);
// canvas.translate(button.x * widthForButtons + addX + AndroidUtilities.dp(5), y + (AndroidUtilities.dp(44) - button.title.getLineBottom(button.title.getLineCount() - 1)) / 2);
button.title.ellipsize(Math.max(1, (int) (button.width * widthForButtons) - dp(10))).draw(canvas, button.x * widthForButtons + addX + (button.width * widthForButtons - button.title.getWidth()) / 2f, y + dp(44) / 2f);
canvas.restore();
if (button.button instanceof TLRPC.TL_keyboardButtonWebView) {
Drawable drawable = getThemedDrawable(Theme.key_drawable_botWebView);
int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
int x = (int) (button.x * widthForButtons) + (int) (button.width * widthForButtons) - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
drawable.draw(canvas);
} else if (button.button instanceof TLRPC.TL_keyboardButtonUrl) {
@ -14063,16 +14095,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
drawable = getThemedDrawable(Theme.key_drawable_botLink);
}
int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
int x = (int) (button.x * widthForButtons) + (int) (button.width * widthForButtons) - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
drawable.draw(canvas);
} else if (button.button instanceof TLRPC.TL_keyboardButtonSwitchInline || button.button instanceof TLRPC.TL_keyboardButtonRequestPeer) {
Drawable drawable = getThemedDrawable(Theme.key_drawable_botInline);
int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
int x = (int) (button.x * widthForButtons) + (int) (button.width * widthForButtons) - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
drawable.draw(canvas);
} else if (button.button instanceof TLRPC.TL_keyboardButtonBuy && hasInvoicePreview && hasInvoicePrice) {
int x = button.x + button.width - AndroidUtilities.dp(5) - Theme.chat_botCardDrawable.getIntrinsicWidth() + addX;
int x = (int) (button.x * widthForButtons) + (int) (button.width * widthForButtons) - AndroidUtilities.dp(5) - Theme.chat_botCardDrawable.getIntrinsicWidth() + addX;
setDrawableBounds(Theme.chat_botCardDrawable, x, y + AndroidUtilities.dp(4));
Theme.chat_botCardDrawable.draw(canvas);
}
@ -14513,7 +14545,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
try {
Emoji.emojiDrawingYOffset = -transitionYOffsetForDrawables;
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, blockSpoilersColor, 0, block.spoilersPatchedTextLayout, block.textLayout, block.spoilers, canvas, currentPosition != null);
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, blockSpoilersColor, 0, block.spoilersPatchedTextLayout, 0, block.textLayout, block.spoilers, canvas, currentPosition != null);
Emoji.emojiDrawingYOffset = 0;
} catch (Exception e) {
FileLog.e(e);
@ -14913,7 +14945,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
buttonState = 1;
}
radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
if (hasMiniProgress == 1) {
if (hasMiniProgress == 1 || currentMessageObject != null && currentMessageObject.hasVideoQualities()) {
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
miniButtonState = -1;
} else {
@ -15087,7 +15119,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
radialProgress.setMiniProgressBackgroundColor(getThemedColor(Theme.key_chat_inLoaderPhoto));
buttonState = 3;
radialProgress.setIcon(getIconForCurrentState(), ifSame, animated);
if (hasMiniProgress == 1 || currentMessageObject.sendPreview) {
if (hasMiniProgress == 1 || currentMessageObject.sendPreview || currentMessageObject != null && currentMessageObject.hasVideoQualities()) {
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
miniButtonState = -1;
} else {
@ -16032,6 +16064,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
long currentUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (fwd_from != null && fwd_from.from_id instanceof TLRPC.TL_peerChannel && (currentMessageObject.getDialogId() == currentUserId || currentMessageObject.getDialogId() == UserObject.REPLY_BOT)) {
currentChat = MessagesController.getInstance(currentAccount).getChat(fwd_from.from_id.channel_id);
} else if (fwd_from != null && currentMessageObject.getDialogId() == UserObject.VERIFY) {
long did = DialogObject.getPeerDialogId(fwd_from.from_id);
if (did >= 0) {
currentUser = messagesController.getUser(did);
} else {
currentChat = messagesController.getChat(-did);
}
} else if (fwd_from != null && fwd_from.saved_from_peer != null) {
if (fwd_from.saved_from_peer.user_id != 0) {
if (!isSavedChat && fwd_from.from_id instanceof TLRPC.TL_peerUser) {
@ -16766,7 +16805,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
replyTextRTL = AndroidUtilities.isRTL(sb);
if (isReplyQuote) {
if (isReplyQuote && !currentMessageObject.shouldDrawWithoutBackground()) {
maxWidth += AndroidUtilities.dp(24 + 12);
// replyTextWidth += AndroidUtilities.dp(24);
}
@ -16874,7 +16913,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
protected boolean isNeedAuthorName() {
if (currentMessageObject.forceAvatar) {
if (currentMessageObject.forceAvatar || currentMessageObject.getDialogId() == UserObject.VERIFY && currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.fwd_from != null) {
return true;
}
if (currentMessageObject.isSponsored()) {
@ -17106,6 +17145,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int buttonMostLeft = Integer.MAX_VALUE;
if (botButtons != null) {
int addX;
final int widthForButtons = getWidthForButtons();
if (currentMessageObject != null && currentMessageObject.isOutOwner()) {
addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
} else {
@ -17113,7 +17153,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
for (int i = 0; i < botButtons.size(); ++i) {
BotButton btn = botButtons.get(i);
buttonMostLeft = Math.max(buttonMostLeft, addX + btn.x);
buttonMostLeft = Math.max(buttonMostLeft, addX + (int) (btn.x * widthForButtons));
}
}
return Math.max(0, Math.min(buttonMostLeft, getBackgroundDrawableLeft() - avatarWidth - shareButtonWidth));
@ -17126,14 +17166,15 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int buttonMostRight = 0;
if (botButtons != null) {
int addX;
final int widthForButtons = getWidthForButtons();
if (currentMessageObject != null && currentMessageObject.isOutOwner()) {
addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
addX = getMeasuredWidth() - getWidthForButtons() - AndroidUtilities.dp(10);
} else {
addX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground || drawPinnedBottom ? 1 : 7);
}
for (int i = 0; i < botButtons.size(); ++i) {
BotButton btn = botButtons.get(i);
buttonMostRight = Math.max(buttonMostRight, addX + btn.x + btn.width);
buttonMostRight = Math.max(buttonMostRight, addX + (int) (btn.x * widthForButtons) + (int) (btn.width * widthForButtons));
}
}
return Math.max(getBackgroundDrawableRight() + shareButtonWidth, buttonMostRight);
@ -17516,7 +17557,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentBackgroundShadowDrawable = currentBackgroundDrawable.getShadowDrawable();
}
backgroundDrawableLeft = AndroidUtilities.dp(((isChat || currentMessageObject != null && (currentMessageObject.isRepostPreview || currentMessageObject.forceAvatar)) && isAvatarVisible ? 48 : 0) + (!mediaBackground ? 3 : 9));
backgroundDrawableLeft = AndroidUtilities.dp(((isChat || currentMessageObject != null && (currentMessageObject.isRepostPreview || currentMessageObject.forceAvatar) || currentMessageObject.getDialogId() == UserObject.VERIFY) && isAvatarVisible ? 48 : 0) + (!mediaBackground ? 3 : 9));
backgroundDrawableRight = backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(3));
if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
if (!currentPosition.edge) {
@ -18095,7 +18136,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawBotButtons(canvas, transitionParams.transitionBotButtons, (int) (0xFF * t));
}
if (!botButtons.isEmpty()) {
drawBotButtons(canvas, botButtons, transitionParams.animateBotButtonsChanged ? (int) (0xFF * transitionParams.animateChangeProgress) : 0xFF);
float alpha = 1f;
if (transitionParams.animateBotButtonsChanged) {
alpha = 1f - MathUtils.clamp(1f - (float) Math.pow(transitionParams.animateChangeProgress, 2f), 0f, 1f);
}
drawBotButtons(canvas, botButtons, (int) (alpha * 0xFF));
}
drawSideButton(canvas);
}
@ -18306,6 +18351,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
sideStartY = sideMin;
}
}
if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
if (drawSideButton == 3 && commentLayout != null) {
sideStartY = dp(18);
} else {
sideStartY = 0;
}
}
if (!currentMessageObject.isOutOwner() && isRoundVideo && !hasLinkPreview) {
float offsetSize = isAvatarVisible ? ((AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f) : AndroidUtilities.dp(50);
float offsetX = isPlayingRound ? offsetSize * (1f - getVideoTranscriptionProgress()) : 0;
@ -18423,10 +18475,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
int r;
if (isRoundVideo) {
r = AndroidUtilities.dp(((isChat || messageObject != null && (messageObject.isRepostPreview || messageObject.forceAvatar)) && isAvatarVisible ? 48 : 0) + 3);
r = AndroidUtilities.dp(((isChat || messageObject != null && (messageObject.isRepostPreview || messageObject.forceAvatar) || messageObject.getDialogId() == UserObject.VERIFY) && isAvatarVisible ? 48 : 0) + 3);
r += (int) (AndroidUtilities.dp(6) * (1f - getVideoTranscriptionProgress()));
} else {
r = AndroidUtilities.dp(((isChat || messageObject != null && (messageObject.isRepostPreview || messageObject.forceAvatar)) && isAvatarVisible ? 48 : 0) + (!mediaBackground ? 3 : 9));
r = AndroidUtilities.dp(((isChat || messageObject != null && (messageObject.isRepostPreview || messageObject.forceAvatar) || messageObject.getDialogId() == UserObject.VERIFY) && isAvatarVisible ? 48 : 0) + (!mediaBackground ? 3 : 9));
}
if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
if (currentPosition.leftSpanOffset != 0) {
@ -18891,8 +18943,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int backWidth = forwardedNameWidthLocal + AndroidUtilities.dp(14);
if (hasReply) {
needDrawReplyBackground = false;
int replyBackWidth = Math.max(replyNameWidth, replyTextWidth) - AndroidUtilities.dp(4);
rect.set((int) forwardNameXLocal - AndroidUtilities.dp(7), forwardNameY - AndroidUtilities.dp(6), forwardNameRight = ((int) forwardNameXLocal - AndroidUtilities.dp(7) + Math.max(backWidth, replyBackWidth)), forwardNameY + forwardHeight + AndroidUtilities.dp(6) + AndroidUtilities.dp(41));
int replyBackWidth = Math.max(replyNameWidth, replyTextWidth) - dp(4) + dp(7);
rect.set((int) forwardNameXLocal - AndroidUtilities.dp(7), forwardNameY - AndroidUtilities.dp(6), forwardNameRight = ((int) forwardNameXLocal - AndroidUtilities.dp(7) + Math.max(backWidth, replyBackWidth)), forwardNameY + forwardHeight + dp(6) + replyHeight + dp(3));
} else {
rect.set((int) forwardNameXLocal - AndroidUtilities.dp(7), forwardNameY - AndroidUtilities.dp(6), (int) forwardNameXLocal - AndroidUtilities.dp(7) + backWidth, forwardNameY + forwardHeight + AndroidUtilities.dp(6));
}
@ -19393,7 +19445,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
final TextPaint paint = transitionParams.animateReplyTextLayout.getPaint();
int wasAlpha2 = paint.getAlpha();
paint.setAlpha((int) (wasAlpha2 * (1f - transitionParams.animateChangeProgress)));
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, transitionParams.animateReplyTextLayout, replySpoilers, canvas, false);
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, 0, transitionParams.animateReplyTextLayout, replySpoilers, canvas, false);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, transitionParams.animateReplyTextLayout, transitionParams.animateOutAnimateEmojiReply, 0, replySpoilers, 0, 0, 0, alpha, getAdaptiveEmojiColorFilter(2, paint.getColor()));
paint.setAlpha(wasAlpha2);
canvas.restore();
@ -19414,7 +19466,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
final TextPaint paint = replyTextLayout.getPaint();
int wasAlpha2 = paint.getAlpha();
paint.setAlpha((int) (wasAlpha2 * (transitionParams.animateReplyTextLayout != null ? transitionParams.animateChangeProgress : 1)));
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, replyTextLayout, replySpoilers, canvas, false);
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, 0, replyTextLayout, replySpoilers, canvas, false);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, replyTextLayout, animatedEmojiReplyStack, 0, replySpoilers, 0, 0, 0, alpha, getAdaptiveEmojiColorFilter(2, paint.getColor()));
paint.setAlpha(wasAlpha2);
canvas.restore();
@ -21324,9 +21376,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
loadingProgressAlpha = animatingLoadingProgressProgress;
} else {
drawLoadingProgress = (buttonState == 1 || miniButtonState == 1 || animatingLoadingProgressProgress != 0) && !currentMessageObject.isSecretMedia() &&
(documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT);
(documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) &&
!currentMessageObject.hasVideoQualities();
if (currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_GIF || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
alpha = currentMessageObject.needDrawBluredPreview() && docTitleLayout == null ? 0 : animatingDrawVideoImageButtonProgress;
alpha = currentMessageObject.needDrawBluredPreview() && docTitleLayout == null || currentMessageObject.hasVideoQualities() ? 0 : animatingDrawVideoImageButtonProgress;
}
drawDocTitleLayout = alpha > 0 && docTitleLayout != null;
if (!drawDocTitleLayout && (drawLoadingProgress || infoLayout == null)) {
@ -22077,7 +22130,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
invalidate();
updateSecretTimeText(currentMessageObject);
}
if ((drawVideoImageButton || animatingDrawVideoImageButton != 0) && !currentMessageObject.isRepostPreview && !currentMessageObject.sendPreview && photoImage.getVisible() && !isSmallImage && !currentMessageObject.isHiddenSensitive()) {
if ((drawVideoImageButton || animatingDrawVideoImageButton != 0) && !currentMessageObject.hasVideoQualities() && !currentMessageObject.isRepostPreview && !currentMessageObject.sendPreview && photoImage.getVisible() && !isSmallImage && !currentMessageObject.isHiddenSensitive()) {
float alpha = controlsAlpha;
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
alpha *= mediaSpoilerRevealProgress;
@ -23291,10 +23344,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
info.setClickable(true);
info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
rect.set(button.x, button.y, button.x + button.width, button.y + button.height);
rect.set((int) (button.x * widthForButtons), button.y, (int) ((button.x + button.width) * widthForButtons), button.y + button.height);
int addX;
if (currentMessageObject.isOutOwner()) {
addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
addX = getMeasuredWidth() - getWidthForButtons() - AndroidUtilities.dp(10);
} else {
addX = backgroundDrawableLeft + AndroidUtilities.dp(mediaBackground ? 1 : 7);
}
@ -23908,6 +23961,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public float animateChangeProgress = 1f;
private ArrayList<BotButton> lastDrawBotButtons = new ArrayList<>();
private ArrayList<BotButton> transitionBotButtons = new ArrayList<>();
public boolean animateWidthForButton;
public int animateFromWidthForButton;
public int lastDrawnWidthForButtons;
public float lastButtonX;
public float lastButtonY;
@ -24052,6 +24108,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
lastDrawingTextX = textX;
lastDrawingLinkPreviewY = linkPreviewY;
lastDrawnWidthForButtons = widthForButtons;
lastDrawnForwardedNameLayout[0] = forwardedNameLayout[0];
lastDrawnForwardedNameLayout[1] = forwardedNameLayout[1];
lastDrawnForwardedName = currentMessageObject != null && currentMessageObject.needDrawForwarded();
@ -24264,7 +24321,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
for (int i = 0; i < botButtons.size(); i++) {
BotButton button1 = botButtons.get(i);
BotButton button2 = lastDrawBotButtons.get(i);
if (button1.x != button2.x || button1.width != button2.width || button1.title != button2.title) {
if (Math.abs(button1.x - button2.x) > 0.01f || Math.abs(button1.width - button2.width) > 0.01f || !TextUtils.equals(button1.title.getText(), button2.title.getText())) {
animateBotButtonsChanged = true;
break;
}
@ -24274,6 +24331,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
transitionBotButtons.addAll(lastDrawBotButtons);
}
}
if (lastDrawnWidthForButtons != widthForButtons) {
animateFromWidthForButton = lastDrawnWidthForButtons;
animateWidthForButton = true;
}
if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC || documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO || documentAttachType == DOCUMENT_ATTACH_TYPE_DOCUMENT) {
if (buttonX != lastButtonX || buttonY != lastButtonY) {
@ -24482,6 +24543,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
animateDrawingTimeAlpha = false;
transitionBotButtons.clear();
animateButton = false;
animateBotButtonsChanged = false;
animateWidthForButton = false;
animateMediaOffsetY = false;
animateReplyTextLayout = null;
@ -24630,6 +24693,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
isChat && !isSavedPreviewChat && (!isThreadPost || isForum) && (
currentMessageObject != null && !currentMessageObject.isOutOwner() && currentMessageObject.needDrawAvatar()
) ||
currentMessageObject != null && currentMessageObject.getDialogId() == UserObject.VERIFY ||
currentMessageObject != null && currentMessageObject.forceAvatar
);
}
@ -24767,4 +24831,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
return hasFactCheck ? factCheckHeight + addheight : 0;
}
public int getWidthForButtons() {
if (transitionParams.animateWidthForButton) {
return lerp(transitionParams.animateFromWidthForButton, widthForButtons, transitionParams.animateChangeProgress);
}
return widthForButtons;
}
}

View file

@ -1488,7 +1488,12 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
if (!isSavedDialog && user != null && user.self && !message.isOutOwner()) {
triedMessageName = AndroidUtilities.removeDiacritics(getMessageNameString());
}
if (isSavedDialog && user != null && !user.self && message != null && message.isOutOwner() || triedMessageName != null || chat != null && chat.id > 0 && (fromChat == null || fromChat.id != chat.id) && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat)) && !ForumUtilities.isTopicCreateMessage(message)) {
if (
isSavedDialog && user != null && !user.self && message != null && message.isOutOwner() ||
triedMessageName != null ||
chat != null && chat.id > 0 && (fromChat == null || fromChat.id != chat.id) && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat)) && !ForumUtilities.isTopicCreateMessage(message) ||
user != null && user.id == UserObject.VERIFY && message != null && message.getForwardedFromId() != null
) {
messageNameString = AndroidUtilities.removeDiacritics(triedMessageName != null ? triedMessageName : getMessageNameString());
if (chat != null && chat.forum && !isTopic && !useFromUserAsAvatar) {
CharSequence topicName = MessagesController.getInstance(currentAccount).getTopicsController().getTopicIconName(chat, message, currentMessagePaint);
@ -5078,6 +5083,19 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
return AndroidUtilities.removeDiacritics(fromChat.title.replace("\n", ""));
}
return null;
} else if (currentDialogId == UserObject.VERIFY && message != null && message.messageOwner != null && message.messageOwner.fwd_from != null) {
if (message.messageOwner.fwd_from.from_name != null) {
return AndroidUtilities.removeDiacritics(message.messageOwner.fwd_from.from_name);
} else {
long did = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.from_id);
if (DialogObject.isUserDialog(did)) {
fromUser = MessagesController.getInstance(currentAccount).getUser(did);
return UserObject.getUserName(fromUser);
} else {
fromChat = MessagesController.getInstance(currentAccount).getChat(-did);
return fromChat == null ? "" : fromChat.title;
}
}
} else if (message.isOutOwner() && fromUser != null) {
return LocaleController.getString(R.string.FromYou);
} else if (!isSavedDialog && message != null && message.messageOwner != null && message.messageOwner.from_id instanceof TLRPC.TL_peerUser && (user = MessagesController.getInstance(currentAccount).getUser(message.messageOwner.from_id.user_id)) != null) {

View file

@ -0,0 +1,287 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.LocaleController.getString;
import static org.telegram.ui.Components.EditTextEmoji.STYLE_GIFT;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextCaption;
import org.telegram.ui.Components.EditTextEmoji;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.SizeNotifierFrameLayout;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.TypefaceSpan;
public class EditEmojiTextCell extends FrameLayout {
private boolean ignoreEditText;
public final EditTextEmoji editTextEmoji;
private int maxLength;
private boolean showLimitWhenEmpty;
private int showLimitWhenNear = -1;
private boolean showLimitWhenFocused;
public boolean autofocused;
private boolean focused;
final AnimatedColor limitColor;
private int limitCount;
final AnimatedTextView.AnimatedTextDrawable limit = new AnimatedTextView.AnimatedTextDrawable(false, true, true); {
limit.setAnimationProperties(.2f, 0, 160, CubicBezierInterpolator.EASE_OUT_QUINT);
limit.setTextSize(dp(15.33f));
limit.setGravity(Gravity.RIGHT);
}
public void setShowLimitWhenEmpty(boolean show) {
showLimitWhenEmpty = show;
if (showLimitWhenEmpty) {
updateLimitText();
}
}
public void setShowLimitWhenNear(int near) {
showLimitWhenNear = near;
updateLimitText();
}
private void updateLimitText() {
if (editTextEmoji == null || editTextEmoji.getEditText() == null) return;
limitCount = maxLength - getText().length();
limit.setText(TextUtils.isEmpty(getText()) && !showLimitWhenEmpty || showLimitWhenFocused && (!focused || autofocused) || (showLimitWhenNear != -1 && limitCount > showLimitWhenNear) ? "" : "" + limitCount);
}
public void whenHitEnter(Runnable whenEnter) {
editTextEmoji.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE);
editTextEmoji.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
whenEnter.run();
return true;
}
return false;
}
});
}
public void hideKeyboardOnEnter() {
whenHitEnter(() -> AndroidUtilities.hideKeyboard(editTextEmoji.getEditText()));
}
public void setShowLimitOnFocus(boolean show) {
showLimitWhenFocused = show;
}
public EditEmojiTextCell(Context context, SizeNotifierFrameLayout parent, String hint, int style, boolean multiline) {
this(context, parent, hint, multiline, -1, style, null);
}
public EditEmojiTextCell(
Context context,
SizeNotifierFrameLayout parent,
String hint,
boolean multiline,
int maxLength,
int style,
Theme.ResourcesProvider resourceProvider
) {
super(context);
this.maxLength = maxLength;
editTextEmoji = new EditTextEmoji(context, parent, null, style, true) {
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == limit || super.verifyDrawable(who);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.save();
canvas.clipRect(getScrollX() + getPaddingLeft(), 0, getScrollX() + getWidth() - getPaddingRight(), getHeight());
super.onDraw(canvas);
canvas.restore();
if (limitColor != null) {
limit.setTextColor(limitColor.set(Theme.getColor(limitCount <= 0 ? Theme.key_text_RedRegular : Theme.key_dialogSearchHint, resourceProvider)));
}
int h = Math.min(dp(48), getHeight());
limit.setBounds(getScrollX(), getHeight() - h, getScrollX() + getWidth() - dp(12), getHeight());
limit.draw(canvas);
}
@Override
protected void extendActionMode(ActionMode actionMode, Menu menu) {
if (menu.findItem(R.id.menu_bold) != null) {
return;
}
if (Build.VERSION.SDK_INT >= 23) {
menu.removeItem(android.R.id.shareText);
}
int order = 6;
menu.add(R.id.menu_groupbolditalic, R.id.menu_spoiler, order++, LocaleController.getString(R.string.Spoiler));
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getString(R.string.Bold));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_bold, order++, stringBuilder);
stringBuilder = new SpannableStringBuilder(getString(R.string.Italic));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM_ITALIC)), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_italic, order++, stringBuilder);
// menu.add(R.id.menu_groupbolditalic, R.id.menu_link, order++, getString(R.string.CreateLink));
stringBuilder = new SpannableStringBuilder(LocaleController.getString(R.string.Strike));
TextStyleSpan.TextStyleRun run = new TextStyleSpan.TextStyleRun();
run.flags |= TextStyleSpan.FLAG_STYLE_STRIKE;
stringBuilder.setSpan(new TextStyleSpan(run), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_strike, order++, stringBuilder);
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, order++, getString(R.string.Regular));
}
};
final EditTextCaption editText = editTextEmoji.getEditText();
editText.setDelegate(new EditTextCaption.EditTextCaptionDelegate() {
@Override
public void onSpansChanged() {
onTextChanged(editText.getText());
}
});
editTextEmoji.setWillNotDraw(false);
limitColor = new AnimatedColor(editTextEmoji);
limit.setCallback(editTextEmoji);
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);
editText.setHintTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteHintText, resourceProvider));
editText.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourceProvider));
editText.setBackground(null);
if (multiline) {
editText.setMaxLines(5);
editText.setSingleLine(false);
} else {
editText.setMaxLines(1);
editText.setSingleLine(true);
}
editText.setPadding(editText.getPaddingLeft(), editText.getPaddingTop(), dp(style == STYLE_GIFT ? 0 : (maxLength > 0 ? 42 : 0) + 21), editText.getPaddingBottom());
editText.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
editText.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_CLASS_TEXT | (multiline ? InputType.TYPE_TEXT_FLAG_MULTI_LINE : 0) | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setHint(hint);
editText.setCursorColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourceProvider));
editText.setCursorSize(dp(19));
editText.setCursorWidth(1.5f);
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
if (!ignoreEditText) {
autofocused = false;
}
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {}
@Override
public void afterTextChanged(Editable editable) {
if (!ignoreEditText) {
if (maxLength > 0 && editable != null && editable.length() > maxLength) {
ignoreEditText = true;
editText.setText(editable.subSequence(0, maxLength));
editText.setSelection(editText.length());
ignoreEditText = false;
}
EditEmojiTextCell.this.onTextChanged(editable);
}
if (multiline) {
int pos;
while ((pos = editable.toString().indexOf("\n")) >= 0) {
editable.delete(pos, pos + 1);
}
}
if (limit != null && maxLength > 0) {
limit.cancelAnimation();
updateLimitText();
}
}
});
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
focused = hasFocus;
if (showLimitWhenFocused) {
updateLimitText();
}
onFocusChanged(hasFocus);
}
});
addView(editTextEmoji, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP));
updateLimitText();
}
public void setText(CharSequence text) {
ignoreEditText = true;
editTextEmoji.setText(text);
editTextEmoji.setSelection(editTextEmoji.getText().length());
ignoreEditText = false;
}
public CharSequence getText() {
return editTextEmoji.getText();
}
public boolean validate() {
return maxLength < 0 || editTextEmoji.getText().length() <= maxLength;
}
protected void onTextChanged(CharSequence newText) {
}
protected void onFocusChanged(boolean focused) {
}
private boolean needDivider;
public void setDivider(boolean divider) {
setWillNotDraw(!(needDivider = divider));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (needDivider) {
canvas.drawLine(
LocaleController.isRTL ? 0 : dp(22),
getMeasuredHeight() - 1,
getMeasuredWidth() - (LocaleController.isRTL ? dp(22) : 0),
getMeasuredHeight() - 1,
Theme.dividerPaint
);
}
}
}

View file

@ -1,20 +1,23 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.decelerateInterpolator;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.LocaleController.getString;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.FrameLayout;
@ -27,22 +30,22 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Business.QuickRepliesController;
import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.EditTextCaption;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.TypefaceSpan;
public class EditTextCell extends FrameLayout {
private boolean ignoreEditText;
public final EditTextBoldCursor editText;
public final EditTextCaption editText;
private int maxLength;
private boolean showLimitWhenEmpty;
private int showLimitWhenNear = -1;
private boolean showLimitWhenFocused;
public boolean autofocused;
@ -63,10 +66,15 @@ public class EditTextCell extends FrameLayout {
}
}
public void setShowLimitWhenNear(int near) {
showLimitWhenNear = near;
updateLimitText();
}
private void updateLimitText() {
if (editText == null) return;
limitCount = maxLength - getText().length();
limit.setText(TextUtils.isEmpty(getText()) && !showLimitWhenEmpty || showLimitWhenFocused && (!focused || autofocused) ? "" : "" + limitCount);
limit.setText(TextUtils.isEmpty(getText()) && !showLimitWhenEmpty || showLimitWhenFocused && (!focused || autofocused) || (showLimitWhenNear != -1 && limitCount > showLimitWhenNear) ? "" : "" + limitCount);
}
public void whenHitEnter(Runnable whenEnter) {
@ -93,20 +101,20 @@ public class EditTextCell extends FrameLayout {
}
public EditTextCell(Context context, String hint, boolean multiline) {
this(context, hint, multiline, -1, null);
this(context, hint, multiline, false, -1, null);
}
public EditTextCell(
Context context,
String hint,
boolean multiline,
int maxLength,
boolean allowEntities, int maxLength,
Theme.ResourcesProvider resourceProvider
) {
super(context);
this.maxLength = maxLength;
editText = new EditTextBoldCursor(context) {
editText = new EditTextCaption(context, resourceProvider) {
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == limit || super.verifyDrawable(who);
@ -136,6 +144,31 @@ public class EditTextCell extends FrameLayout {
super.onDraw(canvas);
canvas.restore();
}
@Override
protected void extendActionMode(ActionMode actionMode, Menu menu) {
if (!allowEntities) return;
if (menu.findItem(R.id.menu_bold) != null) {
return;
}
if (Build.VERSION.SDK_INT >= 23) {
menu.removeItem(android.R.id.shareText);
}
int order = 6;
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(getString(R.string.Bold));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_bold, order++, stringBuilder);
stringBuilder = new SpannableStringBuilder(getString(R.string.Italic));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM_ITALIC)), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_italic, order++, stringBuilder);
// menu.add(R.id.menu_groupbolditalic, R.id.menu_link, order++, getString(R.string.CreateLink));
stringBuilder = new SpannableStringBuilder(LocaleController.getString(R.string.Strike));
TextStyleSpan.TextStyleRun run = new TextStyleSpan.TextStyleRun();
run.flags |= TextStyleSpan.FLAG_STYLE_STRIKE;
stringBuilder.setSpan(new TextStyleSpan(run), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_strike, order++, stringBuilder);
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, order++, getString(R.string.Regular));
}
};
limit.setCallback(editText);
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 17);

View file

@ -74,7 +74,7 @@ public class ProfileChannelCell extends FrameLayout {
headerLayout.addView(subscribersView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 17, Gravity.LEFT | Gravity.TOP, 4, 2, 4, 0));
dialogCell = new DialogCell(null, context, false, true, UserConfig.selectedAccount, resourcesProvider);
dialogCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
dialogCell.setBackgroundColor(0);
dialogCell.setDialogCellDelegate(new DialogCell.DialogCellDelegate() {
@Override
public void onButtonClicked(DialogCell dialogCell) {

View file

@ -495,6 +495,8 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
statusString = LocaleController.formatPluralStringSpaced("BotUsers", user.bot_active_users);
} else if (user.bot) {
statusString = LocaleController.getString(R.string.Bot);
} else if (user.id == UserObject.VERIFY) {
statusString = LocaleController.getString(R.string.VerifyCodesNotifications);
} else if (UserObject.isService(user.id)) {
statusString = LocaleController.getString(R.string.ServiceNotifications);
} else {

View file

@ -346,6 +346,10 @@ public class SessionCell extends FrameLayout {
iconId = R.drawable.fragment;
colorKey = -1;
colorKey2 = -1;
} else if (platform.contains("anonymous")) {
iconId = R.drawable.large_hidden;
colorKey = Theme.key_avatar_backgroundBlue;
colorKey2 = Theme.key_avatar_background2Blue;
} else if (platform.contains("premiumbot")) {
iconId = R.drawable.filled_star_plus;
colorKey = Theme.key_color_yellow;

View file

@ -801,7 +801,7 @@ public class SharedLinkCell extends FrameLayout {
descriptionTextPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), descriptionY);
SpoilerEffect.renderWithRipple(this, false, descriptionTextPaint.getColor(), -AndroidUtilities.dp(2), patchedDescriptionLayout, descriptionLayout, descriptionLayoutSpoilers, canvas, false);
SpoilerEffect.renderWithRipple(this, false, descriptionTextPaint.getColor(), -AndroidUtilities.dp(2), patchedDescriptionLayout, 0, descriptionLayout, descriptionLayoutSpoilers, canvas, false);
canvas.restore();
}
@ -809,7 +809,7 @@ public class SharedLinkCell extends FrameLayout {
descriptionTextPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
canvas.save();
canvas.translate(AndroidUtilities.dp(LocaleController.isRTL ? 8 : AndroidUtilities.leftBaseline), description2Y);
SpoilerEffect.renderWithRipple(this, false, descriptionTextPaint.getColor(), -AndroidUtilities.dp(2), patchedDescriptionLayout2, descriptionLayout2, descriptionLayout2Spoilers, canvas, false);
SpoilerEffect.renderWithRipple(this, false, descriptionTextPaint.getColor(), -AndroidUtilities.dp(2), patchedDescriptionLayout2, 0, descriptionLayout2, descriptionLayout2Spoilers, canvas, false);
canvas.restore();
}

View file

@ -570,7 +570,7 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
}
nameTextView.setText(name);
}
if (currentUser != null && MessagesController.getInstance(currentAccount).isPremiumUser(currentUser)) {
if (currentUser != null && MessagesController.getInstance(currentAccount).isPremiumUser(currentUser) && !MessagesController.getInstance(currentAccount).premiumFeaturesBlocked()) {
if (currentUser.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
emojiStatus.set(((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).document_id, false);
emojiStatus.setColor(Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider));

View file

@ -2271,7 +2271,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
getConnectionsManager().sendRequest(req, (res, err) -> {
AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.TL_boolTrue) {
BulletinFactory.of(this).createSimpleBulletin(R.raw.msg_antispam, getString("ChannelAntiSpamFalsePositiveReported", R.string.ChannelAntiSpamFalsePositiveReported)).show();
BulletinFactory.of(this).createSimpleBulletin(R.raw.msg_antispam, getString(R.string.ChannelAntiSpamFalsePositiveReported)).show();
} else if (res instanceof TLRPC.TL_boolFalse) {
BulletinFactory.of(this).createSimpleBulletin(R.raw.error, getString("UnknownError", R.string.UnknownError)).show();
} else {

View file

@ -58,6 +58,7 @@ import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stars;
import org.telegram.tgnet.tl.TL_stats;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.ActionBar;
@ -1627,7 +1628,7 @@ public class ChannelMonetizationLayout extends SizeNotifierFrameLayout implement
private final ArrayList<TL_stats.BroadcastRevenueTransaction> tonTransactions = new ArrayList<>();
private int tonTransactionsTotalCount;
private final ArrayList<TLRPC.StarsTransaction> starsTransactions = new ArrayList<>();
private final ArrayList<TL_stars.StarsTransaction> starsTransactions = new ArrayList<>();
private String starsLastOffset = "";
private class PageAdapter extends ViewPagerFixed.Adapter {
@ -1803,12 +1804,12 @@ public class ChannelMonetizationLayout extends SizeNotifierFrameLayout implement
if (starsLastOffset == null || !starsRevenueAvailable)
return;
loadingTransactions[type] = true;
TLRPC.TL_payments_getStarsTransactions req = new TLRPC.TL_payments_getStarsTransactions();
TL_stars.TL_payments_getStarsTransactions req = new TL_stars.TL_payments_getStarsTransactions();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId);
req.offset = starsLastOffset;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.TL_payments_starsStatus) {
TLRPC.TL_payments_starsStatus r = (TLRPC.TL_payments_starsStatus) res;
if (res instanceof TL_stars.TL_payments_starsStatus) {
TL_stars.TL_payments_starsStatus r = (TL_stars.TL_payments_starsStatus) res;
MessagesController.getInstance(currentAccount).putUsers(r.users, false);
MessagesController.getInstance(currentAccount).putChats(r.chats, false);
starsTransactions.addAll(r.history);
@ -1880,7 +1881,7 @@ public class ChannelMonetizationLayout extends SizeNotifierFrameLayout implement
private void fillItems(ArrayList<UItem> items, UniversalAdapter adapter) {
if (type == STARS_TRANSACTIONS) {
for (TLRPC.StarsTransaction t : starsTransactions) {
for (TL_stars.StarsTransaction t : starsTransactions) {
items.add(StarsIntroActivity.StarsTransactionView.Factory.asTransaction(t, true));
}
if (!TextUtils.isEmpty(starsLastOffset)) {
@ -1901,8 +1902,8 @@ public class ChannelMonetizationLayout extends SizeNotifierFrameLayout implement
}
private void onClick(UItem item, View view, int position, float x, float y) {
if (item.object instanceof TLRPC.StarsTransaction) {
StarsIntroActivity.showTransactionSheet(getContext(), true, dialogId, currentAccount, (TLRPC.StarsTransaction) item.object, resourcesProvider);
if (item.object instanceof TL_stars.StarsTransaction) {
StarsIntroActivity.showTransactionSheet(getContext(), true, dialogId, currentAccount, (TL_stars.StarsTransaction) item.object, resourcesProvider);
} else if (item.object instanceof TL_stats.BroadcastRevenueTransaction) {
showTransactionSheet(getContext(), currentAccount, (TL_stats.BroadcastRevenueTransaction) item.object, dialogId, resourcesProvider);
}

File diff suppressed because it is too large Load diff

View file

@ -725,6 +725,7 @@ public class ChatPullingDownDrawable implements NotificationCenter.NotificationC
}
public long getChatId() {
if (nextChat == null) return 0;
return nextChat.id;
}

View file

@ -1845,6 +1845,7 @@ public class ChatRightsEditActivity extends BaseFragment {
int sentMediaCount = getSendMediaSelectedCount();
checkCell.setTextAndCheck(LocaleController.getString(R.string.UserRestrictionsSendMedia), sentMediaCount > 0, true, true);
checkCell.setCollapseArrow(String.format(Locale.US, "%d/9", sentMediaCount), !sendMediaExpanded, () -> {
if (!checkCell.isEnabled()) return;
if (allDefaultMediaBanned()) {
new AlertDialog.Builder(getParentActivity())
.setTitle(LocaleController.getString(R.string.UserRestrictionsCantModify))
@ -1863,6 +1864,7 @@ public class ChatRightsEditActivity extends BaseFragment {
int count = getChannelMessagesSelectedCount();
checkCell.setTextAndCheck(LocaleController.getString(R.string.ChannelManageMessages), count > 0, true, true);
checkCell.setCollapseArrow(String.format(Locale.US, "%d/3", count), !channelMessagesExpanded, () -> {
if (!checkCell.isEnabled()) return;
boolean checked = checkCell.isChecked();
checkCell.setChecked(checked);
setChannelMessagesEnabled(checked);
@ -1871,6 +1873,7 @@ public class ChatRightsEditActivity extends BaseFragment {
int count = getChannelStoriesSelectedCount();
checkCell.setTextAndCheck(LocaleController.getString(R.string.ChannelManageStories), count > 0, true, true);
checkCell.setCollapseArrow(String.format(Locale.US, "%d/3", count), !channelStoriesExpanded, () -> {
if (!checkCell.isEnabled()) return;
boolean checked = checkCell.isChecked();
checkCell.setChecked(checked);
setChannelStoriesEnabled(checked);

View file

@ -692,8 +692,8 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
progressBar.setVisibility(View.GONE);
emptyView = new StickerEmptyView(context, progressLayout, StickerEmptyView.STICKER_TYPE_SEARCH);
emptyView.title.setText(getString("NoResult", R.string.NoResult));
emptyView.subtitle.setText(getString("SearchEmptyViewFilteredSubtitle2", R.string.SearchEmptyViewFilteredSubtitle2));
emptyView.title.setText(getString(R.string.NoResult));
emptyView.subtitle.setText(getString(R.string.SearchEmptyViewFilteredSubtitle2));
emptyView.setVisibility(View.GONE);
emptyView.setAnimateLayoutChange(true);
emptyView.showProgress(true, false);
@ -1101,7 +1101,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
}
if (checkCell.hasIcon()) {
if (ChatObject.isPublic(currentChat) && (position == pinMessagesRow || position == changeInfoRow)) {
BulletinFactory.of(this).createErrorBulletin(getString("EditCantEditPermissionsPublic", R.string.EditCantEditPermissionsPublic)).show();
BulletinFactory.of(this).createErrorBulletin(getString(R.string.EditCantEditPermissionsPublic)).show();
} else if (ChatObject.isDiscussionGroup(currentAccount, chatId) && (position == pinMessagesRow || position == changeInfoRow)) {
BulletinFactory.of(this).createErrorBulletin(getString(R.string.EditCantEditPermissionsDiscussion)).show();
} else {
BulletinFactory.of(this).createErrorBulletin(getString("EditCantEditPermissions", R.string.EditCantEditPermissions)).show();
}
@ -3486,7 +3488,9 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
} else if (position == manageTopicsRow) {
checkCell.setTextAndCheck(getString("CreateTopicsPermission", R.string.CreateTopicsPermission), !defaultBannedRights.manage_topics, false, animated);
}
if (ChatObject.canBlockUsers(currentChat)) {
if ((position == pinMessagesRow || position == changeInfoRow) && ChatObject.isDiscussionGroup(currentAccount, chatId)) {
checkCell.setIcon(R.drawable.permission_locked);
} else if (ChatObject.canBlockUsers(currentChat)) {
if (position == addUsersRow && !ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_INVITE) ||
position == pinMessagesRow && !ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_PIN) ||
position == changeInfoRow && !ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_CHANGE_INFO) ||

View file

@ -0,0 +1,100 @@
package org.telegram.ui;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.LocaleController.getString;
import android.content.Context;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.PopupSwipeBackLayout;
import org.telegram.ui.Components.VideoPlayer;
import java.util.ArrayList;
public class ChooseDownloadQualityLayout {
public final ActionBarPopupWindow.ActionBarPopupWindowLayout layout;
public final LinearLayout buttonsLayout;
private final Callback callback;
public ChooseDownloadQualityLayout(Context context, PopupSwipeBackLayout swipeBackLayout, Callback callback) {
this.callback = callback;
layout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(context, 0, null);
layout.setFitItems(true);
ActionBarMenuSubItem backItem = ActionBarMenuItem.addItem(layout, R.drawable.msg_arrow_back, getString(R.string.Back), false, null);
backItem.setOnClickListener(view -> {
swipeBackLayout.closeForeground();
});
backItem.setColors(0xfffafafa, 0xfffafafa);
backItem.setSelectorColor(0x0fffffff);
FrameLayout gap = new FrameLayout(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
gap.setMinimumWidth(dp(196));
gap.setBackgroundColor(0xff181818);
layout.addView(gap);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) gap.getLayoutParams();
if (LocaleController.isRTL) {
layoutParams.gravity = Gravity.RIGHT;
}
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = dp(8);
gap.setLayoutParams(layoutParams);
buttonsLayout = new LinearLayout(context);
buttonsLayout.setOrientation(LinearLayout.VERTICAL);
layout.addView(buttonsLayout);
}
public boolean update(MessageObject messageObject) {
if (messageObject == null || messageObject.messageOwner == null || messageObject.messageOwner.media == null) return false;
if (!messageObject.hasVideoQualities()) return false;
ArrayList<VideoPlayer.Quality> qualities = VideoPlayer.getQualities(messageObject.currentAccount, messageObject.messageOwner.media.document, messageObject.messageOwner.media.alt_documents, 0, false);
buttonsLayout.removeAllViews();
for (int i = 0; i < qualities.size(); ++i) {
final VideoPlayer.Quality q = qualities.get(i);
String title = "", subtitle = "";
String str = q.toString();
if (str.contains("\n")) {
title = str.substring(0, str.indexOf("\n"));
subtitle = str.substring(str.indexOf("\n") + 1);
} else {
title = str;
}
ActionBarMenuSubItem item = ActionBarMenuItem.addItem(buttonsLayout, 0, title, false, null);
if (!TextUtils.isEmpty(subtitle)) {
item.setSubtext(subtitle);
}
item.setColors(0xfffafafa, 0xfffafafa);
item.setOnClickListener((view) -> {
callback.onQualitySelected(messageObject, q);
});
item.setSelectorColor(0x0fffffff);
}
return true;
}
public interface Callback {
void onQualitySelected(MessageObject messageObject, VideoPlayer.Quality quality);
}
}

View file

@ -0,0 +1,196 @@
package org.telegram.ui;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.LocaleController.getString;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.PopupSwipeBackLayout;
import org.telegram.ui.Components.VideoPlayer;
public class ChooseQualityLayout {
public final ActionBarPopupWindow.ActionBarPopupWindowLayout layout;
public final LinearLayout buttonsLayout;
private final Callback callback;
public ChooseQualityLayout(Context context, PopupSwipeBackLayout swipeBackLayout, Callback callback) {
this.callback = callback;
layout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(context, 0, null);
layout.setFitItems(true);
ActionBarMenuSubItem backItem = ActionBarMenuItem.addItem(layout, R.drawable.msg_arrow_back, getString(R.string.Back), false, null);
backItem.setOnClickListener(view -> {
swipeBackLayout.closeForeground();
});
backItem.setColors(0xfffafafa, 0xfffafafa);
backItem.setSelectorColor(0x0fffffff);
FrameLayout gap = new FrameLayout(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
gap.setMinimumWidth(dp(196));
gap.setBackgroundColor(0xff181818);
layout.addView(gap);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) gap.getLayoutParams();
if (LocaleController.isRTL) {
layoutParams.gravity = Gravity.RIGHT;
}
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = dp(8);
gap.setLayoutParams(layoutParams);
buttonsLayout = new LinearLayout(context);
buttonsLayout.setOrientation(LinearLayout.VERTICAL);
layout.addView(buttonsLayout);
}
public boolean update(VideoPlayer player) {
if (player == null) return false;
if (player.getQualitiesCount() <= 1) return false;
buttonsLayout.removeAllViews();
for (int i = -1; i < player.getQualitiesCount(); ++i) {
final VideoPlayer.Quality q = i == -1 ? null : player.getQuality(i);
final int index = i;
String title = "", subtitle = "";
if (q == null) {
title = getString(R.string.QualityAuto);
} else {
String str = q.toString();
if (str.contains("\n")) {
title = str.substring(0, str.indexOf("\n"));
subtitle = str.substring(str.indexOf("\n") + 1);
} else {
title = str;
}
}
ActionBarMenuSubItem item = ActionBarMenuItem.addItem(buttonsLayout, 0, title, true, null);
if (!TextUtils.isEmpty(subtitle)) {
item.setSubtext(subtitle);
}
item.setChecked(index == player.getSelectedQuality());
item.setColors(0xfffafafa, 0xfffafafa);
item.setOnClickListener((view) -> {
callback.onQualitySelected(index, true, true);
});
item.setSelectorColor(0x0fffffff);
}
return true;
}
public interface Callback {
void onQualitySelected(int qualityIndex, boolean isFinal, boolean closeMenu);
}
public static class QualityIcon extends Drawable {
private final Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Drawable base;
private final RectF rect = new RectF();
public final AnimatedTextView.AnimatedTextDrawable text = new AnimatedTextView.AnimatedTextDrawable();
public QualityIcon(Context context) {
base = context.getResources().getDrawable(R.drawable.msg_settings).mutate();
text.setTypeface(AndroidUtilities.getTypeface("fonts/num.otf"));
text.setTextColor(0xFFFFFFFF);
text.setTextSize(dp(8));
text.setCallback(new Callback() {
@Override
public void invalidateDrawable(@NonNull Drawable who) {
QualityIcon.this.invalidateSelf();
}
@Override
public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) {
QualityIcon.this.scheduleSelf(what, when);
}
@Override
public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) {
QualityIcon.this.unscheduleSelf(what);
}
});
text.setGravity(Gravity.CENTER);
text.setOverrideFullWidth(AndroidUtilities.displaySize.x);
}
private float rotation;
public void setRotation(float rotation) {
this.rotation = rotation;
invalidateSelf();
}
@Override
public void draw(@NonNull Canvas canvas) {
final Rect bounds = getBounds();
base.setBounds(bounds);
canvas.save();
canvas.rotate(rotation * -180, bounds.centerX(), bounds.centerY());
base.draw(canvas);
canvas.restore();
bgPaint.setColor(Theme.getColor(Theme.key_featuredStickers_addButton));
final float right = bounds.left + bounds.width() * .97f;
final float cy = bounds.top + bounds.height() * .75f;
final float h = dp(11);
final float w = dp(5) * text.isNotEmpty() + text.getCurrentWidth();
rect.set(right - w, cy - h / 2f, right, cy + h / 2f);
canvas.drawRoundRect(rect, dp(3), dp(3), bgPaint);
text.setBounds(rect);
text.draw(canvas);
}
@Override
public void setAlpha(int alpha) {
base.setAlpha(alpha);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
base.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return base.getOpacity();
}
@Override
public int getIntrinsicWidth() {
return base.getIntrinsicWidth();
}
@Override
public int getIntrinsicHeight() {
return base.getIntrinsicHeight();
}
}
}

View file

@ -101,6 +101,7 @@ import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Business.TimezonesController;
import org.telegram.ui.CacheControlActivity;
@ -117,6 +118,7 @@ import org.telegram.ui.LoginActivity;
import org.telegram.ui.NotificationsCustomSettingsActivity;
import org.telegram.ui.NotificationsSettingsActivity;
import org.telegram.ui.PrivacyControlActivity;
import org.telegram.ui.ProfileActivity;
import org.telegram.ui.ProfileNotificationsActivity;
import org.telegram.ui.Stories.recorder.ButtonWithCounterView;
import org.telegram.ui.ThemePreviewActivity;
@ -274,6 +276,9 @@ public class AlertsCreator {
} else {
peer = null;
}
if (fragment == null) {
fragment = LaunchActivity.getLastFragment();
}
if (error.text.contains("USER_IS_BLOCKED")) {
showSimpleAlert(fragment, LocaleController.getString(R.string.ImportErrorTitle), LocaleController.getString(R.string.ImportErrorUserBlocked));
} else if (error.text.contains("USER_NOT_MUTUAL_CONTACT")) {
@ -300,6 +305,9 @@ public class AlertsCreator {
showSimpleAlert(fragment, LocaleController.getString(R.string.ImportErrorTitle), LocaleController.getString(R.string.ErrorOccurred) + "\n" + error.text);
}
} else if (request instanceof TLRPC.TL_account_saveSecureValue || request instanceof TLRPC.TL_account_getAuthorizationForm) {
if (fragment == null) {
fragment = LaunchActivity.getLastFragment();
}
if (error.text.contains("PHONE_NUMBER_INVALID")) {
showSimpleAlert(fragment, LocaleController.getString(R.string.InvalidPhoneNumber));
} else if (error.text.startsWith("FLOOD_WAIT")) {
@ -338,6 +346,9 @@ public class AlertsCreator {
}
}
} else if (request instanceof TLRPC.TL_messages_createChat) {
if (fragment == null) {
fragment = LaunchActivity.getLastFragment();
}
if (error.text.equals("CHANNELS_TOO_MUCH")) {
if (fragment.getParentActivity() != null) {
fragment.showDialog(new LimitReachedBottomSheet(fragment, fragment.getParentActivity(), LimitReachedBottomSheet.TYPE_TO0_MANY_COMMUNITIES, currentAccount, null));
@ -351,6 +362,9 @@ public class AlertsCreator {
showAddUserAlert(error.text, fragment, false, request);
}
} else if (request instanceof TLRPC.TL_channels_createChannel) {
if (fragment == null) {
fragment = LaunchActivity.getLastFragment();
}
if (error.text.equals("CHANNELS_TOO_MUCH")) {
if (fragment.getParentActivity() != null) {
fragment.showDialog(new LimitReachedBottomSheet(fragment, fragment.getParentActivity(), LimitReachedBottomSheet.TYPE_TO0_MANY_COMMUNITIES, currentAccount, null));
@ -442,6 +456,9 @@ public class AlertsCreator {
}
}
} else if (request instanceof TLRPC.TL_messages_importChatInvite) {
if (fragment == null) {
fragment = LaunchActivity.getLastFragment();
}
if (error.text.startsWith("FLOOD_WAIT")) {
showSimpleAlert(fragment, LocaleController.getString(R.string.FloodWait));
} else if (error.text.equals("USERS_TOO_MUCH")) {
@ -1467,17 +1484,48 @@ public class AlertsCreator {
imageView.setRoundRadius(dp(20));
frameLayout.addView(imageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 22, 5, 22, 0));
TextView textView = new TextView(context);
SimpleTextView textView = new SimpleTextView(context);
textView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
textView.setTextSize(20);
textView.setTypeface(AndroidUtilities.bold());
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setEllipsizeByGradient(true);
textView.setText(user.first_name);
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 11, (LocaleController.isRTL ? 76 : 21), 0));
if (user.verified) {
Drawable verifiedBackground = context.getResources().getDrawable(R.drawable.verified_area).mutate();
verifiedBackground.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_verifiedBackground), PorterDuff.Mode.MULTIPLY));
Drawable verifiedCheck = context.getResources().getDrawable(R.drawable.verified_check).mutate();
verifiedCheck.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_verifiedCheck), PorterDuff.Mode.MULTIPLY));
Drawable verifiedDrawable = new CombinedDrawable(verifiedBackground, verifiedCheck);
textView.setRightDrawable(verifiedDrawable);
}
TextView subtitleView = new TextView(context);
subtitleView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue));
subtitleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
subtitleView.setLines(1);
subtitleView.setMaxLines(1);
subtitleView.setSingleLine(true);
subtitleView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
subtitleView.setEllipsize(TextUtils.TruncateAt.END);
subtitleView.setOnClickListener(v -> {
Bundle args = new Bundle();
args.putLong("user_id", user.id);
if (fragment.getMessagesController().checkCanOpenChat(args, fragment)) {
fragment.presentFragment(new ProfileActivity(args));
}
builder.getDismissRunnable().run();
});
SpannableString ssb = SpannableString.valueOf(LocaleController.getString(R.string.MoreAboutThisBot) + " ");
ColoredImageSpan img = new ColoredImageSpan(R.drawable.attach_arrow_right);
img.setTopOffset(1);
img.setSize(dp(10));
ssb.setSpan(img, ssb.length() - 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
subtitleView.setText(ssb);
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 0, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout.addView(subtitleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 24, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 1));
if (user != null) {
@ -1505,7 +1553,7 @@ public class AlertsCreator {
}
});
messageTextView.setText(AndroidUtilities.replaceSingleTag(getString(R.string.BotWebViewStartPermission), () -> {
messageTextView.setText(AndroidUtilities.replaceSingleTag(getString(R.string.BotWebViewStartPermission2), () -> {
if (dialog != null) {
dialog.dismiss();
}
@ -1553,16 +1601,21 @@ public class AlertsCreator {
imageView.setRoundRadius(dp(20));
frameLayout.addView(imageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 22, 5, 22, 0));
TextView titleView = new TextView(context);
SimpleTextView titleView = new SimpleTextView(context);
titleView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem));
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
titleView.setTextSize(20);
titleView.setTypeface(AndroidUtilities.bold());
titleView.setLines(1);
titleView.setMaxLines(1);
titleView.setSingleLine(true);
titleView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
titleView.setEllipsize(TextUtils.TruncateAt.END);
titleView.setEllipsizeByGradient(true);
titleView.setText(user.first_name);
if (user.verified) {
Drawable verifiedBackground = context.getResources().getDrawable(R.drawable.verified_area).mutate();
verifiedBackground.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_verifiedBackground), PorterDuff.Mode.MULTIPLY));
Drawable verifiedCheck = context.getResources().getDrawable(R.drawable.verified_check).mutate();
verifiedCheck.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_verifiedCheck), PorterDuff.Mode.MULTIPLY));
Drawable verifiedDrawable = new CombinedDrawable(verifiedBackground, verifiedCheck);
titleView.setRightDrawable(verifiedDrawable);
}
TextView subtitleView = new TextView(context);
subtitleView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue));
@ -1576,7 +1629,7 @@ public class AlertsCreator {
Bundle args = new Bundle();
args.putLong("user_id", user.id);
if (fragment.getMessagesController().checkCanOpenChat(args, fragment)) {
fragment.presentFragment(new ChatActivity(args));
fragment.presentFragment(new ProfileActivity(args));
}
builder.getDismissRunnable().run();
@ -1589,7 +1642,7 @@ public class AlertsCreator {
subtitleView.setText(ssb);
frameLayout.addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 0, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout.addView(subtitleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 28, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout.addView(subtitleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 24, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 1));
if (allowWrite != null) {
@ -1598,7 +1651,7 @@ public class AlertsCreator {
cell[0] = new CheckBoxCell(context, 1, fragment.getResourceProvider());
cell[0].allowMultiline();
cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
cell[0].setText(AndroidUtilities.replaceTags(LocaleController.formatString("OpenUrlOption2", R.string.OpenUrlOption2, UserObject.getUserName(user))), "", true, false);
cell[0].setText(AndroidUtilities.replaceTags(LocaleController.formatString(R.string.OpenUrlOption2, UserObject.getUserName(user))), "", true, false);
cell[0].setPadding(LocaleController.isRTL ? dp(16) : dp(8), 0, LocaleController.isRTL ? dp(8) : dp(16), 0);
cell[0].setChecked(true, false);
frameLayout.addView(cell[0], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 0));
@ -1626,7 +1679,7 @@ public class AlertsCreator {
AlertDialog dialog = builder.create();
fragment.showDialog(dialog);
messageTextView.setText(AndroidUtilities.replaceSingleTag(getString(R.string.BotWebViewStartPermission), () -> {
messageTextView.setText(AndroidUtilities.replaceSingleTag(getString(R.string.BotWebViewStartPermission2), () -> {
if (dialog != null) {
dialog.dismiss();
}
@ -1942,6 +1995,85 @@ public class AlertsCreator {
}
}
public static void createClearOrDeleteDialogsAlert(BaseFragment fragment, boolean clear, boolean canDeleteHistory, int canClearCacheCount, int count, boolean hasDialogsToRevoke, MessagesStorage.BooleanCallback onProcessRunnable, Theme.ResourcesProvider resourcesProvider) {
int account = fragment.getCurrentAccount();
Context context = fragment.getParentActivity();
AlertDialog.Builder builder = new AlertDialog.Builder(context, resourcesProvider);
long selfUserId = UserConfig.getInstance(account).getClientUserId();
CheckBoxCell[] cell = new CheckBoxCell[1];
boolean[] deleteForAll = new boolean[1];
TextView messageTextView = new TextView(context);
messageTextView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
FrameLayout frameLayout = new FrameLayout(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (cell[0] != null) {
setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() + cell[0].getMeasuredHeight() + dp(7));
}
}
};
builder.setCustomViewOffset(6);
builder.setView(frameLayout);
TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
textView.setTypeface(AndroidUtilities.bold());
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (canDeleteHistory) {
if (hasDialogsToRevoke) {
cell[0] = new CheckBoxCell(context, 1, resourcesProvider);
cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
cell[0].setText(LocaleController.getString(R.string.DeleteMessagesForBothSidesWherePossible), "", false, false);
cell[0].setPadding(LocaleController.isRTL ? dp(16) : dp(8), 0, LocaleController.isRTL ? dp(8) : dp(16), 0);
frameLayout.addView(cell[0], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.LEFT, 0, 0, 0, 0));
cell[0].setOnClickListener(v -> {
CheckBoxCell cell1 = (CheckBoxCell) v;
deleteForAll[0] = !deleteForAll[0];
cell1.setChecked(deleteForAll[0], true);
});
}
textView.setText(LocaleController.formatString("DeleteFewChatsTitle", R.string.DeleteFewChatsTitle, LocaleController.formatPluralString("ChatsSelected", count)));
messageTextView.setText(LocaleController.getString("AreYouSureDeleteFewChats", R.string.AreYouSureDeleteFewChats));
} else {
if (canClearCacheCount != 0) {
textView.setText(LocaleController.formatString("ClearCacheFewChatsTitle", R.string.ClearCacheFewChatsTitle, LocaleController.formatPluralString("ChatsSelectedClearCache", count)));
messageTextView.setText(LocaleController.getString("AreYouSureClearHistoryCacheFewChats", R.string.AreYouSureClearHistoryCacheFewChats));
} else {
textView.setText(LocaleController.formatString("ClearFewChatsTitle", R.string.ClearFewChatsTitle, LocaleController.formatPluralString("ChatsSelectedClear", count)));
messageTextView.setText(LocaleController.getString("AreYouSureClearHistoryFewChats", R.string.AreYouSureClearHistoryFewChats));
}
}
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 11, 24, 0));
frameLayout.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 1));
String actionText = canDeleteHistory ? LocaleController.getString("Delete", R.string.Delete)
: canClearCacheCount != 0 ? LocaleController.getString("ClearHistoryCache", R.string.ClearHistoryCache)
: LocaleController.getString("ClearHistory", R.string.ClearHistory);
builder.setPositiveButton(actionText, (dialogInterface, i) -> {
if (onProcessRunnable != null) {
onProcessRunnable.run(deleteForAll[0]);
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
AlertDialog alertDialog = builder.create();
fragment.showDialog(alertDialog);
TextView button = (TextView) alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_text_RedBold));
}
}
public static void createClearDaysDialogAlert(BaseFragment fragment, int days, TLRPC.User user, TLRPC.Chat chat, boolean canDeleteHistory, MessagesStorage.BooleanCallback onProcessRunnable, Theme.ResourcesProvider resourcesProvider) {
if (fragment == null || fragment.getParentActivity() == null || (user == null && chat == null)) {
return;
@ -2017,7 +2149,7 @@ public class AlertsCreator {
if (chat != null && canDeleteHistory && ChatObject.isPublic(chat)) {
deleteForAll[0] = true;
}
if ((user != null && user.id != selfUserId) || (chat != null && canDeleteHistory && !ChatObject.isPublic(chat) && !ChatObject.isChannelAndNotMegaGroup(chat))) {
if ((user != null && user.id != selfUserId && user.id != UserObject.VERIFY) || (chat != null && canDeleteHistory && !ChatObject.isPublic(chat) && !ChatObject.isChannelAndNotMegaGroup(chat))) {
cell[0] = new CheckBoxCell(context, 1, resourcesProvider);
cell[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
if (chat != null) {
@ -4727,265 +4859,6 @@ public class AlertsCreator {
return builder.create();
}
public static void sendReport(TLRPC.InputPeer peer, int type, String message, ArrayList<Integer> messages, int storyId) {
TLRPC.ReportReason reason = null;
if (type == AlertsCreator.REPORT_TYPE_SPAM) {
reason = new TLRPC.TL_inputReportReasonSpam();
} else if (type == AlertsCreator.REPORT_TYPE_FAKE_ACCOUNT) {
reason = new TLRPC.TL_inputReportReasonFake();
} else if (type == AlertsCreator.REPORT_TYPE_VIOLENCE) {
reason = new TLRPC.TL_inputReportReasonViolence();
} else if (type == AlertsCreator.REPORT_TYPE_CHILD_ABUSE) {
reason = new TLRPC.TL_inputReportReasonChildAbuse();
} else if (type == AlertsCreator.REPORT_TYPE_PORNOGRAPHY) {
reason = new TLRPC.TL_inputReportReasonPornography();
} else if (type == AlertsCreator.REPORT_TYPE_ILLEGAL_DRUGS) {
reason = new TLRPC.TL_inputReportReasonIllegalDrugs();
} else if (type == AlertsCreator.REPORT_TYPE_PERSONAL_DETAILS) {
reason = new TLRPC.TL_inputReportReasonPersonalDetails();
} else if (type == AlertsCreator.REPORT_TYPE_OTHER) {
reason = new TLRPC.TL_inputReportReasonOther();
}
if (reason == null) {
return;
}
if (storyId != 0) {
TL_stories.TL_stories_report request = new TL_stories.TL_stories_report();
request.peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(peer.user_id);
request.id.add(storyId);
request.message = message;
request.reason = reason;
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(request, (response, error) -> {
});
} else {
TLRPC.TL_messages_report request = new TLRPC.TL_messages_report();
request.peer = peer;
request.id.addAll(messages);
request.message = message;
request.reason = reason;
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(request, (response, error) -> {
});
}
}
public static void createReportAlert(final Context context, final long dialog_id, final int messageId, final BaseFragment parentFragment, Runnable hideDim) {
createReportAlert(context, dialog_id, messageId, 0, parentFragment, null, hideDim);
}
public final static int REPORT_TYPE_SPAM = 0;
public final static int REPORT_TYPE_VIOLENCE = 1;
public final static int REPORT_TYPE_CHILD_ABUSE = 2;
public final static int REPORT_TYPE_ILLEGAL_DRUGS = 3;
public final static int REPORT_TYPE_PERSONAL_DETAILS = 4;
public final static int REPORT_TYPE_PORNOGRAPHY = 5;
public final static int REPORT_TYPE_FAKE_ACCOUNT = 6;
public final static int REPORT_TYPE_OTHER = 100;
public static void createReportAlert(final Context context, final long dialog_id, final int messageId, final int storyId, final BaseFragment parentFragment, Theme.ResourcesProvider resourcesProvider, Runnable hideDim) {
if (context == null || parentFragment == null) {
return;
}
final TLRPC.User user = MessagesController.getInstance(parentFragment.getCurrentAccount()).getUser(dialog_id);
final boolean isBot = user != null && user.bot;
BottomSheet.Builder builder = new BottomSheet.Builder(context, true, resourcesProvider);
builder.setDimBehind(hideDim == null);
builder.setOnPreDismissListener(di -> {
if (hideDim != null) {
hideDim.run();
}
});
builder.setTitle(LocaleController.getString(R.string.ReportChat), true);
CharSequence[] items;
int[] icons;
int[] types;
if (messageId != 0) {
items = new CharSequence[]{
LocaleController.getString(R.string.ReportChatSpam),
LocaleController.getString(R.string.ReportChatViolence),
LocaleController.getString(R.string.ReportChatChild),
LocaleController.getString(R.string.ReportChatIllegalDrugs),
LocaleController.getString(R.string.ReportChatPersonalDetails),
LocaleController.getString(R.string.ReportChatPornography),
LocaleController.getString(R.string.ReportChatOther)
};
icons = new int[]{
R.drawable.msg_clearcache,
R.drawable.msg_report_violence,
R.drawable.msg_block2,
R.drawable.msg_report_drugs,
R.drawable.msg_report_personal,
R.drawable.msg_report_xxx,
R.drawable.msg_report_other
};
types = new int[]{
REPORT_TYPE_SPAM,
REPORT_TYPE_VIOLENCE,
REPORT_TYPE_CHILD_ABUSE,
REPORT_TYPE_ILLEGAL_DRUGS,
REPORT_TYPE_PERSONAL_DETAILS,
REPORT_TYPE_PORNOGRAPHY,
REPORT_TYPE_OTHER
};
} else {
items = new CharSequence[]{
LocaleController.getString(R.string.ReportChatSpam),
LocaleController.getString(R.string.ReportChatFakeAccount),
LocaleController.getString(R.string.ReportChatViolence),
LocaleController.getString(R.string.ReportChatChild),
LocaleController.getString(R.string.ReportChatIllegalDrugs),
LocaleController.getString(R.string.ReportChatPersonalDetails),
LocaleController.getString(R.string.ReportChatPornography),
LocaleController.getString(R.string.ReportChatOther)
};
icons = new int[]{
R.drawable.msg_clearcache,
R.drawable.msg_report_fake,
R.drawable.msg_report_violence,
R.drawable.msg_block2,
R.drawable.msg_report_drugs,
R.drawable.msg_report_personal,
R.drawable.msg_report_xxx,
R.drawable.msg_report_other
};
types = new int[]{
REPORT_TYPE_SPAM,
REPORT_TYPE_FAKE_ACCOUNT,
REPORT_TYPE_VIOLENCE,
REPORT_TYPE_CHILD_ABUSE,
REPORT_TYPE_ILLEGAL_DRUGS,
REPORT_TYPE_PERSONAL_DETAILS,
REPORT_TYPE_PORNOGRAPHY,
REPORT_TYPE_OTHER
};
}
builder.setItems(items, icons, (dialogInterface, i) -> {
int type = types[i];
if (messageId == 0 && (type == REPORT_TYPE_SPAM || type == REPORT_TYPE_VIOLENCE || type == REPORT_TYPE_CHILD_ABUSE || type == REPORT_TYPE_PORNOGRAPHY || type == REPORT_TYPE_ILLEGAL_DRUGS || type == REPORT_TYPE_PERSONAL_DETAILS) && parentFragment instanceof ChatActivity && !isBot) {
((ChatActivity) parentFragment).openReportChat(type);
return;
} else if (messageId == 0 && (type == REPORT_TYPE_OTHER || type == REPORT_TYPE_FAKE_ACCOUNT) || messageId != 0 && type == REPORT_TYPE_OTHER) {
if (parentFragment instanceof ChatActivity) {
AndroidUtilities.requestAdjustNothing(parentFragment.getParentActivity(), parentFragment.getClassGuid());
}
parentFragment.showDialog(new ReportAlert(context, type, resourcesProvider) {
@Override
public void dismissInternal() {
super.dismissInternal();
if (parentFragment instanceof ChatActivity) {
((ChatActivity) parentFragment).checkAdjustResize();
}
}
@Override
protected void onSend(int type, String message) {
ArrayList<Integer> ids = new ArrayList<>();
if (messageId != 0) {
ids.add(messageId);
}
TLRPC.InputPeer peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(dialog_id);
sendReport(peer, type, message, ids, storyId);
if (parentFragment instanceof ChatActivity) {
UndoView undoView = ((ChatActivity) parentFragment).getUndoView();
if (undoView != null) {
undoView.showWithAction(0, UndoView.ACTION_REPORT_SENT, null);
}
} else {
AndroidUtilities.runOnUIThread(() -> {
BulletinFactory bulletinFactory = BulletinFactory.global();
if (bulletinFactory != null) {
bulletinFactory.createReportSent(resourcesProvider).show();
}
});
}
}
});
return;
}
TLObject req;
TLRPC.InputPeer peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(dialog_id);
if (storyId != 0) {
TL_stories.TL_stories_report request = new TL_stories.TL_stories_report();
request.id.add(storyId);
request.peer = MessagesController.getInstance(UserConfig.selectedAccount).getInputPeer(dialog_id);
request.message = "";
if (type == REPORT_TYPE_SPAM) {
request.reason = new TLRPC.TL_inputReportReasonSpam();
} else if (type == REPORT_TYPE_FAKE_ACCOUNT) {
request.reason = new TLRPC.TL_inputReportReasonFake();
} else if (type == REPORT_TYPE_VIOLENCE) {
request.reason = new TLRPC.TL_inputReportReasonViolence();
} else if (type == REPORT_TYPE_CHILD_ABUSE) {
request.reason = new TLRPC.TL_inputReportReasonChildAbuse();
} else if (type == REPORT_TYPE_PORNOGRAPHY) {
request.reason = new TLRPC.TL_inputReportReasonPornography();
} else if (type == REPORT_TYPE_ILLEGAL_DRUGS) {
request.reason = new TLRPC.TL_inputReportReasonIllegalDrugs();
} else if (type == REPORT_TYPE_PERSONAL_DETAILS) {
request.reason = new TLRPC.TL_inputReportReasonPersonalDetails();
}
req = request;
} else if (messageId != 0) {
TLRPC.TL_messages_report request = new TLRPC.TL_messages_report();
request.peer = peer;
request.id.add(messageId);
request.message = "";
if (type == REPORT_TYPE_SPAM) {
request.reason = new TLRPC.TL_inputReportReasonSpam();
} else if (type == REPORT_TYPE_VIOLENCE) {
request.reason = new TLRPC.TL_inputReportReasonViolence();
} else if (type == REPORT_TYPE_CHILD_ABUSE) {
request.reason = new TLRPC.TL_inputReportReasonChildAbuse();
} else if (type == REPORT_TYPE_PORNOGRAPHY) {
request.reason = new TLRPC.TL_inputReportReasonPornography();
} else if (type == REPORT_TYPE_ILLEGAL_DRUGS) {
request.reason = new TLRPC.TL_inputReportReasonIllegalDrugs();
} else if (type == REPORT_TYPE_PERSONAL_DETAILS) {
request.reason = new TLRPC.TL_inputReportReasonPersonalDetails();
}
req = request;
} else {
TLRPC.TL_account_reportPeer request = new TLRPC.TL_account_reportPeer();
request.peer = peer;
request.message = "";
if (type == REPORT_TYPE_SPAM) {
request.reason = new TLRPC.TL_inputReportReasonSpam();
} else if (type == REPORT_TYPE_FAKE_ACCOUNT) {
request.reason = new TLRPC.TL_inputReportReasonFake();
} else if (type == REPORT_TYPE_VIOLENCE) {
request.reason = new TLRPC.TL_inputReportReasonViolence();
} else if (type == REPORT_TYPE_CHILD_ABUSE) {
request.reason = new TLRPC.TL_inputReportReasonChildAbuse();
} else if (type == REPORT_TYPE_PORNOGRAPHY) {
request.reason = new TLRPC.TL_inputReportReasonPornography();
} else if (type == REPORT_TYPE_ILLEGAL_DRUGS) {
request.reason = new TLRPC.TL_inputReportReasonIllegalDrugs();
} else if (type == REPORT_TYPE_PERSONAL_DETAILS) {
request.reason = new TLRPC.TL_inputReportReasonPersonalDetails();
}
req = request;
}
ConnectionsManager.getInstance(UserConfig.selectedAccount).sendRequest(req, (response, error) -> {
});
if (parentFragment instanceof ChatActivity) {
UndoView undoView = ((ChatActivity) parentFragment).getUndoView();
if (undoView != null) {
undoView.showWithAction(0, UndoView.ACTION_REPORT_SENT, null);
}
} else {
BulletinFactory.of(parentFragment).createReportSent(resourcesProvider).show();
}
});
BottomSheet sheet = builder.create();
parentFragment.showDialog(sheet);
}
private static String getFloodWaitString(String error) {
int time = Utilities.parseInt(error);
String timeString;

View file

@ -6,6 +6,7 @@ import android.graphics.drawable.ShapeDrawable;
import android.util.Property;
import android.view.animation.OvershootInterpolator;
import org.telegram.messenger.ImageReceiver;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.PhotoViewer;
@ -65,6 +66,18 @@ public class AnimationProperties {
}
};
public static final Property<ImageReceiver, Float> IMAGE_RECEIVER_ALPHA = new FloatProperty<ImageReceiver>("currentAlpha") {
@Override
public void setValue(ImageReceiver object, float value) {
object.setCurrentAlpha(value);
}
@Override
public Float get(ImageReceiver object) {
return object.getCurrentAlpha();
}
};
public static final Property<ColorDrawable, Integer> COLOR_DRAWABLE_ALPHA = new IntProperty<ColorDrawable>("alpha") {
@Override
public void setValue(ColorDrawable object, int value) {

View file

@ -7,6 +7,8 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@ -20,6 +22,7 @@ import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.ActionBar;
@ -91,6 +94,11 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
this(context, fragment, needFocus, hasFixedSize, useNested, false, actionBarType, resourcesProvider);
}
EditTextEmoji editTextEmoji;
public void setEditTextEmoji(EditTextEmoji editTextEmoji) {
this.editTextEmoji = editTextEmoji;
}
@SuppressLint("AppCompatCustomView")
public BottomSheetWithRecyclerListView(Context context, BaseFragment fragment, boolean needFocus, boolean hasFixedSize, boolean useNested, boolean stackFromEnd, ActionBarType actionBarType, Theme.ResourcesProvider resourcesProvider) {
super(context, needFocus, resourcesProvider);
@ -98,7 +106,7 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
this.hasFixedSize = hasFixedSize;
this.stackFromEnd = stackFromEnd;
headerShadowDrawable = ContextCompat.getDrawable(context, R.drawable.header_shadow).mutate();
FrameLayout containerView;
SizeNotifierFrameLayout containerView;
if (useNested) {
containerView = nestedSizeNotifierLayout = new NestedSizeNotifierLayout(context) {
@ -140,44 +148,177 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
}
};
} else {
containerView = new FrameLayout(context) {
containerView = new SizeNotifierFrameLayout(context) {
private boolean ignoreLayout = false;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
contentHeight = MeasureSpec.getSize(heightMeasureSpec);
onPreMeasure(widthMeasureSpec, heightMeasureSpec);
if (stackFromEnd) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
contentHeight = MeasureSpec.getSize(heightMeasureSpec);
onPreMeasure(widthMeasureSpec, heightMeasureSpec);
if (stackFromEnd) {
heightMeasureSpec = MeasureSpec.makeMeasureSpec(contentHeight, MeasureSpec.EXACTLY);
}
if (editTextEmoji != null) {
onMeasureInternal(widthMeasureSpec, heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
preDrawInternal(canvas, this);
super.dispatchDraw(canvas);
postDrawInternal(canvas, this);
}
private void onMeasureInternal(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (!hasFixedSize && clipToActionBar && child == recyclerListView) {
canvas.save();
canvas.clipRect(0, actionBar.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
super.drawChild(canvas, child, drawingTime);
canvas.restore();
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
setMeasuredDimension(widthSize, heightSize);
// widthSize -= backgroundPaddingLeft * 2;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN && event.getY() < shadowDrawable.getBounds().top) {
dismiss();
}
return super.dispatchTouchEvent(event);
}
int keyboardSize = 0;
if (editTextEmoji != null && !editTextEmoji.isWaitingForKeyboardOpen() && keyboardSize <= AndroidUtilities.dp(20) && !editTextEmoji.isPopupShowing() && !editTextEmoji.isAnimatePopupClosing()) {
ignoreLayout = true;
editTextEmoji.hideEmojiView();
ignoreLayout = false;
}
if (keyboardSize <= AndroidUtilities.dp(20)) {
int paddingBottom = 0;
if (!keyboardVisible) {
if (editTextEmoji != null) {
paddingBottom = editTextEmoji.getEmojiPadding();
}
}
if (!AndroidUtilities.isInMultiwindow) {
heightSize -= paddingBottom;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
}
}
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child == null || child.getVisibility() == GONE) {
continue;
}
if (editTextEmoji != null && editTextEmoji.isPopupView(child)) {
// if (inBubbleMode) {
// child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(heightSize + getPaddingTop(), MeasureSpec.EXACTLY));
// } else
if (AndroidUtilities.isInMultiwindow || AndroidUtilities.isTablet()) {
if (AndroidUtilities.isTablet()) {
child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(Math.min(AndroidUtilities.dp(AndroidUtilities.isTablet() ? 200 : 320), heightSize - AndroidUtilities.statusBarHeight + getPaddingTop()), MeasureSpec.EXACTLY));
} else {
child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(heightSize - AndroidUtilities.statusBarHeight + getPaddingTop(), MeasureSpec.EXACTLY));
}
} else {
child.measure(MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(child.getLayoutParams().height, MeasureSpec.EXACTLY));
}
} else {
measureChildWithMargins(child, widthMeasureSpec, 0, heightMeasureSpec, 0);
}
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
preDrawInternal(canvas, this);
super.dispatchDraw(canvas);
postDrawInternal(canvas, this);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (!hasFixedSize && clipToActionBar && child == recyclerListView) {
canvas.save();
canvas.clipRect(0, actionBar.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
super.drawChild(canvas, child, drawingTime);
canvas.restore();
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN && event.getY() < shadowDrawable.getBounds().top) {
dismiss();
}
return super.dispatchTouchEvent(event);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (editTextEmoji == null) {
super.onLayout(changed, l, t, r, b);
return;
}
final int count = getChildCount();
int keyboardSize = measureKeyboardHeight();
int paddingBottom = getPaddingBottom();
if (!keyboardVisible && editTextEmoji != null) {
if (keyboardSize <= AndroidUtilities.dp(20) && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isTablet()) {
paddingBottom += editTextEmoji.getEmojiPadding();
}
}
setBottomClip(paddingBottom);
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
final int width = child.getMeasuredWidth();
final int height = child.getMeasuredHeight();
int childLeft;
int childTop;
int gravity = lp.gravity;
if (gravity == -1) {
gravity = Gravity.TOP | Gravity.LEFT;
}
final int absoluteGravity = gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
case Gravity.CENTER_HORIZONTAL:
childLeft = (r - l - width) / 2 + lp.leftMargin - lp.rightMargin;
break;
case Gravity.RIGHT:
childLeft = (r - l) - width - lp.rightMargin - getPaddingRight() - backgroundPaddingLeft;
break;
case Gravity.LEFT:
default:
childLeft = lp.leftMargin + getPaddingLeft();
}
switch (verticalGravity) {
case Gravity.TOP:
childTop = lp.topMargin + getPaddingTop();
break;
case Gravity.CENTER_VERTICAL:
childTop = ((b - paddingBottom) - t - height) / 2 + lp.topMargin - lp.bottomMargin;
break;
case Gravity.BOTTOM:
childTop = ((b - paddingBottom) - t) - height - lp.bottomMargin;
break;
default:
childTop = lp.topMargin;
}
if (child instanceof EmojiView) {
if (AndroidUtilities.isTablet()) {
childTop = getMeasuredHeight() - child.getMeasuredHeight();
} else {
childTop = getMeasuredHeight() + keyboardSize - child.getMeasuredHeight();
}
}
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
notifyHeightChanged();
}
};
}
recyclerListView = new RecyclerListView(context, resourcesProvider) {
@ -282,6 +423,8 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
recyclerListView.setClipToPadding(true);
}
public boolean reverseLayout;
protected void resetAdapter(Context context) {
RecyclerListView.SelectionAdapter adapter = createAdapter(recyclerListView);
RecyclerListView.SelectionAdapter wrapperAdapter = new RecyclerListView.SelectionAdapter() {
@ -324,17 +467,17 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position != 0) {
adapter.onBindViewHolder(holder, position - 1);
if (position != (reverseLayout ? getItemCount() - 1 : 0)) {
adapter.onBindViewHolder(holder, position - (reverseLayout ? 0 : 1));
}
}
@Override
public int getItemViewType(int position) {
if (position == 0) {
if (position == (reverseLayout ? getItemCount() - 1 : 0)) {
return -1000;
}
return adapter.getItemViewType(position - 1);
return adapter.getItemViewType(position - (reverseLayout ? 0 : 1));
}
@Override
@ -352,27 +495,27 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
observer.onItemRangeChanged(positionStart + 1, itemCount);
observer.onItemRangeChanged(positionStart + (reverseLayout ? 0 : 1), itemCount);
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
observer.onItemRangeChanged(positionStart + 1, itemCount, payload);
observer.onItemRangeChanged(positionStart + (reverseLayout ? 0 : 1), itemCount, payload);
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
observer.onItemRangeInserted(positionStart + 1, itemCount);
observer.onItemRangeInserted(positionStart + (reverseLayout ? 0 : 1), itemCount);
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
observer.onItemRangeRemoved(positionStart + 1, itemCount);
observer.onItemRangeRemoved(positionStart + (reverseLayout ? 0 : 1), itemCount);
}
@Override
public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) {
observer.onItemRangeMoved(fromPosition + 1, toPosition + 1, itemCount);
observer.onItemRangeMoved(fromPosition + (reverseLayout ? 0 : 1), toPosition + (reverseLayout ? 0 : 1), itemCount);
}
});
}
@ -406,19 +549,38 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
headerShadowDrawable.draw(canvas);
}
}
if (restore) {
canvas.restore();
restore = false;
}
}
private boolean restore;
private void preDrawInternal(Canvas canvas, View parent) {
restore = false;
if (!hasFixedSize) {
RecyclerView.ViewHolder holder = recyclerListView.findViewHolderForAdapterPosition(0);
int top = -AndroidUtilities.dp(16);
if (holder != null) {
top = holder.itemView.getBottom() - AndroidUtilities.dp(16);
if (takeTranslationIntoAccount) {
top += (int) holder.itemView.getTranslationY();
int top;
if (reverseLayout) {
top = recyclerListView.getHeight();
for (int i = 0; i < recyclerListView.getChildCount(); i++) {
View child = recyclerListView.getChildAt(i);
int pos = recyclerListView.getChildAdapterPosition(child);
if (pos != RecyclerView.NO_POSITION && pos != recyclerListView.getAdapter().getItemCount() - 1) {
top = Math.min(top, child.getTop() + (takeTranslationIntoAccount ? (int) child.getTranslationY() : 0));
}
}
top -= AndroidUtilities.dp(16);
} else {
RecyclerView.ViewHolder holder = recyclerListView.findViewHolderForAdapterPosition(0);
top = -AndroidUtilities.dp(16);
if (holder != null) {
top = holder.itemView.getBottom() - AndroidUtilities.dp(16);
if (takeTranslationIntoAccount) {
top += (int) holder.itemView.getTranslationY();
}
}
}
top = top - headerHeight - headerPaddingTop - headerPaddingBottom;
top -= headerHeight + headerPaddingTop + headerPaddingBottom;
if (showHandle && handleOffset) {
top -= dp(actionBarType == ActionBarType.SLIDING ? 8 : 16);
}
@ -434,6 +596,12 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
} else if (actionBarType == ActionBarType.SLIDING) {
float actionBarY = Math.max(top + dp(8) + headerPaddingTop - AndroidUtilities.statusBarHeight, 0.0f);
float t = actionBarSlideProgress.set(actionBarY == 0.0f ? 1.0f : 0.0f);
if (t != 0 && t != 1) {
canvas.save();
canvas.clipRect(0, actionBarY, containerView.getMeasuredWidth(), containerView.getMeasuredHeight());
restore = true;
}
progressToFullView = t;
shadowAlpha = t;
handleAlpha = AndroidUtilities.lerp(1.0f, 0.5f, t);
@ -593,14 +761,16 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
}
public void applyScrolledPosition(boolean ignorePaddingView) {
if (recyclerListView != null && layoutManager != null && savedScrollPosition >= 0) {
if (recyclerListView != null && recyclerListView.getLayoutManager() != null && savedScrollPosition >= 0) {
int offset = savedScrollOffset - containerView.getTop() - recyclerListView.getPaddingTop();
RecyclerView.ViewHolder paddingViewHolder = recyclerListView.findViewHolderForAdapterPosition(0);
if (ignorePaddingView && paddingViewHolder != null) {
View view = paddingViewHolder.itemView;
offset -= Math.max(view.getBottom() - recyclerListView.getPaddingTop(), 0);
}
layoutManager.scrollToPositionWithOffset(savedScrollPosition, offset);
if (recyclerListView.getLayoutManager() instanceof LinearLayoutManager) {
((LinearLayoutManager) recyclerListView.getLayoutManager()).scrollToPositionWithOffset(savedScrollPosition, offset);
}
savedScrollPosition = -1;
}
}

View file

@ -1329,6 +1329,14 @@ public class Bulletin {
}
}
public void setAnimation(TLRPC.Document document, int w, int h, String... layers) {
imageView.setAutoRepeat(true);
imageView.setAnimation(document, w, h);
for (String layer : layers) {
imageView.setLayerColor(layer + ".**", textColor);
}
}
public CharSequence getAccessibilityText() {
return titleTextView.getText() + ".\n" + subtitleTextView.getText();
}

View file

@ -583,6 +583,29 @@ public final class BulletinFactory {
return create(layout, Bulletin.DURATION_LONG);
}
public Bulletin createEmojiBulletin(TLRPC.Document document, CharSequence text, CharSequence subtext) {
final Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(getContext(), resourcesProvider);
if (MessageObject.isTextColorEmoji(document)) {
layout.imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_undo_infoColor), PorterDuff.Mode.SRC_IN));
}
layout.setAnimation(document, 36, 36);
layout.titleTextView.setText(text);
layout.subtitleTextView.setText(subtext);
return create(layout, (text.length() + subtext.length()) < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG);
}
public Bulletin createEmojiBulletin(TLRPC.Document document, CharSequence text, CharSequence subtext, CharSequence buttonText, Runnable onButtonClick) {
final Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(getContext(), resourcesProvider);
if (MessageObject.isTextColorEmoji(document)) {
layout.imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_undo_infoColor), PorterDuff.Mode.SRC_IN));
}
layout.setAnimation(document, 36, 36);
layout.titleTextView.setText(text);
layout.subtitleTextView.setText(subtext);
layout.setButton(new Bulletin.UndoButton(getContext(), true, resourcesProvider).setText(buttonText).setUndoAction(onButtonClick));
return create(layout, (text.length() + subtext.length()) < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG);
}
public Bulletin createStaticEmojiBulletin(TLRPC.Document document, CharSequence text) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
if (MessageObject.isTextColorEmoji(document)) {

View file

@ -0,0 +1,140 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.dpf2;
import static org.telegram.messenger.LocaleController.formatPluralString;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ClickableSpan;
import android.text.style.ReplacementSpan;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Business.QuickRepliesActivity;
public class ButtonSpan extends ReplacementSpan {
private final Theme.ResourcesProvider resourcesProvider;
private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Text text;
private final Runnable onClickListener;
private ButtonBounce bounce;
private ButtonSpan(CharSequence buttonText, Runnable onClick, Theme.ResourcesProvider resourcesProvider) {
this.resourcesProvider = resourcesProvider;
this.onClickListener = onClick;
text = new Text(buttonText, 12);
}
public static CharSequence make(CharSequence buttonText, Runnable onClick) {
return make(buttonText, onClick, null);
}
public static CharSequence make(CharSequence buttonText, Runnable onClick, Theme.ResourcesProvider resourcesProvider) {
SpannableString ss = new SpannableString("btn");
ButtonSpan span1 = new ButtonSpan(buttonText, onClick, resourcesProvider);
ss.setSpan(span1, 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
return ss;
}
public int getSize() {
return (int) (this.text.getCurrentWidth() + dp(14));
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
return getSize();
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
final float h = dpf2(17), cy = (top + bottom) / 2f;
AndroidUtilities.rectTmp.set(x, cy - h / 2f, x + getSize(), cy + h / 2f);
final float s = bounce == null ? 1f : bounce.getScale(.025f);
canvas.save();
canvas.scale(s, s, AndroidUtilities.rectTmp.centerX(), AndroidUtilities.rectTmp.centerY());
final int color = Theme.getColor(Theme.key_featuredStickers_addButton, resourcesProvider);
backgroundPaint.setColor(Theme.multAlpha(color, .15f));
canvas.drawRoundRect(AndroidUtilities.rectTmp, h / 2, h / 2, backgroundPaint);
this.text.draw(canvas, x + dp(7), (top + bottom) / 2f, color, 1f);
canvas.restore();
}
public void setPressed(View view, boolean pressed) {
if (bounce == null) {
bounce = new ButtonBounce(view);
}
bounce.setPressed(pressed);
}
public static class TextViewButtons extends LinkSpanDrawable.LinksTextView {
public TextViewButtons(Context context) {
super(context);
}
public TextViewButtons(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, resourcesProvider);
}
public ButtonSpan findSpan(float x, int y) {
if (!(getText() instanceof Spanned)) return null;
Layout layout = getLayout();
if (layout == null) return null;
int line = layout.getLineForVertical(y);
int offset = layout.getOffsetForHorizontal(line, x);
Spanned spanned = (Spanned) getText();
ButtonSpan[] spans = spanned.getSpans(layout.getLineStart(line), layout.getLineEnd(line), ButtonSpan.class);
for (int i = 0; i < spans.length; ++i) {
ButtonSpan span = spans[i];
if (spanned.getSpanStart(span) <= offset && spanned.getSpanEnd(span) >= offset) {
return span;
}
}
return null;
}
private ButtonSpan pressedSpan;
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
ButtonSpan span = findSpan(event.getX(), (int) event.getY());
if (action == MotionEvent.ACTION_DOWN) {
pressedSpan = span;
if (pressedSpan != null) {
pressedSpan.setPressed(this, true);
return true;
}
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (pressedSpan != null) {
pressedSpan.setPressed(this, false);
if (action == MotionEvent.ACTION_UP && pressedSpan.onClickListener != null) {
pressedSpan.onClickListener.run();
}
}
pressedSpan = null;
} else if (action == MotionEvent.ACTION_MOVE) {
if (pressedSpan != null && pressedSpan != span) {
pressedSpan.setPressed(this, false);
pressedSpan = null;
}
}
return pressedSpan != null || super.onTouchEvent(event);
}
}
}

View file

@ -160,12 +160,11 @@ import org.telegram.ui.BasePermissionsActivity;
import org.telegram.ui.Business.BusinessLinksController;
import org.telegram.ui.Business.QuickRepliesController;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.Premium.boosts.BoostRepository;
import org.telegram.ui.Components.Premium.boosts.PremiumPreviewGiftToUsersBottomSheet;
import org.telegram.ui.ContentPreviewViewer;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.Gifts.GiftSheet;
import org.telegram.ui.GroupStickersActivity;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.MessageSendPreview;
@ -3253,20 +3252,18 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
ArrayList<TLRPC.TL_premiumGiftOption> options = new ArrayList<>(getParentFragment().getCurrentUserInfo().premium_gifts);
if (options.isEmpty()) {
final AlertDialog progressDialog = new AlertDialog(getContext(), AlertDialog.ALERT_TYPE_SPINNER);
final int reqId = BoostRepository.loadGiftOptions(null, loadedOptions -> {
final int reqId = BoostRepository.loadGiftOptions(currentAccount, null, loadedOptions -> {
progressDialog.dismiss();
loadedOptions = BoostRepository.filterGiftOptions(loadedOptions, 1);
loadedOptions = BoostRepository.filterGiftOptionsByBilling(loadedOptions);
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(user);
PremiumPreviewGiftToUsersBottomSheet.show(users, loadedOptions);
new GiftSheet(getContext(), currentAccount, user.id, loadedOptions, null).show();
});
progressDialog.setOnCancelListener(di -> {
parentFragment.getConnectionsManager().cancelRequest(reqId, true);
});
progressDialog.showDelayed(200);
} else {
new GiftPremiumBottomSheet(getParentFragment(), getParentFragment().getCurrentUser()).show();
new GiftSheet(getContext(), currentAccount, user.id, null, null).show();
}
});
}
@ -9877,7 +9874,11 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
return false;
}
if (parentFragment != null && parentFragment.getChatMode() == ChatActivity.MODE_QUICK_REPLIES) return false;
if (button instanceof TLRPC.TL_keyboardButton) {
if (button instanceof TLRPC.TL_keyboardButtonCopy) {
final TLRPC.TL_keyboardButtonCopy btn = (TLRPC.TL_keyboardButtonCopy) button;
AndroidUtilities.addToClipboard(btn.copy_text);
BulletinFactory.of(parentFragment).createCopyBulletin(LocaleController.formatString(R.string.ExactTextCopied, btn.copy_text)).show(true);
} else if (button instanceof TLRPC.TL_keyboardButton) {
SendMessagesHelper.SendMessageParams params = SendMessagesHelper.SendMessageParams.of(button.text, dialog_id, replyMessageObject, getThreadMessage(), null, false, null, null, null, true, 0, null, false);
params.quick_reply_shortcut = parentFragment != null ? parentFragment.quickReplyShortcut : null;
params.quick_reply_shortcut_id = parentFragment != null ? parentFragment.getQuickReplyId() : 0;
@ -10353,7 +10354,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
AlertDialog.Builder builder = new AlertDialog.Builder(parentActivity, resourcesProvider);
builder.setTitle(getString(R.string.ClearRecentEmojiTitle));
builder.setMessage(getString(R.string.ClearRecentEmojiText));
builder.setPositiveButton(getString(R.string.ClearForAll), (dialogInterface, i) -> emojiView.clearRecentEmoji());
builder.setPositiveButton(getString(R.string.ClearButton), (dialogInterface, i) -> emojiView.clearRecentEmoji());
builder.setNegativeButton(getString(R.string.Cancel), null);
parentFragment.showDialog(builder.create());
}

View file

@ -41,6 +41,10 @@ public interface ChatActivityInterface {
return 0;
}
default boolean isRightFragment() {
return false;
}
ChatAvatarContainer getAvatarContainer();
default void checkAndUpdateAvatar() {

View file

@ -164,7 +164,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
parentFragment = (ChatActivity) baseFragment;
}
final boolean avatarClickable = parentFragment != null && parentFragment.getChatMode() == 0 && !UserObject.isReplyUser(parentFragment.getCurrentUser());
final boolean avatarClickable = parentFragment != null && parentFragment.getChatMode() == 0 && !UserObject.isReplyUser(parentFragment.getCurrentUser()) && (parentFragment.getCurrentUser() == null || parentFragment.getCurrentUser().id != UserObject.VERIFY);
avatarImageView = new BackupImageView(context) {
StoriesUtilities.AvatarStoryParams params = new StoriesUtilities.AvatarStoryParams(true) {
@ -325,7 +325,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
}
if (parentFragment != null && (parentFragment.getChatMode() == 0 || parentFragment.getChatMode() == ChatActivity.MODE_SAVED)) {
if ((!parentFragment.isThreadChat() || parentFragment.isTopic) && !UserObject.isReplyUser(parentFragment.getCurrentUser())) {
if ((!parentFragment.isThreadChat() || parentFragment.isTopic || parentFragment.isComments) && !UserObject.isReplyUser(parentFragment.getCurrentUser()) && (parentFragment.getCurrentUser() == null || parentFragment.getCurrentUser().id != UserObject.VERIFY)) {
setOnClickListener(v -> {
openProfile(false);
});
@ -377,6 +377,12 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
return super.onTouchEvent(ev);
}
@Override
public void setPressed(boolean pressed) {
super.setPressed(pressed);
bounce.setPressed(pressed);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
@ -509,7 +515,16 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
}
}
if (parentFragment.isComments) {
if (chat == null) return;
parentFragment.presentFragment(ProfileActivity.of(-chat.id), removeLast);
return;
}
if (user != null) {
if (user.id == UserObject.VERIFY) {
return;
}
Bundle args = new Bundle();
if (UserObject.isUserSelf(user)) {
if (!sharedMediaPreloader.hasSharedMedia()) {
@ -940,7 +955,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
return;
}
TLRPC.User user = parentFragment.getCurrentUser();
if ((UserObject.isUserSelf(user) || UserObject.isReplyUser(user) || parentFragment.getChatMode() != 0) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) {
if ((UserObject.isUserSelf(user) || UserObject.isReplyUser(user) || user != null && user.id == UserObject.VERIFY || parentFragment.getChatMode() != 0) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) {
if (getSubtitleTextView().getVisibility() != GONE) {
getSubtitleTextView().setVisibility(GONE);
}
@ -1017,6 +1032,8 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
String newStatus;
if (UserObject.isReplyUser(user)) {
newStatus = "";
} else if (user.id == UserObject.VERIFY) {
newStatus = "";//LocaleController.getString(R.string.VerifyCodesNotifications);
} else if (user.id == UserConfig.getInstance(currentAccount).getClientUserId()) {
newStatus = LocaleController.getString(R.string.ChatYourSelf);
} else if (user.id == 333000 || user.id == 777000 || user.id == 42777) {

View file

@ -100,10 +100,7 @@ public class ChatGreetingsView extends LinearLayout {
updateColors();
titleView.setText(getString(R.string.NoMessages));
descriptionView.setText(getString(R.string.NoMessagesGreetingsDescription));
descriptionView.setMaxWidth(HintView2.cutInFancyHalf(descriptionView.getText(), descriptionView.getPaint()));
stickerToSendView.setContentDescription(descriptionView.getText());
setText(getString(R.string.NoMessages), getString(R.string.NoMessagesGreetingsDescription));
preloadedGreetingsSticker = sticker;
if (preloadedGreetingsSticker == null) {
@ -111,6 +108,13 @@ public class ChatGreetingsView extends LinearLayout {
}
}
public void setText(CharSequence title, CharSequence description) {
titleView.setText(title);
descriptionView.setText(description);
descriptionView.setMaxWidth(HintView2.cutInFancyHalf(descriptionView.getText(), descriptionView.getPaint()));
stickerToSendView.setContentDescription(descriptionView.getText());
}
private RLottieImageView premiumIconView;
private TextView premiumTextView;
private TextView premiumButtonView;

View file

@ -8,7 +8,11 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.util.TypedValue;
@ -18,20 +22,24 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.Theme;
import java.util.ArrayList;
public class ContactsEmptyView extends LinearLayout implements NotificationCenter.NotificationCenterDelegate {
public class ContactsEmptyView extends LinearLayout {
private TextView titleTextView;
private TextView subtitleTextView;
private LinkSpanDrawable.LinksTextView buttonTextView;
private BackupImageView stickerView;
private ArrayList<TextView> textViews = new ArrayList<>();
private ArrayList<ImageView> imageViews = new ArrayList<>();
@ -39,8 +47,6 @@ public class ContactsEmptyView extends LinearLayout implements NotificationCente
private int currentAccount = UserConfig.selectedAccount;
private static final String stickerSetName = AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME;
public static final String svg = "m418 282.6c13.4-21.1 20.2-44.9 20.2-70.8 0-88.3-79.8-175.3-178.9-175.3-100.1 0-178.9 88-178.9 175.3 0 46.6 16.9 73.1 29.1 86.1-19.3 23.4-30.9 52.3-34.6 86.1-2.5 22.7 3.2 41.4 17.4 57.3 14.3 16 51.7 35 148.1 35 41.2 0 119.9-5.3 156.7-18.3 49.5-17.4 59.2-41.1 59.2-76.2 0-41.5-12.9-74.8-38.3-99.2z";
public ContactsEmptyView(Context context) {
super(context);
@ -56,52 +62,44 @@ public class ContactsEmptyView extends LinearLayout implements NotificationCente
}
titleTextView = new TextView(context);
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
titleTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
titleTextView.setGravity(Gravity.CENTER_HORIZONTAL);
titleTextView.setText(LocaleController.getString(R.string.NoContactsYet));
titleTextView.setText(LocaleController.getString(R.string.NoContactsYet2));
titleTextView.setTypeface(AndroidUtilities.bold());
titleTextView.setMaxWidth(AndroidUtilities.dp(260));
addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 18, 0, 14));
addView(titleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 18, 0, 9));
LinearLayout linesContainer = new LinearLayout(context);
linesContainer.setOrientation(VERTICAL);
addView(linesContainer, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
subtitleTextView = new TextView(context);
subtitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
subtitleTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
subtitleTextView.setGravity(Gravity.CENTER_HORIZONTAL);
subtitleTextView.setText(LocaleController.getString(R.string.NoContactsYet2Sub));
subtitleTextView.setMaxWidth(AndroidUtilities.dp(260));
addView(subtitleTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 0, 0, 14));
for (int a = 0; a < 3; a++) {
if (a == 1) continue;
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linesContainer.addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT, 0, 8, 0, 0));
buttonTextView = new LinkSpanDrawable.LinksTextView(context);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
buttonTextView.setLinkTextColor(Theme.getColor(Theme.key_chat_messageLinkIn));
buttonTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
buttonTextView.setGravity(Gravity.CENTER_HORIZONTAL);
buttonTextView.setPadding(dp(8), dp(2), dp(2), dp(8));
buttonTextView.setDisablePaddingsOffsetY(true);
buttonTextView.setText(AndroidUtilities.replaceArrows(AndroidUtilities.makeClickable(LocaleController.getString(R.string.NoContactsYet2Invite), () -> {
onInviteClick();
}), true, dp(8f / 3f), dp(1)));
buttonTextView.setMaxWidth(AndroidUtilities.dp(260));
addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 0, 0, 14));
}
ImageView imageView = new ImageView(context);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText), PorterDuff.Mode.MULTIPLY));
imageView.setImageResource(R.drawable.list_circle);
imageViews.add(imageView);
protected void onInviteClick() {
Activity activity = AndroidUtilities.findActivity(getContext());
if (activity == null || activity.isFinishing()) return;
TextView textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
textView.setMaxWidth(AndroidUtilities.dp(260));
textViews.add(textView);
textView.setGravity(Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT));
switch (a) {
case 0:
textView.setText(LocaleController.getString(R.string.NoContactsYetLine1));
break;
case 2:
textView.setText(LocaleController.getString(R.string.NoContactsYetLine3));
break;
}
if (LocaleController.isRTL) {
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
linearLayout.addView(imageView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 8, 7, 0, 0));
} else {
linearLayout.addView(imageView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, 8, 8, 0));
linearLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
}
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
String text = ContactsController.getInstance(currentAccount).getInviteText(0);
intent.putExtra(Intent.EXTRA_TEXT, text);
activity.startActivityForResult(Intent.createChooser(intent, text), 500);
}
public void setColors() {
@ -115,40 +113,12 @@ public class ContactsEmptyView extends LinearLayout implements NotificationCente
}
private void setSticker() {
TLRPC.TL_messages_stickerSet set = MediaDataController.getInstance(currentAccount).getStickerSetByName(stickerSetName);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(stickerSetName);
}
if (set != null && set.documents.size() >= 1) {
TLRPC.Document document = set.documents.get(0);
ImageLocation imageLocation = ImageLocation.getForDocument(document);
stickerView.setImage(imageLocation, "130_130", "tgs", drawable, set);
} else {
MediaDataController.getInstance(currentAccount).loadStickersByEmojiOrName(stickerSetName, false, true);
stickerView.setImageDrawable(drawable);
}
stickerView.setImageDrawable(new RLottieDrawable(R.raw.utyan_empty, "utyan_empty", dp(130), dp(130)));
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
setSticker();
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.diceStickersDidLoad);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.diceStickersDidLoad);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.diceStickersDidLoad) {
String name = (String) args[0];
if (stickerSetName.equals(name)) {
setSticker();
}
}
}
}

View file

@ -1,9 +1,12 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Build;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
@ -28,7 +31,7 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.GroupCreateUserCell;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import java.util.ArrayList;
import java.util.List;
@ -36,7 +39,7 @@ import java.util.List;
public class CreateGroupCallBottomSheet extends BottomSheetWithRecyclerListView {
private static final int
HOLDER_TYPE_HEADER = 0,
HOLDER_TYPE_DIVIDER = 1,
HOLDER_TYPE_SHADOW_TEXT = 1,
HOLDER_TYPE_SUBTITLE = 2,
HOLDER_TYPE_USER = 3;
@ -62,10 +65,14 @@ public class CreateGroupCallBottomSheet extends BottomSheetWithRecyclerListView
private boolean isScheduleSelected;
private TLRPC.Peer selectedPeer;
private TLRPC.InputPeer selectAfterDismiss;
private final BaseFragment fragment;
private final long dialogId;
public CreateGroupCallBottomSheet(BaseFragment fragment, ArrayList<TLRPC.Peer> arrayList, long dialogId, JoinCallAlert.JoinCallAlertDelegate joinCallDelegate) {
super(fragment, false, false);
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
this.fragment = fragment;
this.dialogId = dialogId;
this.topPadding = 0.26f;
this.chats = new ArrayList<>(arrayList);
this.joinCallDelegate = joinCallDelegate;
@ -152,7 +159,7 @@ public class CreateGroupCallBottomSheet extends BottomSheetWithRecyclerListView
public void dismissInternal() {
super.dismissInternal();
if (selectAfterDismiss != null) {
joinCallDelegate.didSelectChat(selectAfterDismiss, chats.size() > 1, isScheduleSelected);
joinCallDelegate.didSelectChat(selectAfterDismiss, chats.size() > 1, isScheduleSelected, false);
}
}
@ -183,15 +190,19 @@ public class CreateGroupCallBottomSheet extends BottomSheetWithRecyclerListView
case HOLDER_TYPE_HEADER:
view = new TopCell(context, isChannelOrGiga);
break;
case HOLDER_TYPE_DIVIDER:
view = new ShadowSectionCell(context, 12, Theme.getColor(Theme.key_windowBackgroundGray));
break;
case HOLDER_TYPE_SUBTITLE:
view = new HeaderCell(context, 22);
break;
case HOLDER_TYPE_USER:
view = new GroupCreateUserCell(context, 1, 0, false);
break;
case HOLDER_TYPE_SHADOW_TEXT:
TextInfoPrivacyCell cell = new TextInfoPrivacyCell(context);
cell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray, resourcesProvider));
cell.setTopPadding(17);
cell.setBottomPadding(17);
view = cell;
break;
}
view.setLayoutParams(new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
return new RecyclerListView.Holder(view);
@ -219,6 +230,12 @@ public class CreateGroupCallBottomSheet extends BottomSheetWithRecyclerListView
cell.setTextSize(15);
cell.setPadding(0, 0, 0, AndroidUtilities.dp(2));
cell.setText(LocaleController.getString(R.string.VoipChatDisplayedAs).replace(":", ""));
} else if (holder.getItemViewType() == HOLDER_TYPE_SHADOW_TEXT) {
TextInfoPrivacyCell cell = (TextInfoPrivacyCell) holder.itemView;
CharSequence text = AndroidUtilities.replaceArrows(AndroidUtilities.replaceSingleTag(LocaleController.getString(R.string.VoipChatStreamWithAnotherApp), Theme.key_windowBackgroundWhiteBlueHeader, AndroidUtilities.REPLACING_TAG_TYPE_LINK, () -> {
CreateRtmpStreamBottomSheet.show(selectedPeer, fragment, dialogId, chats.size() > 1, joinCallDelegate);
}), true, dp(1), dp(1f));
cell.setText(text);
}
}
@ -228,7 +245,7 @@ public class CreateGroupCallBottomSheet extends BottomSheetWithRecyclerListView
case 0:
return HOLDER_TYPE_HEADER;
case 1:
return HOLDER_TYPE_DIVIDER;
return HOLDER_TYPE_SHADOW_TEXT;
case 2:
return HOLDER_TYPE_SUBTITLE;
default:

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