update to 10.5.0 (4228)

This commit is contained in:
dkaraush 2023-12-31 16:05:27 +04:00
parent 33a48d8945
commit a746a072dc
368 changed files with 26674 additions and 3963 deletions

View file

@ -46,6 +46,16 @@ dependencies {
implementation 'com.google.code.gson:gson:2.10'
implementation 'com.google.guava:guava:31.1-android'
implementation 'com.google.android.gms:play-services-mlkit-subject-segmentation:16.0.0-beta1'
constraints {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0") {
because("kotlin-stdlib-jdk7 is now a part of kotlin-stdlib")
}
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0") {
because("kotlin-stdlib-jdk8 is now a part of kotlin-stdlib")
}
}
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
@ -108,6 +118,7 @@ android {
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
@ -121,6 +132,7 @@ android {
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PRIVATE") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
@ -134,6 +146,7 @@ android {
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_PUBLIC") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
@ -147,6 +160,7 @@ android {
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"" + getProps("APP_CENTER_HASH_HARDCORE") + "\""
buildConfigField "boolean", "DEBUG_VERSION", "true"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "true"
@ -160,6 +174,7 @@ android {
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
buildConfigField "boolean", "DEBUG_VERSION", "false"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"
@ -174,6 +189,7 @@ android {
multiDexEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../TMessagesProj/proguard-rules.pro'
ndk.debugSymbolLevel = 'FULL'
buildConfigField "String", "BUILD_VERSION_STRING", "\"" + APP_VERSION_NAME + "\""
buildConfigField "String", "APP_CENTER_HASH", "\"\""
buildConfigField "boolean", "DEBUG_VERSION", "false"
buildConfigField "boolean", "DEBUG_PRIVATE_VERSION", "false"

View file

@ -1186,6 +1186,7 @@ std::vector<std::pair<float, float>> gatherPositions(std::vector<std::pair<float
}
thread_local static float *pixelCache = nullptr;
thread_local static int pixelCacheSize = 0;
JNIEXPORT void Java_org_telegram_messenger_Utilities_generateGradient(JNIEnv *env, jclass clazz, jobject bitmap, jboolean unpin, jint phase, jfloat progress, jint width, jint height, jint stride, jintArray colors) {
if (!bitmap) {
@ -1221,6 +1222,13 @@ JNIEXPORT void Java_org_telegram_messenger_Utilities_generateGradient(JNIEnv *en
auto colorsArray = (uint8_t *) env->GetIntArrayElements(colors, nullptr);
float *newPixelCache = nullptr;
if (width * height != pixelCacheSize && pixelCache != nullptr) {
delete[] pixelCache;
pixelCache = nullptr;
}
pixelCacheSize = width * height;
if (pixelCache == nullptr) {
newPixelCache = new float[width * height * 2];
}

View file

@ -122,6 +122,7 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
buffer->rewind();
NativeByteBuffer *reuseLater = nullptr;
while (buffer->hasRemaining()) {
if (!hasSomeDataSinceLastConnect) {
currentDatacenter->storeCurrentAddressAndPortNum();
@ -154,14 +155,11 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
if ((fByte & (1 << 7)) != 0) {
buffer->position(mark);
if (buffer->remaining() < 4) {
NativeByteBuffer *reuseLater = restOfTheData;
reuseLater = restOfTheData;
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
restOfTheData->writeBytes(buffer);
restOfTheData->limit(restOfTheData->position());
lastPacketLength = 0;
if (reuseLater != nullptr) {
reuseLater->reuse();
}
break;
}
int32_t ackId = buffer->readBigInt32(nullptr) & (~(1 << 31));
@ -175,14 +173,11 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
buffer->position(mark);
if (buffer->remaining() < 4) {
if (restOfTheData == nullptr || (restOfTheData != nullptr && restOfTheData->position() != 0)) {
NativeByteBuffer *reuseLater = restOfTheData;
reuseLater = restOfTheData;
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
restOfTheData->writeBytes(buffer);
restOfTheData->limit(restOfTheData->position());
lastPacketLength = 0;
if (reuseLater != nullptr) {
reuseLater->reuse();
}
} else {
restOfTheData->position(restOfTheData->limit());
}
@ -195,14 +190,11 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
} else {
if (buffer->remaining() < 4) {
if (restOfTheData == nullptr || (restOfTheData != nullptr && restOfTheData->position() != 0)) {
NativeByteBuffer *reuseLater = restOfTheData;
reuseLater = restOfTheData;
restOfTheData = BuffersStorage::getInstance().getFreeBuffer(16384);
restOfTheData->writeBytes(buffer);
restOfTheData->limit(restOfTheData->position());
lastPacketLength = 0;
if (reuseLater != nullptr) {
reuseLater->reuse();
}
} else {
restOfTheData->position(restOfTheData->limit());
}
@ -223,7 +215,7 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
if (currentProtocolType != ProtocolTypeDD && currentProtocolType != ProtocolTypeTLS && currentPacketLength % 4 != 0 || currentPacketLength > 2 * 1024 * 1024) {
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received invalid packet length", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType);
reconnect();
return;
break;
}
if (currentPacketLength < buffer->remaining()) {
@ -233,8 +225,6 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
} else {
if (LOGS_ENABLED) DEBUG_D("connection(%p, account%u, dc%u, type %d) received packet size less(%u) then message size(%u)", this, currentDatacenter->instanceNum, currentDatacenter->getDatacenterId(), connectionType, buffer->remaining(), currentPacketLength);
NativeByteBuffer *reuseLater = nullptr;
if (restOfTheData != nullptr && restOfTheData->capacity() < len) {
reuseLater = restOfTheData;
restOfTheData = nullptr;
@ -248,10 +238,7 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
restOfTheData->limit(len);
}
lastPacketLength = len;
if (reuseLater != nullptr) {
reuseLater->reuse();
}
return;
break;
}
uint32_t old = buffer->limit();
@ -262,7 +249,7 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
if (restOfTheData != nullptr) {
if ((lastPacketLength != 0 && restOfTheData->position() == lastPacketLength) || (lastPacketLength == 0 && !restOfTheData->hasRemaining())) {
restOfTheData->reuse();
reuseLater = restOfTheData;
restOfTheData = nullptr;
} else {
restOfTheData->compact();
@ -276,6 +263,9 @@ void Connection::onReceivedData(NativeByteBuffer *buffer) {
parseLaterBuffer = nullptr;
}
}
if (reuseLater != nullptr) {
reuseLater->reuse();
}
}
void Connection::connect() {

View file

@ -253,6 +253,54 @@ private:
bool _isMuted = true;
};
namespace {
class AudioSinkImpl: public webrtc::AudioSinkInterface {
public:
AudioSinkImpl(std::function<void(float, float)> update) :
_update(update) {
}
virtual ~AudioSinkImpl() {
}
virtual void OnData(const Data& audio) override {
if (_update && audio.channels == 1) {
const int16_t *samples = (const int16_t *)audio.data;
int numberOfSamplesInFrame = (int)audio.samples_per_channel;
int16_t currentPeak = 0;
for (int i = 0; i < numberOfSamplesInFrame; i++) {
int16_t sample = samples[i];
if (sample < 0) {
sample = -sample;
}
if (_peak < sample) {
_peak = sample;
}
if (currentPeak < sample) {
currentPeak = sample;
}
_peakCount += 1;
}
if (_peakCount >= 4400) {
float level = ((float)(_peak)) / 8000.0f;
_peak = 0;
_peakCount = 0;
_update(0, level);
}
}
}
private:
std::function<void(float, float)> _update;
int _peakCount = 0;
uint16_t _peak = 0;
};
}
class IncomingV2AudioChannel : public sigslot::has_slots<> {
public:
IncomingV2AudioChannel(
@ -261,6 +309,7 @@ public:
webrtc::RtpTransport *rtpTransport,
rtc::UniqueRandomIdGenerator *randomIdGenerator,
signaling::MediaContent const &mediaContent,
std::function<void(float, float)> &&onAudioLevelUpdated,
std::shared_ptr<Threads> threads) :
_threads(threads),
_ssrc(mediaContent.ssrc),
@ -278,9 +327,7 @@ public:
_threads->getNetworkThread()->BlockingCall([&]() {
_audioChannel->SetRtpTransport(rtpTransport);
});
std::vector<cricket::AudioCodec> codecs;
for (const auto &payloadType : mediaContent.payloadTypes) {
cricket::AudioCodec codec(payloadType.id, payloadType.name, payloadType.clockrate, 0, payloadType.channels);
@ -317,11 +364,14 @@ public:
streamParams.set_stream_ids({ streamId });
incomingAudioDescription->AddStream(streamParams);
threads->getWorkerThread()->BlockingCall([&]() {
threads->getWorkerThread()->BlockingCall([this, &outgoingAudioDescription, &incomingAudioDescription, onAudioLevelUpdated = std::move(onAudioLevelUpdated), ssrc = mediaContent.ssrc]() {
_audioChannel->SetPayloadTypeDemuxingEnabled(false);
std::string errorDesc;
_audioChannel->SetLocalContent(outgoingAudioDescription.get(), webrtc::SdpType::kOffer, errorDesc);
_audioChannel->SetRemoteContent(incomingAudioDescription.get(), webrtc::SdpType::kAnswer, errorDesc);
std::unique_ptr<AudioSinkImpl> audioLevelSink(new AudioSinkImpl(std::move(onAudioLevelUpdated)));
_audioChannel->media_channel()->SetRawAudioSink(ssrc, std::move(audioLevelSink));
});
outgoingAudioDescription.reset();
@ -1101,7 +1151,7 @@ public:
mediaDeps.adm = _audioDeviceModule;
webrtc:: AudioProcessingBuilder builder;
webrtc::AudioProcessingBuilder builder;
mediaDeps.audio_processing = builder.Create();
_availableVideoFormats = mediaDeps.video_encoder_factory->GetSupportedFormats();
@ -1468,6 +1518,9 @@ public:
_rtpTransport,
_uniqueRandomIdGenerator.get(),
content,
[audioLevelUpdated = _audioLevelUpdated](float myLvl, float level) {
audioLevelUpdated(myLvl, level);
},
_threads
));
}

View file

@ -79,6 +79,8 @@
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-sdk tools:overrideLibrary="com.google.mlkit.vision.segmentation.subject"/>
<queries>
<package android:name="com.google.android.apps.maps"/>
<intent>
@ -266,6 +268,9 @@
</intent-filter>
<meta-data android:name="android.service.chooser.chooser_target_service" android:value="androidx.sharetarget.ChooserTargetServiceCompat" />
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts" />
<meta-data
android:name="com.google.mlkit.vision.DEPENDENCIES"
android:value="subject_segment" />
</activity>
<activity-alias
android:name="org.telegram.ui.CallsActivity"
@ -564,8 +569,8 @@
<meta-data android:name="com.google.android.gms.wallet.api.enabled" android:value="true" />
<meta-data android:name="com.google.android.gms.car.notification.SmallIcon" android:resource="@drawable/ic_player" />
<meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />
<!-- <meta-data android:name="com.google.android.gms.car.notification.SmallIcon" android:resource="@drawable/ic_player" />-->
<!-- <meta-data android:name="com.google.android.gms.car.application" android:resource="@xml/automotive_app_desc" />-->
<meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="face,barcode" />

View file

@ -429,7 +429,7 @@ chat_searchPanelText=-8796932
chat_inContactIcon=-1
code_comment=-2130706433
chat_outCodeBackground=857487708
chat_inCodeBackground=856033549
chat_inCodeBackground=-1
code_keyword=-27776
code_constant=-27776
code_function=-27776

View file

@ -454,7 +454,7 @@ chat_searchPanelText=-10767620
chat_inContactIcon=-1
code_comment=-2130706433
chat_outCodeBackground=859062986
chat_inCodeBackground=855638016
chat_inCodeBackground=-1
code_keyword=-27776
code_constant=-27776
code_function=-27776

View file

@ -5,6 +5,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.util.LongSparseArray;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.Interpolator;
@ -14,11 +15,13 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.BotHelpCell;
import org.telegram.ui.Cells.ChatActionCell;
@ -27,6 +30,7 @@ import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.ChatGreetingsView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ThanosEffect;
import org.telegram.ui.TextMessageEnterTransition;
import org.telegram.ui.VoiceMessageEnterTransition;
@ -125,9 +129,60 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
return;
}
// First, remove stuff
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
animateRemoveImpl(holder);
boolean hadThanos = false;
final boolean supportsThanos = getThanosEffectContainer != null && supportsThanosEffectContainer != null && supportsThanosEffectContainer.run();
if (supportsThanos) {
LongSparseArray<ArrayList<RecyclerView.ViewHolder>> groupsToRemoveWithThanos = null;
for (int i = 0; i < mPendingRemovals.size(); ++i) {
RecyclerView.ViewHolder holder = mPendingRemovals.get(i);
if (toBeSnapped.contains(holder) && holder.itemView instanceof ChatMessageCell && ((ChatMessageCell) holder.itemView).getCurrentMessagesGroup() != null) {
MessageObject msg = ((ChatMessageCell) holder.itemView).getMessageObject();
if (msg != null && msg.getGroupId() != 0) {
if (groupsToRemoveWithThanos == null) {
groupsToRemoveWithThanos = new LongSparseArray<>();
}
ArrayList<RecyclerView.ViewHolder> holders = groupsToRemoveWithThanos.get(msg.getGroupId());
if (holders == null) {
groupsToRemoveWithThanos.put(msg.getGroupId(), holders = new ArrayList<>());
}
toBeSnapped.remove(holder);
mPendingRemovals.remove(i);
i--;
holders.add(holder);
}
}
}
if (groupsToRemoveWithThanos != null) {
for (int i = 0; i < groupsToRemoveWithThanos.size(); ++i) {
// check whether we remove the whole group
ArrayList<RecyclerView.ViewHolder> holders = groupsToRemoveWithThanos.valueAt(i);
if (holders.size() <= 0) continue;
boolean wholeGroup = true;
RecyclerView.ViewHolder firstHolder = holders.get(0);
if (firstHolder.itemView instanceof ChatMessageCell) {
MessageObject.GroupedMessages group = ((ChatMessageCell) firstHolder.itemView).getCurrentMessagesGroup();
if (group != null) {
wholeGroup = group.messages.size() <= holders.size();
}
}
if (!wholeGroup) {
// not whole group, fallback to prev animation
mPendingRemovals.addAll(holders);
} else {
animateRemoveGroupImpl(holders);
hadThanos = true;
}
}
}
}
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
boolean thanos = toBeSnapped.remove(holder) && supportsThanos;
animateRemoveImpl(holder, thanos);
if (thanos) {
hadThanos = true;
}
}
final boolean finalThanos = hadThanos;
mPendingRemovals.clear();
// Next, move stuff
if (movesPending) {
@ -139,7 +194,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
@Override
public void run() {
for (MoveInfo moveInfo : moves) {
animateMoveImpl(moveInfo.holder, moveInfo);
animateMoveImpl(moveInfo.holder, moveInfo, finalThanos);
}
moves.clear();
mMovesList.remove(moves);
@ -147,7 +202,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
};
if (delayAnimations && removalsPending) {
View view = moves.get(0).holder.itemView;
ViewCompat.postOnAnimationDelayed(view, mover, getMoveAnimationDelay());
ViewCompat.postOnAnimationDelayed(view, mover, hadThanos ? 0 : getMoveAnimationDelay());
} else {
mover.run();
}
@ -661,6 +716,9 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
@Override
protected void animateMoveImpl(RecyclerView.ViewHolder holder, MoveInfo moveInfo) {
animateMoveImpl(holder, moveInfo, false);
}
protected void animateMoveImpl(RecyclerView.ViewHolder holder, MoveInfo moveInfo, boolean withThanos) {
int fromX = moveInfo.fromX;
int fromY = moveInfo.fromY;
int toX = moveInfo.toX;
@ -843,10 +901,12 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
}
}
if (translationInterpolator != null) {
if (withThanos) {
animatorSet.setInterpolator(CubicBezierInterpolator.EASE_OUT);
} else if (translationInterpolator != null) {
animatorSet.setInterpolator(translationInterpolator);
}
animatorSet.setDuration(getMoveDuration());
animatorSet.setDuration((long) (getMoveDuration() * (withThanos ? 1.9f : 1f)));
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
@ -1372,36 +1432,72 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
animatorSet.start();
}
protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
protected void animateRemoveImpl(final RecyclerView.ViewHolder holder, boolean thanos) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("animate remove impl");
FileLog.d("animate remove impl " + (thanos ? " with thanos" : ""));
}
final View view = holder.itemView;
mRemoveAnimations.add(holder);
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 0f);
dispatchRemoveStarting(holder);
animator.setDuration(getRemoveDuration());
animator.addListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
animator.removeAllListeners();
view.setAlpha(1);
view.setScaleX(1f);
view.setScaleY(1f);
view.setTranslationX(0);
view.setTranslationY(0);
if (mRemoveAnimations.remove(holder)) {
dispatchRemoveFinished(holder);
dispatchFinishedWhenDone();
if (thanos && getThanosEffectContainer != null) {
ThanosEffect thanosEffect = getThanosEffectContainer.run();
dispatchRemoveStarting(holder);
thanosEffect.animate(view, () -> {
view.setVisibility(View.VISIBLE);
if (mRemoveAnimations.remove(holder)) {
dispatchRemoveFinished(holder);
dispatchFinishedWhenDone();
}
});
} else {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 0f);
dispatchRemoveStarting(holder);
animator.setDuration(getRemoveDuration());
animator.addListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
animator.removeAllListeners();
view.setAlpha(1);
view.setScaleX(1f);
view.setScaleY(1f);
view.setTranslationX(0);
view.setTranslationY(0);
if (mRemoveAnimations.remove(holder)) {
dispatchRemoveFinished(holder);
dispatchFinishedWhenDone();
}
}
}
});
animators.put(holder, animator);
animator.start();
});
animators.put(holder, animator);
animator.start();
}
recyclerListView.stopScroll();
}
private void animateRemoveGroupImpl(final ArrayList<RecyclerView.ViewHolder> holders) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("animate remove group impl with thanos");
}
mRemoveAnimations.addAll(holders);
ThanosEffect thanosEffect = getThanosEffectContainer.run();
for (int i = 0; i < holders.size(); ++i) {
dispatchRemoveStarting(holders.get(i));
}
final ArrayList<View> views = new ArrayList<>();
for (int i = 0; i < holders.size(); ++i) {
views.add(holders.get(i).itemView);
}
thanosEffect.animateGroup(views, () -> {
for (int i = 0; i < views.size(); ++i) {
views.get(i).setVisibility(View.VISIBLE);
}
if (mRemoveAnimations.removeAll(holders)) {
for (int i = 0; i < holders.size(); ++i) {
dispatchRemoveFinished(holders.get(i));
}
dispatchFinishedWhenDone();
}
});
recyclerListView.stopScroll();
}
@ -1502,5 +1598,27 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
int captionX;
int captionY;
}
private final ArrayList<RecyclerView.ViewHolder> toBeSnapped = new ArrayList<>();
public void prepareThanos(RecyclerView.ViewHolder viewHolder) {
if (viewHolder == null) return;
toBeSnapped.add(viewHolder);
if (viewHolder.itemView instanceof ChatMessageCell) {
MessageObject msg = ((ChatMessageCell) viewHolder.itemView).getMessageObject();
if (msg != null) {
msg.deletedByThanos = true;
}
}
}
private Utilities.Callback0Return<Boolean> supportsThanosEffectContainer;
private Utilities.Callback0Return<ThanosEffect> getThanosEffectContainer;
public void setOnSnapMessage(
Utilities.Callback0Return<Boolean> supportsThanosEffectContainer,
Utilities.Callback0Return<ThanosEffect> getThanosEffectContainer
) {
this.supportsThanosEffectContainer = supportsThanosEffectContainer;
this.getThanosEffectContainer = getThanosEffectContainer;
}
}

View file

@ -4893,6 +4893,10 @@ public class AndroidUtilities {
}
public static void updateViewVisibilityAnimated(View view, boolean show, float scaleFactor, boolean goneOnHide, boolean animated) {
updateViewVisibilityAnimated(view, show, scaleFactor, goneOnHide, 1f, animated);
}
public static void updateViewVisibilityAnimated(View view, boolean show, float scaleFactor, boolean goneOnHide, float maxAlpha, boolean animated) {
if (view == null) {
return;
}
@ -4904,7 +4908,7 @@ public class AndroidUtilities {
view.animate().setListener(null).cancel();
view.setVisibility(show ? View.VISIBLE : (goneOnHide ? View.GONE : View.INVISIBLE));
view.setTag(show ? 1 : null);
view.setAlpha(1f);
view.setAlpha(maxAlpha);
view.setScaleX(1f);
view.setScaleY(1f);
} else if (show && view.getTag() == null) {
@ -4915,7 +4919,7 @@ public class AndroidUtilities {
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
}
view.animate().alpha(1f).scaleY(1f).scaleX(1f).setDuration(150).start();
view.animate().alpha(maxAlpha).scaleY(1f).scaleX(1f).setDuration(150).start();
view.setTag(1);
} else if (!show && view.getTag() != null) {
view.animate().setListener(null).cancel();
@ -5112,7 +5116,7 @@ public class AndroidUtilities {
);
}
public static CharSequence replaceCharSequence(String what, CharSequence from, CharSequence obj) {
public static SpannableStringBuilder replaceCharSequence(String what, CharSequence from, CharSequence obj) {
SpannableStringBuilder spannableStringBuilder;
if (from instanceof SpannableStringBuilder) {
spannableStringBuilder = (SpannableStringBuilder) from;
@ -5241,14 +5245,14 @@ public class AndroidUtilities {
canvas.restore();
}
Utilities.stackBlurBitmap(bitmap, Math.max((int) amount, Math.max(w, h) / 180));
AndroidUtilities.runOnUIThread(() -> {
// AndroidUtilities.runOnUIThread(() -> {
onBitmapDone.run(bitmap);
});
// });
} catch (Exception e) {
FileLog.e(e);
AndroidUtilities.runOnUIThread(() -> {
// AndroidUtilities.runOnUIThread(() -> {
onBitmapDone.run(null);
});
// });
}
// });
}

View file

@ -17,6 +17,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.net.Network;
@ -260,7 +262,11 @@ public class ApplicationLoader extends Application {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("app start time = " + (startTime = SystemClock.elapsedRealtime()));
FileLog.d("buildVersion = " + BuildVars.BUILD_VERSION);
try {
FileLog.d("buildVersion = " + ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0).versionCode);
} catch (Exception e) {
FileLog.e(e);
}
}
if (applicationContext == null) {
applicationContext = getApplicationContext();
@ -350,6 +356,13 @@ public class ApplicationLoader extends Application {
return true;
}
private static long lastNetworkCheck = -1;
private static void ensureCurrentNetworkGet() {
final long now = System.currentTimeMillis();
ensureCurrentNetworkGet(now - lastNetworkCheck > 5000);
lastNetworkCheck = now;
}
private static void ensureCurrentNetworkGet(boolean force) {
if (force || currentNetworkInfo == null) {
try {
@ -416,6 +429,11 @@ public class ApplicationLoader extends Application {
return false;
}
public static boolean useLessData() {
ensureCurrentNetworkGet();
return BuildVars.DEBUG_PRIVATE_VERSION && (SharedConfig.forceLessData || isConnectionSlow());
}
public static boolean isConnectionSlow() {
try {
ensureCurrentNetworkGet(false);

View file

@ -96,7 +96,7 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
}
public String formatCurrency(long amount, String currency, int exp, boolean rounded) {
if (currency.isEmpty()) {
if (currency == null || currency.isEmpty()) {
return String.valueOf(amount);
}
Currency cur = Currency.getInstance(currency);

View file

@ -24,8 +24,7 @@ public class BuildVars {
public static boolean USE_CLOUD_STRINGS = true;
public static boolean CHECK_UPDATES = true;
public static boolean NO_SCOPED_STORAGE = Build.VERSION.SDK_INT <= 29;
public static int BUILD_VERSION = 4139;
public static String BUILD_VERSION_STRING = "10.3.2";
public static String BUILD_VERSION_STRING = BuildConfig.BUILD_VERSION_STRING;
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";

View file

@ -2107,13 +2107,13 @@ public class ChatObject {
public static int getProfileColorId(TLRPC.Chat chat) {
if (chat == null) return 0;
// if (chat.profile_color != null && (chat.profile_color.flags & 1) != 0) return chat.profile_color.color;
if (chat.profile_color != null && (chat.profile_color.flags & 1) != 0) return chat.profile_color.color;
return -1;
}
public static long getProfileEmojiId(TLRPC.Chat chat) {
// if (chat != null && chat.profile_color != null && (chat.profile_color.flags & 2) != 0) return chat.profile_color.background_emoji_id;
return -1;
if (chat != null && chat.profile_color != null && (chat.profile_color.flags & 2) != 0) return chat.profile_color.background_emoji_id;
return 0;
}
}

View file

@ -214,7 +214,7 @@ public class ChatThemeController extends BaseController {
if (wallPaper.uploadingImage != null) {
return TextUtils.equals(oldWallpaper.uploadingImage, wallPaper.uploadingImage);
}
return wallPaper.id == oldWallpaper.id && TextUtils.equals(ChatBackgroundDrawable.hash(wallPaper.settings), ChatBackgroundDrawable.hash(oldWallpaper.settings));
return wallPaper.id == oldWallpaper.id && TextUtils.equals(ChatBackgroundDrawable.hash(wallPaper.settings), ChatBackgroundDrawable.hash(oldWallpaper.settings)) && TextUtils.equals(ChatThemeController.getWallpaperEmoticon(wallPaper), ChatThemeController.getWallpaperEmoticon(oldWallpaper));
}
return false;
}
@ -263,6 +263,10 @@ public class ChatThemeController extends BaseController {
emoticon = getEmojiSharedPreferences().getString("chatTheme_" + currentAccount + "_" + dialogId, null);
dialogEmoticonsMap.put(dialogId, emoticon);
}
return getTheme(emoticon);
}
public EmojiThemes getTheme(String emoticon) {
if (emoticon != null) {
for (EmojiThemes theme : allChatThemes) {
if (emoticon.equals(theme.getEmoticon())) {
@ -274,10 +278,10 @@ public class ChatThemeController extends BaseController {
}
public void saveChatWallpaper(long dialogId, TLRPC.WallPaper wallPaper) {
if (dialogId < 0) {
return;
}
if (wallPaper != null) {
if (wallPaper.document == null) {
return;
}
SerializedData data = new SerializedData(wallPaper.getObjectSize());
wallPaper.serializeToStream(data);
String wallpaperString = Utilities.bytesToHex(data.toByteArray());
@ -293,12 +297,16 @@ public class ChatThemeController extends BaseController {
}
public TLRPC.WallPaper getDialogWallpaper(long dialogId) {
if (dialogId < 0) {
return null;
}
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId);
if (userFull != null) {
return userFull.wallpaper;
if (dialogId >= 0) {
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId);
if (userFull != null) {
return userFull.wallpaper;
}
} else {
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-dialogId);
if (chatFull != null) {
return chatFull.wallpaper;
}
}
String wallpaperString = getEmojiSharedPreferences().getString("chatWallpaper_" + currentAccount + "_" + dialogId, null);
if (wallpaperString != null) {
@ -411,30 +419,75 @@ public class ChatThemeController extends BaseController {
return;
}
final long dialogId = userFull.id;
userFull.wallpaper_overridden = update.wallpaper_overridden;
userFull.wallpaper = update.wallpaper;
userFull.flags |= 16777216;
if ((update.flags & 1) != 0) {
userFull.wallpaper_overridden = update.wallpaper_overridden;
userFull.wallpaper = update.wallpaper;
userFull.flags |= 16777216;
} else {
userFull.wallpaper_overridden = false;
userFull.wallpaper = null;
userFull.flags &=~ 16777216;
}
getMessagesStorage().updateUserInfo(userFull, false);
saveChatWallpaper(dialogId, null);
saveChatWallpaper(dialogId, userFull.wallpaper);
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, dialogId, userFull);
});
}
} else {
// todo
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-DialogObject.getPeerDialogId(update.peer));
if (chatFull != null) {
if (wallpaperEquals(chatFull.wallpaper, update.wallpaper)) {
return;
}
final long dialogId = -chatFull.id;
if ((update.flags & 1) != 0) {
chatFull.wallpaper = update.wallpaper;
chatFull.flags2 |= 128;
} else {
chatFull.wallpaper = null;
chatFull.flags2 &=~ 128;
}
getMessagesStorage().updateChatInfo(chatFull, false);
saveChatWallpaper(dialogId, chatFull.wallpaper);
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
});
}
}
}
public static boolean wallpaperEquals(TLRPC.WallPaper a, TLRPC.WallPaper b) {
if ((a == null || a instanceof TLRPC.TL_wallPaperNoFile) && (b == null || b instanceof TLRPC.TL_wallPaperNoFile)) {
if (a == null && b == null) {
return true;
}
if (a instanceof TLRPC.TL_wallPaper && b instanceof TLRPC.TL_wallPaper) {
return a.id == b.id;
}
if (a instanceof TLRPC.TL_wallPaperNoFile && b instanceof TLRPC.TL_wallPaperNoFile) {
if (a.settings != null && b.settings != null) {
return TextUtils.equals(getWallpaperEmoticon(a), getWallpaperEmoticon(b));
}
return a.id == b.id;
}
return false;
}
public static String getWallpaperEmoticon(TLRPC.WallPaper a) {
if (a != null) {
if (a.settings != null && !TextUtils.isEmpty(a.settings.emoticon)) {
return a.settings.emoticon;
}
return "";
}
return null;
}
public static boolean isNotEmoticonWallpaper(TLRPC.WallPaper a) {
String emoticon = getWallpaperEmoticon(a);
return emoticon != null && emoticon.length() == 0;
}
public void clearWallpaper(long dialogId, boolean notify) {
clearWallpaper(dialogId, notify, false);
}
@ -460,6 +513,16 @@ public class ChatThemeController extends BaseController {
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
req.peer = MessagesController.getInputPeer(chat);
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-dialogId);
if (chatFull != null) {
chatFull.wallpaper = null;
chatFull.flags2 &= ~128;
getMessagesStorage().updateChatInfo(chatFull, false);
}
saveChatWallpaper(dialogId, null);
if (notify) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
}
}
getConnectionsManager().sendRequest(req, (response, error) -> {
@ -467,13 +530,12 @@ public class ChatThemeController extends BaseController {
});
}
public int setWallpaperToUser(long dialogId, String wallpaperLocalPath, Theme.OverrideWallpaperInfo wallpaperInfo, MessageObject serverWallpaper, Runnable callback) {
public int setWallpaperToPeer(long dialogId, String wallpaperLocalPath, Theme.OverrideWallpaperInfo wallpaperInfo, MessageObject serverWallpaper, Runnable callback) {
TLRPC.TL_messages_setChatWallPaper req = new TLRPC.TL_messages_setChatWallPaper();
if (dialogId > 0) {
if (dialogId >= 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
req.peer = MessagesController.getInputPeer(user);
} else {
//chat not supported yet
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
req.peer = MessagesController.getInputPeer(chat);
}
@ -484,52 +546,71 @@ public class ChatThemeController extends BaseController {
req.flags |= 2;
req.id = serverWallpaper.getId();
TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId);
TLRPC.UserFull userFull = null;
TLRPC.ChatFull chatFull = null;
if (dialogId >= 0) {
userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId);
} else {
chatFull = MessagesController.getInstance(currentAccount).getChatFull(-dialogId);
}
TLRPC.TL_messageActionSetChatWallPaper action = (TLRPC.TL_messageActionSetChatWallPaper) serverWallpaper.messageOwner.action;
TLRPC.WallPaper wallPaper = new TLRPC.TL_wallPaper();
wallPaper.id = action.wallpaper.id;
wallPaper.document = action.wallpaper.document;
wallPaper.settings = new TLRPC.TL_wallPaperSettings();
wallPaper.settings.intensity = (int) (wallpaperInfo.intensity * 100);
wallPaper.settings.motion = wallpaperInfo.isMotion;
wallPaper.settings.blur = wallpaperInfo.isBlurred;
wallPaper.settings.background_color = wallpaperInfo.color;
wallPaper.settings.second_background_color = wallpaperInfo.gradientColor1;
wallPaper.settings.third_background_color = wallpaperInfo.gradientColor2;
wallPaper.settings.fourth_background_color = wallpaperInfo.gradientColor3;
wallPaper.settings.rotation = wallpaperInfo.rotation;
wallPaper.uploadingImage = wallpaperLocalPath;
TLRPC.WallPaper pastWallpaper = null;
if (userFull != null) {
TLRPC.TL_messageActionSetChatWallPaper action = (TLRPC.TL_messageActionSetChatWallPaper) serverWallpaper.messageOwner.action;
TLRPC.WallPaper wallPaper = new TLRPC.TL_wallPaper();
wallPaper.id = action.wallpaper.id;
wallPaper.document = action.wallpaper.document;
wallPaper.settings = new TLRPC.TL_wallPaperSettings();
wallPaper.settings.intensity = (int) (wallpaperInfo.intensity * 100);
wallPaper.settings.motion = wallpaperInfo.isMotion;
wallPaper.settings.blur = wallpaperInfo.isBlurred;
wallPaper.settings.background_color = wallpaperInfo.color;
wallPaper.settings.second_background_color = wallpaperInfo.gradientColor1;
wallPaper.settings.third_background_color = wallpaperInfo.gradientColor2;
wallPaper.settings.fourth_background_color = wallpaperInfo.gradientColor3;
wallPaper.settings.rotation = wallpaperInfo.rotation;
wallPaper.uploadingImage = wallpaperLocalPath;
if (userFull.wallpaper != null && userFull.wallpaper.uploadingImage != null && userFull.wallpaper.uploadingImage.equals(wallPaper.uploadingImage)) {
wallPaper.stripedThumb = userFull.wallpaper.stripedThumb;
}
pastWallpaper = userFull.wallpaper;
} else if (chatFull != null) {
pastWallpaper = chatFull.wallpaper;
}
if (pastWallpaper != null && pastWallpaper.uploadingImage != null && pastWallpaper.uploadingImage.equals(wallPaper.uploadingImage)) {
wallPaper.stripedThumb = pastWallpaper.stripedThumb;
}
wallPaper.settings.flags |= 1;
wallPaper.settings.flags |= 8;
wallPaper.settings.flags |= 16;
wallPaper.settings.flags |= 32;
wallPaper.settings.flags |= 64;
wallPaper.settings.flags |= 1;
wallPaper.settings.flags |= 8;
wallPaper.settings.flags |= 16;
wallPaper.settings.flags |= 32;
wallPaper.settings.flags |= 64;
userFull.wallpaper = new TLRPC.TL_wallPaper();
userFull.wallpaper.pattern = action.wallpaper.pattern;
userFull.wallpaper.id = action.wallpaper.id;
userFull.wallpaper.document = action.wallpaper.document;
userFull.wallpaper.flags = action.wallpaper.flags;
userFull.wallpaper.creator = action.wallpaper.creator;
userFull.wallpaper.dark = action.wallpaper.dark;
userFull.wallpaper.isDefault = action.wallpaper.isDefault;
userFull.wallpaper.slug = action.wallpaper.slug;
userFull.wallpaper.access_hash = action.wallpaper.access_hash;
userFull.wallpaper.stripedThumb = action.wallpaper.stripedThumb;
userFull.wallpaper.settings = wallPaper.settings;
userFull.wallpaper.flags |= 4;
TLRPC.TL_wallPaper wallpaper = new TLRPC.TL_wallPaper();
wallpaper.pattern = action.wallpaper.pattern;
wallpaper.id = action.wallpaper.id;
wallpaper.document = action.wallpaper.document;
wallpaper.flags = action.wallpaper.flags;
wallpaper.creator = action.wallpaper.creator;
wallpaper.dark = action.wallpaper.dark;
wallpaper.isDefault = action.wallpaper.isDefault;
wallpaper.slug = action.wallpaper.slug;
wallpaper.access_hash = action.wallpaper.access_hash;
wallpaper.stripedThumb = action.wallpaper.stripedThumb;
wallpaper.settings = wallPaper.settings;
wallpaper.flags |= 4;
if (userFull != null) {
userFull.wallpaper = wallpaper;
userFull.flags |= 16777216;
getMessagesStorage().updateUserInfo(userFull, false);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, dialogId, userFull);
if (callback != null) {
callback.run();
}
} else if (chatFull != null) {
chatFull.wallpaper = wallpaper;
chatFull.flags2 |= 128;
getMessagesStorage().updateChatInfo(chatFull, false);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
}
if (callback != null) {
callback.run();
}
} else {
req.flags |= 1;
@ -543,27 +624,44 @@ public class ChatThemeController extends BaseController {
return ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.Updates) {
TLRPC.Updates res = (TLRPC.Updates) response;
TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId);
TLRPC.UserFull userFull = null;
TLRPC.ChatFull chatFull = null;
if (dialogId >= 0) {
userFull = MessagesController.getInstance(currentAccount).getUserFull(dialogId);
} else {
chatFull = MessagesController.getInstance(currentAccount).getChatFull(-dialogId);
}
TLRPC.WallPaper pastWallpaper = null;
if (userFull != null) {
for (int i = 0; i < res.updates.size(); i++) {
if (res.updates.get(i) instanceof TLRPC.TL_updateNewMessage) {
TLRPC.Message message = ((TLRPC.TL_updateNewMessage) res.updates.get(i)).message;
if (message.action instanceof TLRPC.TL_messageActionSetChatWallPaper) {
if (finalApplyOnRequest) {
TLRPC.TL_messageActionSetChatWallPaper actionSetChatWallPaper = (TLRPC.TL_messageActionSetChatWallPaper) message.action;
actionSetChatWallPaper.wallpaper.uploadingImage = wallpaperLocalPath;
if (userFull.wallpaper != null && userFull.wallpaper.uploadingImage != null && userFull.wallpaper.uploadingImage.equals(actionSetChatWallPaper.wallpaper.uploadingImage)) {
actionSetChatWallPaper.wallpaper.stripedThumb = userFull.wallpaper.stripedThumb;
}
pastWallpaper = userFull.wallpaper;
} else if (chatFull != null) {
pastWallpaper = chatFull.wallpaper;
}
for (int i = 0; i < res.updates.size(); i++) {
if (res.updates.get(i) instanceof TLRPC.TL_updateNewMessage) {
TLRPC.Message message = ((TLRPC.TL_updateNewMessage) res.updates.get(i)).message;
if (message.action instanceof TLRPC.TL_messageActionSetChatWallPaper) {
if (finalApplyOnRequest) {
TLRPC.TL_messageActionSetChatWallPaper actionSetChatWallPaper = (TLRPC.TL_messageActionSetChatWallPaper) message.action;
actionSetChatWallPaper.wallpaper.uploadingImage = wallpaperLocalPath;
if (pastWallpaper != null && pastWallpaper.uploadingImage != null && pastWallpaper.uploadingImage.equals(actionSetChatWallPaper.wallpaper.uploadingImage)) {
actionSetChatWallPaper.wallpaper.stripedThumb = pastWallpaper.stripedThumb;
}
if (userFull != null) {
userFull.wallpaper = actionSetChatWallPaper.wallpaper;
userFull.flags |= 16777216;
saveChatWallpaper(dialogId, userFull.wallpaper);
getMessagesStorage().updateUserInfo(userFull, false);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, dialogId, userFull);
} else if (chatFull != null) {
chatFull.wallpaper = actionSetChatWallPaper.wallpaper;
chatFull.flags2 |= 128;
saveChatWallpaper(dialogId, chatFull.wallpaper);
getMessagesStorage().updateChatInfo(chatFull, false);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
}
break;
}
break;
}
}
}

View file

@ -163,4 +163,26 @@ public class DialogObject {
}
return null;
}
public static long getEmojiStatusDocumentId(TLRPC.EmojiStatus emojiStatus) {
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)) {
return ((TLRPC.TL_emojiStatusUntil) emojiStatus).document_id;
} else {
return 0;
}
}
public static int getEmojiStatusUntil(TLRPC.EmojiStatus emojiStatus) {
if (emojiStatus instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) emojiStatus).until > (int) (System.currentTimeMillis() / 1000)) {
return ((TLRPC.TL_emojiStatusUntil) emojiStatus).until;
}
return 0;
}
public static boolean emojiStatusesEqual(TLRPC.EmojiStatus a, TLRPC.EmojiStatus b) {
return getEmojiStatusDocumentId(a) == getEmojiStatusDocumentId(b) && getEmojiStatusUntil(a) == getEmojiStatusUntil(b);
}
}

View file

@ -2102,7 +2102,7 @@ public class FileLoadOperation {
requestingReference = true;
if (parentObject instanceof MessageObject) {
MessageObject messageObject = (MessageObject) parentObject;
if (messageObject.getId() < 0 && messageObject.messageOwner.media.webpage != null) {
if (messageObject.getId() < 0 && messageObject.messageOwner != null && messageObject.messageOwner.media != null && messageObject.messageOwner.media.webpage != null) {
parentObject = messageObject.messageOwner.media.webpage;
}
}

View file

@ -887,7 +887,7 @@ public class FileLoader extends BaseController {
} else {
storeDir = getDirectory(type);
}
} else if (cacheType == 2) {
} else if (cacheType == ImageLoader.CACHE_TYPE_ENCRYPTED) {
operation.setEncryptFile(true);
}
operation.setPaths(currentAccount, fileName, loaderQueue, storeDir, tempDir, storeFileName);

View file

@ -248,7 +248,7 @@ public class FileRefController extends BaseController {
}
if (parentObject instanceof MessageObject) {
MessageObject messageObject = (MessageObject) parentObject;
if (messageObject.getRealId() < 0 && messageObject.messageOwner.media.webpage != null) {
if (messageObject.getRealId() < 0 && messageObject.messageOwner != null && messageObject.messageOwner.media != null && messageObject.messageOwner.media.webpage != null) {
parentObject = messageObject.messageOwner.media.webpage;
}
}
@ -1087,6 +1087,9 @@ public class FileRefController extends BaseController {
if (storyItem.media.document != null) {
result = getFileReference(storyItem.media.document, requester.location, needReplacement, locationReplacement);
}
if (storyItem.media.alt_document != null) {
result = getFileReference(storyItem.media.alt_document, requester.location, needReplacement, locationReplacement);
}
}
}
Object arg = requester.args[1];

View file

@ -103,6 +103,10 @@ import java.util.zip.GZIPInputStream;
*/
public class ImageLoader {
public static final int CACHE_TYPE_NONE = 0;
public static final int CACHE_TYPE_CACHE = 1;
public static final int CACHE_TYPE_ENCRYPTED = 2;
private static final boolean DEBUG_MODE = false;
private HashMap<String, Integer> bitmapUseCounts = new HashMap<>();
@ -4225,7 +4229,7 @@ public class ImageLoader {
} else {
File file = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(photoSize, true);
boolean isEncrypted = false;
if (MessageObject.shouldEncryptPhotoOrVideo(message)) {
if (MessageObject.shouldEncryptPhotoOrVideo(UserConfig.selectedAccount, message)) {
file = new File(file.getAbsolutePath() + ".enc");
isEncrypted = true;
}

View file

@ -1017,7 +1017,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
} else if (bitmapDrawable instanceof AnimatedFileDrawable) {
AnimatedFileDrawable animatedFileDrawable = (AnimatedFileDrawable) drawable;
animatedFileDrawable.setRoundRadius(roundRadius);
} else if (bitmapDrawable.getBitmap() != null) {
} else if (bitmapDrawable.getBitmap() != null && !bitmapDrawable.getBitmap().isRecycled()) {
setDrawableShader(drawable, new BitmapShader(bitmapDrawable.getBitmap(), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
}
}

View file

@ -39,7 +39,8 @@ public class LiteMode {
public static final int FLAG_CHAT_SPOILER = 128;
public static final int FLAG_CHAT_BLUR = 256;
public static final int FLAG_CHAT_SCALE = 32768;
public static final int FLAGS_CHAT = FLAG_CHAT_BACKGROUND | FLAG_CHAT_FORUM_TWOCOLUMN | FLAG_CHAT_SPOILER | FLAG_CHAT_BLUR | FLAG_CHAT_SCALE;
public static final int FLAG_CHAT_THANOS = 65536;
public static final int FLAGS_CHAT = FLAG_CHAT_BACKGROUND | FLAG_CHAT_FORUM_TWOCOLUMN | FLAG_CHAT_SPOILER | FLAG_CHAT_BLUR | FLAG_CHAT_SCALE | FLAG_CHAT_THANOS;
public static final int FLAG_CALLS_ANIMATIONS = 512;
public static final int FLAG_AUTOPLAY_VIDEOS = 1024;
@ -49,8 +50,9 @@ public class LiteMode {
FLAG_ANIMATED_EMOJI_CHAT_PREMIUM |
FLAG_ANIMATED_EMOJI_KEYBOARD_PREMIUM |
FLAG_ANIMATED_EMOJI_REACTIONS_PREMIUM |
FLAG_AUTOPLAY_GIFS
); // 2076
FLAG_AUTOPLAY_GIFS |
FLAG_CHAT_THANOS
); // 67612
public static int PRESET_MEDIUM = (
FLAGS_ANIMATED_STICKERS |
FLAG_ANIMATED_EMOJI_KEYBOARD_PREMIUM |
@ -59,16 +61,18 @@ public class LiteMode {
FLAG_CHAT_FORUM_TWOCOLUMN |
FLAG_CALLS_ANIMATIONS |
FLAG_AUTOPLAY_VIDEOS |
FLAG_AUTOPLAY_GIFS
); // 7775
FLAG_AUTOPLAY_GIFS |
FLAG_CHAT_THANOS
); // 73311
public static int PRESET_HIGH = (
FLAGS_ANIMATED_STICKERS |
FLAGS_ANIMATED_EMOJI |
FLAGS_CHAT |
FLAG_CALLS_ANIMATIONS |
FLAG_AUTOPLAY_VIDEOS |
FLAG_AUTOPLAY_GIFS
); // 65535
FLAG_AUTOPLAY_GIFS |
FLAG_CHAT_THANOS
); // 131071
public static int PRESET_POWER_SAVER = 0;
private static int BATTERY_LOW = 10;
@ -196,8 +200,12 @@ public class LiteMode {
}
final SharedPreferences preferences = MessagesController.getGlobalMainSettings();
if (!preferences.contains("lite_mode2")) {
if (preferences.contains("lite_mode")) {
if (!preferences.contains("lite_mode3")) {
if (preferences.contains("lite_mode2")) {
defaultValue = preferences.getInt("lite_mode2", defaultValue);
defaultValue |= FLAG_CHAT_THANOS;
preferences.edit().putInt("lite_mode3", defaultValue).apply();
} else if (preferences.contains("lite_mode")) {
defaultValue = preferences.getInt("lite_mode", defaultValue);
if (defaultValue == 4095) {
defaultValue = PRESET_HIGH;
@ -248,7 +256,7 @@ public class LiteMode {
}
int prevValue = value;
value = preferences.getInt("lite_mode2", defaultValue);
value = preferences.getInt("lite_mode3", defaultValue);
if (loaded) {
onFlagsUpdate(prevValue, value);
}
@ -257,7 +265,7 @@ public class LiteMode {
}
public static void savePreference() {
MessagesController.getGlobalMainSettings().edit().putInt("lite_mode2", value).putInt("lite_mode_battery_level", powerSaverLevel).apply();
MessagesController.getGlobalMainSettings().edit().putInt("lite_mode3", value).putInt("lite_mode_battery_level", powerSaverLevel).apply();
}
public static int getPowerSaverLevel() {

View file

@ -1061,10 +1061,10 @@ public class LocaleController {
}
private String getStringInternal(String key, int res) {
return getStringInternal(key, null, res);
return getStringInternal(key, null, 0, res);
}
private String getStringInternal(String key, String fallback, int res) {
private String getStringInternal(String key, String fallback, int fallbackRes, int res) {
String value = BuildVars.USE_CLOUD_STRINGS ? localeValues.get(key) : null;
if (value == null) {
if (BuildVars.USE_CLOUD_STRINGS && fallback != null) {
@ -1074,6 +1074,11 @@ public class LocaleController {
try {
value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) {
if (fallbackRes != 0) {
try {
value = ApplicationLoader.applicationContext.getString(fallbackRes);
} catch (Exception ignored) {}
}
FileLog.e(e);
}
}
@ -1107,8 +1112,12 @@ public class LocaleController {
return getInstance().getStringInternal(key, res);
}
public static String getString(String key, String fallback, int fallbackRes, int res) {
return getInstance().getStringInternal(key, fallback, fallbackRes, res);
}
public static String getString(String key, String fallback, int res) {
return getInstance().getStringInternal(key, fallback, res);
return getInstance().getStringInternal(key, fallback, 0, res);
}
public static String getString(String key) {
@ -1129,7 +1138,8 @@ public class LocaleController {
String param = getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(plural));
param = key + "_" + param;
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
return getString(param, key + "_other", resourceId);
int fallbackResourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(key + "_other", "string", ApplicationLoader.applicationContext.getPackageName());
return getString(param, key + "_other", resourceId, fallbackResourceId);
}
public static String formatPluralString(String key, int plural, Object... args) {
@ -1146,6 +1156,10 @@ public class LocaleController {
return formatString(param, key + "_other", resourceId, fallbackResourceId, argsWithPlural);
}
public static String getStringParamForNumber(int number) {
return getInstance().stringForQuantity(getInstance().currentPluralRules.quantityForNumber(number));
}
public static String formatPluralStringComma(String key, int plural) {
return formatPluralStringComma(key, plural, ',');
}
@ -1611,6 +1625,24 @@ public class LocaleController {
return "LOC_ERR: formatDateChat";
}
public static String formatSmallDateChat(long date) {
try {
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int currentYear = calendar.get(Calendar.YEAR);
date *= 1000;
calendar.setTimeInMillis(date);
if (currentYear == calendar.get(Calendar.YEAR)) {
return getInstance().formatterDayMonth.format(date);
}
return getInstance().formatterDayMonth.format(date) + ", " + calendar.get(Calendar.YEAR);
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR: formatDateChat";
}
public static String formatDate(long date) {
try {
date *= 1000;

View file

@ -779,6 +779,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
private int sendAfterDone;
private boolean sendAfterDoneNotify;
private int sendAfterDoneScheduleDate;
private boolean sendAfterDoneOnce;
private Runnable recordStartRunnable;
private DispatchQueue recordQueue;
@ -867,7 +868,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
} else {
recordBuffers.add(buffer);
if (sendAfterDone != 3) {
stopRecordingInternal(sendAfterDone, sendAfterDoneNotify, sendAfterDoneScheduleDate);
stopRecordingInternal(sendAfterDone, sendAfterDoneNotify, sendAfterDoneScheduleDate, sendAfterDoneOnce);
}
}
}
@ -1133,7 +1134,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (isPlayingMessage(playingMessageObject) && !isMessagePaused()) {
pauseMessage(playingMessageObject);
} else if (recordStartRunnable != null || recordingAudio != null) {
stopRecording(2, false, 0);
stopRecording(2, false, 0, false);
}
EmbedBottomSheet embedBottomSheet = EmbedBottomSheet.getInstance();
if (embedBottomSheet != null) {
@ -1585,6 +1586,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
int addedCount = 0;
for (int a = 0; a < arr.size(); a++) {
MessageObject message = arr.get(a);
if (message.isVoiceOnce()) continue;
if (playlistMap.containsKey(message.getId())) {
continue;
}
@ -1618,7 +1620,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
ArrayList<MessageObject> arr = (ArrayList<MessageObject>) args[1];
for (int a = 0; a < arr.size(); a++) {
messageObject = arr.get(a);
if ((messageObject.isVoice() || messageObject.isRoundVideo()) && (!voiceMessagesPlaylistUnread || messageObject.isContentUnread() && !messageObject.isOut())) {
if ((messageObject.isVoice() || messageObject.isRoundVideo()) && !messageObject.isVoiceOnce() && !messageObject.isRoundOnce() && (!voiceMessagesPlaylistUnread || messageObject.isContentUnread() && !messageObject.isOut())) {
voiceMessagesPlaylist.add(messageObject);
voiceMessagesPlaylistMap.put(messageObject.getId(), messageObject);
}
@ -1913,7 +1915,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
if (BuildVars.LOGS_ENABLED) {
FileLog.d("stop record");
}
stopRecording(2, false, 0);
stopRecording(2, false, 0, false);
raiseToEarRecord = false;
ignoreOnPause = false;
// if (!ignoreAccelerometerGestures() && proximityHasDifferentValues && proximityWakeLock != null && proximityWakeLock.isHeld()) {
@ -2051,7 +2053,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return;
}
if (stopRecording) {
stopRecording(fromChat ? 2 : 0, false, 0);
stopRecording(fromChat ? 2 : 0, false, 0, false);
}
if (!sensorsStarted || ignoreOnPause || accelerometerSensor == null && (gravitySensor == null || linearAcceleration == null) || proximitySensor == null || raiseChat != chatActivity) {
return;
@ -2361,6 +2363,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
int addedCount = 0;
for (int i = 0; i < n; i++) {
MessageObject messageObject = new MessageObject(currentAccount, res.messages.get(i), false, true);
if (messageObject.isVoiceOnce()) continue;
if (playlistMap.containsKey(messageObject.getId())) {
continue;
}
@ -3761,6 +3764,9 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
public boolean isPlayingMessage(MessageObject messageObject) {
if (messageObject != null && messageObject.isRepostPreview) {
return false;
}
if (audioPlayer == null && videoPlayer == null || messageObject == null || playingMessageObject == null) {
return false;
}
@ -3954,7 +3960,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
});
}
private void stopRecordingInternal(final int send, boolean notify, int scheduleDate) {
private void stopRecordingInternal(final int send, boolean notify, int scheduleDate, boolean once) {
if (send != 0) {
final TLRPC.TL_document audioToSend = recordingAudio;
final File recordingAudioFileToSend = recordingAudioFile;
@ -3987,7 +3993,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
audioToSend.attributes.add(attributeAudio);
if (duration > 700) {
if (send == 1) {
SendMessagesHelper.SendMessageParams params = SendMessagesHelper.SendMessageParams.of(audioToSend, null, recordingAudioFileToSend.getAbsolutePath(), recordDialogId, recordReplyingMsg, recordReplyingTopMsg, null, null, null, null, notify, scheduleDate, 0, null, null, false);
SendMessagesHelper.SendMessageParams params = SendMessagesHelper.SendMessageParams.of(audioToSend, null, recordingAudioFileToSend.getAbsolutePath(), recordDialogId, recordReplyingMsg, recordReplyingTopMsg, null, null, null, null, notify, scheduleDate, once ? 0x7FFFFFFF : 0, null, null, false);
params.replyToStoryItem = recordReplyingStory;
SendMessagesHelper.getInstance(recordingCurrentAccount).sendMessage(params);
}
@ -4020,7 +4026,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
manualRecording = false;
}
public void stopRecording(final int send, boolean notify, int scheduleDate) {
public void stopRecording(final int send, boolean notify, int scheduleDate, boolean once) {
if (recordStartRunnable != null) {
recordQueue.cancelRunnable(recordStartRunnable);
recordStartRunnable = null;
@ -4028,7 +4034,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
recordQueue.postRunnable(() -> {
if (sendAfterDone == 3) {
sendAfterDone = 0;
stopRecordingInternal(send, notify, scheduleDate);
stopRecordingInternal(send, notify, scheduleDate, once);
return;
}
if (audioRecorder == null) {
@ -4038,6 +4044,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
sendAfterDone = send;
sendAfterDoneNotify = notify;
sendAfterDoneScheduleDate = scheduleDate;
sendAfterDoneOnce = once;
audioRecorder.stop();
setBluetoothScoOn(false);
} catch (Exception e) {
@ -4050,7 +4057,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
}
}
if (send == 0) {
stopRecordingInternal(0, false, 0);
stopRecordingInternal(0, false, 0, false);
}
try {
feedbackView.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
@ -5018,12 +5025,13 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
thread.start();
}
public static boolean forceBroadcastNewPhotos;
private static void broadcastNewPhotos(final int guid, final ArrayList<AlbumEntry> mediaAlbumsSorted, final ArrayList<AlbumEntry> photoAlbumsSorted, final Integer cameraAlbumIdFinal, final AlbumEntry allMediaAlbumFinal, final AlbumEntry allPhotosAlbumFinal, final AlbumEntry allVideosAlbumFinal, int delay) {
if (broadcastPhotosRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(broadcastPhotosRunnable);
}
AndroidUtilities.runOnUIThread(broadcastPhotosRunnable = () -> {
if (PhotoViewer.getInstance().isVisible()) {
if (PhotoViewer.getInstance().isVisible() && !forceBroadcastNewPhotos) {
broadcastNewPhotos(guid, mediaAlbumsSorted, photoAlbumsSorted, cameraAlbumIdFinal, allMediaAlbumFinal, allPhotosAlbumFinal, allVideosAlbumFinal, 1000);
return;
}
@ -5376,20 +5384,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
framerate, bitrate, originalBitrate,
startTime, endTime, avatarStartTime,
needCompress, duration,
info.filterState,
info.paintPath,
info.blurPath,
info.mediaEntities,
info.isPhoto,
info.cropState,
info.roundVideo,
callback,
info.gradientTopColor,
info.gradientBottomColor,
info.muted,
info.isStory,
info.hdrInfo,
info.parts);
info);
convertVideoParams.soundInfos.addAll(info.mixedSoundInfos);
boolean error = videoConvertor.convertVideo(convertVideoParams);

View file

@ -260,6 +260,7 @@ public class MediaDataController extends BaseController {
private LongSparseArray<TLRPC.TL_messages_stickerSet> groupStickerSets = new LongSparseArray<>();
private ConcurrentHashMap<String, TLRPC.TL_messages_stickerSet> stickerSetsByName = new ConcurrentHashMap<>(100, 1.0f, 1);
private TLRPC.TL_messages_stickerSet stickerSetDefaultStatuses = null;
private TLRPC.TL_messages_stickerSet stickerSetDefaultChannelStatuses = null;
private HashMap<String, TLRPC.TL_messages_stickerSet> diceStickerSetsByEmoji = new HashMap<>();
private LongSparseArray<String> diceEmojiStickerSetsById = new LongSparseArray<>();
private HashSet<String> loadingDiceStickerSets = new HashSet<>();
@ -317,11 +318,11 @@ public class MediaDataController extends BaseController {
public final ArrayList<TLRPC.Document> premiumPreviewStickers = new ArrayList<>();
boolean previewStickersLoading;
private long[] emojiStatusesHash = new long[2];
private ArrayList<TLRPC.EmojiStatus>[] emojiStatuses = new ArrayList[2];
private Long[] emojiStatusesFetchDate = new Long[2];
private boolean[] emojiStatusesFromCacheFetched = new boolean[2];
private boolean[] emojiStatusesFetching = new boolean[2];
private long[] emojiStatusesHash = new long[4];
private ArrayList<TLRPC.EmojiStatus>[] emojiStatuses = new ArrayList[4];
private Long[] emojiStatusesFetchDate = new Long[4];
private boolean[] emojiStatusesFromCacheFetched = new boolean[4];
private boolean[] emojiStatusesFetching = new boolean[4];
public void cleanup() {
for (int a = 0; a < recentStickers.length; a++) {
@ -1217,6 +1218,8 @@ public class MediaDataController extends BaseController {
cacheSet = stickerSetsByName.get(inputStickerSet.short_name.toLowerCase());
} else if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses && stickerSetDefaultStatuses != null) {
cacheSet = stickerSetDefaultStatuses;
} else if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiChannelDefaultStatuses && stickerSetDefaultChannelStatuses != null) {
cacheSet = stickerSetDefaultChannelStatuses;
}
if (cacheSet != null) {
if (onResponse != null) {
@ -1264,6 +1267,9 @@ public class MediaDataController extends BaseController {
if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses) {
stickerSetDefaultStatuses = set;
}
if (inputStickerSet instanceof TLRPC.TL_inputStickerSetEmojiDefaultStatuses) {
stickerSetDefaultChannelStatuses = set;
}
}
saveStickerSetIntoCache(set);
getNotificationCenter().postNotificationName(NotificationCenter.groupStickersDidLoad, set.set.id, set);
@ -5567,6 +5573,13 @@ public class MediaDataController extends BaseController {
}
}
if (channelId != 0 && messageObject.getDialogId() != -channelId) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(channelId);
if (chat != null && !ChatObject.isPublic(chat)) {
continue;
}
}
SparseArray<ArrayList<MessageObject>> sparseArray = replyMessageOwners.get(dialogId);
ArrayList<Integer> ids = dialogReplyMessagesIds.get(channelId);
if (sparseArray == null) {
@ -8180,6 +8193,16 @@ public class MediaDataController extends BaseController {
return emojiStatuses[type];
}
public ArrayList<TLRPC.EmojiStatus> getDefaultChannelEmojiStatuses() {
final int type = 2; // default channel
if (!emojiStatusesFromCacheFetched[type]) {
fetchEmojiStatuses(type, true);
} else if (emojiStatuses[type] == null || emojiStatusesFetchDate[type] != null && (System.currentTimeMillis() / 1000 - emojiStatusesFetchDate[type]) > 60 * 30) {
fetchEmojiStatuses(type, false);
}
return emojiStatuses[type];
}
public ArrayList<TLRPC.EmojiStatus> getRecentEmojiStatuses() {
final int type = 0; // recent
if (!emojiStatusesFromCacheFetched[type]) {
@ -8271,10 +8294,14 @@ public class MediaDataController extends BaseController {
TLRPC.TL_account_getRecentEmojiStatuses recentReq = new TLRPC.TL_account_getRecentEmojiStatuses();
recentReq.hash = emojiStatusesHash[type];
req = recentReq;
} else {
} else if (type == 1) {
TLRPC.TL_account_getDefaultEmojiStatuses defaultReq = new TLRPC.TL_account_getDefaultEmojiStatuses();
defaultReq.hash = emojiStatusesHash[type];
req = defaultReq;
} else {
TLRPC.TL_account_getChannelDefaultEmojiStatuses defaultReq = new TLRPC.TL_account_getChannelDefaultEmojiStatuses();
defaultReq.hash = emojiStatusesHash[type];
req = defaultReq;
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (res, err) -> {
emojiStatusesFetchDate[type] = System.currentTimeMillis() / 1000;
@ -8518,4 +8545,42 @@ public class MediaDataController extends BaseController {
}));
}
}
public TLRPC.TL_emojiList restrictedStatusEmojis;
public void loadRestrictedStatusEmojis() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("restrictedstatuses_" + currentAccount, Context.MODE_PRIVATE);
String value = preferences.getString("restrictedstatuses", null);
long lastCheckTime = preferences.getLong("restrictedstatuses_last_check", 0);
TLRPC.TL_emojiList emojiList = null;
if (value != null) {
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
try {
emojiList = (TLRPC.TL_emojiList) TLRPC.TL_emojiList.TLdeserialize(serializedData, serializedData.readInt32(true), true);
restrictedStatusEmojis = emojiList;
} catch (Throwable e) {
FileLog.e(e);
}
}
if (emojiList == null || (System.currentTimeMillis() - lastCheckTime) > 24 * 60 * 60 * 1000) {
TLRPC.TL_account_getChannelRestrictedStatusEmojis req = new TLRPC.TL_account_getChannelRestrictedStatusEmojis();
if (emojiList != null) {
req.hash = emojiList.hash;
}
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_emojiList) {
SerializedData data = new SerializedData(response.getObjectSize());
response.serializeToStream(data);
SharedPreferences.Editor editor = preferences.edit();
restrictedStatusEmojis = (TLRPC.TL_emojiList) response;
editor.putString("restrictedstatuses", Utilities.bytesToHex(data.toByteArray()));
editor.putLong("restrictedstatuses_last_check", System.currentTimeMillis());
editor.apply();
}
}));
}
}
}

View file

@ -69,6 +69,7 @@ import org.telegram.ui.Components.URLSpanNoUnderlineBold;
import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.URLSpanUserMention;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PeerColorActivity;
import java.io.BufferedReader;
import java.io.File;
@ -122,6 +123,7 @@ public class MessageObject {
public static final int TYPE_GIFT_PREMIUM_CHANNEL = 25;
public static final int TYPE_GIVEAWAY = 26;
public static final int TYPE_JOINED_CHANNEL = 27; // recommendations list
public static final int TYPE_GIVEAWAY_RESULTS = 28;
public int localType;
public String localName;
@ -165,6 +167,7 @@ public class MessageObject {
public String dateKey;
public String monthKey;
public boolean deleted;
public boolean deletedByThanos;
public float audioProgress;
public float forceSeekTo = -1;
public int audioProgressMs;
@ -212,7 +215,6 @@ public class MessageObject {
public boolean replyTextRevealed;
public int overrideLinkColor = -1;
public long overrideLinkEmoji = -1;
public MessagesController.PeerColor overrideProfilePeerColor;
private boolean channelJoined;
public boolean channelJoinedExpanded;
@ -305,6 +307,8 @@ public class MessageObject {
" & ",
" . "
};
public boolean isRepostPreview;
public boolean isRepostVideoPreview;
public boolean forceAvatar;
public Drawable customAvatarDrawable;
@ -441,7 +445,14 @@ public class MessageObject {
}
public boolean hasMediaSpoilers() {
return messageOwner.media != null && messageOwner.media.spoiler || needDrawBluredPreview();
return !isRepostPreview && (messageOwner.media != null && messageOwner.media.spoiler || needDrawBluredPreview());
}
public boolean shouldDrawReactions() {
if (isRepostPreview) {
return false;
}
return true;
}
public boolean shouldDrawReactionsInLayout() {
@ -1487,8 +1498,15 @@ public class MessageObject {
}
public MessageObject(int accountNum, TLRPC.Message message, MessageObject replyToMessage, AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, LongSparseArray<TLRPC.User> sUsers, LongSparseArray<TLRPC.Chat> sChats, boolean generateLayout, boolean checkMediaExists, long eid) {
this(accountNum, message, replyToMessage, users, chats, sUsers, sChats, generateLayout, checkMediaExists, eid, false, false);
}
public MessageObject(int accountNum, TLRPC.Message message, MessageObject replyToMessage, AbstractMap<Long, TLRPC.User> users, AbstractMap<Long, TLRPC.Chat> chats, LongSparseArray<TLRPC.User> sUsers, LongSparseArray<TLRPC.Chat> sChats, boolean generateLayout, boolean checkMediaExists, long eid, boolean isRepostPreview, boolean isRepostVideoPreview) {
Theme.createCommonMessageResources();
this.isRepostPreview = isRepostPreview;
this.isRepostVideoPreview = isRepostVideoPreview;
currentAccount = accountNum;
messageOwner = message;
replyMessageObject = replyToMessage;
@ -2696,6 +2714,133 @@ public class MessageObject {
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeColor) {
TLRPC.TL_channelAdminLogEventActionChangeColor action = (TLRPC.TL_channelAdminLogEventActionChangeColor) event.action;
messageText = replaceWithLink(LocaleController.formatString(R.string.EventLogChangedColor, AvatarDrawable.colorName(action.prev_value).toLowerCase(), AvatarDrawable.colorName(action.new_value).toLowerCase()), "un1", fromUser);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangePeerColor) {
TLRPC.TL_channelAdminLogEventActionChangePeerColor action = (TLRPC.TL_channelAdminLogEventActionChangePeerColor) event.action;
SpannableStringBuilder ssb = new SpannableStringBuilder(LocaleController.getString(R.string.EventLogChangedPeerColorIcon));
SpannableStringBuilder prev = new SpannableStringBuilder();
if ((action.prev_value.flags & 1) != 0) {
prev.append("c");
prev.setSpan(new PeerColorActivity.PeerColorSpan(false, currentAccount, action.prev_value.color).setSize(dp(18)), prev.length() - 1, prev.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if ((action.prev_value.flags & 2) != 0) {
if (prev.length() > 0)
prev.append(", ");
prev.append("e");
prev.setSpan(new AnimatedEmojiSpan(action.prev_value.background_emoji_id, Theme.chat_actionTextPaint.getFontMetricsInt()), prev.length() - 1, prev.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (prev.length() == 0) {
prev.append(LocaleController.getString(R.string.EventLogEmojiNone));
}
SpannableStringBuilder next = new SpannableStringBuilder();
if ((action.new_value.flags & 1) != 0) {
next.append("c");
next.setSpan(new PeerColorActivity.PeerColorSpan(false, currentAccount, action.new_value.color).setSize(dp(18)), next.length() - 1, next.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if ((action.new_value.flags & 2) != 0) {
if (next.length() > 0)
next.append(", ");
next.append("e");
next.setSpan(new AnimatedEmojiSpan(action.new_value.background_emoji_id, Theme.chat_actionTextPaint.getFontMetricsInt()), next.length() - 1, next.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (next.length() == 0) {
next.append(LocaleController.getString(R.string.EventLogEmojiNone));
}
ssb = AndroidUtilities.replaceCharSequence("%1$s", ssb, prev);
ssb = AndroidUtilities.replaceCharSequence("%2$s", ssb, next);
messageText = replaceWithLink(ssb, "un1", fromUser);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeProfilePeerColor) {
TLRPC.TL_channelAdminLogEventActionChangeProfilePeerColor action = (TLRPC.TL_channelAdminLogEventActionChangeProfilePeerColor) event.action;
SpannableStringBuilder ssb = new SpannableStringBuilder(LocaleController.getString(R.string.EventLogChangedProfileColorIcon));
SpannableStringBuilder prev = new SpannableStringBuilder();
if ((action.prev_value.flags & 1) != 0) {
prev.append("c");
prev.setSpan(new PeerColorActivity.PeerColorSpan(true, currentAccount, action.prev_value.color).setSize(dp(18)), prev.length() - 1, prev.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if ((action.prev_value.flags & 2) != 0) {
if (prev.length() > 0)
prev.append(", ");
prev.append("e");
prev.setSpan(new AnimatedEmojiSpan(action.prev_value.background_emoji_id, Theme.chat_actionTextPaint.getFontMetricsInt()), prev.length() - 1, prev.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (prev.length() == 0) {
prev.append(LocaleController.getString(R.string.EventLogEmojiNone));
}
SpannableStringBuilder next = new SpannableStringBuilder();
if ((action.new_value.flags & 1) != 0) {
next.append("c");
next.setSpan(new PeerColorActivity.PeerColorSpan(true, currentAccount, action.new_value.color).setSize(dp(18)), next.length() - 1, next.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if ((action.new_value.flags & 2) != 0) {
if (next.length() > 0)
next.append(", ");
next.append("e");
next.setSpan(new AnimatedEmojiSpan(action.new_value.background_emoji_id, Theme.chat_actionTextPaint.getFontMetricsInt()), next.length() - 1, next.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
if (next.length() == 0) {
next.append(LocaleController.getString(R.string.EventLogEmojiNone));
}
ssb = AndroidUtilities.replaceCharSequence("%1$s", ssb, prev);
ssb = AndroidUtilities.replaceCharSequence("%2$s", ssb, next);
messageText = replaceWithLink(ssb, "un1", fromUser);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeEmojiStatus) {
TLRPC.TL_channelAdminLogEventActionChangeEmojiStatus action = (TLRPC.TL_channelAdminLogEventActionChangeEmojiStatus) event.action;
boolean prevNone = false;
SpannableString prev;
if (action.prev_value instanceof TLRPC.TL_emojiStatusEmpty) {
prev = new SpannableString(LocaleController.getString(R.string.EventLogEmojiNone));
prevNone = true;
} else {
prev = new SpannableString("e");
prev.setSpan(new AnimatedEmojiSpan(DialogObject.getEmojiStatusDocumentId(action.prev_value), Theme.chat_actionTextPaint.getFontMetricsInt()), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
boolean hasUntil = action.new_value instanceof TLRPC.TL_emojiStatusUntil;
SpannableString next;
if (action.new_value instanceof TLRPC.TL_emojiStatusEmpty) {
next = new SpannableString(LocaleController.getString(R.string.EventLogEmojiNone));
} else {
next = new SpannableString("e");
next.setSpan(new AnimatedEmojiSpan(DialogObject.getEmojiStatusDocumentId(action.new_value), Theme.chat_actionTextPaint.getFontMetricsInt()), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
SpannableStringBuilder ssb = new SpannableStringBuilder(LocaleController.getString(
prevNone ? (
hasUntil ? R.string.EventLogChangedEmojiStatusFor : R.string.EventLogChangedEmojiStatus
) : (
hasUntil ? R.string.EventLogChangedEmojiStatusFromFor : R.string.EventLogChangedEmojiStatusFrom
)
));
ssb = AndroidUtilities.replaceCharSequence("%1$s", ssb, prev);
ssb = AndroidUtilities.replaceCharSequence("%2$s", ssb, next);
if (hasUntil) {
String until = LocaleController.formatTTLString((int) ((DialogObject.getEmojiStatusUntil(action.new_value) - event.date) * 1.05f));
ssb = AndroidUtilities.replaceCharSequence("%3$s", ssb, until);
}
messageText = replaceWithLink(ssb, "un1", fromUser);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeWallpaper) {
TLRPC.TL_channelAdminLogEventActionChangeWallpaper action = (TLRPC.TL_channelAdminLogEventActionChangeWallpaper) event.action;
if (action.new_value instanceof TLRPC.TL_wallPaperNoFile && action.new_value.id == 0 && action.new_value.settings == null) {
messageText = replaceWithLink(LocaleController.getString(R.string.EventLogRemovedWallpaper), "un1", fromUser);
} else {
photoThumbs = new ArrayList<>();
if (action.new_value.document != null) {
photoThumbs.addAll(action.new_value.document.thumbs);
photoThumbsObject = action.new_value.document;
}
messageText = replaceWithLink(LocaleController.getString(R.string.EventLogChangedWallpaper), "un1", fromUser);
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeBackgroundEmoji) {
TLRPC.TL_channelAdminLogEventActionChangeBackgroundEmoji action = (TLRPC.TL_channelAdminLogEventActionChangeBackgroundEmoji) event.action;
messageText = replaceWithLink(LocaleController.getString(R.string.EventLogChangedEmoji), "un1", fromUser);
@ -3441,7 +3586,7 @@ public class MessageObject {
}
public boolean hasInlineBotButtons() {
return !isRestrictedMessage && messageOwner != null && messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup && !messageOwner.reply_markup.rows.isEmpty();
return !isRestrictedMessage && !isRepostPreview && messageOwner != null && messageOwner.reply_markup instanceof TLRPC.TL_replyInlineMarkup && !messageOwner.reply_markup.rows.isEmpty();
}
public void measureInlineBotButtons() {
@ -3555,6 +3700,8 @@ public class MessageObject {
} else {
messageText = LocaleController.formatString(R.string.ActionSetSameWallpaperForThisChat, user.first_name);
}
} else if (fromChat != null) {
messageText = LocaleController.getString(R.string.ActionSetWallpaperForThisChannel);
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) {
contentType = 1;
@ -3593,6 +3740,8 @@ public class MessageObject {
}
messageText = AndroidUtilities.replaceCharSequence("%s", messageText, userName);
}
} else if (fromChat != null) {
messageText = LocaleController.getString(R.string.ActionSetWallpaperForThisChannel);
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGroupCallScheduled) {
TLRPC.TL_messageActionGroupCallScheduled action = (TLRPC.TL_messageActionGroupCallScheduled) messageOwner.action;
@ -3790,9 +3939,9 @@ public class MessageObject {
stringBuilder.append(LocaleController.formatPluralString("BoostingGiveawayServiceUndistributed", giveawayResults.unclaimed_count));
}
messageText = stringBuilder;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode && ((TLRPC.TL_messageActionGiftCode) messageOwner.action).boost_peer != null) {
messageText = LocaleController.getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName);
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium) {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium || messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
if (fromObject instanceof TLRPC.User && ((TLRPC.User) fromObject).self) {
TLRPC.User user = getUser(users, sUsers, messageOwner.peer_id.user_id);
messageText = replaceWithLink(AndroidUtilities.replaceTags(LocaleController.getString(R.string.ActionGiftOutbound)), "un1", user);
@ -3874,39 +4023,61 @@ public class MessageObject {
}
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionRequestedPeer) {
TLRPC.Peer peer = ((TLRPC.TL_messageActionRequestedPeer) messageOwner.action).peer;
TLObject peerObject = null;
if (peer instanceof TLRPC.TL_peerUser) {
peerObject = MessagesController.getInstance(currentAccount).getUser(peer.user_id);
if (peerObject == null) {
peerObject = getUser(users, sUsers, peer.user_id);
List<TLObject> peerObjects = new ArrayList<>();
int sharedUsers = 0;
int sharedChannels = 0;
int sharedChats = 0;
List<TLRPC.Peer> peers = ((TLRPC.TL_messageActionRequestedPeer) messageOwner.action).peers;
for (TLRPC.Peer peer : peers) {
TLObject peerObject = null;
if (peer instanceof TLRPC.TL_peerUser) {
peerObject = MessagesController.getInstance(currentAccount).getUser(peer.user_id);
if (peerObject == null) {
peerObject = getUser(users, sUsers, peer.user_id);
}
} else if (peer instanceof TLRPC.TL_peerChat) {
peerObject = MessagesController.getInstance(currentAccount).getChat(peer.chat_id);
if (peerObject == null) {
peerObject = getChat(chats, sChats, peer.chat_id);
}
} else if (peer instanceof TLRPC.TL_peerChannel) {
peerObject = MessagesController.getInstance(currentAccount).getChat(peer.channel_id);
if (peerObject == null) {
peerObject = getChat(chats, sChats, peer.channel_id);
}
}
} else if (peer instanceof TLRPC.TL_peerChat) {
peerObject = MessagesController.getInstance(currentAccount).getChat(peer.chat_id);
if (peerObject == null) {
peerObject = getChat(chats, sChats, peer.chat_id);
if (peer instanceof TLRPC.TL_peerUser) {
sharedUsers++;
} else if (peer instanceof TLRPC.TL_peerChat) {
sharedChats++;
} else {
sharedChannels++;
}
} else if (peer instanceof TLRPC.TL_peerChannel) {
peerObject = MessagesController.getInstance(currentAccount).getChat(peer.channel_id);
if (peerObject == null) {
peerObject = getChat(chats, sChats, peer.channel_id);
if (peerObject != null) {
peerObjects.add(peerObject);
}
}
if (sharedUsers > 0 && sharedUsers != peerObjects.size()) {
messageText = LocaleController.getPluralString("ActionRequestedPeerUserPlural", sharedUsers);
} else if (sharedChannels > 0 && sharedChannels != peerObjects.size()) {
messageText = LocaleController.getPluralString("ActionRequestedPeerChannelPlural", sharedChannels);
} else if (sharedChats > 0 && sharedChats != peerObjects.size()) {
messageText = LocaleController.getPluralString("ActionRequestedPeerChatPlural", sharedChats);
} else {
String separator = ", ";
SpannableStringBuilder names = new SpannableStringBuilder();
for (int i = 0; i < peerObjects.size(); i++) {
names.append(replaceWithLink("un1", "un1", peerObjects.get(i)));
if (i < peerObjects.size() - 1) {
names.append(separator);
}
}
messageText = AndroidUtilities.replaceCharSequence("un1", LocaleController.getString(R.string.ActionRequestedPeer), names);
}
TLRPC.User bot = MessagesController.getInstance(currentAccount).getUser(getDialogId());
if (bot == null) {
bot = getUser(users, sUsers, getDialogId());
}
if (peerObject == null) {
if (peer instanceof TLRPC.TL_peerUser) {
messageText = LocaleController.getString(R.string.ActionRequestedPeerUser);
} else if (peer instanceof TLRPC.TL_peerChat) {
messageText = LocaleController.getString(R.string.ActionRequestedPeerChat);
} else {
messageText = LocaleController.getString(R.string.ActionRequestedPeerChannel);
}
} else {
messageText = replaceWithLink(LocaleController.getString(R.string.ActionRequestedPeer), "un1", peerObject);
}
messageText = replaceWithLink(messageText, "un2", bot);
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSetMessagesTTL) {
TLRPC.TL_messageActionSetMessagesTTL action = (TLRPC.TL_messageActionSetMessagesTTL) messageOwner.action;
@ -4241,15 +4412,19 @@ public class MessageObject {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSetChatTheme) {
String emoticon = ((TLRPC.TL_messageActionSetChatTheme) messageOwner.action).emoticon;
String userName = UserObject.getFirstName(fromUser);
boolean isChannel = fromUser == null && fromChat != null;
if (isChannel) {
userName = fromChat.title;
}
boolean isUserSelf = UserObject.isUserSelf(fromUser);
if (TextUtils.isEmpty(emoticon)) {
messageText = isUserSelf
? LocaleController.formatString("ChatThemeDisabledYou", R.string.ChatThemeDisabledYou)
: LocaleController.formatString("ChatThemeDisabled", R.string.ChatThemeDisabled, userName, emoticon);
: LocaleController.formatString(isChannel ? R.string.ChannelThemeDisabled : R.string.ChatThemeDisabled, userName, emoticon);
} else {
messageText = isUserSelf
? LocaleController.formatString("ChatThemeChangedYou", R.string.ChatThemeChangedYou, emoticon)
: LocaleController.formatString("ChatThemeChangedTo", R.string.ChatThemeChangedTo, userName, emoticon);
: LocaleController.formatString(isChannel ? R.string.ChannelThemeChangedTo : R.string.ChatThemeChangedTo, userName, emoticon);
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByRequest) {
if (UserObject.isUserSelf(fromUser)) {
@ -4272,6 +4447,8 @@ public class MessageObject {
// messageText = getMediaTitle(getMedia(messageOwner)); // I'm afraid doing this
if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGiveaway) {
messageText = LocaleController.getString("BoostingGiveawayChannelStarted", R.string.BoostingGiveawayChannelStarted);
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGiveawayResults) {
messageText = LocaleController.getString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaStory) {
if (getMedia(messageOwner).via_mention) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(getMedia(messageOwner).user_id);
@ -4375,6 +4552,8 @@ public class MessageObject {
public CharSequence getMediaTitle(TLRPC.MessageMedia media) {
if (media instanceof TLRPC.TL_messageMediaGiveaway) {
return LocaleController.getString("BoostingGiveaway", R.string.BoostingGiveaway);
} else if (media instanceof TLRPC.TL_messageMediaGiveawayResults) {
return LocaleController.getString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (media instanceof TLRPC.TL_messageMediaStory) {
if (media.via_mention) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(media.user_id);
@ -4522,6 +4701,8 @@ public class MessageObject {
type = TYPE_DATE;
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGiveaway) {
type = TYPE_GIVEAWAY;
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGiveawayResults) {
type = TYPE_GIVEAWAY_RESULTS;
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDice) {
type = TYPE_ANIMATED_STICKER;
if (getMedia(messageOwner).document == null) {
@ -4579,6 +4760,19 @@ public class MessageObject {
contentType = 1;
}
}
} else if (currentEvent != null && currentEvent.action instanceof TLRPC.TL_channelAdminLogEventActionChangeWallpaper) {
TLRPC.TL_channelAdminLogEventActionChangeWallpaper wallPaper = (TLRPC.TL_channelAdminLogEventActionChangeWallpaper) currentEvent.action;
contentType = 1;
if (wallPaper.new_value instanceof TLRPC.TL_wallPaperNoFile && wallPaper.new_value.id == 0 && wallPaper.new_value.settings == null) {
type = TYPE_DATE;
} else {
type = TYPE_ACTION_WALLPAPER;
photoThumbs = new ArrayList<>();
if (wallPaper.new_value.document != null) {
photoThumbs.addAll(wallPaper.new_value.document.thumbs);
photoThumbsObject = wallPaper.new_value.document;
}
}
} else if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper) {
contentType = 1;
@ -4600,10 +4794,10 @@ public class MessageObject {
photoThumbsObject = messageOwner.action.photo;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionLoginUnknownLocation) {
type = TYPE_TEXT;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode && ((TLRPC.TL_messageActionGiftCode) messageOwner.action).boost_peer != null) {
contentType = 1;
type = TYPE_GIFT_PREMIUM_CHANNEL;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium) {
} 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_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
@ -5937,6 +6131,9 @@ public class MessageObject {
}
public boolean needDrawShareButton() {
if (isRepostPreview) {
return false;
}
if (type == TYPE_JOINED_CHANNEL) {
return false;
} else if (isSponsored()) {
@ -6158,10 +6355,11 @@ public class MessageObject {
final float lineSpacing = 1f;
final float lineAdd = totalAnimatedEmojiCount >= 4 ? -1 : 0;
Layout.Alignment align = Layout.Alignment.ALIGN_NORMAL; //type == TYPE_EMOJIS && isOut() ? Layout.Alignment.ALIGN_OPPOSITE : Layout.Alignment.ALIGN_NORMAL;
CharSequence text = messageText;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(messageText, 0, messageText.length(), paint, maxWidth)
StaticLayout.Builder.obtain(text, 0, text.length(), paint, maxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
@ -6174,13 +6372,76 @@ public class MessageObject {
}
textLayout = builder.build();
} else {
textLayout = new StaticLayout(messageText, paint, maxWidth, align, lineSpacing, lineAdd, false);
textLayout = new StaticLayout(text, paint, maxWidth, align, lineSpacing, lineAdd, false);
}
} catch (Exception e) {
FileLog.e(e);
return;
}
if (isRepostPreview) {
int maxLines = 22;
if (type != MessageObject.TYPE_TEXT) {
maxLines = hasValidGroupId() ? 7 : 12;
}
if (isWebpage()) {
maxLines -= 8;
}
if (textLayout.getLineCount() > maxLines) {
String readMore = LocaleController.getString(R.string.ReadMore);
int readMoreWidth = (int) Math.ceil(paint.measureText("" + readMore) + AndroidUtilities.dp(1));
float maxRight = 0;
for (int i = 0; i < maxLines; ++i) {
maxRight = Math.max(maxRight, textLayout.getLineRight(i));
}
int start = textLayout.getLineStart(maxLines - 1);
int end = textLayout.getLineEnd(maxLines - 1) - 1;
int offset = end;
for (; offset >= start; --offset) {
if (textLayout.getPrimaryHorizontal(offset) < maxRight - readMoreWidth) {
break;
}
}
for (; offset >= start; --offset) {
if (Character.isWhitespace(text.charAt(offset))) {
break;
}
}
text = new SpannableStringBuilder(text.subSequence(0, offset)).append("").append(readMore);
((SpannableStringBuilder) text).setSpan(new CharacterStyle() {
@Override
public void updateDrawState(TextPaint tp) {
tp.setColor(Theme.chat_msgTextPaint.linkColor);
}
}, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), paint, maxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
if (emojiOnlyCount > 0) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
textLayout = builder.build();
} else {
textLayout = new StaticLayout(text, paint, maxWidth, align, lineSpacing, lineAdd, false);
}
} catch (Exception e) {
FileLog.e(e);
return;
}
}
}
if (hasSingleQuote) {
maxWidth += AndroidUtilities.dp(32);
} else if (hasSingleCode) {
@ -6202,9 +6463,9 @@ public class MessageObject {
float prevOffset = 0;
ArrayList<TextRange> textRanges = new ArrayList<>();
if (messageText instanceof Spanned && (hasQuote || hasCode)) {
if (text instanceof Spanned && (hasQuote || hasCode)) {
singleLayout = false;
cutIntoRanges(messageText, textRanges);
cutIntoRanges(text, textRanges);
} else if (singleLayout || blocksCount == 1) {
textRanges.add(new TextRange(0, textLayout.getText().length()));
} else {
@ -6281,7 +6542,7 @@ public class MessageObject {
}
}
CharSequence blockText = messageText.subSequence(range.start, range.end);
CharSequence blockText = text.subSequence(range.start, range.end);
int blockMaxWidth = maxWidth;
if (block.quote) {
blockMaxWidth -= dp(24);
@ -6506,6 +6767,9 @@ public class MessageObject {
textWidth = Math.max(textWidth, Math.min(maxWidth, linesMaxWidth));
}
if (block.languageLayout != null) {
textWidth = (int) Math.max(textWidth, Math.min(block.languageLayout.getCurrentWidth() + dp(15), block.textLayout == null ? 0 : block.textLayout.getWidth()));
}
linesOffset += currentBlockLinesCount;
@ -6589,6 +6853,62 @@ public class MessageObject {
FileLog.e(e);
return;
}
if (messageObject != null && messageObject.isRepostPreview) {
int maxLines = 22;
if (messageObject.type != MessageObject.TYPE_TEXT) {
maxLines = messageObject.hasValidGroupId() ? 7 : 12;
}
if (messageObject.isWebpage()) {
maxLines -= 8;
}
if (textLayout.getLineCount() > maxLines) {
String readMore = LocaleController.getString(R.string.ReadMore);
int readMoreWidth = (int) Math.ceil(textPaint.measureText("" + readMore) + AndroidUtilities.dp(1));
float maxRight = 0;
for (int i = 0; i < maxLines; ++i) {
maxRight = Math.max(maxRight, textLayout.getLineRight(i));
}
int start = textLayout.getLineStart(maxLines - 1);
int end = textLayout.getLineEnd(maxLines - 1) - 1;
int offset = end;
for (; offset >= start; --offset) {
if (textLayout.getPrimaryHorizontal(offset) < maxRight - readMoreWidth) {
break;
}
}
for (; offset >= start; --offset) {
if (Character.isWhitespace(text.charAt(offset))) {
break;
}
}
text = new SpannableStringBuilder(text.subSequence(0, offset)).append("").append(readMore);
((SpannableStringBuilder) text).setSpan(new CharacterStyle() {
@Override
public void updateDrawState(TextPaint tp) {
tp.setColor(Theme.chat_msgTextPaint.linkColor);
}
}, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(text, 0, text.length(), textPaint, width)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
textLayout = builder.build();
} else {
textLayout = new StaticLayout(text, textPaint, width, align, lineSpacing, lineAdd, false);
}
} catch (Exception e) {
FileLog.e(e);
return;
}
}
}
if (hasSingleQuote) {
width += AndroidUtilities.dp(32);
@ -6874,6 +7194,9 @@ public class MessageObject {
textWidth = Math.max(textWidth, Math.min(width, linesMaxWidth));
}
if (block.languageLayout != null) {
textWidth = (int) Math.max(textWidth, Math.min(block.languageLayout.getCurrentWidth() + dp(15), block.textLayout == null ? 0 : block.textLayout.getWidth()));
}
linesOffset += currentBlockLinesCount;
if (messageObject != null && !messageObject.isSpoilersRevealed && !messageObject.spoiledLoginCode) {
@ -6918,6 +7241,9 @@ public class MessageObject {
}
public boolean needDrawAvatar() {
if (isRepostPreview) {
return true;
}
if (forceAvatar || customAvatarDrawable != null) {
return true;
}
@ -6925,6 +7251,9 @@ public class MessageObject {
}
private boolean needDrawAvatarInternal() {
if (isRepostPreview) {
return true;
}
if (forceAvatar || customAvatarDrawable != null) {
return true;
}
@ -7199,7 +7528,22 @@ public class MessageObject {
return 0;
}
public static boolean shouldEncryptPhotoOrVideo(TLRPC.Message message) {
public static long getChatId(TLRPC.Message message) {
if (message == null) {
return 0;
}
if (message.peer_id instanceof TLRPC.TL_peerChat) {
return message.peer_id.chat_id;
} else if (message.peer_id instanceof TLRPC.TL_peerChannel) {
return message.peer_id.channel_id;
}
return 0;
}
public static boolean shouldEncryptPhotoOrVideo(int currentAccount, TLRPC.Message message) {
if (MessagesController.getInstance(currentAccount).isChatNoForwards(getChatId(message)) || message != null && message.noforwards) {
return true;
}
if (message instanceof TLRPC.TL_message_secret) {
return (getMedia(message) instanceof TLRPC.TL_messageMediaPhoto || isVideoMessage(message)) && message.ttl > 0 && message.ttl <= 60;
} else {
@ -7208,7 +7552,7 @@ public class MessageObject {
}
public boolean shouldEncryptPhotoOrVideo() {
return shouldEncryptPhotoOrVideo(messageOwner);
return shouldEncryptPhotoOrVideo(currentAccount, messageOwner);
}
public static boolean isSecretPhotoOrVideo(TLRPC.Message message) {
@ -7230,6 +7574,9 @@ public class MessageObject {
}
public boolean needDrawBluredPreview() {
if (isRepostPreview) {
return false;
}
if (hasExtendedMediaPreview()) {
return true;
} else if (messageOwner instanceof TLRPC.TL_message_secret) {
@ -8063,6 +8410,14 @@ public class MessageObject {
return isVoiceMessage(messageOwner);
}
public boolean isVoiceOnce() {
return isVoice() && messageOwner != null && messageOwner.media != null && messageOwner.media.ttl_seconds == 0x7FFFFFFF;
}
public boolean isRoundOnce() {
return isRoundVideo() && messageOwner != null && messageOwner.media != null && messageOwner.media.ttl_seconds == 0x7FFFFFFF;
}
public boolean isVideo() {
return isVideoMessage(messageOwner);
}
@ -9095,6 +9450,7 @@ public class MessageObject {
}
public boolean probablyRingtone() {
if (isVoiceOnce()) return false;
if (getDocument() != null && RingtoneDataStore.ringtoneSupportedMimeType.contains(getDocument().mime_type) && getDocument().size < MessagesController.getInstance(currentAccount).ringtoneSizeMax * 2) {
for (int a = 0; a < getDocument().attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = getDocument().attributes.get(a);
@ -9166,6 +9522,14 @@ public class MessageObject {
return type == MessageObject.TYPE_GIVEAWAY;
}
public boolean isGiveawayOrGiveawayResults() {
return isGiveaway() || isGiveawayResults();
}
public boolean isGiveawayResults() {
return type == MessageObject.TYPE_GIVEAWAY_RESULTS;
}
public boolean isAnyGift() {
return type == MessageObject.TYPE_GIFT_PREMIUM || type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL;
}
@ -9332,7 +9696,7 @@ public class MessageObject {
final boolean hasLinkPreview = !isRestrictedMessage && MessageObject.getMedia(messageOwner) instanceof TLRPC.TL_messageMediaWebPage && MessageObject.getMedia(messageOwner).webpage instanceof TLRPC.TL_webPage;
final TLRPC.WebPage webpage = hasLinkPreview ? MessageObject.getMedia(messageOwner).webpage : null;
final String webpageType = webpage != null ? webpage.type : null;
return hasLinkPreview && !isGiveaway() &&
return hasLinkPreview && !isGiveawayOrGiveawayResults() &&
webpage != null && (webpage.photo != null || isVideoDocument(webpage.document)) &&
!(webpage != null && TextUtils.isEmpty(webpage.description) && TextUtils.isEmpty(webpage.title)) &&
!(isSponsored() && sponsoredWebPage == null && sponsoredChannelPost == 0) && // drawInstantViewType = 1

View file

@ -196,6 +196,7 @@ public class MessagePreviewParams {
public boolean webpagePhoto;
public boolean noforwards;
public boolean hasSecretMessages;
public TLRPC.WebPage webpage;
public CharacterStyle currentLink;
@ -206,10 +207,13 @@ public class MessagePreviewParams {
}
public void updateReply(MessageObject replyMessageObject, MessageObject.GroupedMessages group, long dialogId, ChatActivity.ReplyQuote replyQuote) {
if (isSecret || replyMessageObject == null || replyMessageObject.type == MessageObject.TYPE_DATE || replyMessageObject.type == MessageObject.TYPE_ACTION_PHOTO || replyMessageObject.type == MessageObject.TYPE_ACTION_WALLPAPER || replyMessageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
if (isSecret || replyMessageObject == null || replyMessageObject.type == MessageObject.TYPE_DATE || replyMessageObject.type == MessageObject.TYPE_ACTION_PHOTO
|| replyMessageObject.type == MessageObject.TYPE_ACTION_WALLPAPER || replyMessageObject.type == MessageObject.TYPE_SUGGEST_PHOTO
|| replyMessageObject.type == MessageObject.TYPE_GIFT_PREMIUM || replyMessageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL || replyMessageObject.type == MessageObject.TYPE_PHONE_CALL) {
replyMessageObject = null;
replyQuote = null;
}
hasSecretMessages = replyMessageObject != null && (replyMessageObject.isVoiceOnce() || replyMessageObject.isRoundOnce());
if (replyMessageObject != null || replyQuote != null) {
if (group != null) {
replyMessage = new Messages(null, 1, group.messages, dialogId, null);
@ -341,19 +345,23 @@ public class MessagePreviewParams {
public boolean hasLink(CharSequence text, String url) {
if (url != null) {
Spannable spanned = SpannableString.valueOf(text);
try {
AndroidUtilities.addLinks(spanned, Linkify.WEB_URLS);
Spannable spanned = SpannableString.valueOf(text);
try {
AndroidUtilities.addLinks(spanned, Linkify.WEB_URLS);
} catch (Exception e2) {
FileLog.e(e2);
}
URLSpan[] urlSpans = spanned.getSpans(0, spanned.length(), URLSpan.class);
for (int i = 0; i < urlSpans.length; ++i) {
if (areUrlsEqual(urlSpans[i].getURL(), url)) {
return true;
}
}
} catch (Exception e) {
FileLog.e(e);
}
URLSpan[] urlSpans = spanned.getSpans(0, spanned.length(), URLSpan.class);
for (int i = 0; i < urlSpans.length; ++i) {
if (areUrlsEqual(urlSpans[i].getURL(), url)) {
return true;
}
}
}
return false;
}
@ -449,6 +457,10 @@ public class MessagePreviewParams {
}
message.out = out == null ? messageObject.messageOwner.out : out;
if (message.out) {
message.from_id = new TLRPC.TL_peerUser();
message.from_id.user_id = UserConfig.getInstance(messageObject.currentAccount).getClientUserId();
}
message.unread = false;
message.via_bot_id = messageObject.messageOwner.via_bot_id;
message.reply_markup = messageObject.messageOwner.reply_markup;
@ -464,7 +476,7 @@ public class MessagePreviewParams {
if (msgtype == 0) {
TLRPC.MessageFwdHeader header = null;
long clientUserId = UserConfig.getInstance(messageObject.currentAccount).clientUserId;
long clientUserId = UserConfig.getInstance(messageObject.currentAccount).getClientUserId();
if (!isSecret) {
if (messageObject.messageOwner.fwd_from != null) {
header = messageObject.messageOwner.fwd_from;

View file

@ -515,7 +515,6 @@ public class MessagesController extends BaseController implements NotificationCe
public int ringtoneSizeMax;
public boolean storiesExportNopublicLink;
public int authorizationAutoconfirmPeriod;
public int channelColorLevelMin;
public int quoteLengthMax;
public boolean giveawayGiftsPurchaseAvailable;
public PeerColors peerColors;
@ -565,6 +564,13 @@ public class MessagesController extends BaseController implements NotificationCe
public int storiesSentWeeklyLimitPremium;
public int storiesSentMonthlyLimitDefault;
public int storiesSentMonthlyLimitPremium;
public int storiesSuggestedReactionsLimitDefault;
public int storiesSuggestedReactionsLimitPremium;
public int channelBgIconLevelMin;
public int channelProfileIconLevelMin;
public int channelEmojiStatusLevelMin;
public int channelWallpaperLevelMin;
public int channelCustomWallpaperLevelMin;
public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium;
@ -580,6 +586,13 @@ public class MessagesController extends BaseController implements NotificationCe
public boolean premiumLocked;
public int transcribeButtonPressed;
public boolean premiumFeaturesBlocked() {
return premiumLocked && !getUserConfig().isPremium();
}
public boolean premiumPurchaseBlocked() {
return premiumLocked;
}
public List<String> directPaymentsCurrency = new ArrayList<>();
public NewMessageCallback newMessageCallback;
@ -715,7 +728,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
public boolean isPremiumUser(TLRPC.User currentUser) {
return !premiumLocked && currentUser.premium;
return !premiumFeaturesBlocked() && currentUser.premium;
}
public boolean didPressTranscribeButtonEnough() {
@ -733,7 +746,7 @@ public class MessagesController extends BaseController implements NotificationCe
public ArrayList<TLRPC.TL_messages_stickerSet> filterPremiumStickers(ArrayList<TLRPC.TL_messages_stickerSet> stickerSets) {
if (!premiumLocked) {
if (!premiumFeaturesBlocked()) {
return stickerSets;
}
for (int i = 0; i < stickerSets.size(); i++) {
@ -749,7 +762,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
public TLRPC.TL_messages_stickerSet filterPremiumStickers(TLRPC.TL_messages_stickerSet stickerSet) {
if (!premiumLocked || stickerSet == null) {
if (!premiumFeaturesBlocked() || stickerSet == null) {
return stickerSet;
}
try {
@ -1416,9 +1429,16 @@ public class MessagesController extends BaseController implements NotificationCe
storyExpiringLimitDefault = mainPreferences.getInt("storyExpiringLimitDefault", 50);
storyExpiringLimitPremium = mainPreferences.getInt("storyExpiringLimitPremium", 100);
storiesSentWeeklyLimitDefault = mainPreferences.getInt("storiesSentWeeklyLimitDefault", 7);
storiesSuggestedReactionsLimitDefault = mainPreferences.getInt("storiesSuggestedReactionsLimitDefault", 1);
storiesSuggestedReactionsLimitPremium = mainPreferences.getInt("storiesSuggestedReactionsLimitPremium", 5);
storiesSentWeeklyLimitPremium = mainPreferences.getInt("storiesSentWeeklyLimitPremium", 70);
storiesSentMonthlyLimitDefault = mainPreferences.getInt("storiesSentMonthlyLimitDefault", 30);
storiesSentMonthlyLimitPremium = mainPreferences.getInt("storiesSentMonthlyLimitPremium", 300);
channelBgIconLevelMin = mainPreferences.getInt("channelBgIconLevelMin", 1);
channelProfileIconLevelMin = mainPreferences.getInt("channelProfileIconLevelMin", 1);
channelEmojiStatusLevelMin = mainPreferences.getInt("channelEmojiStatusLevelMin", 1);
channelWallpaperLevelMin = mainPreferences.getInt("channelWallpaperLevelMin", 1);
channelCustomWallpaperLevelMin = mainPreferences.getInt("channelCustomWallpaperLevelMin", 1);
chatlistInvitesLimitPremium = mainPreferences.getInt("chatlistInvitesLimitPremium", isTest ? 5 : 20);
chatlistJoinedLimitDefault = mainPreferences.getInt("chatlistJoinedLimitDefault", 2);
chatlistJoinedLimitPremium = mainPreferences.getInt("chatlistJoinedLimitPremium", isTest ? 5 : 20);
@ -1426,7 +1446,6 @@ public class MessagesController extends BaseController implements NotificationCe
storiesEntities = mainPreferences.getString("storiesEntities", "premium");
storiesExportNopublicLink = mainPreferences.getBoolean("storiesExportNopublicLink", false);
authorizationAutoconfirmPeriod = mainPreferences.getInt("authorization_autoconfirm_period", 604800);
channelColorLevelMin = mainPreferences.getInt("channelColorLevelMin", 1);
quoteLengthMax = mainPreferences.getInt("quoteLengthMax", 1024);
giveawayGiftsPurchaseAvailable = mainPreferences.getBoolean("giveawayGiftsPurchaseAvailable", false);
peerColors = PeerColors.fromString(PeerColors.TYPE_NAME, mainPreferences.getString("peerColors", ""));
@ -3348,6 +3367,28 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "stories_suggested_reactions_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != storiesSuggestedReactionsLimitDefault) {
storiesSuggestedReactionsLimitDefault = (int) num.value;
editor.putInt("storiesSuggestedReactionsLimitDefault", storiesSuggestedReactionsLimitDefault);
changed = true;
}
}
break;
}
case "stories_suggested_reactions_limit_premium": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != storiesSuggestedReactionsLimitPremium) {
storiesSuggestedReactionsLimitPremium = (int) num.value;
editor.putInt("storiesSuggestedReactionsLimitPremium", storiesSuggestedReactionsLimitPremium);
changed = true;
}
}
break;
}
case "stories_sent_weekly_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
@ -3480,17 +3521,6 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "channel_color_level_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (channelColorLevelMin != num.value) {
channelColorLevelMin = (int) num.value;
editor.putInt("channelColorLevelMin", channelColorLevelMin);
changed = true;
}
}
break;
}
case "quote_length_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
@ -3570,6 +3600,61 @@ public class MessagesController extends BaseController implements NotificationCe
}
break;
}
case "channel_bg_icon_level_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != channelBgIconLevelMin) {
channelBgIconLevelMin = (int) num.value;
editor.putInt("channelBgIconLevelMin", channelBgIconLevelMin);
changed = true;
}
}
break;
}
case "channel_profile_bg_icon_level_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != channelProfileIconLevelMin) {
channelProfileIconLevelMin = (int) num.value;
editor.putInt("channelProfileIconLevelMin", channelProfileIconLevelMin);
changed = true;
}
}
break;
}
case "channel_emoji_status_level_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != channelEmojiStatusLevelMin) {
channelEmojiStatusLevelMin = (int) num.value;
editor.putInt("channelEmojiStatusLevelMin", channelEmojiStatusLevelMin);
changed = true;
}
}
break;
}
case "channel_wallpaper_level_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != channelWallpaperLevelMin) {
channelWallpaperLevelMin = (int) num.value;
editor.putInt("channelWallpaperLevelMin", channelWallpaperLevelMin);
changed = true;
}
}
break;
}
case "channel_custom_wallpaper_level_min": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (num.value != channelCustomWallpaperLevelMin) {
channelCustomWallpaperLevelMin = (int) num.value;
editor.putInt("channelCustomWallpaperLevelMin", channelCustomWallpaperLevelMin);
changed = true;
}
}
break;
}
}
}
@ -3652,6 +3737,50 @@ public class MessagesController extends BaseController implements NotificationCe
public final ArrayList<PeerColor> colors = new ArrayList<>();
private final LongSparseArray<PeerColor> colorsById = new LongSparseArray<>();
public boolean needUpdate() {
boolean noLevels = true;
boolean hasStandardColors = false;
for (int i = 0; i < colors.size(); ++i) {
if (colors.get(i).lvl > 0) {
noLevels = false;
}
if (colors.get(i).id < 7) {
hasStandardColors = true;
}
}
return noLevels || type == TYPE_NAME && !hasStandardColors;
}
public int colorsAvailable(int lvl) {
int count = 0;
for (int i = 0; i < colors.size(); ++i) {
if (!colors.get(i).hidden && lvl >= colors.get(i).lvl) {
count++;
}
}
return count;
}
public int maxLevel() {
int maxLvl = 0;
for (int i = 0; i < colors.size(); ++i) {
if (!colors.get(i).hidden) {
maxLvl = Math.max(maxLvl, colors.get(i).lvl);
}
}
return maxLvl;
}
public int minLevel() {
int minLvl = maxLevel();
for (int i = 0; i < colors.size(); ++i) {
if (!colors.get(i).hidden) {
minLvl = Math.min(minLvl, colors.get(i).lvl);
}
}
return minLvl;
}
private PeerColors(int type, int hash) {
this.type = type;
this.hash = hash;
@ -3692,6 +3821,7 @@ public class MessagesController extends BaseController implements NotificationCe
PeerColor peerColor = PeerColor.fromString(colorParts[i]);
if (peerColor == null)
continue;
peerColor.isDefaultName = peerColor.id < 7 && type == TYPE_NAME;
if (!peerColor.hidden)
peerColors.colors.add(peerColor);
peerColors.colorsById.put(peerColor.id, peerColor);
@ -3702,7 +3832,7 @@ public class MessagesController extends BaseController implements NotificationCe
private static int color(String str) {
return Integer.parseUnsignedInt("ff" + str, 16);
}
public static PeerColors fromTL(int type, TLRPC.TL_help_peerColors tl) {
if (tl == null) return null;
try {
@ -3710,7 +3840,7 @@ public class MessagesController extends BaseController implements NotificationCe
for (int i = 0; i < tl.colors.size(); ++i) {
PeerColor peerColor = PeerColor.fromTL(tl.colors.get(i));
if (peerColor == null) continue;
if (peerColor.id < 7 && type == TYPE_NAME) continue;
peerColor.isDefaultName = peerColor.id < 7 && type == TYPE_NAME;
if (!peerColor.hidden)
peerColors.colors.add(peerColor);
peerColors.colorsById.put(peerColor.id, peerColor);
@ -3748,7 +3878,7 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.e(e2);
continue;
}
if (type == TYPE_NAME && peerColor.id < 7) continue;
peerColor.isDefaultName = peerColor.id < 7 && type == TYPE_NAME;
peerColors.colorsById.put(id, peerColor);
}
}
@ -3794,10 +3924,20 @@ public class MessagesController extends BaseController implements NotificationCe
}
public static class PeerColor {
public boolean isDefaultName;
public int id;
public boolean hidden;
public int lvl;
private final int[] colors = new int[6];
private final int[] darkColors = new int[6];
public int getColor(int i, Theme.ResourcesProvider resourcesProvider) {
if (i < 0 || i > 5) return 0;
if (isDefaultName && id >= 0 && id < 7) {
return Theme.getColor(Theme.keys_avatar_nameInMessage[id], resourcesProvider);
}
final boolean isDark = resourcesProvider != null ? resourcesProvider.isDark() : Theme.isCurrentThemeDark();
return (isDark ? darkColors : colors)[i];
}
public int getColor1(boolean isDark) {
return (isDark ? darkColors : colors)[0];
}
@ -3831,9 +3971,6 @@ public class MessagesController extends BaseController implements NotificationCe
public int getColor5() {
return (Theme.isCurrentThemeDark() ? darkColors : colors)[4];
}
public int getColor6() {
return (Theme.isCurrentThemeDark() ? darkColors : colors)[5];
}
public boolean hasColor2() {
return getColor2() != getColor1();
}
@ -3870,6 +4007,9 @@ public class MessagesController extends BaseController implements NotificationCe
public void appendString(StringBuilder sb) {
sb.append("#");
if (hidden) sb.append("H");
if (lvl > 0) {
sb.append("[").append(lvl).append("]");
}
sb.append(id);
sb.append("{");
sb.append(colors[0]);
@ -3918,6 +4058,9 @@ public class MessagesController extends BaseController implements NotificationCe
final PeerColor peerColor = new PeerColor();
peerColor.id = tl.color_id;
peerColor.hidden = tl.hidden;
if ((tl.flags & 8) != 0) {
peerColor.lvl = tl.channel_min_level;
}
System.arraycopy(optionToColors(tl.colors), 0, peerColor.colors, 0, 6);
System.arraycopy(optionToColors(tl.dark_colors), 0, peerColor.darkColors, 0, 6);
@ -3962,16 +4105,25 @@ public class MessagesController extends BaseController implements NotificationCe
if (string == null || string.isEmpty() || string.charAt(0) != '#')
return null;
int startIndex = 1;
boolean hidden = string.length() > 1 && string.charAt(1) == 'H';
boolean hidden = string.length() > 1 && string.charAt(startIndex) == 'H';
if (hidden) {
startIndex++;
}
int lvl = 0;
if (string.length() > startIndex && string.charAt(startIndex) == '[') {
int eindex = string.indexOf(']');
if (eindex > startIndex) {
lvl = Utilities.parseInt(string.substring(startIndex + 1, eindex));
startIndex = eindex + 1;
}
}
int index = string.indexOf('{');
if (index < 0) return null;
try {
final PeerColor peerColor = new PeerColor();
peerColor.id = Utilities.parseInt(string.substring(startIndex, index));
peerColor.hidden = hidden;
peerColor.lvl = lvl;
final String[] parts = string.substring(index + 1, string.length() - 1).split("@");
String[] colorsString = parts[0].split(",");
for (int i = 0; i < 6; ++i)
@ -4458,7 +4610,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.wallpapersNeedReload, wallPaper.slug);
if (uploadingWallpaperInfo.requestIds != null && overrideWallpaperInfo.dialogId != 0) {
uploadingWallpaperInfo.requestIds.add(ChatThemeController.getInstance(currentAccount).setWallpaperToUser(overrideWallpaperInfo.dialogId, uploadingWallpaperFinal, overrideWallpaperInfo, null, null));
uploadingWallpaperInfo.requestIds.add(ChatThemeController.getInstance(currentAccount).setWallpaperToPeer(overrideWallpaperInfo.dialogId, uploadingWallpaperFinal, overrideWallpaperInfo, null, null));
}
}
});
@ -4853,7 +5005,6 @@ public class MessagesController extends BaseController implements NotificationCe
loadingSuggestedFilters = false;
loadingRemoteFilters = false;
suggestedFilters.clear();
gettingAppChangelog = false;
dialogFiltersLoaded = false;
ignoreSetOnline = false;
@ -5230,6 +5381,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
updateEmojiStatusUntilUpdate(-chat.id, chat.emoji_status);
if (chat.min) {
if (oldChat != null) {
if (!fromCache) {
@ -5311,7 +5463,7 @@ public class MessagesController extends BaseController implements NotificationCe
} else {
oldChat.flags |= 16384;
}
if (!chat.stories_hidden_min) {
if (chat.stories_hidden_min) {
chat.stories_hidden = oldChat.stories_hidden;
}
if (oldFlags != newFlags || oldFlags2 != newFlags2) {
@ -5699,6 +5851,7 @@ public class MessagesController extends BaseController implements NotificationCe
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
getMessagesStorage().updateChatInfo(res.full_chat, false);
getStoriesController().updateStoriesFromFullPeer(dialogId, res.full_chat.stories);
ChatThemeController.getInstance(currentAccount).saveChatWallpaper(-chatId, res.full_chat.wallpaper);
if (ChatObject.isChannel(chat)) {
Integer value = dialogs_read_inbox_max.get(dialogId);
if (value == null) {
@ -5780,7 +5933,10 @@ public class MessagesController extends BaseController implements NotificationCe
dialog.ttl_period = res.full_chat.ttl_period;
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
dialog.view_forum_as_messages = res.full_chat.view_forum_as_messages;
if (dialog.view_forum_as_messages != res.full_chat.view_forum_as_messages) {
dialog.view_forum_as_messages = res.full_chat.view_forum_as_messages;
getMessagesStorage().setDialogViewThreadAsMessages(dialogId, res.full_chat.view_forum_as_messages);
}
}
});
} else {
@ -10975,7 +11131,6 @@ public class MessagesController extends BaseController implements NotificationCe
migratingDialogs = false;
getNotificationCenter().postNotificationName(NotificationCenter.needReloadRecentDialogsSearch);
} else {
generateUpdateMessage();
if (!added && loadType == DIALOGS_LOAD_TYPE_CACHE && dialogsEndReached.get(folderId)) {
loadDialogs(folderId, 0, count, false);
}
@ -12117,13 +12272,28 @@ public class MessagesController extends BaseController implements NotificationCe
processUpdates((TLRPC.Updates) response, false);
AndroidUtilities.runOnUIThread(() -> {
if (convertRunnable != null) {
TLRPC.Chat prevChat = null;
for (int a = 0; a < updates.chats.size(); a++) {
TLRPC.Chat chat = updates.chats.get(a);
if (ChatObject.isChannel(chat)) {
convertRunnable.run(chat.id);
if (chatId == chat.id) {
prevChat = chat;
break;
}
}
if (prevChat != null && prevChat.migrated_to != null) {
long newChatId = prevChat.migrated_to.channel_id;
TLRPC.Chat newChat = null;
for (int a = 0; a < updates.chats.size(); a++) {
TLRPC.Chat chat = updates.chats.get(a);
if (newChatId == chat.id) {
newChat = chat;
break;
}
}
if (newChat != null) {
convertRunnable.run(newChatId);
}
}
}
});
} else {
@ -12960,27 +13130,6 @@ public class MessagesController extends BaseController implements NotificationCe
getContactsController().deleteUnknownAppAccounts();
}
private boolean gettingAppChangelog;
public void generateUpdateMessage() {
if (gettingAppChangelog || BuildVars.DEBUG_VERSION || SharedConfig.lastUpdateVersion == null || SharedConfig.lastUpdateVersion.equals(BuildVars.BUILD_VERSION_STRING)) {
return;
}
gettingAppChangelog = true;
TLRPC.TL_help_getAppChangelog req = new TLRPC.TL_help_getAppChangelog();
req.prev_app_version = SharedConfig.lastUpdateVersion;
getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
SharedConfig.lastUpdateVersion = BuildVars.BUILD_VERSION_STRING;
SharedConfig.saveConfig();
}
if (response instanceof TLRPC.Updates) {
processUpdates((TLRPC.Updates) response, false);
}
});
}
public void registerForPush(@PushListenerController.PushType int pushType, String regid) {
if (TextUtils.isEmpty(regid) || registeringForPush || getUserConfig().getClientUserId() == 0) {
return;
@ -17256,9 +17405,13 @@ public class MessagesController extends BaseController implements NotificationCe
}
TLRPC.Dialog dialog = getDialog(-update.channel_id);
if (dialog != null) {
dialog.view_forum_as_messages = update.enabled;
if (dialog.view_forum_as_messages != update.enabled) {
dialog.view_forum_as_messages = update.enabled;
getMessagesStorage().setDialogViewThreadAsMessages(-update.channel_id, update.enabled);
}
} else {
getMessagesStorage().setDialogViewThreadAsMessages(-update.channel_id, update.enabled);
}
getMessagesStorage().setDialogViewThreadAsMessages(-update.channel_id, update.enabled);
}
}
if (editor != null) {
@ -19191,13 +19344,13 @@ public class MessagesController extends BaseController implements NotificationCe
boolean onMessageReceived(TLRPC.Message message);
}
public void updateEmojiStatusUntilUpdate(long userId, TLRPC.EmojiStatus status) {
public void updateEmojiStatusUntilUpdate(long dialogId, TLRPC.EmojiStatus status) {
if (status instanceof TLRPC.TL_emojiStatusUntil) {
emojiStatusUntilValues.put(userId, ((TLRPC.TL_emojiStatusUntil) status).until);
emojiStatusUntilValues.put(dialogId, ((TLRPC.TL_emojiStatusUntil) status).until);
} else {
if (!emojiStatusUntilValues.containsKey(userId))
if (!emojiStatusUntilValues.containsKey(dialogId))
return;
emojiStatusUntilValues.remove(userId);
emojiStatusUntilValues.remove(dialogId);
}
updateEmojiStatusUntil();
@ -19413,10 +19566,18 @@ public class MessagesController extends BaseController implements NotificationCe
}
FileLoader.getInstance(currentAccount).cancelFileUpload(uploadingWallpaper, false);
if (uploadingWallpaperInfo.dialogId != 0) {
TLRPC.UserFull userFull = getUserFull(uploadingWallpaperInfo.dialogId);
if (userFull != null) {
userFull.wallpaper = uploadingWallpaperInfo.prevUserWallpaper;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, uploadingWallpaperInfo.dialogId, userFull);
if (uploadingWallpaperInfo.dialogId >= 0) {
TLRPC.UserFull userFull = getUserFull(uploadingWallpaperInfo.dialogId);
if (userFull != null) {
userFull.wallpaper = uploadingWallpaperInfo.prevUserWallpaper;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, uploadingWallpaperInfo.dialogId, userFull);
}
} else {
TLRPC.ChatFull chatFull = getChatFull(-uploadingWallpaperInfo.dialogId);
if (chatFull != null) {
chatFull.wallpaper = uploadingWallpaperInfo.prevUserWallpaper;
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.chatInfoDidLoad, chatFull, 0, false, false);
}
}
}
uploadingWallpaperInfo = null;
@ -19544,9 +19705,12 @@ public class MessagesController extends BaseController implements NotificationCe
}
public void checkPeerColors(boolean force) {
if (peerColors == null || force) {
if (peerColors == null || peerColors.needUpdate() || force) {
TLRPC.TL_help_getPeerColors req = new TLRPC.TL_help_getPeerColors();
req.hash = peerColors != null ? peerColors.hash : 0;
if (peerColors != null && peerColors.needUpdate()) {
req.hash = 0;
}
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.TL_help_peerColors) {
AndroidUtilities.runOnUIThread(() -> {
@ -19556,9 +19720,12 @@ public class MessagesController extends BaseController implements NotificationCe
}
});
}
if (profilePeerColors == null || force) {
if (profilePeerColors == null || profilePeerColors.needUpdate() || force) {
TLRPC.TL_help_getPeerProfileColors req = new TLRPC.TL_help_getPeerProfileColors();
req.hash = profilePeerColors != null ? profilePeerColors.hash : 0;
if (profilePeerColors != null && profilePeerColors.needUpdate()) {
req.hash = 0;
}
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.TL_help_peerColors) {
AndroidUtilities.runOnUIThread(() -> {

View file

@ -14160,6 +14160,14 @@ public class MessagesStorage extends BaseController {
}
}
}
if (message.media instanceof TLRPC.TL_messageMediaGiveawayResults) {
TLRPC.TL_messageMediaGiveawayResults giveaway = (TLRPC.TL_messageMediaGiveawayResults) message.media;
for (Long uid : giveaway.winners) {
if (!usersToLoad.contains(uid)) {
usersToLoad.add(uid);
}
}
}
if (message.media instanceof TLRPC.TL_messageMediaPoll) {
TLRPC.TL_messageMediaPoll messageMediaPoll = (TLRPC.TL_messageMediaPoll) message.media;
if (!messageMediaPoll.results.recent_voters.isEmpty()) {
@ -14168,8 +14176,19 @@ public class MessagesStorage extends BaseController {
}
}
}
if (message.media instanceof TLRPC.TL_messageMediaStory && message.media.storyItem != null && message.media.storyItem.fwd_from != null) {
addLoadPeerInfo(message.media.storyItem.fwd_from.from, usersToLoad, chatsToLoad);
if (message.media instanceof TLRPC.TL_messageMediaStory && message.media.storyItem != null) {
if (message.media.storyItem.fwd_from != null) {
addLoadPeerInfo(message.media.storyItem.fwd_from.from, usersToLoad, chatsToLoad);
}
if (message.media.storyItem != null && message.media.storyItem.media_areas != null) {
for (int j = 0; j < message.media.storyItem.media_areas.size(); ++j) {
if (message.media.storyItem.media_areas.get(j) instanceof TL_stories.TL_mediaAreaChannelPost) {
long channelId = ((TL_stories.TL_mediaAreaChannelPost) message.media.storyItem.media_areas.get(j)).channel_id;
if (!chatsToLoad.contains(channelId))
chatsToLoad.add(channelId);
}
}
}
}
if (message.media instanceof TLRPC.TL_messageMediaWebPage && message.media.webpage != null && message.media.webpage.attributes != null) {
for (int i = 0; i < message.media.webpage.attributes.size(); ++i) {
@ -14178,6 +14197,15 @@ public class MessagesStorage extends BaseController {
if (attr.storyItem != null && attr.storyItem.fwd_from != null) {
addLoadPeerInfo(attr.storyItem.fwd_from.from, usersToLoad, chatsToLoad);
}
if (attr.storyItem != null && attr.storyItem.media_areas != null) {
for (int j = 0; j < attr.storyItem.media_areas.size(); ++j) {
if (attr.storyItem.media_areas.get(j) instanceof TL_stories.TL_mediaAreaChannelPost) {
long channelId = ((TL_stories.TL_mediaAreaChannelPost) attr.storyItem.media_areas.get(j)).channel_id;
if (!chatsToLoad.contains(channelId))
chatsToLoad.add(channelId);
}
}
}
}
}
}

View file

@ -210,6 +210,8 @@ public class NotificationCenter {
public static final int updateBotMenuButton = totalEvents++;
public static final int giftsToUserSent = totalEvents++;
public static final int didStartedMultiGiftsSelector = totalEvents++;
public static final int boostedChannelByUser = totalEvents++;
public static final int boostByChannelCreated = totalEvents++;
public static final int didUpdatePremiumGiftStickers = totalEvents++;
@ -221,6 +223,7 @@ public class NotificationCenter {
public static final int unconfirmedAuthUpdate = totalEvents++;
public static final int dialogPhotosUpdate = totalEvents++;
public static final int channelRecommendationsLoaded = totalEvents++;
public static final int savedMessagesUpdate = totalEvents++;
//global
public static final int pushMessagesUpdated = totalEvents++;
@ -285,21 +288,22 @@ public class NotificationCenter {
public static final int userEmojiStatusUpdated = totalEvents++;
public static final int requestPermissions = totalEvents++;
public static final int permissionsGranted = totalEvents++;
public static int topicsDidLoaded = totalEvents++;
public static int chatSwithcedToForum = totalEvents++;
public static int didUpdateGlobalAutoDeleteTimer = totalEvents++;
public static int onDatabaseReset = totalEvents++;
public static int wallpaperSettedToUser = totalEvents++;
public static int storiesUpdated = totalEvents++;
public static int storiesListUpdated = totalEvents++;
public static int storiesDraftsUpdated = totalEvents++;
public static int chatlistFolderUpdate = totalEvents++;
public static final int topicsDidLoaded = totalEvents++;
public static final int chatSwithcedToForum = totalEvents++;
public static final int didUpdateGlobalAutoDeleteTimer = totalEvents++;
public static final int onDatabaseReset = totalEvents++;
public static final int wallpaperSettedToUser = totalEvents++;
public static final int storiesUpdated = totalEvents++;
public static final int storiesListUpdated = totalEvents++;
public static final int storiesDraftsUpdated = totalEvents++;
public static final int chatlistFolderUpdate = totalEvents++;
public static final int uploadStoryProgress = totalEvents++;
public static final int uploadStoryEnd = totalEvents++;
public static final int customTypefacesLoaded = totalEvents++;
public static final int stealthModeChanged = totalEvents++;
public static final int onReceivedChannelDifference = totalEvents++;
public static final int storiesReadUpdated = totalEvents++;
public static final int nearEarEvent = totalEvents++;
public static boolean alreadyLogged;

View file

@ -2120,6 +2120,8 @@ public class NotificationsController extends BaseController {
}
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGiveaway) {
return LocaleController.getString("BoostingGiveaway", R.string.BoostingGiveaway);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGiveawayResults) {
return LocaleController.getString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
return LocaleController.getString("AttachLocation", R.string.AttachLocation);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {
@ -2369,6 +2371,8 @@ public class NotificationsController extends BaseController {
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGiveaway) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) messageObject.messageOwner.media;
msg = LocaleController.formatString("NotificationMessageChannelGiveaway", R.string.NotificationMessageChannelGiveaway, name, giveaway.quantity, giveaway.months);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGiveawayResults) {
msg = LocaleController.formatString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) messageObject.messageOwner.media;
if (mediaPoll.poll.quiz) {
@ -2823,6 +2827,8 @@ public class NotificationsController extends BaseController {
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGiveaway) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) messageObject.messageOwner.media;
msg = LocaleController.formatString("NotificationMessageChannelGiveaway", R.string.NotificationMessageChannelGiveaway, chat.title, giveaway.quantity, giveaway.months);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGiveawayResults) {
msg = LocaleController.formatString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeo || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaVenue) {
msg = LocaleController.formatString("NotificationMessageGroupMap", R.string.NotificationMessageGroupMap, name, chat.title);
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaGeoLive) {

View file

@ -0,0 +1,76 @@
package org.telegram.messenger;
import androidx.collection.LongSparseArray;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteDatabase;
import org.telegram.SQLite.SQLiteException;
import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLRPC;
import java.util.ArrayList;
import java.util.HashMap;
public class SavedMessagesController {
private final int currentAccount;
public boolean loading, loaded;
public LongSparseArray<ArrayList<MessageObject>> messages = new LongSparseArray<ArrayList<MessageObject>>();
public SavedMessagesController(int account) {
this.currentAccount = account;
}
public void getSavedMessagesDialogs() {
if (loaded || loading) {
return;
}
loading = true;
final long myself = UserConfig.getInstance(currentAccount).getClientUserId();
MessagesStorage storage = MessagesStorage.getInstance(currentAccount);
storage.getStorageQueue().postRunnable(() -> {
SQLiteDatabase database = storage.getDatabase();
SQLiteCursor cursor = null;
final LongSparseArray<ArrayList<MessageObject>> messages = new LongSparseArray<>();
try {
cursor = database.queryFinalized("SELECT data, mid, date, send_state, read_state, custom_params FROM messages_v2 WHERE out = 0 AND uid = ?", myself);
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message.fwd_from == null || message.fwd_from.saved_from_peer == null) {
continue;
}
long did = DialogObject.getPeerDialogId(message.fwd_from.saved_from_peer);
message.id = cursor.intValue(1);
message.date = cursor.intValue(2);
message.send_state = cursor.intValue(3);
MessageObject.setUnreadFlags(message, cursor.intValue(4));
MessageObject messageObject = new MessageObject(currentAccount, message, true, true);
ArrayList<MessageObject> messageObjects = messages.get(did);
if (messageObjects == null) {
messages.put(did, messageObjects = new ArrayList<>());
}
messageObjects.add(messageObject);
}
}
AndroidUtilities.runOnUIThread(() -> {
SavedMessagesController.this.messages.clear();
SavedMessagesController.this.messages.putAll(messages);
loading = false;
});
} catch (SQLiteException e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.dispose();
cursor = null;
}
}
});
}
}

View file

@ -21,7 +21,6 @@ import android.os.Environment;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.webkit.WebView;
import androidx.annotation.IntDef;
@ -234,7 +233,6 @@ public class SharedConfig {
public static int lastPauseTime;
public static boolean isWaitingForPasscodeEnter;
public static boolean useFingerprint = true;
public static String lastUpdateVersion;
public static int suggestStickers;
public static boolean suggestAnimatedEmoji;
public static int keepMedia = CacheByChatsController.KEEP_MEDIA_ONE_MONTH; //deprecated
@ -312,6 +310,8 @@ public class SharedConfig {
public static int messageSeenHintCount;
public static int emojiInteractionsHintCount;
public static int dayNightThemeSwitchHintCount;
public static boolean forceLessData;
public static int callEncryptionHintDisplayedCount;
public static TLRPC.TL_help_appUpdate pendingAppUpdate;
public static int pendingAppUpdateBuildVersion;
@ -431,7 +431,6 @@ public class SharedConfig {
editor.putInt("badPasscodeTries", badPasscodeTries);
editor.putInt("autoLockIn", autoLockIn);
editor.putInt("lastPauseTime", lastPauseTime);
editor.putString("lastUpdateVersion2", lastUpdateVersion);
editor.putBoolean("useFingerprint", useFingerprint);
editor.putBoolean("allowScreenCapture", allowScreenCapture);
editor.putString("pushString2", pushString);
@ -511,7 +510,6 @@ public class SharedConfig {
autoLockIn = preferences.getInt("autoLockIn", 60 * 60);
lastPauseTime = preferences.getInt("lastPauseTime", 0);
useFingerprint = preferences.getBoolean("useFingerprint", true);
lastUpdateVersion = preferences.getString("lastUpdateVersion2", "3.5");
allowScreenCapture = preferences.getBoolean("allowScreenCapture", false);
lastLocalId = preferences.getInt("lastLocalId", -210000);
pushString = preferences.getString("pushString2", "");
@ -541,7 +539,7 @@ public class SharedConfig {
try {
String update = preferences.getString("appUpdate", null);
if (update != null) {
pendingAppUpdateBuildVersion = preferences.getInt("appUpdateBuild", BuildVars.BUILD_VERSION);
pendingAppUpdateBuildVersion = preferences.getInt("appUpdateBuild", buildVersion());
byte[] arr = Base64.decode(update, Base64.DEFAULT);
if (arr != null) {
SerializedData data = new SerializedData(arr);
@ -561,7 +559,7 @@ public class SharedConfig {
FileLog.e(e);
}
if (updateVersion == 0) {
updateVersion = BuildVars.BUILD_VERSION;
updateVersion = buildVersion();
}
if (updateVersionString == null) {
updateVersionString = BuildVars.BUILD_VERSION_STRING;
@ -651,6 +649,8 @@ public class SharedConfig {
payByInvoice = preferences.getBoolean("payByInvoice", false);
photoViewerBlur = preferences.getBoolean("photoViewerBlur", true);
multipleReactionsPromoShowed = preferences.getBoolean("multipleReactionsPromoShowed", false);
forceLessData = preferences.getBoolean("forceLessData", false);
callEncryptionHintDisplayedCount = preferences.getInt("callEncryptionHintDisplayedCount", 0);
loadDebugConfig(preferences);
@ -669,6 +669,15 @@ public class SharedConfig {
}
}
public static int buildVersion() {
try {
return ApplicationLoader.applicationContext.getPackageManager().getPackageInfo(ApplicationLoader.applicationContext.getPackageName(), 0).versionCode;
} catch (Exception e) {
FileLog.e(e);
return 0;
}
}
public static void updateTabletConfig() {
if (fontSizeIsDefault) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
@ -752,7 +761,7 @@ public class SharedConfig {
currentVersion = pInfo.versionCode;
} catch (Exception e) {
FileLog.e(e);
currentVersion = BuildVars.BUILD_VERSION;
currentVersion = buildVersion();
}
return pendingAppUpdateBuildVersion == currentVersion;
}
@ -768,7 +777,7 @@ public class SharedConfig {
FileLog.e(e);
}
if (versionCode == 0) {
versionCode = BuildVars.BUILD_VERSION;
versionCode = buildVersion();
}
if (updateVersionString == null) {
updateVersionString = BuildVars.BUILD_VERSION_STRING;
@ -847,7 +856,6 @@ public class SharedConfig {
useFingerprint = true;
isWaitingForPasscodeEnter = false;
allowScreenCapture = false;
lastUpdateVersion = BuildVars.BUILD_VERSION_STRING;
textSelectionHintShows = 0;
scheduledOrNoSoundHintShows = 0;
scheduledOrNoSoundHintSeenAt = 0;
@ -1071,6 +1079,14 @@ public class SharedConfig {
editor.apply();
}
public static void incrementCallEncryptionHintDisplayed(int count) {
callEncryptionHintDisplayedCount += count;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("callEncryptionHintDisplayedCount", callEncryptionHintDisplayedCount);
editor.apply();
}
public static void toggleLoopStickers() {
LiteMode.toggleFlag(LiteMode.FLAG_ANIMATED_STICKERS_CHAT);
}
@ -1529,6 +1545,10 @@ public class SharedConfig {
preferences.edit().putInt("emojiInteractionsHintCount", emojiInteractionsHintCount).apply();
}
public static void setForceLessData(boolean value) {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
preferences.edit().putBoolean("forceLessData", forceLessData = value).apply();
}
public static void updateDayNightThemeSwitchHintCount(int count) {
dayNightThemeSwitchHintCount = count;

View file

@ -662,7 +662,11 @@ public class TopicsController extends BaseController {
TLRPC.TL_channels_toggleViewForumAsMessages request = new TLRPC.TL_channels_toggleViewForumAsMessages();
request.channel_id = getMessagesController().getInputChannel(channelId);
request.enabled = enabled;
getConnectionsManager().sendRequest(request, null);
getConnectionsManager().sendRequest(request, (res, err) -> {
if (res != null) {
getMessagesController().processUpdates((TLRPC.Updates) res, false);
}
});
}
public void pinTopic(long chatId, int topicId, boolean pin, BaseFragment fragment) {

View file

@ -144,9 +144,9 @@ public class UserObject {
}
public static MessagesController.PeerColor getPeerColorForAvatar(int currentAccount, TLRPC.User user) {
if (user != null && user.profile_color != null && user.profile_color.color >= 0 && MessagesController.getInstance(currentAccount).profilePeerColors != null) {
return MessagesController.getInstance(currentAccount).profilePeerColors.getColor(user.profile_color.color);
}
// if (user != null && user.profile_color != null && user.profile_color.color >= 0 && MessagesController.getInstance(currentAccount).profilePeerColors != null) {
// return MessagesController.getInstance(currentAccount).profilePeerColors.getColor(user.profile_color.color);
// }
return null;
}

View file

@ -55,15 +55,17 @@ public class VideoEditedInfo {
public byte[] key;
public byte[] iv;
public MediaController.SavedFilterState filterState;
public String paintPath, blurPath;
public String paintPath, blurPath, messagePath, messageVideoMaskPath, backgroundPath;
public ArrayList<MediaEntity> mediaEntities;
public MediaController.CropState cropState;
public boolean isPhoto;
public boolean isStory;
public StoryEntry.HDRInfo hdrInfo;
public ArrayList<StoryEntry.Part> parts;
public Integer gradientTopColor, gradientBottomColor;
public int account;
public boolean isDark;
public long wallpaperPeerId = Long.MIN_VALUE;
public boolean forceFragmenting;
public boolean alreadyScheduledConverting;
@ -115,6 +117,7 @@ public class VideoEditedInfo {
public static final byte TYPE_LOCATION = 3;
public static final byte TYPE_REACTION = 4;
public static final byte TYPE_ROUND = 5;
public static final byte TYPE_MESSAGE = 6;
public byte type;
public byte subType;
@ -135,7 +138,9 @@ public class VideoEditedInfo {
public int viewHeight;
public float roundRadius;
public float scale;
public String segmentedPath = "";
public float scale = 1.0f;
public float textViewWidth;
public float textViewHeight;
public float textViewX;
@ -172,50 +177,53 @@ public class VideoEditedInfo {
public MediaEntity() {
}
public MediaEntity(AbstractSerializedData data, boolean full) {
type = data.readByte(false);
subType = data.readByte(false);
x = data.readFloat(false);
y = data.readFloat(false);
rotation = data.readFloat(false);
width = data.readFloat(false);
height = data.readFloat(false);
text = data.readString(false);
int count = data.readInt32(false);
this(data, full, false);
}
public MediaEntity(AbstractSerializedData data, boolean full, boolean exception) {
type = data.readByte(exception);
subType = data.readByte(exception);
x = data.readFloat(exception);
y = data.readFloat(exception);
rotation = data.readFloat(exception);
width = data.readFloat(exception);
height = data.readFloat(exception);
text = data.readString(exception);
int count = data.readInt32(exception);
for (int i = 0; i < count; ++i) {
EmojiEntity entity = new EmojiEntity();
data.readInt32(false);
entity.readParams(data, false);
data.readInt32(exception);
entity.readParams(data, exception);
entities.add(entity);
}
color = data.readInt32(false);
fontSize = data.readInt32(false);
viewWidth = data.readInt32(false);
viewHeight = data.readInt32(false);
textAlign = data.readInt32(false);
textTypeface = PaintTypeface.find(textTypefaceKey = data.readString(false));
scale = data.readFloat(false);
textViewWidth = data.readFloat(false);
textViewHeight = data.readFloat(false);
textViewX = data.readFloat(false);
textViewY = data.readFloat(false);
color = data.readInt32(exception);
fontSize = data.readInt32(exception);
viewWidth = data.readInt32(exception);
viewHeight = data.readInt32(exception);
textAlign = data.readInt32(exception);
textTypeface = PaintTypeface.find(textTypefaceKey = data.readString(exception));
scale = data.readFloat(exception);
textViewWidth = data.readFloat(exception);
textViewHeight = data.readFloat(exception);
textViewX = data.readFloat(exception);
textViewY = data.readFloat(exception);
if (full) {
int magic = data.readInt32(false);
int magic = data.readInt32(exception);
if (magic == TLRPC.TL_null.constructor) {
document = null;
} else {
document = TLRPC.Document.TLdeserialize(data, magic, false);
document = TLRPC.Document.TLdeserialize(data, magic, exception);
}
}
if (type == TYPE_LOCATION) {
density = data.readFloat(false);
mediaArea = TL_stories.MediaArea.TLdeserialize(data, data.readInt32(false), false);
mediaGeo = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(false), false);
density = data.readFloat(exception);
mediaArea = TL_stories.MediaArea.TLdeserialize(data, data.readInt32(exception), exception);
mediaGeo = TLRPC.MessageMedia.TLdeserialize(data, data.readInt32(exception), exception);
if (data.remaining() > 0) {
int magic = data.readInt32(false);
int magic = data.readInt32(exception);
if (magic == 0xdeadbeef) {
String emoji = data.readString(false);
String emoji = data.readString(exception);
if (mediaGeo instanceof TLRPC.TL_messageMediaVenue) {
((TLRPC.TL_messageMediaVenue) mediaGeo).emoji = emoji;
}
@ -223,13 +231,16 @@ public class VideoEditedInfo {
}
}
if (type == TYPE_REACTION) {
mediaArea = TL_stories.MediaArea.TLdeserialize(data, data.readInt32(false), false);
mediaArea = TL_stories.MediaArea.TLdeserialize(data, data.readInt32(exception), exception);
}
if (type == TYPE_ROUND) {
roundOffset = data.readInt64(false);
roundLeft = data.readInt64(false);
roundRight = data.readInt64(false);
roundDuration = data.readInt64(false);
roundOffset = data.readInt64(exception);
roundLeft = data.readInt64(exception);
roundRight = data.readInt64(exception);
roundDuration = data.readInt64(exception);
}
if (type == TYPE_PHOTO) {
segmentedPath = data.readString(exception);
}
}
@ -293,6 +304,9 @@ public class VideoEditedInfo {
data.writeInt64(roundRight);
data.writeInt64(roundDuration);
}
if (type == TYPE_PHOTO) {
data.writeString(segmentedPath);
}
}
public MediaEntity copy() {
@ -452,14 +466,7 @@ public class VideoEditedInfo {
} else {
serializedData.writeByte(0);
}
if (parts != null && !parts.isEmpty()) {
serializedData.writeInt32(parts.size());
for (StoryEntry.Part part : parts) {
part.serializeToStream(serializedData);
}
} else {
serializedData.writeInt32(0);
}
serializedData.writeInt32(0);
serializedData.writeBool(isStory);
serializedData.writeBool(fromCamera);
if (blurPathBytes != null) {
@ -582,11 +589,7 @@ public class VideoEditedInfo {
}
}
if (version >= 6) {
int count = serializedData.readInt32(false);
for (int i = 0; i < count; ++i) {
StoryEntry.Part part = new StoryEntry.Part();
part.readParams(serializedData, false);
}
serializedData.readInt32(false);
}
if (version >= 7) {
isStory = serializedData.readBool(false);

View file

@ -89,7 +89,6 @@ public class MediaCodecVideoConvertor {
boolean muted = convertVideoParams.muted;
boolean isStory = convertVideoParams.isStory;
StoryEntry.HDRInfo hdrInfo = convertVideoParams.hdrInfo;
ArrayList<StoryEntry.Part> parts = convertVideoParams.parts;
FileLog.d("convertVideoInternal original=" + originalWidth + "x" + originalHeight + " result=" + resultWidth + "x" + resultHeight + " " + avatarStartTime);
long time = System.currentTimeMillis();
@ -178,7 +177,7 @@ public class MediaCodecVideoConvertor {
inputSurface.makeCurrent();
encoder.start();
outputSurface = new OutputSurface(savedFilterState, videoPath, paintPath, blurPath, mediaEntities, cropState != null && cropState.useMatrix != null ? cropState : null, resultWidth, resultHeight, originalWidth, originalHeight, rotationValue, framerate, true, gradientTopColor, gradientBottomColor, null, parts);
outputSurface = new OutputSurface(savedFilterState, videoPath, paintPath, blurPath, mediaEntities, cropState != null && cropState.useMatrix != null ? cropState : null, resultWidth, resultHeight, originalWidth, originalHeight, rotationValue, framerate, true, gradientTopColor, gradientBottomColor, null, convertVideoParams);
ByteBuffer[] encoderOutputBuffers = null;
ByteBuffer[] encoderInputBuffers = null;
@ -493,7 +492,7 @@ public class MediaCodecVideoConvertor {
inputSurface.makeCurrent();
encoder.start();
outputSurface = new OutputSurface(savedFilterState, null, paintPath, blurPath, mediaEntities, cropState, resultWidth, resultHeight, originalWidth, originalHeight, rotationValue, framerate, false, gradientTopColor, gradientBottomColor, hdrInfo, parts);
outputSurface = new OutputSurface(savedFilterState, null, paintPath, blurPath, mediaEntities, cropState, resultWidth, resultHeight, originalWidth, originalHeight, rotationValue, framerate, false, gradientTopColor, gradientBottomColor, hdrInfo, convertVideoParams);
if (hdrInfo == null && outputSurface.supportsEXTYUV() && hasHDR) {
hdrInfo = new StoryEntry.HDRInfo();
hdrInfo.colorTransfer = colorTransfer;
@ -1333,6 +1332,9 @@ public class MediaCodecVideoConvertor {
MediaController.SavedFilterState savedFilterState;
String paintPath;
String blurPath;
String messagePath;
String messageVideoMaskPath;
String backgroundPath;
ArrayList<VideoEditedInfo.MediaEntity> mediaEntities;
boolean isPhoto;
MediaController.CropState cropState;
@ -1343,8 +1345,10 @@ public class MediaCodecVideoConvertor {
boolean muted;
boolean isStory;
StoryEntry.HDRInfo hdrInfo;
ArrayList<StoryEntry.Part> parts;
public ArrayList<MixedSoundInfo> soundInfos = new ArrayList<MixedSoundInfo>();
int account;
boolean isDark;
long wallpaperPeerId;
private ConvertVideoParams() {
@ -1357,16 +1361,8 @@ public class MediaCodecVideoConvertor {
int framerate, int bitrate, int originalBitrate,
long startTime, long endTime, long avatarStartTime,
boolean needCompress, long duration,
MediaController.SavedFilterState savedFilterState,
String paintPath, String blurPath,
ArrayList<VideoEditedInfo.MediaEntity> mediaEntities,
boolean isPhoto,
MediaController.CropState cropState,
boolean isRound,
MediaController.VideoConvertorListener callback,
Integer gradientTopColor, Integer gradientBottomColor,
boolean muted, boolean isStory, StoryEntry.HDRInfo hdrInfo,
ArrayList<StoryEntry.Part> parts) {
VideoEditedInfo info) {
ConvertVideoParams params = new ConvertVideoParams();
params.videoPath = videoPath;
params.cacheFile = cacheFile;
@ -1384,21 +1380,25 @@ public class MediaCodecVideoConvertor {
params.avatarStartTime = avatarStartTime;
params.needCompress = needCompress;
params.duration = duration;
params.savedFilterState = savedFilterState;
params.paintPath = paintPath;
params.blurPath = blurPath;
params.mediaEntities = mediaEntities;
params.isPhoto = isPhoto;
params.cropState = cropState;
params.isRound = isRound;
params.savedFilterState = info.filterState;
params.paintPath = info.paintPath;
params.blurPath = info.blurPath;
params.mediaEntities = info.mediaEntities;
params.isPhoto = info.isPhoto;
params.cropState = info.cropState;
params.isRound = info.roundVideo;
params.callback = callback;
params.gradientTopColor = gradientTopColor;
params.gradientBottomColor = gradientBottomColor;
params.muted = muted;
params.isStory = isStory;
params.hdrInfo = hdrInfo;
params.parts = parts;
params.gradientTopColor = info.gradientTopColor;
params.gradientBottomColor = info.gradientBottomColor;
params.muted = info.muted;
params.isStory = info.isStory;
params.hdrInfo = info.hdrInfo;
params.isDark = info.isDark;
params.wallpaperPeerId = info.wallpaperPeerId;
params.account = info.account;
params.messagePath = info.messagePath;
params.messageVideoMaskPath = info.messageVideoMaskPath;
params.backgroundPath = info.backgroundPath;
return params;
}
}

View file

@ -39,8 +39,8 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener {
private boolean mFrameAvailable;
private TextureRenderer mTextureRender;
public OutputSurface(MediaController.SavedFilterState savedFilterState, String imagePath, String paintPath, String blurPath, ArrayList<VideoEditedInfo.MediaEntity> mediaEntities, MediaController.CropState cropState, int w, int h, int originalW, int originalH, int rotation, float fps, boolean photo, Integer gradientTopColor, Integer gradientBottomColor, StoryEntry.HDRInfo hdrInfo, ArrayList<StoryEntry.Part> parts) {
mTextureRender = new TextureRenderer(savedFilterState, imagePath, paintPath, blurPath, mediaEntities, cropState, w, h, originalW, originalH, rotation, fps, photo, gradientTopColor, gradientBottomColor, hdrInfo, parts);
public OutputSurface(MediaController.SavedFilterState savedFilterState, String imagePath, String paintPath, String blurPath, ArrayList<VideoEditedInfo.MediaEntity> mediaEntities, MediaController.CropState cropState, int w, int h, int originalW, int originalH, int rotation, float fps, boolean photo, Integer gradientTopColor, Integer gradientBottomColor, StoryEntry.HDRInfo hdrInfo, MediaCodecVideoConvertor.ConvertVideoParams params) {
mTextureRender = new TextureRenderer(savedFilterState, imagePath, paintPath, blurPath, mediaEntities, cropState, w, h, originalW, originalH, rotation, fps, photo, gradientTopColor, gradientBottomColor, hdrInfo, params);
mTextureRender.surfaceCreated();
mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
mSurfaceTexture.setOnFrameAvailableListener(this);

View file

@ -21,6 +21,7 @@ import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.opengl.GLES11Ext;
import android.opengl.GLES20;
import android.opengl.GLES30;
@ -30,6 +31,7 @@ import android.os.Build;
import android.text.Layout;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ReplacementSpan;
import android.util.Log;
import android.util.Pair;
@ -70,6 +72,7 @@ import org.telegram.ui.Components.Paint.Views.LocationMarker;
import org.telegram.ui.Components.Paint.Views.PaintTextOptionsView;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Rect;
import org.telegram.ui.Stories.recorder.PreviewView;
import org.telegram.ui.Stories.recorder.StoryEntry;
import java.io.File;
@ -89,15 +92,11 @@ public class TextureRenderer {
private FloatBuffer gradientTextureBuffer;
private FloatBuffer textureBuffer;
private FloatBuffer renderTextureBuffer;
private FloatBuffer maskTextureBuffer;
private FloatBuffer bitmapVerticesBuffer;
private FloatBuffer blurVerticesBuffer;
private FloatBuffer partsVerticesBuffer[];
private FloatBuffer partsTextureBuffer;
private ArrayList<StoryEntry.Part> parts;
private int[] partsTexture;
private boolean useMatrixForImagePath;
float[] bitmapData = {
@ -109,6 +108,9 @@ public class TextureRenderer {
private FilterShaders filterShaders;
private String paintPath;
private String messagePath;
private String messageVideoMaskPath;
private String backgroundPath;
private String blurPath;
private String imagePath;
private int imageWidth, imageHeight;
@ -118,6 +120,7 @@ public class TextureRenderer {
private int originalHeight;
private int transformedWidth;
private int transformedHeight;
private Drawable backgroundDrawable;
private BlurringShader blur;
@ -144,6 +147,35 @@ public class TextureRenderer {
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
"}\n";
private static final String VERTEX_SHADER_MASK =
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"attribute vec4 mTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"varying vec2 MTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
" MTextureCoord = (uSTMatrix * mTextureCoord).xy;\n" +
"}\n";
private static final String VERTEX_SHADER_MASK_300 =
"#version 320 es\n" +
"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"in vec4 aPosition;\n" +
"in vec4 aTextureCoord;\n" +
"in vec4 mTextureCoord;\n" +
"out vec2 vTextureCoord;\n" +
"out vec2 MTextureCoord;\n" +
"void main() {\n" +
" gl_Position = uMVPMatrix * aPosition;\n" +
" vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
" MTextureCoord = (uSTMatrix * mTextureCoord).xy;\n" +
"}\n";
private static final String FRAGMENT_EXTERNAL_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision highp float;\n" +
@ -153,6 +185,17 @@ public class TextureRenderer {
" gl_FragColor = texture2D(sTexture, vTextureCoord);" +
"}\n";
private static final String FRAGMENT_EXTERNAL_MASK_SHADER =
"#extension GL_OES_EGL_image_external : require\n" +
"precision highp float;\n" +
"varying vec2 vTextureCoord;\n" +
"varying vec2 MTextureCoord;\n" +
"uniform samplerExternalOES sTexture;\n" +
"uniform sampler2D sMask;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord) * texture2D(sMask, MTextureCoord).a;\n" +
"}\n";
private static final String FRAGMENT_SHADER =
"precision highp float;\n" +
"varying vec2 vTextureCoord;\n" +
@ -161,6 +204,16 @@ public class TextureRenderer {
" gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
"}\n";
private static final String FRAGMENT_MASK_SHADER =
"precision highp float;\n" +
"varying vec2 vTextureCoord;\n" +
"varying vec2 MTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"uniform sampler2D sMask;\n" +
"void main() {\n" +
" gl_FragColor = texture2D(sTexture, vTextureCoord) * texture2D(sMask, MTextureCoord).a;\n" +
"}\n";
private static final String GRADIENT_FRAGMENT_SHADER =
"precision highp float;\n" +
"varying vec2 vTextureCoord;\n" +
@ -181,11 +234,14 @@ public class TextureRenderer {
private float[] mSTMatrix = new float[16];
private float[] mSTMatrixIdentity = new float[16];
private int mTextureID;
private int videoMaskTexture;
private int[] mProgram;
private int[] muMVPMatrixHandle;
private int[] muSTMatrixHandle;
private int[] maPositionHandle;
private int[] maTextureHandle;
private int[] mmTextureHandle;
private int[] maskTextureHandle;
private int gradientTopColorHandle, gradientBottomColorHandle;
private int texSizeHandle;
// todo: HDR handles
@ -207,6 +263,11 @@ public class TextureRenderer {
private Canvas stickerCanvas;
private float videoFps;
private int imagePathIndex = -1;
private int paintPathIndex = -1;
private int messagePathIndex = -1;
private int backgroundPathIndex = -1;
private Bitmap roundBitmap;
private Canvas roundCanvas;
private final android.graphics.Rect roundSrc = new android.graphics.Rect();
@ -244,10 +305,9 @@ public class TextureRenderer {
Integer gradientTopColor,
Integer gradientBottomColor,
StoryEntry.HDRInfo hdrInfo,
ArrayList<StoryEntry.Part> parts
MediaCodecVideoConvertor.ConvertVideoParams params
) {
isPhoto = photo;
this.parts = parts;
float[] texData = {
0.f, 0.f,
@ -285,6 +345,9 @@ public class TextureRenderer {
this.originalHeight = originalHeight;
imagePath = image;
paintPath = paint;
messagePath = params.messagePath;
messageVideoMaskPath = params.messageVideoMaskPath;
backgroundPath = params.backgroundPath;
blurPath = blurtex;
mediaEntities = entities;
videoFps = fps == 0 ? 30 : fps;
@ -292,21 +355,12 @@ public class TextureRenderer {
int count = 0;
NUM_EXTERNAL_SHADER = count++;
if (gradientBottomColor != null && gradientTopColor != null) {
NUM_GRADIENT_SHADER = count++;
}
if (filterShaders != null) {
NUM_FILTER_SHADER = count++;
}
mProgram = new int[count];
muMVPMatrixHandle = new int[count];
muSTMatrixHandle = new int[count];
maPositionHandle = new int[count];
maTextureHandle = new int[count];
Matrix.setIdentityM(mMVPMatrix, 0);
int textureRotation = 0;
if (gradientBottomColor != null && gradientTopColor != null) {
if (params != null && params.wallpaperPeerId != Long.MIN_VALUE) {
backgroundDrawable = PreviewView.getBackgroundDrawable(null, params.account, params.wallpaperPeerId, params.isDark);
} else if (gradientBottomColor != null && gradientTopColor != null) {
final float[] verticesData = {
-1.0f, -1.0f,
1.0f, -1.0f,
@ -325,7 +379,18 @@ public class TextureRenderer {
gradientTextureBuffer.put(textureData).position(0);
this.gradientTopColor = gradientTopColor;
this.gradientBottomColor = gradientBottomColor;
NUM_GRADIENT_SHADER = count++;
}
if (filterShaders != null) {
NUM_FILTER_SHADER = count++;
}
mProgram = new int[count];
muMVPMatrixHandle = new int[count];
muSTMatrixHandle = new int[count];
maPositionHandle = new int[count];
maTextureHandle = new int[count];
mmTextureHandle = new int[count];
maskTextureHandle = new int[count];
if (cropState != null) {
if (cropState.useMatrix != null) {
useMatrixForImagePath = true;
@ -455,35 +520,53 @@ public class TextureRenderer {
}
renderTextureBuffer = ByteBuffer.allocateDirect(textureData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
renderTextureBuffer.put(textureData).position(0);
textureData = new float[]{
0.f, 0.f,
1.f, 0.f,
0.f, 1.f,
1.f, 1.f
};
maskTextureBuffer = ByteBuffer.allocateDirect(textureData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
maskTextureBuffer.put(textureData).position(0);
}
public int getTextureId() {
return mTextureID;
}
private void drawGradient() {
if (NUM_GRADIENT_SHADER < 0) {
return;
private void drawBackground() {
if (NUM_GRADIENT_SHADER >= 0) {
GLES20.glUseProgram(mProgram[NUM_GRADIENT_SHADER]);
GLES20.glVertexAttribPointer(maPositionHandle[NUM_GRADIENT_SHADER], 2, GLES20.GL_FLOAT, false, 8, gradientVerticesBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle[NUM_GRADIENT_SHADER]);
GLES20.glVertexAttribPointer(maTextureHandle[NUM_GRADIENT_SHADER], 2, GLES20.GL_FLOAT, false, 8, gradientTextureBuffer);
GLES20.glEnableVertexAttribArray(maTextureHandle[NUM_GRADIENT_SHADER]);
GLES20.glUniformMatrix4fv(muSTMatrixHandle[NUM_GRADIENT_SHADER], 1, false, mSTMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle[NUM_GRADIENT_SHADER], 1, false, mMVPMatrix, 0);
GLES20.glUniform4f(gradientTopColorHandle, Color.red(gradientTopColor) / 255f, Color.green(gradientTopColor) / 255f, Color.blue(gradientTopColor) / 255f, Color.alpha(gradientTopColor) / 255f);
GLES20.glUniform4f(gradientBottomColorHandle, Color.red(gradientBottomColor) / 255f, Color.green(gradientBottomColor) / 255f, Color.blue(gradientBottomColor) / 255f, Color.alpha(gradientBottomColor) / 255f);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
} else if (backgroundPathIndex >= 0) {
GLES20.glUseProgram(simpleShaderProgram);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glUniform1i(simpleSourceImageHandle, 0);
GLES20.glEnableVertexAttribArray(simpleInputTexCoordHandle);
GLES20.glVertexAttribPointer(simpleInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);
GLES20.glEnableVertexAttribArray(simplePositionHandle);
drawTexture(true, paintTexture[backgroundPathIndex], -10000, -10000, -10000, -10000, 0, false, false, -1);
}
GLES20.glUseProgram(mProgram[NUM_GRADIENT_SHADER]);
GLES20.glVertexAttribPointer(maPositionHandle[NUM_GRADIENT_SHADER], 2, GLES20.GL_FLOAT, false, 8, gradientVerticesBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle[NUM_GRADIENT_SHADER]);
GLES20.glVertexAttribPointer(maTextureHandle[NUM_GRADIENT_SHADER], 2, GLES20.GL_FLOAT, false, 8, gradientTextureBuffer);
GLES20.glEnableVertexAttribArray(maTextureHandle[NUM_GRADIENT_SHADER]);
GLES20.glUniformMatrix4fv(muSTMatrixHandle[NUM_GRADIENT_SHADER], 1, false, mSTMatrix, 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle[NUM_GRADIENT_SHADER], 1, false, mMVPMatrix, 0);
GLES20.glUniform4f(gradientTopColorHandle, Color.red(gradientTopColor) / 255f, Color.green(gradientTopColor) / 255f, Color.blue(gradientTopColor) / 255f, Color.alpha(gradientTopColor) / 255f);
GLES20.glUniform4f(gradientBottomColorHandle, Color.red(gradientBottomColor) / 255f, Color.green(gradientBottomColor) / 255f, Color.blue(gradientBottomColor) / 255f, Color.alpha(gradientBottomColor) / 255f);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
public void drawFrame(SurfaceTexture st, long time) {
boolean blurred = false;
if (isPhoto) {
drawGradient();
drawBackground();
} else {
st.getTransformMatrix(mSTMatrix);
if (BuildVars.LOGS_ENABLED && firstFrame) {
@ -530,16 +613,26 @@ public class TextureRenderer {
stMatrix = mSTMatrix;
}
drawGradient();
drawBackground();
GLES20.glUseProgram(mProgram[index]);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(target, texture);
if (messageVideoMaskPath != null && videoMaskTexture != -1) {
GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, videoMaskTexture);
GLES20.glUniform1i(maskTextureHandle[index], 1);
}
GLES20.glVertexAttribPointer(maPositionHandle[index], 2, GLES20.GL_FLOAT, false, 8, verticesBuffer);
GLES20.glEnableVertexAttribArray(maPositionHandle[index]);
GLES20.glVertexAttribPointer(maTextureHandle[index], 2, GLES20.GL_FLOAT, false, 8, renderTextureBuffer);
GLES20.glEnableVertexAttribArray(maTextureHandle[index]);
if (messageVideoMaskPath != null && videoMaskTexture != -1) {
GLES20.glVertexAttribPointer(mmTextureHandle[index], 2, GLES20.GL_FLOAT, false, 8, maskTextureBuffer);
GLES20.glEnableVertexAttribArray(mmTextureHandle[index]);
}
if (texSizeHandle != 0) {
GLES20.glUniform2f(texSizeHandle, transformedWidth, transformedHeight);
@ -590,7 +683,7 @@ public class TextureRenderer {
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
if (isPhoto || paintTexture != null || stickerTexture != null || partsTexture != null) {
if (isPhoto || paintTexture != null || stickerTexture != null) {
GLES20.glUseProgram(simpleShaderProgram);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
@ -599,20 +692,14 @@ public class TextureRenderer {
GLES20.glVertexAttribPointer(simpleInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);
GLES20.glEnableVertexAttribArray(simplePositionHandle);
}
if (paintTexture != null && imagePath != null) {
for (int a = 0; a < 1; a++) {
drawTexture(true, paintTexture[a], -10000, -10000, -10000, -10000, 0, false, useMatrixForImagePath && isPhoto && a == 0, -1);
}
if (imagePathIndex >= 0) {
drawTexture(true, paintTexture[imagePathIndex], -10000, -10000, -10000, -10000, 0, false, useMatrixForImagePath && isPhoto, -1);
}
if (partsTexture != null) {
for (int a = 0; a < partsTexture.length; a++) {
drawTexture(true, partsTexture[a], -10000, -10000, -10000, -10000, 0, false, false, a);
}
if (paintPathIndex >= 0) {
drawTexture(true, paintTexture[paintPathIndex], -10000, -10000, -10000, -10000, 0, false, false, -1);
}
if (paintTexture != null) {
for (int a = (imagePath != null ? 1 : 0); a < paintTexture.length; a++) {
drawTexture(true, paintTexture[a], -10000, -10000, -10000, -10000, 0, false, useMatrixForImagePath && isPhoto && a == 0, -1);
}
if (messagePathIndex >= 0) {
drawTexture(true, paintTexture[messagePathIndex], -10000, -10000, -10000, -10000, 0, false, false, -1);
}
if (stickerTexture != null) {
for (int a = 0, N = mediaEntities.size(); a < N; a++) {
@ -857,9 +944,9 @@ public class TextureRenderer {
}
}
bitmapVerticesBuffer.put(bitmapData).position(0);
GLES20.glVertexAttribPointer(simplePositionHandle, 2, GLES20.GL_FLOAT, false, 8, matrixIndex >= 0 ? partsVerticesBuffer[matrixIndex] : (useCropMatrix ? verticesBuffer : bitmapVerticesBuffer));
GLES20.glVertexAttribPointer(simplePositionHandle, 2, GLES20.GL_FLOAT, false, 8, useCropMatrix ? verticesBuffer : bitmapVerticesBuffer);
GLES20.glEnableVertexAttribArray(simpleInputTexCoordHandle);
GLES20.glVertexAttribPointer(simpleInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, matrixIndex >= 0 ? partsTextureBuffer : (useCropMatrix ? renderTextureBuffer : textureBuffer));
GLES20.glVertexAttribPointer(simpleInputTexCoordHandle, 2, GLES20.GL_FLOAT, false, 8, useCropMatrix ? renderTextureBuffer : textureBuffer);
if (bind) {
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
}
@ -874,22 +961,27 @@ public class TextureRenderer {
@SuppressLint("WrongConstant")
public void surfaceCreated() {
for (int a = 0; a < mProgram.length; a++) {
String shader = null;
String fragSshader = null;
String vertexShader = VERTEX_SHADER;
if (a == NUM_EXTERNAL_SHADER) {
shader = FRAGMENT_EXTERNAL_SHADER;
fragSshader = messageVideoMaskPath != null ? FRAGMENT_EXTERNAL_MASK_SHADER : FRAGMENT_EXTERNAL_SHADER;
vertexShader = messageVideoMaskPath != null ? VERTEX_SHADER_MASK : VERTEX_SHADER;
} else if (a == NUM_FILTER_SHADER) {
shader = FRAGMENT_SHADER;
fragSshader = messageVideoMaskPath != null ? FRAGMENT_MASK_SHADER : FRAGMENT_SHADER;
vertexShader = messageVideoMaskPath != null ? VERTEX_SHADER_MASK : VERTEX_SHADER;
} else if (a == NUM_GRADIENT_SHADER) {
shader = GRADIENT_FRAGMENT_SHADER;
fragSshader = GRADIENT_FRAGMENT_SHADER;
}
if (shader == null) {
if (vertexShader == null || fragSshader == null) {
continue;
}
mProgram[a] = createProgram(VERTEX_SHADER, shader, false);
mProgram[a] = createProgram(vertexShader, fragSshader, false);
maPositionHandle[a] = GLES20.glGetAttribLocation(mProgram[a], "aPosition");
maTextureHandle[a] = GLES20.glGetAttribLocation(mProgram[a], "aTextureCoord");
mmTextureHandle[a] = GLES20.glGetAttribLocation(mProgram[a], "mTextureCoord");
muMVPMatrixHandle[a] = GLES20.glGetUniformLocation(mProgram[a], "uMVPMatrix");
muSTMatrixHandle[a] = GLES20.glGetUniformLocation(mProgram[a], "uSTMatrix");
maskTextureHandle[a] = GLES20.glGetUniformLocation(mProgram[a], "sMask");
if (a == NUM_GRADIENT_SHADER) {
gradientTopColorHandle = GLES20.glGetUniformLocation(mProgram[a], "gradientTopColor");
gradientBottomColorHandle = GLES20.glGetUniformLocation(mProgram[a], "gradientBottomColor");
@ -904,6 +996,23 @@ public class TextureRenderer {
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
if (messageVideoMaskPath != null) {
try {
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GL10.GL_TEXTURE_2D, videoMaskTexture = textures[0]);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
Bitmap bitmap = BitmapFactory.decodeFile(messageVideoMaskPath);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
} catch (Exception e) {
FileLog.e(e);
videoMaskTexture = -1;
}
}
if (blurPath != null && cropState != null && cropState.useMatrix != null) {
blur = new BlurringShader();
if (!blur.setup(transformedWidth / (float) transformedHeight, true, 0)) {
@ -980,7 +1089,7 @@ public class TextureRenderer {
}
}
}
if (filterShaders != null || imagePath != null || paintPath != null || mediaEntities != null || parts != null) {
if (filterShaders != null || imagePath != null || paintPath != null || messagePath != null || mediaEntities != null) {
int vertexShader = FilterShaders.loadShader(GLES20.GL_VERTEX_SHADER, FilterShaders.simpleVertexShaderCode);
int fragmentShader = FilterShaders.loadShader(GLES20.GL_FRAGMENT_SHADER, FilterShaders.simpleFragmentShaderCode);
if (vertexShader != 0 && fragmentShader != 0) {
@ -1008,24 +1117,41 @@ public class TextureRenderer {
filterShaders.create();
filterShaders.setRenderData(null, 0, mTextureID, originalWidth, originalHeight);
}
if (imagePath != null || paintPath != null) {
paintTexture = new int[(imagePath != null ? 1 : 0) + (paintPath != null ? 1 : 0)];
if (imagePath != null || paintPath != null || messagePath != null) {
int texturePathesCount = 0;
if (imagePath != null) {
imagePathIndex = texturePathesCount++;
}
if (paintPath != null) {
paintPathIndex = texturePathesCount++;
}
if (messagePath != null) {
messagePathIndex = texturePathesCount++;
}
if (backgroundPath != null) {
backgroundPathIndex = texturePathesCount++;
}
paintTexture = new int[texturePathesCount];
GLES20.glGenTextures(paintTexture.length, paintTexture, 0);
try {
for (int a = 0; a < paintTexture.length; a++) {
String path;
int angle = 0, invert = 0;
if (a == 0 && imagePath != null) {
if (a == imagePathIndex) {
path = imagePath;
Pair<Integer, Integer> orientation = AndroidUtilities.getImageOrientation(path);
angle = orientation.first;
invert = orientation.second;
} else {
} else if (a == paintPathIndex) {
path = paintPath;
} else if (a == backgroundPathIndex) {
path = backgroundPath;
} else { // messagePathIndex
path = messagePath;
}
Bitmap bitmap = BitmapFactory.decodeFile(path);
if (bitmap != null) {
if (a == 0 && imagePath != null && !useMatrixForImagePath) {
if (a == imagePathIndex && !useMatrixForImagePath) {
Bitmap newBitmap = Bitmap.createBitmap(transformedWidth, transformedHeight, Bitmap.Config.ARGB_8888);
newBitmap.eraseColor(0xff000000);
Canvas canvas = new Canvas(newBitmap);
@ -1045,7 +1171,7 @@ public class TextureRenderer {
bitmap = newBitmap;
}
if (a == 0 && imagePath != null) {
if (a == imagePathIndex) {
imageWidth = bitmap.getWidth();
imageHeight = bitmap.getHeight();
}
@ -1062,56 +1188,7 @@ public class TextureRenderer {
FileLog.e(e);
}
}
if (parts != null && !parts.isEmpty()) {
partsTexture = new int[parts.size()];
partsVerticesBuffer = new FloatBuffer[parts.size()];
GLES20.glGenTextures(partsTexture.length, partsTexture, 0);
try {
for (int a = 0; a < partsTexture.length; a++) {
StoryEntry.Part part = parts.get(a);
String path = part.file.getAbsolutePath();
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, opts);
opts.inJustDecodeBounds = false;
opts.inSampleSize = StoryEntry.calculateInSampleSize(opts, transformedWidth, transformedHeight);
Bitmap bitmap = BitmapFactory.decodeFile(path, opts);
GLES20.glBindTexture(GL10.GL_TEXTURE_2D, partsTexture[a]);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
final float[] verticesData = {
0, 0,
part.width, 0,
0, part.height,
part.width, part.height
};
part.matrix.mapPoints(verticesData);
for (int i = 0; i < 4; i++) {
verticesData[i * 2] = verticesData[i * 2] / transformedWidth * 2f - 1f;
verticesData[i * 2 + 1] = 1f - verticesData[i * 2 + 1] / transformedHeight * 2f;
}
partsVerticesBuffer[a] = ByteBuffer.allocateDirect(verticesData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
partsVerticesBuffer[a].put(verticesData).position(0);
}
} catch (Throwable e2) {
FileLog.e(e2);
}
final float[] textureData = {
0, 0,
1f, 0,
0, 1f,
1f, 1f
};
partsTextureBuffer = ByteBuffer.allocateDirect(textureData.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
partsTextureBuffer.put(textureData).position(0);
}
if (mediaEntities != null) {
if (mediaEntities != null || backgroundDrawable != null) {
try {
stickerBitmap = Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888);
stickerTexture = new int[1];
@ -1335,17 +1412,21 @@ public class TextureRenderer {
entity.firstSeek = true;
}
} else {
String path = entity.text;
if (!TextUtils.isEmpty(entity.segmentedPath) && (entity.subType & 16) != 0) {
path = entity.segmentedPath;
}
if (Build.VERSION.SDK_INT >= 19) {
BitmapFactory.Options opts = new BitmapFactory.Options();
if (entity.type == VideoEditedInfo.MediaEntity.TYPE_PHOTO) {
opts.inMutable = true;
}
entity.bitmap = BitmapFactory.decodeFile(entity.text, opts);
entity.bitmap = BitmapFactory.decodeFile(path, opts);
} else {
try {
File path = new File(entity.text);
RandomAccessFile file = new RandomAccessFile(path, "r");
ByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, path.length());
File filePath = new File(path);
RandomAccessFile file = new RandomAccessFile(filePath, "r");
ByteBuffer buffer = file.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, filePath.length());
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
Utilities.loadWebpImage(null, buffer, buffer.limit(), bmOptions, true);
@ -1461,8 +1542,14 @@ public class TextureRenderer {
}
public void changeFragmentShader(String fragmentExternalShader, String fragmentShader, boolean is300) {
String vertexCode;
if (messageVideoMaskPath != null) {
vertexCode = is300 ? VERTEX_SHADER_MASK_300 : VERTEX_SHADER_MASK;
} else {
vertexCode = is300 ? VERTEX_SHADER_300 : VERTEX_SHADER;
}
if (NUM_EXTERNAL_SHADER >= 0 && NUM_EXTERNAL_SHADER < mProgram.length) {
int newProgram = createProgram(is300 ? VERTEX_SHADER_300 : VERTEX_SHADER, fragmentExternalShader, is300);
int newProgram = createProgram(vertexCode, fragmentExternalShader, is300);
if (newProgram != 0) {
GLES20.glDeleteProgram(mProgram[NUM_EXTERNAL_SHADER]);
mProgram[NUM_EXTERNAL_SHADER] = newProgram;
@ -1471,7 +1558,7 @@ public class TextureRenderer {
}
}
if (NUM_FILTER_SHADER >= 0 && NUM_FILTER_SHADER < mProgram.length) {
int newProgram = createProgram(is300 ? VERTEX_SHADER_300 : VERTEX_SHADER, fragmentShader, is300);
int newProgram = createProgram(vertexCode, fragmentShader, is300);
if (newProgram != 0) {
GLES20.glDeleteProgram(mProgram[NUM_FILTER_SHADER]);
mProgram[NUM_FILTER_SHADER] = newProgram;

View file

@ -77,8 +77,8 @@ import android.telephony.TelephonyManager;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.LruCache;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
@ -236,6 +236,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
private BluetoothAdapter btAdapter;
private Instance.TrafficStats prevTrafficStats;
private boolean isBtHeadsetConnected;
private volatile boolean isCallEnded;
private Runnable updateNotificationRunnable;
@ -1115,6 +1116,10 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
tgVoip[CAPTURE_DEVICE_CAMERA].switchCamera(!isFrontFaceCamera);
}
public boolean isSwitchingCamera() {
return switchingCamera;
}
public void createCaptureDevice(boolean screencast) {
int index = screencast ? CAPTURE_DEVICE_SCREEN : CAPTURE_DEVICE_CAMERA;
int deviceType;
@ -1598,6 +1603,10 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
}
public void sendCallRating(int rating) {
VoIPHelper.sendCallRating(privateCall.id, privateCall.access_hash, currentAccount, rating);
}
public byte[] getEncryptionKey() {
return authKey;
}
@ -2711,16 +2720,38 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
public void toggleSpeakerphoneOrShowRouteSheet(Context context, boolean fromOverlayWindow) {
toggleSpeakerphoneOrShowRouteSheet(context, fromOverlayWindow, null);
}
public void switchToSpeaker() {
AndroidUtilities.runOnUIThread(() -> {
VoipAudioManager vam = VoipAudioManager.get();
if ((isBluetoothHeadsetConnected() && hasEarpiece()) || isHeadsetPlugged || isSpeakerphoneOn()) {
return;
}
vam.setSpeakerphoneOn(true);
vam.isBluetoothAndSpeakerOnAsync((isBluetoothOn, isSpeakerOn) -> {
updateOutputGainControlState();
for (StateListener l : stateListeners) {
l.onAudioSettingsChanged();
}
});
}, 500);
}
public void toggleSpeakerphoneOrShowRouteSheet(Context context, boolean fromOverlayWindow, Integer selectedPos) {
if (isBluetoothHeadsetConnected() && hasEarpiece()) {
BottomSheet.Builder builder = new BottomSheet.Builder(context)
.setTitle(LocaleController.getString("VoipOutputDevices", R.string.VoipOutputDevices), true)
.selectedPos(selectedPos)
.setCellType(selectedPos != null ? BottomSheet.Builder.CELL_TYPE_CALL : 0)
.setItems(new CharSequence[]{
LocaleController.getString("VoipAudioRoutingSpeaker", R.string.VoipAudioRoutingSpeaker),
isHeadsetPlugged ? LocaleController.getString("VoipAudioRoutingHeadset", R.string.VoipAudioRoutingHeadset) : LocaleController.getString("VoipAudioRoutingEarpiece", R.string.VoipAudioRoutingEarpiece),
currentBluetoothDeviceName != null ? currentBluetoothDeviceName : LocaleController.getString("VoipAudioRoutingBluetooth", R.string.VoipAudioRoutingBluetooth)},
new int[]{R.drawable.calls_menu_speaker,
isHeadsetPlugged ? R.drawable.calls_menu_headset : R.drawable.calls_menu_phone,
R.drawable.calls_menu_bluetooth}, (dialog, which) -> {
new int[]{R.drawable.msg_call_speaker,
isHeadsetPlugged ? R.drawable.calls_menu_headset : R.drawable.msg_call_earpiece,
R.drawable.msg_call_bluetooth}, (dialog, which) -> {
if (getSharedInstance() == null) {
return;
}
@ -2728,6 +2759,15 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
});
BottomSheet bottomSheet = builder.create();
bottomSheet.setOnShowListener(dialog -> {
for (int i = 0; i < bottomSheet.getItemViews().size(); i++) {
bottomSheet.setItemColor(i, Theme.getColor(Theme.key_dialogTextBlack), Theme.getColor(Theme.key_dialogTextBlack));
}
if (selectedPos != null) {
int selectedColor = Theme.getColor(Theme.key_dialogTextLink);
bottomSheet.setItemColor(selectedPos, selectedColor, selectedColor);
}
});
if (fromOverlayWindow) {
if (Build.VERSION.SDK_INT >= 26) {
bottomSheet.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
@ -2752,7 +2792,13 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
} else {
am.setBluetoothScoOn(!am.isBluetoothScoOn());
}
updateOutputGainControlState();
vam.isBluetoothAndSpeakerOnAsync((isBluetoothOn, isSpeakerOn) -> {
updateOutputGainControlState();
for (StateListener l : stateListeners) {
l.onAudioSettingsChanged();
}
});
return;
} else {
speakerphoneStateToSet = !speakerphoneStateToSet;
}
@ -3482,6 +3528,10 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
return ret;
}
public boolean hasRate() {
return needRateCall || forceRating;
}
private void onTgVoipStop(Instance.FinalState finalState) {
if (user == null) {
return;
@ -3493,11 +3543,6 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
e.printStackTrace();
}
}
if (needRateCall || forceRating || finalState.isRatingSuggested) {
startRatingActivity();
needRateCall = false;
}
if (needSendDebugLog && finalState.debugLog != null) {
TLRPC.TL_phone_saveCallDebug req = new TLRPC.TL_phone_saveCallDebug();
req.debug = new TLRPC.TL_dataJSON();
@ -3753,6 +3798,10 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
} else {
audioRouteToSet = AUDIO_ROUTE_EARPIECE;
}
if (lastSensorEvent != null) {
//For the case when the phone was put to the ear before configureDeviceForCall.
onSensorChanged(lastSensorEvent);
}
}
updateOutputGainControlState();
audioConfigured = true;
@ -3787,9 +3836,12 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
}
private SensorEvent lastSensorEvent;
@SuppressLint("NewApi")
@Override
public void onSensorChanged(SensorEvent event) {
lastSensorEvent = event;
if (unmutedByHold || remoteVideoState == Instance.VIDEO_STATE_ACTIVE || videoState[CAPTURE_DEVICE_CAMERA] == Instance.VIDEO_STATE_ACTIVE) {
return;
}
@ -3801,6 +3853,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
boolean newIsNear = event.values[0] < Math.min(event.sensor.getMaximumRange(), 3);
checkIsNear(newIsNear);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.nearEarEvent, newIsNear);
}
}
@ -4255,9 +4308,9 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
if (groupCall == null && !wasEstablished) {
wasEstablished = true;
if (!isProximityNear && !privateCall.video) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (vibrator.hasVibrator()) {
vibrator.vibrate(100);
try {
LaunchActivity.getLastFragment().getFragmentView().performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignore) {
}
}
AndroidUtilities.runOnUIThread(new Runnable() {
@ -4276,7 +4329,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
}
}
}
if (newState == STATE_RECONNECTING) {
if (newState == STATE_RECONNECTING && !isCallEnded) {
Utilities.globalQueue.postRunnable(() -> {
if (spPlayId != 0) {
soundPool.stop(spPlayId);
@ -4324,6 +4377,7 @@ public class VoIPService extends Service implements SensorEventListener, AudioMa
if (BuildVars.LOGS_ENABLED) {
FileLog.d("Call " + getCallID() + " ended");
}
isCallEnded = true;
if (groupCall != null && (!playedConnectedSound || onDestroyRunnable != null)) {
needPlayEndSound = false;
}

View file

@ -4,6 +4,8 @@ import static android.content.Context.AUDIO_SERVICE;
import android.media.AudioManager;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Utilities;
@ -47,6 +49,15 @@ public class VoipAudioManager {
return isSpeakerphoneOn;
}
public void isBluetoothAndSpeakerOnAsync(Utilities.Callback2<Boolean, Boolean> onDone) {
Utilities.globalQueue.postRunnable(() -> {
AudioManager audioManager = getAudioManager();
boolean isBluetoothScoOn = audioManager.isBluetoothScoOn();
boolean isSpeakerphoneOn = audioManager.isSpeakerphoneOn();
AndroidUtilities.runOnUIThread(() -> onDone.run(isBluetoothScoOn, isSpeakerphoneOn));
});
}
private AudioManager getAudioManager() {
return (AudioManager) ApplicationLoader.applicationContext.getSystemService(AUDIO_SERVICE);
}

View file

@ -245,7 +245,7 @@ public class ConnectionsManager extends BaseController {
if (getUserConfig().getCurrentUser() != null) {
userPremium = getUserConfig().getCurrentUser().premium;
}
init(BuildVars.BUILD_VERSION, TLRPC.LAYER, BuildVars.APP_ID, deviceModel, systemVersion, appVersion, langCode, systemLangCode, configPath, FileLog.getNetworkLogPath(), pushString, fingerprint, timezoneOffset, getUserConfig().getClientUserId(), userPremium, enablePushConnection);
init(SharedConfig.buildVersion(), TLRPC.LAYER, BuildVars.APP_ID, deviceModel, systemVersion, appVersion, langCode, systemLangCode, configPath, FileLog.getNetworkLogPath(), pushString, fingerprint, timezoneOffset, getUserConfig().getClientUserId(), userPremium, enablePushConnection);
}
private String getRegId() {

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
package org.telegram.tgnet.tl;
import org.telegram.messenger.DialogObject;
import org.telegram.tgnet.AbstractSerializedData;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
@ -78,8 +79,7 @@ public class TL_stories {
}
}
public static class TL_storyView extends TLObject {
public static final int constructor = 0xb0bdeac5;
public static class StoryView extends TLObject {
public int flags;
public boolean blocked;
@ -87,19 +87,35 @@ public class TL_stories {
public long user_id;
public int date;
public TLRPC.Reaction reaction;
public TLRPC.Message message;
public TLRPC.Peer peer_id;
public StoryItem story;
public static TL_storyView TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_storyView.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_storyView", constructor));
} else {
return null;
}
public static StoryView TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
StoryView result = null;
switch (constructor) {
case TL_storyView.constructor:
result = new TL_storyView();
break;
case TL_storyViewPublicForward.constructor:
result = new TL_storyViewPublicForward();
break;
case TL_storyViewPublicRepost.constructor:
result = new TL_storyViewPublicRepost();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in StoryView", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
TL_storyView result = new TL_storyView();
result.readParams(stream, exception);
return result;
}
}
public static class TL_storyView extends StoryView {
public static final int constructor = 0xb0bdeac5;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
@ -125,6 +141,46 @@ public class TL_stories {
}
}
public static class TL_storyViewPublicForward extends StoryView {
public static final int constructor = 0x9083670b;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
blocked = (flags & 1) != 0;
blocked_my_stories_from = (flags & 2) != 0;
message = TLRPC.Message.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = blocked ? (flags | 1) : (flags &~ 1);
flags = blocked_my_stories_from ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
message.serializeToStream(stream);
}
}
public static class TL_storyViewPublicRepost extends StoryView {
public static final int constructor = 0xbd74cf49;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
blocked = (flags & 1) != 0;
blocked_my_stories_from = (flags & 2) != 0;
peer_id = TLRPC.Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
story = StoryItem.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = blocked ? (flags | 1) : (flags &~ 1);
flags = blocked_my_stories_from ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
peer_id.serializeToStream(stream);
story.serializeToStream(stream);
}
}
public static abstract class PeerStories extends TLObject {
public int flags;
@ -862,28 +918,131 @@ public class TL_stories {
}
}
public static class TL_stories_storyViewsList extends TLObject {
public static final int constructor = 0x46e9b9ec;
public static class StoryViewsList extends TLObject {
public int flags;
public int count;
public int views_count;
public int forwards_count;
public int reactions_count;
public ArrayList<TL_storyView> views = new ArrayList<>();
public ArrayList<StoryView> views = new ArrayList<>();
public ArrayList<TLRPC.Chat> chats = new ArrayList<>();
public ArrayList<TLRPC.User> users = new ArrayList<>();
public String next_offset = "";
public static TL_stories_storyViewsList TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_stories_storyViewsList.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_stories_storyViewsList", constructor));
} else {
return null;
}
public static StoryViewsList TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
StoryViewsList result = null;
switch (constructor) {
case TL_storyViewsList.constructor:
result = new TL_storyViewsList();
break;
case TL_storyViewsList_layer167.constructor:
result = new TL_storyViewsList_layer167();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in StoryViewsList", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
TL_stories_storyViewsList result = new TL_stories_storyViewsList();
result.readParams(stream, exception);
return result;
}
}
public static class TL_storyViewsList extends StoryViewsList {
public static final int constructor = 0x59d78fc5;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
count = stream.readInt32(exception);
views_count = stream.readInt32(exception);
forwards_count = stream.readInt32(exception);
reactions_count = stream.readInt32(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
StoryView object = StoryView.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
views.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.Chat object = TLRPC.Chat.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
chats.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.User object = TLRPC.User.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
users.add(object);
}
if ((flags & 1) != 0) {
next_offset = stream.readString(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeInt32(count);
stream.writeInt32(views_count);
stream.writeInt32(forwards_count);
stream.writeInt32(reactions_count);
stream.writeInt32(0x1cb5c415);
int count = views.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
views.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = chats.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
chats.get(a).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = users.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
users.get(a).serializeToStream(stream);
}
if ((flags & 1) != 0) {
stream.writeString(next_offset);
}
}
}
public static class TL_storyViewsList_layer167 extends StoryViewsList {
public static final int constructor = 0x46e9b9ec;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
@ -898,7 +1057,7 @@ public class TL_stories {
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TL_storyView object = TL_storyView.TLdeserialize(stream, stream.readInt32(exception), exception);
StoryView object = StoryView.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
@ -975,6 +1134,7 @@ public class TL_stories {
public int flags;
public boolean just_contacts;
public boolean reactions_first;
public boolean forwards_first;
public TLRPC.InputPeer peer;
public String q;
public int id;
@ -982,13 +1142,14 @@ public class TL_stories {
public int limit;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_stories_storyViewsList.TLdeserialize(stream, constructor, exception);
return StoryViewsList.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = just_contacts ? (flags | 1) : (flags &~ 1);
flags = reactions_first ? (flags | 4) : (flags &~ 4);
flags = forwards_first ? (flags | 8) : (flags &~ 8);
stream.writeInt32(flags);
peer.serializeToStream(stream);
if ((flags & 2) != 0) {
@ -2543,9 +2704,15 @@ public class TL_stories {
case TL_inputMediaAreaVenue.constructor:
result = new TL_inputMediaAreaVenue();
break;
case TL_inputMediaAreaChannelPost.constructor:
result = new TL_inputMediaAreaChannelPost();
break;
case TL_mediaAreaSuggestedReaction.constructor:
result = new TL_mediaAreaSuggestedReaction();
break;
case TL_mediaAreaChannelPost.constructor:
result = new TL_mediaAreaChannelPost();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in MediaArea", constructor));
@ -2578,6 +2745,26 @@ public class TL_stories {
}
}
public static class TL_mediaAreaChannelPost extends MediaArea {
public static final int constructor = 0x770416af;
public long channel_id;
public int msg_id;
public void readParams(AbstractSerializedData stream, boolean exception) {
coordinates = TL_mediaAreaCoordinates.TLdeserialize(stream, stream.readInt32(exception), exception);
channel_id = stream.readInt64(exception);
msg_id = stream.readInt32(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
coordinates.serializeToStream(stream);
stream.writeInt64(channel_id);
stream.writeInt32(msg_id);
}
}
public static class TL_mediaAreaVenue extends MediaArea {
public static final int constructor = 0xbe82db9c;
@ -2634,6 +2821,28 @@ public class TL_stories {
}
}
public static class TL_inputMediaAreaChannelPost extends MediaArea {
public static final int constructor = 0x2271f2bf;
public TLRPC.InputChannel channel;
public int msg_id;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
coordinates = TL_mediaAreaCoordinates.TLdeserialize(stream, stream.readInt32(exception), exception);
channel = TLRPC.InputChannel.TLdeserialize(stream, stream.readInt32(exception), exception);
msg_id = stream.readInt32(exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
coordinates.serializeToStream(stream);
channel.serializeToStream(stream);
stream.writeInt32(msg_id);
}
}
public static class TL_mediaAreaGeoPoint extends MediaArea {
public static final int constructor = 0xdf8b3b22;
@ -2741,4 +2950,229 @@ public class TL_stories {
stream.writeInt32(id);
}
}
public static class StoryReaction extends TLObject {
public TLRPC.Peer peer_id;
public StoryItem story;
public TLRPC.Message message;
public static StoryReaction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
StoryReaction result = null;
switch (constructor) {
case TL_storyReaction.constructor:
result = new TL_storyReaction();
break;
case TL_storyReactionPublicForward.constructor:
result = new TL_storyReactionPublicForward();
break;
case TL_storyReactionPublicRepost.constructor:
result = new TL_storyReactionPublicRepost();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in StoryReaction", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_storyReactionPublicForward extends StoryReaction {
public final static int constructor = 0xbbab2643;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
message = TLRPC.Message.TLdeserialize(stream, stream.readInt32(exception), exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
message.serializeToStream(stream);
}
}
public static class TL_storyReactionPublicRepost extends StoryReaction {
public final static int constructor = 0xcfcd0f13;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
peer_id = TLRPC.Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
story = StoryItem.TLdeserialize(stream, stream.readInt32(exception), exception);
if (story != null) {
story.dialogId = DialogObject.getPeerDialogId(peer_id);
}
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer_id.serializeToStream(stream);
story.serializeToStream(stream);
}
}
public static class TL_storyReaction extends StoryReaction {
public final static int constructor = 0x6090d6d5;
public int date;
public TLRPC.Reaction reaction;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
peer_id = TLRPC.Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
date = stream.readInt32(exception);
reaction = TLRPC.Reaction.TLdeserialize(stream, stream.readInt32(exception), exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer_id.serializeToStream(stream);
stream.writeInt32(date);
reaction.serializeToStream(stream);
}
}
public static class TL_storyReactionsList extends TLObject {
public final static int constructor = 0xaa5f789c;
public int flags;
public int count;
public ArrayList<StoryReaction> reactions = new ArrayList<>();
public ArrayList<TLRPC.Chat> chats = new ArrayList<>();
public ArrayList<TLRPC.User> users = new ArrayList<>();
public String next_offset;
public static TL_storyReactionsList TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_storyReactionsList.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_storyReactionsList", constructor));
} else {
return null;
}
}
TL_storyReactionsList result = new TL_storyReactionsList();
result.readParams(stream, exception);
return result;
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeInt32(count);
stream.writeInt32(0x1cb5c415);
int count = reactions.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
reactions.get(i).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = chats.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
chats.get(i).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = users.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
users.get(i).serializeToStream(stream);
}
if ((flags & 1) != 0) {
stream.writeString(next_offset);
}
}
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
count = stream.readInt32(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
StoryReaction object = StoryReaction.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
reactions.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.Chat object = TLRPC.Chat.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
chats.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.User object = TLRPC.User.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
users.add(object);
}
if ((flags & 1) != 0) {
next_offset = stream.readString(exception);
}
}
}
public static class TL_getStoryReactionsList extends TLObject {
public final static int constructor = 0xb9b2881f;
public int flags;
public boolean forwards_first;
public TLRPC.InputPeer peer;
public int id;
public TLRPC.Reaction reaction;
public String offset;
public int limit;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_storyReactionsList.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = forwards_first ? (flags | 4) : (flags &~ 4);
stream.writeInt32(flags);
peer.serializeToStream(stream);
stream.writeInt32(id);
if ((flags & 1) != 0) {
reaction.serializeToStream(stream);
}
if ((flags & 2) != 0) {
stream.writeString(offset);
}
stream.writeInt32(limit);
}
}
}

View file

@ -8,6 +8,8 @@
package org.telegram.ui.ActionBar;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@ -192,7 +194,7 @@ public class ActionBar extends FrameLayout {
if (itemsColor != 0) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, colorFilterMode));
}
backButtonImageView.setPadding(AndroidUtilities.dp(1), 0, 0, 0);
backButtonImageView.setPadding(dp(1), 0, 0, 0);
addView(backButtonImageView, LayoutHelper.createFrame(54, 54, Gravity.LEFT | Gravity.TOP));
backButtonImageView.setOnClickListener(v -> {
@ -302,19 +304,18 @@ public class ActionBar extends FrameLayout {
canvas.clipRect(0, -getTranslationY() + (occupyStatusBar ? AndroidUtilities.statusBarHeight : 0), getMeasuredWidth(), getMeasuredHeight());
}
boolean result = super.drawChild(canvas, child, drawingTime);
if (supportsHolidayImage && !titleOverlayShown && !LocaleController.isRTL && (child == titleTextView[0] || child == titleTextView[1])) {
if (supportsHolidayImage && !titleOverlayShown && !LocaleController.isRTL && (child == titleTextView[0] || child == titleTextView[1] || child == titlesContainer && useContainerForTitles)) {
Drawable drawable = Theme.getCurrentHolidayDrawable();
if (drawable != null) {
SimpleTextView titleView = (SimpleTextView) child;
if (titleView.getVisibility() == View.VISIBLE && titleView.getText() instanceof String) {
SimpleTextView titleView = child == titlesContainer ? titleTextView[0] : (SimpleTextView) child;
if (titleView != null && titleView.getVisibility() == View.VISIBLE && titleView.getText() instanceof String) {
TextPaint textPaint = titleView.getTextPaint();
textPaint.getFontMetricsInt(fontMetricsInt);
textPaint.getTextBounds((String) titleView.getText(), 0, 1, rect);
int x = titleView.getTextStartX() + Theme.getCurrentHolidayDrawableXOffset() + (rect.width() - (drawable.getIntrinsicWidth() + Theme.getCurrentHolidayDrawableXOffset())) / 2;
int y = titleView.getTextStartY() + Theme.getCurrentHolidayDrawableYOffset() + (int) Math.ceil((titleView.getTextHeight() - rect.height()) / 2.0f);
int y = titleView.getTextStartY() + Theme.getCurrentHolidayDrawableYOffset() + (int) Math.ceil((titleView.getTextHeight() - rect.height()) / 2.0f) + (int) (dp(8) * (1f - titlesContainer.getScaleY()));
drawable.setBounds(x, y - drawable.getIntrinsicHeight(), x + drawable.getIntrinsicWidth(), y);
drawable.setAlpha((int) (255 * titleView.getAlpha()));
drawable.setAlpha((int) (255 * titlesContainer.getAlpha() * titleView.getAlpha()));
drawable.draw(canvas);
if (overlayTitleAnimationInProgress) {
child.invalidate();
@ -425,9 +426,9 @@ public class ActionBar extends FrameLayout {
titleTextView[i].setTextColor(getThemedColor(Theme.key_actionBarDefaultTitle));
}
titleTextView[i].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextView[i].setDrawablePadding(AndroidUtilities.dp(4));
titleTextView[i].setPadding(0, AndroidUtilities.dp(8), 0, AndroidUtilities.dp(8));
titleTextView[i].setRightDrawableTopPadding(-AndroidUtilities.dp(1));
titleTextView[i].setDrawablePadding(dp(4));
titleTextView[i].setPadding(0, dp(8), 0, dp(8));
titleTextView[i].setRightDrawableTopPadding(-dp(1));
if (useContainerForTitles) {
titlesContainer.addView(titleTextView[i], 0, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
} else {
@ -1209,10 +1210,10 @@ public class ActionBar extends FrameLayout {
int textLeft;
if (backButtonImageView != null && backButtonImageView.getVisibility() != GONE) {
backButtonImageView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(54), MeasureSpec.EXACTLY), actionBarHeightSpec);
textLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 80 : 72);
backButtonImageView.measure(MeasureSpec.makeMeasureSpec(dp(54), MeasureSpec.EXACTLY), actionBarHeightSpec);
textLeft = dp(AndroidUtilities.isTablet() ? 80 : 72);
} else {
textLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 26 : 18);
textLeft = dp(AndroidUtilities.isTablet() ? 26 : 18);
}
if (menu != null && menu.getVisibility() != GONE) {
@ -1222,12 +1223,12 @@ public class ActionBar extends FrameLayout {
menuWidth = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST);
menu.measure(menuWidth, actionBarHeightSpec);
int itemsWidth = menu.getItemsMeasuredWidth(true);
menuWidth = MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) + menu.getItemsMeasuredWidth(true), MeasureSpec.EXACTLY);
menuWidth = MeasureSpec.makeMeasureSpec(width - dp(AndroidUtilities.isTablet() ? 74 : 66) + menu.getItemsMeasuredWidth(true), MeasureSpec.EXACTLY);
if (!isMenuOffsetSuppressed) {
menu.translateXItems(-itemsWidth);
}
} else if (isSearchFieldVisible) {
menuWidth = MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66), MeasureSpec.EXACTLY);
menuWidth = MeasureSpec.makeMeasureSpec(width - dp(AndroidUtilities.isTablet() ? 74 : 66), MeasureSpec.EXACTLY);
if (!isMenuOffsetSuppressed) {
menu.translateXItems(0);
}
@ -1243,7 +1244,7 @@ public class ActionBar extends FrameLayout {
for (int i = 0; i < 2; i++) {
if (titleTextView[0] != null && titleTextView[0].getVisibility() != GONE || subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
int availableWidth = width - (menu != null ? menu.getMeasuredWidth() : 0) - AndroidUtilities.dp(16) - textLeft - titleRightMargin;
int availableWidth = width - (menu != null ? menu.getMeasuredWidth() : 0) - dp(16) - textLeft - titleRightMargin;
if (((fromBottom && i == 0) || (!fromBottom && i == 1)) && overlayTitleAnimation && titleAnimationRunning) {
titleTextView[i].setTextSize(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 18 : 20);
@ -1270,29 +1271,29 @@ public class ActionBar extends FrameLayout {
}
if (titleTextView[i] != null && titleTextView[i].getVisibility() != GONE) {
titleTextView[i].measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24) + titleTextView[i].getPaddingTop() + titleTextView[i].getPaddingBottom(), MeasureSpec.AT_MOST));
titleTextView[i].measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(24) + titleTextView[i].getPaddingTop() + titleTextView[i].getPaddingBottom(), MeasureSpec.AT_MOST));
if (centerScale) {
CharSequence text = titleTextView[i].getText();
titleTextView[i].setPivotX(titleTextView[i].getTextPaint().measureText(text, 0, text.length()) / 2f);
titleTextView[i].setPivotY((AndroidUtilities.dp(24) >> 1));
titleTextView[i].setPivotY((dp(24) >> 1));
} else {
titleTextView[i].setPivotX(0);
titleTextView[i].setPivotY(0);
}
}
if (subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.AT_MOST));
}
if (additionalSubtitleTextView != null && additionalSubtitleTextView.getVisibility() != GONE) {
additionalSubtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
additionalSubtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.AT_MOST));
}
}
}
if (avatarSearchImageView != null) {
avatarSearchImageView.measure(
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(42), MeasureSpec.EXACTLY)
MeasureSpec.makeMeasureSpec(dp(42), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dp(42), MeasureSpec.EXACTLY)
);
}
@ -1317,13 +1318,13 @@ public class ActionBar extends FrameLayout {
int textLeft;
if (backButtonImageView != null && backButtonImageView.getVisibility() != GONE) {
backButtonImageView.layout(0, additionalTop, backButtonImageView.getMeasuredWidth(), additionalTop + backButtonImageView.getMeasuredHeight());
textLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 80 : 72);
textLeft = dp(AndroidUtilities.isTablet() ? 80 : 72);
} else {
textLeft = AndroidUtilities.dp(AndroidUtilities.isTablet() ? 26 : 18);
textLeft = dp(AndroidUtilities.isTablet() ? 26 : 18);
}
if (menu != null && menu.getVisibility() != GONE) {
int menuLeft = menu.searchFieldVisible() ? AndroidUtilities.dp(AndroidUtilities.isTablet() ? 74 : 66) : (right - left) - menu.getMeasuredWidth();
int menuLeft = menu.searchFieldVisible() ? dp(AndroidUtilities.isTablet() ? 74 : 66) : (right - left) - menu.getMeasuredWidth();
menu.layout(menuLeft, additionalTop, menuLeft + menu.getMeasuredWidth(), additionalTop + menu.getMeasuredHeight());
}
@ -1334,7 +1335,7 @@ public class ActionBar extends FrameLayout {
textTop = (getCurrentActionBarHeight() - titleTextView[i].getTextHeight()) / 2;
} else {
if ((subtitleTextView != null && subtitleTextView.getVisibility() != GONE)) {
textTop = (getCurrentActionBarHeight() / 2 - titleTextView[i].getTextHeight()) / 2 + AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 2 : 3);
textTop = (getCurrentActionBarHeight() / 2 - titleTextView[i].getTextHeight()) / 2 + dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 2 : 3);
} else {
textTop = (getCurrentActionBarHeight() - titleTextView[i].getTextHeight()) / 2;
}
@ -1343,20 +1344,20 @@ public class ActionBar extends FrameLayout {
}
}
if (subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
int textTop = getCurrentActionBarHeight() / 2 + (getCurrentActionBarHeight() / 2 - subtitleTextView.getTextHeight()) / 2 - AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
int textTop = getCurrentActionBarHeight() / 2 + (getCurrentActionBarHeight() / 2 - subtitleTextView.getTextHeight()) / 2 - dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
subtitleTextView.layout(textLeft, additionalTop + textTop, textLeft + subtitleTextView.getMeasuredWidth(), additionalTop + textTop + subtitleTextView.getTextHeight());
}
if (additionalSubtitleTextView != null && additionalSubtitleTextView.getVisibility() != GONE) {
int textTop = getCurrentActionBarHeight() / 2 + (getCurrentActionBarHeight() / 2 - additionalSubtitleTextView.getTextHeight()) / 2 - AndroidUtilities.dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
int textTop = getCurrentActionBarHeight() / 2 + (getCurrentActionBarHeight() / 2 - additionalSubtitleTextView.getTextHeight()) / 2 - dp(!AndroidUtilities.isTablet() && getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ? 1 : 1);
additionalSubtitleTextView.layout(textLeft, additionalTop + textTop, textLeft + additionalSubtitleTextView.getMeasuredWidth(), additionalTop + textTop + additionalSubtitleTextView.getTextHeight());
}
if (avatarSearchImageView != null) {
avatarSearchImageView.layout(
AndroidUtilities.dp(56 + 8),
dp(56 + 8),
additionalTop + (getCurrentActionBarHeight() - avatarSearchImageView.getMeasuredHeight()) / 2,
AndroidUtilities.dp(56 + 8) + avatarSearchImageView.getMeasuredWidth(),
dp(56 + 8) + avatarSearchImageView.getMeasuredWidth(),
additionalTop + (getCurrentActionBarHeight() + avatarSearchImageView.getMeasuredHeight()) / 2
);
}
@ -1476,7 +1477,7 @@ public class ActionBar extends FrameLayout {
invalidate();
}
titleTextView[0].setText(textToSet);
titleTextView[0].setDrawablePadding(AndroidUtilities.dp(4));
titleTextView[0].setDrawablePadding(dp(4));
titleTextView[0].setRightDrawable(rightDrawableToSet);
titleTextView[0].setRightDrawableOnClick(rightDrawableOnClickListener);
if (rightDrawableToSet instanceof AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable) {
@ -1496,7 +1497,7 @@ public class ActionBar extends FrameLayout {
createTitleTextView(1);
}
titleTextView[1].setText(textToSet);
titleTextView[1].setDrawablePadding(AndroidUtilities.dp(4));
titleTextView[1].setDrawablePadding(dp(4));
titleTextView[1].setRightDrawable(rightDrawableToSet);
titleTextView[1].setRightDrawableOnClick(rightDrawableOnClickListener);
if (rightDrawableToSet instanceof AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable) {
@ -1510,7 +1511,7 @@ public class ActionBar extends FrameLayout {
titleTextView[1] = titleTextView[0];
titleTextView[0] = tmp;
titleTextView[0].setAlpha(0);
titleTextView[0].setTranslationY(-AndroidUtilities.dp(20));
titleTextView[0].setTranslationY(-dp(20));
titleTextView[0].animate()
.alpha(1f)
.translationY(0)
@ -1518,7 +1519,7 @@ public class ActionBar extends FrameLayout {
ViewPropertyAnimator animator = titleTextView[1].animate()
.alpha(0);
if (subtitleTextView == null) {
animator.translationY(AndroidUtilities.dp(20));
animator.translationY(dp(20));
} else {
animator.scaleY(0.7f).scaleX(0.7f);
}
@ -1627,11 +1628,11 @@ public class ActionBar extends FrameLayout {
public static int getCurrentActionBarHeight() {
if (AndroidUtilities.isTablet()) {
return AndroidUtilities.dp(64);
return dp(64);
} else if (AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) {
return AndroidUtilities.dp(48);
return dp(48);
} else {
return AndroidUtilities.dp(56);
return dp(56);
}
}
@ -1665,7 +1666,7 @@ public class ActionBar extends FrameLayout {
this.fromBottom = fromBottom;
titleTextView[0].setAlpha(0);
if (!crossfade) {
titleTextView[0].setTranslationY(fromBottom ? AndroidUtilities.dp(20) : -AndroidUtilities.dp(20));
titleTextView[0].setTranslationY(fromBottom ? dp(20) : -dp(20));
}
ViewPropertyAnimator a1 = titleTextView[0].animate().alpha(1f).translationY(0).setDuration(duration);
if (interpolator != null) {
@ -1676,7 +1677,7 @@ public class ActionBar extends FrameLayout {
titleAnimationRunning = true;
ViewPropertyAnimator a = titleTextView[1].animate().alpha(0);
if (!crossfade) {
a.translationY(fromBottom ? -AndroidUtilities.dp(20) : AndroidUtilities.dp(20));
a.translationY(fromBottom ? -dp(20) : dp(20));
}
if (interpolator != null) {
a.setInterpolator(interpolator);

View file

@ -396,6 +396,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
private float themeAnimationValue;
private boolean animateThemeAfterAnimation;
private Theme.ThemeInfo animateSetThemeAfterAnimation;
private boolean animateSetThemeAfterAnimationApply;
private boolean animateSetThemeNightAfterAnimation;
private int animateSetThemeAccentIdAfterAnimation;
private boolean rebuildAfterAnimation;
@ -1256,10 +1257,10 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
}
BaseFragment lastFragment = getLastFragment();
Dialog dialog = lastFragment != null ? lastFragment.getVisibleDialog() : null;
if (dialog == null && LaunchActivity.instance != null && LaunchActivity.instance.visibleDialog != null) {
dialog = LaunchActivity.instance.visibleDialog;
if (dialog == null && LaunchActivity.instance != null && LaunchActivity.instance.getVisibleDialog() != null) {
dialog = LaunchActivity.instance.getVisibleDialog();
}
if (shouldOpenFragmentOverlay(dialog)) {
if (lastFragment != null && shouldOpenFragmentOverlay(dialog)) {
BaseFragment.BottomSheetParams bottomSheetParams = new BaseFragment.BottomSheetParams();
bottomSheetParams.transitionFromLeft = true;
bottomSheetParams.allowNestedScroll = false;
@ -1564,7 +1565,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
}
private boolean shouldOpenFragmentOverlay(Dialog visibleDialog) {
return visibleDialog instanceof ChatAttachAlert || visibleDialog instanceof BotWebViewSheet;
return (visibleDialog != null && visibleDialog.isShowing()) && (visibleDialog instanceof ChatAttachAlert || visibleDialog instanceof BotWebViewSheet);
}
@Override
@ -1726,6 +1727,10 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
fragment.setInPreviewMode(false);
fragment.setInMenuMode(false);
try {
AndroidUtilities.setLightStatusBar(parentActivity.getWindow(), Theme.getColor(Theme.key_actionBarDefault) == Color.WHITE || (fragment.hasForceLightStatusBar() && !Theme.getCurrentTheme().isDark()), fragment.hasForceLightStatusBar());
} catch (Exception ignore) {}
}
@Override
@ -2124,6 +2129,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
animateSetThemeAfterAnimation = settings.theme;
animateSetThemeNightAfterAnimation = settings.nightTheme;
animateSetThemeAccentIdAfterAnimation = settings.accentId;
animateSetThemeAfterAnimationApply = settings.applyTrulyTheme;
if (onDone != null) {
onDone.run();
}
@ -2259,7 +2265,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
onDone.run();
}
};
if (fragmentCount >= 1 && settings.applyTheme) {
if (fragmentCount >= 1 && settings.applyTheme && settings.applyTrulyTheme) {
if (settings.accentId != -1 && settings.theme != null) {
settings.theme.setCurrentAccentId(settings.accentId);
Theme.saveThemeAccents(settings.theme, true, false, true, false);
@ -2363,7 +2369,11 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
rebuildAllFragmentViews(rebuildLastAfterAnimation, showLastAfterAnimation);
rebuildAfterAnimation = false;
} else if (animateThemeAfterAnimation) {
animateThemedValues(animateSetThemeAfterAnimation, animateSetThemeAccentIdAfterAnimation, animateSetThemeNightAfterAnimation, false);
ThemeAnimationSettings settings = new ThemeAnimationSettings(animateSetThemeAfterAnimation, animateSetThemeAccentIdAfterAnimation, animateSetThemeNightAfterAnimation, false);
if (!animateSetThemeAfterAnimationApply) {
settings.applyTheme = settings.applyTrulyTheme = animateSetThemeAfterAnimationApply;
}
animateThemedValues(settings, null);
animateSetThemeAfterAnimation = null;
animateThemeAfterAnimation = false;
}

View file

@ -83,6 +83,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
private View customView;
private View bottomView;
private View aboveMessageView;
private int customViewHeight = LayoutHelper.WRAP_CONTENT;
private TextView titleTextView;
private TextView secondTitleTextView;
@ -766,9 +767,12 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
progressView.setProgressColor(getThemedColor(Theme.key_dialog_inlineProgress));
progressViewContainer.addView(progressView, LayoutHelper.createFrame(86, 86, Gravity.CENTER));
} else {
if (aboveMessageView != null) {
scrollContainer.addView(aboveMessageView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 22, 4, 22, 12));
}
scrollContainer.addView(messageTextView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (topAnimationIsNew ? Gravity.CENTER_HORIZONTAL : LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 0, 24, customView != null || items != null ? customViewOffset : 0));
if (bottomView != null) {
scrollContainer.addView(bottomView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 24, -24, 24, 0));
scrollContainer.addView(bottomView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 22, 12, 22, 0));
}
}
if (!TextUtils.isEmpty(message)) {
@ -1170,6 +1174,21 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
}
public void setTextSize(int titleSizeDp, int messageSizeDp) {
if (titleTextView != null) {
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, titleSizeDp);
}
if (messageTextView != null) {
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, messageSizeDp);
}
}
public void setMessageLineSpacing(float spaceDp) {
if (messageTextView != null) {
messageTextView.setLineSpacing(AndroidUtilities.dp(spaceDp), 1.0f);
}
}
private void showCancelAlert() {
if (!canCacnel || cancelDialog != null) {
return;
@ -1523,6 +1542,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
return this;
}
public Builder aboveMessageView(View view) {
alertDialog.aboveMessageView = view;
return this;
}
public Builder addBottomView(View view) {
alertDialog.bottomView = view;
return this;

View file

@ -109,6 +109,8 @@ public class BottomSheet extends Dialog {
protected boolean fullWidth;
protected boolean isFullscreen;
private boolean fullHeight;
private int cellType;
private Integer selectedPos;
protected ColorDrawable backDrawable = new ColorDrawable(0xff000000) {
@Override
public void setAlpha(int alpha) {
@ -897,7 +899,9 @@ public class BottomSheet extends Dialog {
this.resourcesProvider = resourcesProvider;
currentType = type;
setBackgroundDrawable(Theme.getSelectorDrawable(false, resourcesProvider));
if (type != Builder.CELL_TYPE_CALL) {
setBackgroundDrawable(Theme.getSelectorDrawable(false, resourcesProvider));
}
//setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
imageView = new ImageView(context);
@ -910,7 +914,7 @@ public class BottomSheet extends Dialog {
textView.setSingleLine(true);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (type == 0) {
if (type == 0 || type == Builder.CELL_TYPE_CALL) {
textView.setTextColor(getThemedColor(Theme.key_dialogTextBlack));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL));
@ -1234,7 +1238,7 @@ public class BottomSheet extends Dialog {
if (items[a] == null) {
continue;
}
BottomSheetCell cell = new BottomSheetCell(getContext(), 0, resourcesProvider);
BottomSheetCell cell = new BottomSheetCell(getContext(), cellType, resourcesProvider);
cell.setTextAndIcon(items[a], itemIcons != null ? itemIcons[a] : 0, null, bigTitle);
containerView.addView(cell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.TOP, 0, topOffset, 0, 0));
topOffset += 48;
@ -1617,7 +1621,7 @@ public class BottomSheet extends Dialog {
ObjectAnimator.ofFloat(containerView, View.TRANSLATION_Y, getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? getBottomInset() : 0)),
ObjectAnimator.ofInt(backDrawable, AnimationProperties.COLOR_DRAWABLE_ALPHA, 0)
);
currentSheetAnimation.setDuration(180);
currentSheetAnimation.setDuration(cellType == Builder.CELL_TYPE_CALL ? 330 : 180);
currentSheetAnimation.setInterpolator(CubicBezierInterpolator.EASE_OUT);
currentSheetAnimation.addListener(new AnimatorListenerAdapter() {
@Override
@ -1652,6 +1656,27 @@ public class BottomSheet extends Dialog {
});
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
currentSheetAnimation.start();
if (cellType == Builder.CELL_TYPE_CALL && selectedPos != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int color1 = getItemViews().get(selectedPos).getTextView().getCurrentTextColor();
int color2 = getItemViews().get(item).getTextView().getCurrentTextColor();
ValueAnimator animator = ValueAnimator.ofArgb(color1, color2);
animator.addUpdateListener(a -> {
int color = (int) a.getAnimatedValue();
setItemColor(selectedPos, color, color);
});
animator.setDuration(130);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.start();
ValueAnimator animator2 = ValueAnimator.ofArgb(color2, color1);
animator2.addUpdateListener(a -> {
int color = (int) a.getAnimatedValue();
setItemColor(item, color, color);
});
animator2.setDuration(130);
animator2.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator2.start();
}
}
@Override
@ -1796,6 +1821,8 @@ public class BottomSheet extends Dialog {
public static class Builder {
public static int CELL_TYPE_CALL = 4;
private BottomSheet bottomSheet;
public Builder(Context context) {
@ -1863,6 +1890,16 @@ public class BottomSheet extends Dialog {
return this;
}
public Builder selectedPos(Integer pos) {
bottomSheet.selectedPos = pos;
return this;
}
public Builder setCellType(int cellType) {
bottomSheet.cellType = cellType;
return this;
}
public Builder setTitleMultipleLines(boolean allowMultipleLines) {
bottomSheet.multipleLinesTitle = allowMultipleLines;
return this;

View file

@ -254,10 +254,12 @@ public class EmojiThemes {
} else {
baseTheme = Theme.getTheme("Blue");
}
themeInfo = new Theme.ThemeInfo(baseTheme);
accent = themeInfo.createNewAccent(tlTheme, currentAccount, true, settingsIndex);
if (accent != null) {
themeInfo.setCurrentAccentId(accent.id);
if (baseTheme != null) {
themeInfo = new Theme.ThemeInfo(baseTheme);
accent = themeInfo.createNewAccent(tlTheme, currentAccount, true, settingsIndex);
if (accent != null) {
themeInfo.setCurrentAccentId(accent.id);
}
}
} else {
if (themeInfo.themeAccentsMap != null) {
@ -265,6 +267,10 @@ public class EmojiThemes {
}
}
if (themeInfo == null) {
return currentColors;
}
SparseIntArray currentColorsNoAccent;
String[] wallpaperLink = new String[1];
if (themeInfo.pathToFile != null) {

View file

@ -1007,7 +1007,7 @@ public final class FloatingToolbar {
});
}
final int size = menuItems.size();
final boolean premiumLocked = MessagesController.getInstance(UserConfig.selectedAccount).premiumLocked;
final boolean premiumLocked = MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked();
for (int i = 0; i < size; i++) {
final MenuItem menuItem = menuItems.get(i);
final boolean show;

View file

@ -368,6 +368,7 @@ public interface INavigationLayout {
public final boolean instant;
public boolean onlyTopFragment;
public boolean applyTheme = true;
public boolean applyTrulyTheme = true;
public Runnable afterStartDescriptionsAddedRunnable;
public Runnable beforeAnimationRunnable;
public Runnable afterAnimationRunnable;

View file

@ -61,6 +61,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
private SpannableStringBuilder spannableStringBuilder;
private Drawable leftDrawable;
private Drawable rightDrawable;
private Drawable rightDrawable2;
private Drawable replacedDrawable;
private String replacedText;
private int replacingDrawableTextIndex;
@ -273,6 +274,10 @@ public class SimpleTextView extends View implements Drawable.Callback {
int dw = (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale);
size += dw + drawablePadding;
}
if (rightDrawable2 != null) {
int dw = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
size += dw + drawablePadding;
}
return size;
}
@ -342,6 +347,11 @@ public class SimpleTextView extends View implements Drawable.Callback {
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (replacedText != null && replacedDrawable != null) {
replacingDrawableTextIndex = text.toString().indexOf(replacedText);
if (replacingDrawableTextIndex >= 0) {
@ -450,7 +460,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
scrollingOffset = 0;
currentScrollDelay = SCROLL_DELAY_MS;
}
createLayout(width - getPaddingLeft() - getPaddingRight() - minusWidth - (rightDrawableOutside && rightDrawable != null ? rightDrawable.getIntrinsicWidth() + drawablePadding : 0));
createLayout(width - getPaddingLeft() - getPaddingRight() - minusWidth - (rightDrawableOutside && rightDrawable != null ? rightDrawable.getIntrinsicWidth() + drawablePadding : 0) - (rightDrawableOutside && rightDrawable2 != null ? rightDrawable2.getIntrinsicWidth() + drawablePadding : 0));
int finalHeight;
if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.EXACTLY) {
@ -460,7 +470,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
if (widthWrapContent) {
// textWidth = (int) Math.ceil(layout.getLineWidth(0));
width = Math.min(width, getPaddingLeft() + textWidth + getPaddingRight() + minusWidth + (rightDrawableOutside && rightDrawable != null ? rightDrawable.getIntrinsicWidth() + drawablePadding : 0));
width = Math.min(width, getPaddingLeft() + textWidth + getPaddingRight() + minusWidth + (rightDrawableOutside && rightDrawable != null ? rightDrawable.getIntrinsicWidth() + drawablePadding : 0) + (rightDrawableOutside && rightDrawable2 != null ? rightDrawable2.getIntrinsicWidth() + drawablePadding : 0));
}
setMeasuredDimension(width, finalHeight);
@ -549,7 +559,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == rightDrawable || who == leftDrawable || super.verifyDrawable(who);
return who == rightDrawable || who == rightDrawable2 || who == leftDrawable || super.verifyDrawable(who);
}
public void replaceTextWithDrawable(Drawable drawable, String replacedText) {
@ -599,6 +609,26 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
}
public void setRightDrawable2(Drawable drawable) {
if (rightDrawable2 == drawable) {
return;
}
if (rightDrawable2 != null) {
rightDrawable2.setCallback(null);
}
rightDrawable2 = drawable;
if (drawable != null) {
drawable.setCallback(this);
}
if (!recreateLayoutMaybe()) {
invalidate();
}
}
public Drawable getRightDrawable2() {
return rightDrawable2;
}
public void setRightDrawableScale(float scale) {
rightDrawableScale = scale;
}
@ -717,6 +747,11 @@ public class SimpleTextView extends View implements Drawable.Callback {
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (rightDrawable2 != null && !rightDrawableOutside) {
rightDrawableWidth = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
width -= rightDrawableWidth;
width -= drawablePadding;
}
if (replacedText != null && replacedDrawable != null) {
if ((replacingDrawableTextIndex = text.toString().indexOf(replacedText)) < 0) {
width -= replacedDrawable.getIntrinsicWidth();
@ -808,6 +843,27 @@ public class SimpleTextView extends View implements Drawable.Callback {
rightDrawable.draw(canvas);
totalWidth += drawablePadding + dw;
}
if (rightDrawable2 != null && !rightDrawableHidden && rightDrawableScale > 0 && !rightDrawableOutside) {
int x = textOffsetX + textWidth + drawablePadding + (int) -scrollingOffset;
if (rightDrawable != null) {
x += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale) + drawablePadding;
}
if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.CENTER_HORIZONTAL ||
(gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.RIGHT) {
x += offsetX;
}
int dw = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
int dh = (int) (rightDrawable2.getIntrinsicHeight() * rightDrawableScale);
int y;
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.CENTER_VERTICAL) {
y = (getMeasuredHeight() - dh) / 2 + rightDrawableTopPadding;
} else {
y = getPaddingTop() + (textHeight - dh) / 2 + rightDrawableTopPadding;
}
rightDrawable2.setBounds(x, y, x + dw, y + dh);
rightDrawable2.draw(canvas);
totalWidth += drawablePadding + dw;
}
int nextScrollX = totalWidth + AndroidUtilities.dp(DIST_BETWEEN_SCROLLING_TEXT);
if (scrollingOffset != 0) {
@ -835,6 +891,22 @@ public class SimpleTextView extends View implements Drawable.Callback {
rightDrawable.setBounds(x, y, x + dw, y + dh);
rightDrawable.draw(canvas);
}
if (rightDrawable2 != null && !rightDrawableOutside) {
int dw = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
int dh = (int) (rightDrawable2.getIntrinsicHeight() * rightDrawableScale);
int x = textOffsetX + textWidth + drawablePadding + (int) -scrollingOffset + nextScrollX;
if (rightDrawable != null) {
x += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale) + drawablePadding;
}
int y;
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.CENTER_VERTICAL) {
y = (getMeasuredHeight() - dh) / 2 + rightDrawableTopPadding;
} else {
y = getPaddingTop() + (textHeight - dh) / 2 + rightDrawableTopPadding;
}
rightDrawable2.setBounds(x, y, x + dw, y + dh);
rightDrawable2.draw(canvas);
}
}
if (layout != null) {
@ -939,6 +1011,25 @@ public class SimpleTextView extends View implements Drawable.Callback {
rightDrawableY = y + (dh >> 1);
rightDrawable.draw(canvas);
}
if (rightDrawable2 != null && rightDrawableOutside) {
int x = Math.min(
textOffsetX + textWidth + drawablePadding + (scrollingOffset == 0 ? -nextScrollX : (int) -scrollingOffset) + nextScrollX,
getMaxTextWidth() - paddingRight + drawablePadding
);
if (rightDrawable != null) {
x += (int) (rightDrawable.getIntrinsicWidth() * rightDrawableScale) + drawablePadding;
}
int dw = (int) (rightDrawable2.getIntrinsicWidth() * rightDrawableScale);
int dh = (int) (rightDrawable2.getIntrinsicHeight() * rightDrawableScale);
int y;
if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.CENTER_VERTICAL) {
y = (getMeasuredHeight() - dh) / 2 + rightDrawableTopPadding;
} else {
y = getPaddingTop() + (textHeight - dh) / 2 + rightDrawableTopPadding;
}
rightDrawable2.setBounds(x, y, x + dw, y + dh);
rightDrawable2.draw(canvas);
}
}
public int getRightDrawableX() {
@ -950,7 +1041,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
private int getMaxTextWidth() {
return getMeasuredWidth() - (rightDrawableOutside && rightDrawable != null ? rightDrawable.getIntrinsicWidth() + drawablePadding : 0);
return getMeasuredWidth() - (rightDrawableOutside && rightDrawable != null ? rightDrawable.getIntrinsicWidth() + drawablePadding : 0) - (rightDrawableOutside && rightDrawable2 != null ? rightDrawable2.getIntrinsicWidth() + drawablePadding : 0);
}
private void drawLayout(Canvas canvas) {
@ -1035,6 +1126,8 @@ public class SimpleTextView extends View implements Drawable.Callback {
invalidate(leftDrawable.getBounds());
} else if (who == rightDrawable) {
invalidate(rightDrawable.getBounds());
} else if (who == rightDrawable2) {
invalidate(rightDrawable2.getBounds());
} else if (who == replacedDrawable) {
invalidate(replacedDrawable.getBounds());
}

View file

@ -958,7 +958,7 @@ public class Theme {
}
if (currentType == TYPE_MEDIA) {
if (customPaint || drawFullBottom) {
int radToUse = isBottomNear ? nearRad : rad;
int radToUse = isBottomNear || botButtonsBottom ? nearRad : rad;
path.lineTo(bounds.left + padding, bounds.bottom - padding - radToUse);
rect.set(bounds.left + padding, bounds.bottom - padding - radToUse * 2, bounds.left + padding + radToUse * 2, bounds.bottom - padding);
@ -1749,7 +1749,6 @@ public class Theme {
Math.max(0, Color.blue(submenuBackground) - 10)
));
currentColors.put(key_chat_inCodeBackground, codeBackground(inBubble, isDarkTheme));
if (isDarkTheme && currentColors.get(key_chat_outBubbleGradient1) != 0) {
int outBubbleAverage = averageColor(currentColors, key_chat_outBubbleGradient1, key_chat_outBubbleGradient2, key_chat_outBubbleGradient3);
Color.colorToHSV(outBubbleAverage, tempHSV);
@ -4126,7 +4125,6 @@ public class Theme {
public static final int key_stories_circle_closeFriends1 = colorsCount++;
public static final int key_stories_circle_closeFriends2 = colorsCount++;
public static final int key_code_background = colorsCount++;
public static final int key_chat_inCodeBackground = colorsCount++;
public static final int key_chat_outCodeBackground = colorsCount++;
public static final int key_code_keyword = colorsCount++;
@ -4411,6 +4409,7 @@ public class Theme {
themeAccentExclusionKeys.add(key_statisticChartLine_lightgreen);
themeAccentExclusionKeys.add(key_statisticChartLine_orange);
themeAccentExclusionKeys.add(key_statisticChartLine_indigo);
themeAccentExclusionKeys.add(key_chat_inCodeBackground);
themeAccentExclusionKeys.add(key_voipgroup_checkMenu);
themeAccentExclusionKeys.add(key_voipgroup_muteButton);
@ -5757,7 +5756,7 @@ public class Theme {
ripple = new ShapeDrawable(new RectShape());
((ShapeDrawable) ripple).getPaint().setColor(rippleColor);
}
Drawable pressed = new LayerDrawable(new Drawable[] { background, ripple });
Drawable pressed = background == null ? ripple : new LayerDrawable(new Drawable[] { background, ripple });
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressed);
stateListDrawable.addState(new int[]{android.R.attr.state_selected}, pressed);
stateListDrawable.addState(StateSet.WILD_CARD, background);
@ -5791,7 +5790,7 @@ public class Theme {
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
Drawable ripple = new CircleDrawable(radius, rippleColor);
Drawable pressed = new LayerDrawable(new Drawable[] { background, ripple });
Drawable pressed = background == null ? ripple : new LayerDrawable(new Drawable[] { background, ripple });
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressed);
stateListDrawable.addState(new int[]{android.R.attr.state_selected}, pressed);
stateListDrawable.addState(StateSet.WILD_CARD, background);
@ -9868,9 +9867,13 @@ public class Theme {
MotionBackgroundDrawable motionBackgroundDrawable = new MotionBackgroundDrawable(backgroundColor, gradientToColor1, gradientToColor2, gradientToColor3, false);
Bitmap patternBitmap = null;
if (wallpaperFile != null && wallpaperDocument != null) {
File f = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(wallpaperDocument, true);
patternBitmap = SvgHelper.getBitmap(f, AndroidUtilities.dp(360), AndroidUtilities.dp(640), false);
if (wallpaperFile != null && !isCustomTheme()) {
if (wallpaperDocument != null) {
File f = FileLoader.getInstance(UserConfig.selectedAccount).getPathToAttach(wallpaperDocument, true);
patternBitmap = SvgHelper.getBitmap(f, AndroidUtilities.dp(360), AndroidUtilities.dp(640), false);
} else {
patternBitmap = SvgHelper.getBitmap(R.raw.default_pattern, AndroidUtilities.dp(360), AndroidUtilities.dp(640), Color.WHITE);
}
if (patternBitmap != null) {
FileOutputStream stream = null;
try {

View file

@ -771,8 +771,7 @@ public class ThemeColors {
defaultColors[key_stories_circle_closeFriends1] = 0xFFC9EB38;
defaultColors[key_stories_circle_closeFriends2] = 0xFF09C167;
defaultColors[key_code_background] = 0x20000000;
defaultColors[key_chat_inCodeBackground] = 0x08484848;
defaultColors[key_chat_inCodeBackground] = 0xff6F889E;
defaultColors[key_chat_outCodeBackground] = 0x123c7503;
defaultColors[key_code_keyword] = 0xFFE05356;
defaultColors[key_code_operator] = 0xFF4DBBFF;
@ -1513,7 +1512,6 @@ public class ThemeColors {
colorKeysMap.put(key_stories_circle_dialog2, "stories_circle_dialog2");
colorKeysMap.put(key_stories_circle_closeFriends1, "stories_circle_closeFriends1");
colorKeysMap.put(key_stories_circle_closeFriends2, "stories_circle_closeFriends2");
colorKeysMap.put(key_code_background, "code_background");
colorKeysMap.put(key_chat_inCodeBackground, "chat_inCodeBackground");
colorKeysMap.put(key_chat_outCodeBackground, "chat_outCodeBackground");
colorKeysMap.put(key_code_keyword, "code_keyword");

View file

@ -152,7 +152,7 @@ public class AppIconsSelectorCell extends RecyclerListView implements Notificati
private void updateIconsVisibility() {
availableIcons.clear();
availableIcons.addAll(Arrays.asList(LauncherIconController.LauncherIcon.values()));
if (MessagesController.getInstance(currentAccount).premiumLocked) {
if (MessagesController.getInstance(currentAccount).premiumFeaturesBlocked()) {
for (int i = 0; i < availableIcons.size(); i++) {
if (availableIcons.get(i).premium) {
availableIcons.remove(i);

View file

@ -9,12 +9,15 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import org.telegram.ui.ActionBar.Theme;
public abstract class BaseCell extends ViewGroup {
private final class CheckForTap implements Runnable {
@ -110,4 +113,12 @@ public abstract class BaseCell extends ViewGroup {
protected boolean onLongPress() {
return true;
}
public int getBoundsLeft() {
return 0;
}
public int getBoundsRight() {
return getWidth();
}
}

View file

@ -22,6 +22,7 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
@ -42,11 +43,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.DownloadController;
@ -65,6 +68,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.TLObject;
@ -94,6 +98,7 @@ import org.telegram.ui.PhotoViewer;
import org.telegram.ui.Stories.StoriesUtilities;
import org.telegram.ui.Stories.UploadingDotsSpannable;
import org.telegram.ui.Stories.recorder.HintView2;
import org.telegram.ui.Stories.recorder.PreviewView;
import java.util.ArrayList;
import java.util.HashMap;
@ -167,7 +172,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
default void didClickButton(ChatActionCell cell) {
}
default void didOpenPremiumGift(ChatActionCell cell, TLRPC.TL_premiumGiftOption giftOption, boolean animateConfetti) {
default void didOpenPremiumGift(ChatActionCell cell, TLRPC.TL_premiumGiftOption giftOption, String slug, boolean animateConfetti) {
}
default void didOpenPremiumGiftChannel(ChatActionCell cell, String slug, boolean animateConfetti) {
@ -219,6 +224,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private URLSpan pressedLink;
private int currentAccount = UserConfig.selectedAccount;
private ImageReceiver imageReceiver;
private Drawable wallpaperPreviewDrawable;
private Path clipPath;
private AvatarDrawable avatarDrawable;
private StaticLayout textLayout;
private int textWidth;
@ -267,6 +274,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private ArrayList<Integer> lineWidths = new ArrayList<>();
private ArrayList<Integer> lineHeights = new ArrayList<>();
private Path backgroundPath = new Path();
private int backgroundLeft, backgroundRight;
private RectF rect = new RectF();
private boolean invalidatePath = true;
private boolean invalidateColors = false;
@ -449,6 +457,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
previousWidth = 0;
imageReceiver.setAutoRepeatCount(0);
imageReceiver.clearDecorators();
if (messageObject.type != MessageObject.TYPE_ACTION_WALLPAPER) {
wallpaperPreviewDrawable = null;
}
if (messageObject.isStoryMention()) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.media.user_id);
avatarDrawable.setInfo(currentAccount, user);
@ -470,11 +481,34 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
}
}
TLRPC.MessageAction action = messageObject.messageOwner.action;
if (action.wallpaper.uploadingImage != null) {
imageReceiver.setImage(ImageLocation.getForPath(action.wallpaper.uploadingImage), "150_150_wallpaper" + action.wallpaper.id + ChatBackgroundDrawable.hash(action.wallpaper.settings), null, null, ChatBackgroundDrawable.createThumb(action.wallpaper), 0, null, action.wallpaper, 1);
TLRPC.WallPaper wallPaper = null;
if (messageObject.currentEvent != null && messageObject.currentEvent.action instanceof TLRPC.TL_channelAdminLogEventActionChangeWallpaper) {
wallPaper = ((TLRPC.TL_channelAdminLogEventActionChangeWallpaper) messageObject.currentEvent.action).new_value;
} else if (messageObject.messageOwner != null && messageObject.messageOwner.action != null) {
TLRPC.MessageAction action = messageObject.messageOwner.action;
wallPaper = action.wallpaper;
}
if (!TextUtils.isEmpty(ChatThemeController.getWallpaperEmoticon(wallPaper))) {
final boolean isDark = themeDelegate != null ? themeDelegate.isDark() : Theme.isCurrentThemeDark();
imageReceiver.clearImage();
wallpaperPreviewDrawable = PreviewView.getBackgroundDrawableFromTheme(currentAccount, ChatThemeController.getWallpaperEmoticon(wallPaper), isDark, false);
if (wallpaperPreviewDrawable != null) {
wallpaperPreviewDrawable.setCallback(this);
}
} else if (wallPaper != null && wallPaper.uploadingImage != null) {
imageReceiver.setImage(ImageLocation.getForPath(wallPaper.uploadingImage), "150_150_wallpaper" + wallPaper.id + ChatBackgroundDrawable.hash(wallPaper.settings), null, null, ChatBackgroundDrawable.createThumb(wallPaper), 0, null, wallPaper, 1);
wallpaperPreviewDrawable = null;
} else if (wallPaper != null) {
TLRPC.Document document = null;
if (messageObject.photoThumbsObject instanceof TLRPC.Document) {
document = (TLRPC.Document) messageObject.photoThumbsObject;
} else if (wallPaper != null) {
document = wallPaper.document;
}
imageReceiver.setImage(ImageLocation.getForDocument(document), "150_150_wallpaper" + wallPaper.id + ChatBackgroundDrawable.hash(wallPaper.settings), null, null, ChatBackgroundDrawable.createThumb(wallPaper), 0, null, wallPaper, 1);
wallpaperPreviewDrawable = null;
} else {
imageReceiver.setImage(ImageLocation.getForDocument((TLRPC.Document) messageObject.photoThumbsObject), "150_150_wallpaper" + action.wallpaper.id + ChatBackgroundDrawable.hash(action.wallpaper.settings), null, null, ChatBackgroundDrawable.createThumb(action.wallpaper), 0, null, action.wallpaper, 1);
wallpaperPreviewDrawable = null;
}
imageReceiver.setRoundRadius((int) (stickerSize / 2f));
@ -548,12 +582,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(packName);
}
if (set != null) {
int months;
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
months = ((TLRPC.TL_messageActionGiftCode) messageObject.messageOwner.action).months;
} else {
months = messageObject.messageOwner.action.months;
}
int months = messageObject.messageOwner.action.months;
String monthsEmoticon;
if (USE_PREMIUM_GIFT_MONTHS_AS_EMOJI_NUMBERS) {
StringBuilder monthsEmoticonBuilder = new StringBuilder();
@ -916,15 +945,33 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
}
private boolean isSelfGiftCode() {
if (currentMessageObject != null && currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
if (currentMessageObject.messageOwner.from_id instanceof TLRPC.TL_peerUser) {
return MessagesController.getInstance(currentAccount).getUser(currentMessageObject.messageOwner.from_id.user_id).self;
}
}
return false;
}
private boolean isGiftCode() {
return currentMessageObject != null && currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftCode;
}
private void openPremiumGiftPreview() {
TLRPC.TL_premiumGiftOption giftOption = new TLRPC.TL_premiumGiftOption();
TLRPC.MessageAction action = currentMessageObject.messageOwner.action;
giftOption.amount = action.amount;
giftOption.months = action.months;
giftOption.currency = action.currency;
String slug;
if (isGiftCode()) {
slug = isSelfGiftCode() ? null : ((TLRPC.TL_messageActionGiftCode) currentMessageObject.messageOwner.action).slug;
} else {
slug = null;
}
if (delegate != null) {
AndroidUtilities.runOnUIThread(() -> delegate.didOpenPremiumGift(ChatActionCell.this, giftOption, false));
AndroidUtilities.runOnUIThread(() -> delegate.didOpenPremiumGift(ChatActionCell.this, giftOption, slug, false));
}
}
@ -1159,7 +1206,13 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (messageObject.messageOwner.media.photo != null) {
text = LocaleController.getString(R.string.AttachPhotoExpired);
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_documentEmpty || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && messageObject.messageOwner.media.document == null) {
text = LocaleController.getString(R.string.AttachVideoExpired);
if (messageObject.messageOwner.media.voice) {
text = LocaleController.getString(R.string.AttachVoiceExpired);
} else if (messageObject.messageOwner.media.round) {
text = LocaleController.getString(R.string.AttachRoundExpired);
} else {
text = LocaleController.getString(R.string.AttachVideoExpired);
}
} else {
text = AnimatedEmojiSpan.cloneSpans(messageObject.messageText);
}
@ -1177,7 +1230,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
createGiftPremiumChannelLayouts();
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
createGiftPremiumLayouts(LocaleController.getString(R.string.ActionGiftPremiumTitle), LocaleController.formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), LocaleController.getString(R.string.ActionGiftPremiumView), giftRectSize, true);
String actionName = isGiftCode() && !isSelfGiftCode() ? LocaleController.getString("GiftPremiumUseGiftBtn", R.string.GiftPremiumUseGiftBtn) :
LocaleController.getString("ActionGiftPremiumView", R.string.ActionGiftPremiumView);
createGiftPremiumLayouts(LocaleController.getString(R.string.ActionGiftPremiumTitle), LocaleController.formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), actionName, giftRectSize, true);
} else if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
TLRPC.TL_messageActionSuggestProfilePhoto actionSuggestProfilePhoto = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action;
String description;
@ -1212,11 +1267,13 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
CharSequence description;
String action = null;
boolean actionClickableAsImage = true;
if (!messageObject.isOutOwner() && messageObject.isWallpaperForBoth() && messageObject.isCurrentWallpaper()) {
if (messageObject.getDialogId() < 0) {
description = messageObject.messageText;
} else if (!messageObject.isOutOwner() && messageObject.isWallpaperForBoth() && messageObject.isCurrentWallpaper()) {
description = messageObject.messageText;
action = LocaleController.getString(R.string.RemoveWallpaperAction);
actionClickableAsImage = false;
} else if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
} else if (user != null && user.id == UserConfig.getInstance(currentAccount).clientUserId) {
description = messageObject.messageText;
} else {
description = messageObject.messageText;
@ -1310,7 +1367,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
giftSubtitlePaint.setTextSize(dp(15));
}
int subtitleWidth = giftPremiumSubtitleWidth = width;
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_ACTION_WALLPAPER) {
if (currentMessageObject != null && (currentMessageObject.type == MessageObject.TYPE_ACTION_WALLPAPER && currentMessageObject.getDialogId() >= 0)) {
final int recommendedWidthForTwoLines = HintView2.cutInFancyHalf(subtitle, giftSubtitlePaint);
if (recommendedWidthForTwoLines < subtitleWidth && recommendedWidthForTwoLines > subtitleWidth / 5f) {
subtitleWidth = recommendedWidthForTwoLines;
@ -1384,6 +1441,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
if (giftSubtitlePaint != null && giftSubtitlePaint.getColor() != textPaint.getColor()) {
giftSubtitlePaint.setColor(textPaint.getColor());
giftSubtitlePaint.linkColor = textPaint.getColor();
}
}
}
@ -1391,7 +1449,20 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
drawBackground(canvas, false);
if (isButtonLayout(messageObject) || (messageObject != null && messageObject.type == MessageObject.TYPE_ACTION_PHOTO)) {
if (messageObject.isStoryMention()) {
if (wallpaperPreviewDrawable != null) {
canvas.save();
canvas.translate(imageReceiver.getImageX(), imageReceiver.getImageY());
if (clipPath == null) {
clipPath = new Path();
} else {
clipPath.rewind();
}
clipPath.addCircle(imageReceiver.getImageWidth() / 2f, imageReceiver.getImageHeight() / 2f, imageReceiver.getImageWidth() / 2f, Path.Direction.CW);
canvas.clipPath(clipPath);
wallpaperPreviewDrawable.setBounds(0, 0, (int) imageReceiver.getImageWidth(), (int) imageReceiver.getImageHeight());
wallpaperPreviewDrawable.draw(canvas);
canvas.restore();
} else if (messageObject.isStoryMention()) {
long dialogId = messageObject.messageOwner.media.user_id;
avatarStoryParams.storyId = messageObject.messageOwner.media.id;
StoriesUtilities.drawAvatarWithStory(dialogId, canvas, imageReceiver, avatarStoryParams);
@ -1519,6 +1590,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
int oldColor = giftSubtitlePaint.getColor();
settingWallpaperPaint.setAlpha((int) (Color.alpha(oldColor) * (1f - p)));
giftSubtitlePaint.setAlpha((int) (Color.alpha(oldColor) * p));
giftSubtitlePaint.linkColor = giftSubtitlePaint.getColor();
float s = 0.8f + 0.2f * p;
canvas.save();
@ -1528,6 +1600,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
canvas.restore();
giftSubtitlePaint.setAlpha((int) (Color.alpha(oldColor) * (1f - p)));
giftSubtitlePaint.linkColor = giftSubtitlePaint.getColor();
s = 0.8f + 0.2f * (1f - p);
canvas.save();
canvas.scale(s, s, settingWallpaperLayout.getWidth() / 2f, settingWallpaperLayout.getHeight() / 2f);
@ -1542,6 +1615,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
giftSubtitlePaint.setColor(oldColor);
giftSubtitlePaint.linkColor = oldColor;
} else {
settingWallpaperLayout.draw(canvas);
canvas.save();
@ -1679,6 +1753,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
return super.drawChild(canvas, child, drawingTime);
}
private void checkLeftRightBounds() {
backgroundLeft = (int) Math.min(backgroundLeft, rect.left);
backgroundRight = (int) Math.max(backgroundRight, rect.right);
}
public void drawBackground(Canvas canvas, boolean fromParent) {
if (canDrawInParent) {
if (hasGradientService() && !fromParent) {
@ -1706,6 +1785,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
if (invalidatePath) {
invalidatePath = false;
backgroundLeft = getWidth();
backgroundRight = 0;
lineWidths.clear();
final int count = textLayout == null ? 0 : textLayout.getLineCount();
final int corner = dp(11);
@ -1771,9 +1852,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (a == 0 || lineWidth > prevLineWidth) {
rect.set(startX - cornerOffset - corner, y, startX + cornerRest, y + corner * 2);
checkLeftRightBounds();
backgroundPath.arcTo(rect, -90, 90);
} else if (lineWidth < prevLineWidth) {
rect.set(startX + cornerRest, y, startX + cornerRest + innerCornerRad * 2, y + innerCornerRad * 2);
checkLeftRightBounds();
backgroundPath.arcTo(rect, -90, -90);
}
y += height;
@ -1790,9 +1873,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (a == count - 1 || lineWidth > nextLineWidth) {
rect.set(startX - cornerOffset - corner, y - corner * 2, startX + cornerRest, y);
checkLeftRightBounds();
backgroundPath.arcTo(rect, 0, 90);
} else if (lineWidth < nextLineWidth) {
rect.set(startX + cornerRest, y - innerCornerRad * 2, startX + cornerRest + innerCornerRad * 2, y);
checkLeftRightBounds();
backgroundPath.arcTo(rect, 180, -90);
}
@ -1814,9 +1899,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (a == count - 1 || lineWidth > nextLineWidth) {
rect.set(startX - cornerRest, y - corner * 2, startX + cornerOffset + corner, y);
checkLeftRightBounds();
backgroundPath.arcTo(rect, 90, 90);
} else if (lineWidth < nextLineWidth) {
rect.set(startX - cornerRest - innerCornerRad * 2, y - innerCornerRad * 2, startX - cornerRest, y);
checkLeftRightBounds();
backgroundPath.arcTo(rect, 90, -90);
}
@ -1824,9 +1911,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (a == 0 || lineWidth > prevLineWidth) {
rect.set(startX - cornerRest, y, startX + cornerOffset + corner, y + corner * 2);
checkLeftRightBounds();
backgroundPath.arcTo(rect, 180, 90);
} else if (lineWidth < prevLineWidth) {
rect.set(startX - cornerRest - innerCornerRad * 2, y, startX - cornerRest, y + innerCornerRad * 2);
checkLeftRightBounds();
backgroundPath.arcTo(rect, 0, -90);
}
}
@ -1896,6 +1985,30 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
}
@Override
public int getBoundsLeft() {
if (isButtonLayout(currentMessageObject)) {
return (getWidth() - giftRectSize) / 2;
}
int left = backgroundLeft;
if (imageReceiver != null && imageReceiver.getVisible()) {
left = Math.min((int) imageReceiver.getImageX(), left);
}
return left;
}
@Override
public int getBoundsRight() {
if (isButtonLayout(currentMessageObject)) {
return (getWidth() + giftRectSize) / 2;
}
int right = backgroundRight;
if (imageReceiver != null && imageReceiver.getVisible()) {
right = Math.max((int) imageReceiver.getImageX2(), right);
}
return right;
}
public boolean hasGradientService() {
return overrideBackgroundPaint == null && (themeDelegate != null ? themeDelegate.hasGradientService() : Theme.hasGradientService());
}
@ -1987,7 +2100,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
return Theme.getColor(key, themeDelegate);
}
private Paint getThemedPaint(String paintKey) {
protected Paint getThemedPaint(String paintKey) {
Paint paint = themeDelegate != null ? themeDelegate.getPaint(paintKey) : null;
return paint != null ? paint : Theme.getThemePaint(paintKey);
}
@ -2031,6 +2144,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
}
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == wallpaperPreviewDrawable || super.verifyDrawable(who);
}
public boolean isFloating() {
return false;
}

View file

@ -1169,6 +1169,11 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else if (chat.fake) {
drawScam = 2;
Theme.dialogs_fakeDrawable.checkText();
} else if (DialogObject.getEmojiStatusDocumentId(chat.emoji_status) != 0) {
drawPremium = true;
nameLayoutEllipsizeByGradient = true;
emojiStatus.center = LocaleController.isRTL;
emojiStatus.set(DialogObject.getEmojiStatusDocumentId(chat.emoji_status), false);
} else {
drawVerified = !forbidVerified && chat.verified;
}
@ -1472,7 +1477,13 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && message.messageOwner.media.photo instanceof TLRPC.TL_photoEmpty && message.messageOwner.media.ttl_seconds != 0) {
messageString = LocaleController.getString("AttachPhotoExpired", R.string.AttachPhotoExpired);
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && (message.messageOwner.media.document instanceof TLRPC.TL_documentEmpty || message.messageOwner.media.document == null) && message.messageOwner.media.ttl_seconds != 0) {
messageString = LocaleController.getString("AttachVideoExpired", R.string.AttachVideoExpired);
if (message.messageOwner.media.voice) {
messageString = LocaleController.getString(R.string.AttachVoiceExpired);
} else if (message.messageOwner.media.round) {
messageString = LocaleController.getString(R.string.AttachRoundExpired);
} else {
messageString = LocaleController.getString(R.string.AttachVideoExpired);
}
} else if (getCaptionMessage() != null) {
MessageObject message = getCaptionMessage();
String emoji;
@ -1522,8 +1533,9 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
currentMessagePaint = Theme.dialogs_messagePrintingPaint[paintIndex];
} else {
if (message.messageOwner.media instanceof TLRPC.TL_messageMediaGiveaway) {
TLRPC.TL_messageMediaGiveaway mediaPoll = (TLRPC.TL_messageMediaGiveaway) message.messageOwner.media;
messageString = LocaleController.getString("BoostingGiveawayChannelStarted", R.string.BoostingGiveawayChannelStarted);
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaGiveawayResults) {
messageString = LocaleController.getString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (message.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
TLRPC.TL_messageMediaPoll mediaPoll = (TLRPC.TL_messageMediaPoll) message.messageOwner.media;
messageString = "\uD83D\uDCCA " + mediaPoll.poll.question;
@ -2722,17 +2734,29 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
invalidate = true;
}
}
if (user != null && (mask & MessagesController.UPDATE_MASK_EMOJI_STATUS) != 0) {
user = MessagesController.getInstance(currentAccount).getUser(user.id);
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user);
if (emojiStatusId != null) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(emojiStatusId, animated);
} else {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(PremiumGradient.getInstance().premiumStarDrawableMini, animated);
if ((mask & MessagesController.UPDATE_MASK_EMOJI_STATUS) != 0) {
if (user != null) {
user = MessagesController.getInstance(currentAccount).getUser(user.id);
if (user != null && DialogObject.getEmojiStatusDocumentId(user.emoji_status) != 0) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(DialogObject.getEmojiStatusDocumentId(user.emoji_status), animated);
} else {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(PremiumGradient.getInstance().premiumStarDrawableMini, animated);
}
invalidate = true;
}
if (chat != null) {
chat = MessagesController.getInstance(currentAccount).getChat(chat.id);
if (chat != null && DialogObject.getEmojiStatusDocumentId(chat.emoji_status) != 0) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(DialogObject.getEmojiStatusDocumentId(chat.emoji_status), animated);
} else {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(PremiumGradient.getInstance().premiumStarDrawableMini, animated);
}
invalidate = true;
}
invalidate = true;
}
if (isDialogCell || isTopic) {
if ((mask & MessagesController.UPDATE_MASK_USER_PRINT) != 0) {

View file

@ -17,16 +17,18 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
public class DialogsHintCell extends FrameLayout {
private LinearLayout contentView;
private TextView titleView;
private TextView messageView;
private ImageView chevronView;
private final LinearLayout contentView;
private final TextView titleView;
private final TextView messageView;
private final ImageView chevronView;
private final ImageView closeView;
public DialogsHintCell(@NonNull Context context) {
super(context);
@ -43,7 +45,7 @@ public class DialogsHintCell extends FrameLayout {
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
titleView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
titleView.setSingleLine();
contentView.addView(titleView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, Gravity.TOP));
contentView.addView(titleView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP));
messageView = new TextView(context);
messageView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
@ -55,6 +57,12 @@ public class DialogsHintCell extends FrameLayout {
chevronView.setImageResource(R.drawable.arrow_newchat);
addView(chevronView, LayoutHelper.createFrame(16, 16, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL));
closeView = new ImageView(context);
closeView.setImageResource(R.drawable.msg_close);
closeView.setPadding(dp(6), dp(6), dp(6), dp(6));
addView(closeView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, LocaleController.isRTL ? -15 : 0, 0, LocaleController.isRTL ? 0 : -15, 0));
closeView.setVisibility(GONE);
setClipToPadding(false);
updateColors();
}
@ -62,12 +70,28 @@ public class DialogsHintCell extends FrameLayout {
titleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
messageView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
chevronView.setColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText), PorterDuff.Mode.SRC_IN);
closeView.setColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText), PorterDuff.Mode.SRC_IN);
closeView.setBackground(Theme.AdaptiveRipple.filledCircle());
setBackground(Theme.AdaptiveRipple.filledRect());
}
public void setText(CharSequence title, CharSequence subtitle) {
titleView.setText(title);
titleView.setCompoundDrawables(null, null, null, null);
messageView.setText(subtitle);
chevronView.setVisibility(VISIBLE);
closeView.setVisibility(GONE);
}
public void setChristmasStyle(OnClickListener closeListener) {
chevronView.setVisibility(INVISIBLE);
closeView.setVisibility(VISIBLE);
closeView.setOnClickListener(closeListener);
Emoji.EmojiDrawable drawable = Emoji.getEmojiDrawable("\uD83C\uDF84");
if (drawable != null) {
drawable.setBounds(dp(2), -dp(2), Emoji.drawImgSize + dp(2), Emoji.drawImgSize - dp(2));
titleView.setCompoundDrawables(null, null, drawable, null);
}
}
@Override
@ -85,8 +109,8 @@ public class DialogsHintCell extends FrameLayout {
width = AndroidUtilities.displaySize.x;
}
contentView.measure(
MeasureSpec.makeMeasureSpec(width - getPaddingLeft() - getPaddingRight(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, MeasureSpec.AT_MOST)
MeasureSpec.makeMeasureSpec(width - getPaddingLeft() - getPaddingRight(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, MeasureSpec.AT_MOST)
);
this.height = contentView.getMeasuredHeight() + getPaddingTop() + getPaddingBottom() + 1;
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));

View file

@ -29,6 +29,7 @@ import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LiteMode;
import org.telegram.messenger.LocaleController;
@ -474,10 +475,8 @@ public class GroupCallUserCell extends FrameLayout {
nameTextView.setText(UserObject.getUserName(currentUser));
if (currentUser != null && currentUser.verified) {
rightDrawable.set(verifiedDrawable = (verifiedDrawable == null ? new VerifiedDrawable(getContext()) : verifiedDrawable), animated);
} else if (currentUser != null && currentUser.emoji_status instanceof TLRPC.TL_emojiStatus) {
rightDrawable.set(((TLRPC.TL_emojiStatus) currentUser.emoji_status).document_id, animated);
} else if (currentUser != null && currentUser.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
rightDrawable.set(((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).document_id, animated);
} else if (currentUser != null && DialogObject.getEmojiStatusDocumentId(currentUser.emoji_status) != 0) {
rightDrawable.set(DialogObject.getEmojiStatusDocumentId(currentUser.emoji_status), animated);
} else if (currentUser != null && currentUser.premium) {
if (premiumDrawable == null) {
premiumDrawable = getContext().getResources().getDrawable(R.drawable.msg_premium_liststar).mutate();
@ -515,6 +514,8 @@ public class GroupCallUserCell extends FrameLayout {
nameTextView.setText(currentChat.title);
if (currentChat.verified) {
rightDrawable.set(verifiedDrawable = (verifiedDrawable == null ? new VerifiedDrawable(getContext()) : verifiedDrawable), animated);
} else if (currentChat != null && DialogObject.getEmojiStatusDocumentId(currentChat.emoji_status) != 0) {
rightDrawable.set(DialogObject.getEmojiStatusDocumentId(currentChat.emoji_status), animated);
} else {
rightDrawable.set((Drawable) null, animated);
}

View file

@ -21,6 +21,7 @@ import org.telegram.messenger.ChatObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
@ -106,6 +107,7 @@ public class ManageChatUserCell extends FrameLayout {
nameTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
nameTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 20, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 28 + 18 : (68 + namePadding), 11.5f, LocaleController.isRTL ? (68 + namePadding) : 28 + 18, 0));
NotificationCenter.listenEmojiLoading(nameTextView);
statusTextView = new SimpleTextView(context);
statusTextView.setTextSize(14);

View file

@ -308,7 +308,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
nameLeft = AndroidUtilities.dp(11);
}
nameLockTop = AndroidUtilities.dp(22.0f);
updateStatus(false, null, false);
updateStatus(false, null, null, false);
} else if (chat != null) {
dialog_id = -chat.id;
drawCheck = chat.verified;
@ -317,7 +317,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
} else {
nameLeft = AndroidUtilities.dp(11);
}
updateStatus(drawCheck, null, false);
updateStatus(drawCheck, null, chat, false);
} else if (user != null) {
dialog_id = user.id;
if (!LocaleController.isRTL) {
@ -328,7 +328,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
nameLockTop = AndroidUtilities.dp(21);
drawCheck = user.verified;
drawPremium = !savedMessages && MessagesController.getInstance(currentAccount).isPremiumUser(user);
updateStatus(drawCheck, user, false);
updateStatus(drawCheck, user, null, false);
} else if (contact != null) {
dialog_id = 0;
if (!LocaleController.isRTL) {
@ -587,16 +587,16 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
nameLockLeft += getPaddingLeft();
}
public void updateStatus(boolean verified, TLRPC.User user, boolean animated) {
public void updateStatus(boolean verified, TLRPC.User user, TLRPC.Chat chat, boolean animated) {
statusDrawable.center = LocaleController.isRTL;
if (verified) {
statusDrawable.set(new CombinedDrawable(Theme.dialogs_verifiedDrawable, Theme.dialogs_verifiedCheckDrawable, 0, 0), animated);
statusDrawable.setColor(null);
} else if (user != null && !savedMessages && user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
statusDrawable.set(((TLRPC.TL_emojiStatusUntil) user.emoji_status).document_id, animated);
} else if (user != null && !savedMessages && DialogObject.getEmojiStatusDocumentId(user.emoji_status) != 0) {
statusDrawable.set(DialogObject.getEmojiStatusDocumentId(user.emoji_status), animated);
statusDrawable.setColor(Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider));
} else if (user != null && !savedMessages && user.emoji_status instanceof TLRPC.TL_emojiStatus) {
statusDrawable.set(((TLRPC.TL_emojiStatus) user.emoji_status).document_id, animated);
} else if (chat != null && !savedMessages && DialogObject.getEmojiStatusDocumentId(chat.emoji_status) != 0) {
statusDrawable.set(DialogObject.getEmojiStatusDocumentId(chat.emoji_status), animated);
statusDrawable.setColor(Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider));
} else if (user != null && !savedMessages && MessagesController.getInstance(currentAccount).isPremiumUser(user)) {
statusDrawable.set(PremiumGradient.getInstance().premiumStarDrawableMini, animated);
@ -662,8 +662,8 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
continueUpdate = true;
}
}
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_EMOJI_STATUS) != 0 && user != null) {
updateStatus(user.verified, user, true);
if (!continueUpdate && (mask & MessagesController.UPDATE_MASK_EMOJI_STATUS) != 0 && (user != null || chat != null)) {
updateStatus(user != null ? user.verified : chat.verified, user, chat, true);
}
if (!continueUpdate && ((mask & MessagesController.UPDATE_MASK_NAME) != 0 && user != null) || (mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0 && chat != null) {
String newName;

View file

@ -8,7 +8,10 @@ import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.RelativeSizeSpan;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@ -23,6 +26,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
@ -33,12 +37,14 @@ import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.DotDividerSpan;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MessageSeenCheckDrawable;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
@ -57,6 +63,8 @@ public class ReactedUserHolderView extends FrameLayout {
SimpleTextView titleView;
SimpleTextView subtitleView;
BackupImageView reactView;
public BackupImageView storyPreviewView;
public int storyId;
AvatarDrawable avatarDrawable = new AvatarDrawable();
View overlaySelectorView;
StatusBadgeComponent statusBadgeComponent;
@ -73,6 +81,8 @@ public class ReactedUserHolderView extends FrameLayout {
public static final MessageSeenCheckDrawable seenDrawable = new MessageSeenCheckDrawable(R.drawable.msg_mini_checks, Theme.key_windowBackgroundWhiteGrayText);
public static final MessageSeenCheckDrawable reactDrawable = new MessageSeenCheckDrawable(R.drawable.msg_reactions, Theme.key_windowBackgroundWhiteGrayText, 16, 16, 5.66f);
public static final MessageSeenCheckDrawable repostDrawable = new MessageSeenCheckDrawable(R.drawable.mini_repost_story, Theme.key_stories_circle1);
public static final MessageSeenCheckDrawable forwardDrawable = new MessageSeenCheckDrawable(R.drawable.mini_forward_story, Theme.key_stories_circle1);
public ReactedUserHolderView(int style, int currentAccount, @NonNull Context context, Theme.ResourcesProvider resourcesProvider) {
this(style, currentAccount, context, resourcesProvider, true);
@ -148,6 +158,9 @@ public class ReactedUserHolderView extends FrameLayout {
reactView = new BackupImageView(context);
addView(reactView, LayoutHelper.createFrameRelatively(24, 24, Gravity.END | Gravity.CENTER_VERTICAL, 0, 0, 12, 0));
storyPreviewView = new BackupImageView(context);
addView(storyPreviewView, LayoutHelper.createFrameRelatively(22, 35, Gravity.END | Gravity.CENTER_VERTICAL, 0, 0, 12, 0));
if (useOverlaySelector) {
overlaySelectorView = new View(context);
overlaySelectorView.setBackground(Theme.getSelectorDrawable(false));
@ -155,7 +168,7 @@ public class ReactedUserHolderView extends FrameLayout {
}
}
public void setUserReaction(TLRPC.User user, TLRPC.Chat chat, TLRPC.Reaction reaction, boolean like, long date, boolean dateIsSeen, boolean animated) {
public void setUserReaction(TLRPC.User user, TLRPC.Chat chat, TLRPC.Reaction reaction, boolean like, long date, TL_stories.StoryItem storyItem, boolean isForward, boolean dateIsSeen, boolean animated) {
TLObject u = user;
if (u == null) {
u = chat;
@ -223,6 +236,24 @@ public class ReactedUserHolderView extends FrameLayout {
contentDescription = LocaleController.formatString("AccDescrPersonHasSeen", R.string.AccDescrPersonHasSeen, titleView.getText());
}
if (storyItem != null) {
storyId = storyItem.id;
if (storyItem.media != null && storyItem.media.photo != null) {
final TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(storyItem.media.photo.sizes, 35, false, null, true);
storyPreviewView.setImage(ImageLocation.getForPhoto(photoSize, storyItem.media.photo), "22_35", null, null, -1, storyItem);
} else if (storyItem.media != null && storyItem.media.document != null) {
final TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(storyItem.media.document.thumbs, 35, false, null, true);
storyPreviewView.setImage(ImageLocation.getForDocument(photoSize, storyItem.media.document), "22_35", null, null, -1, storyItem);
}
storyPreviewView.setRoundRadius(AndroidUtilities.dp(3.33f));
if (date <= 0) {
date = storyItem.date;
}
} else {
storyId = -1;
storyPreviewView.setImageDrawable(null);
}
if (date != 0) {
contentDescription += " " + LocaleController.formatSeenDate(date);
}
@ -230,8 +261,41 @@ public class ReactedUserHolderView extends FrameLayout {
if (date != 0) {
subtitleView.setVisibility(View.VISIBLE);
CharSequence icon = dateIsSeen ? seenDrawable.getSpanned(getContext(), resourcesProvider) : reactDrawable.getSpanned(getContext(), resourcesProvider);
subtitleView.setText(TextUtils.concat(icon, LocaleController.formatSeenDate(date)));
MessageSeenCheckDrawable drawable;
if (storyItem != null) {
drawable = isForward ? forwardDrawable : repostDrawable;
} else if (dateIsSeen) {
drawable = seenDrawable;
} else {
drawable = reactDrawable;
}
SpannableStringBuilder ssb = new SpannableStringBuilder();
ssb.append(drawable.getSpanned(getContext(), resourcesProvider));
ssb.append(LocaleController.formatSeenDate(date));
if (!isForward && storyItem != null && !TextUtils.isEmpty(storyItem.caption)) {
ssb.append("");
ssb.append(".");
DotDividerSpan dotSpan = new DotDividerSpan();
dotSpan.setSize(2.33333f);
dotSpan.setTopPadding(AndroidUtilities.dp(5));
ssb.setSpan(dotSpan, ssb.length() - 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append("");
int index = ssb.length();
ssb.append(LocaleController.getString(R.string.StoryRepostCommented));
ssb.setSpan(new RelativeSizeSpan(.95f), index, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (!isForward && storyItem != null && storyItem.fwd_from != null && storyItem.fwd_from.modified) {
ssb.append("");
ssb.append(".");
DotDividerSpan dotSpan = new DotDividerSpan();
dotSpan.setSize(2.33333f);
dotSpan.setTopPadding(AndroidUtilities.dp(5));
ssb.setSpan(dotSpan, ssb.length() - 1, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.append("");
int index = ssb.length();
ssb.append("edited");
ssb.setSpan(new RelativeSizeSpan(.95f), index, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
subtitleView.setText(ssb);
subtitleView.setTranslationY(!dateIsSeen ? AndroidUtilities.dp(-1) : 0);
titleView.setTranslationY(0);
if (animated) {
@ -263,7 +327,7 @@ public class ReactedUserHolderView extends FrameLayout {
} else {
chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
}
setUserReaction(user, chat, reaction.reaction, false, reaction.date, reaction.dateIsSeen, false);
setUserReaction(user, chat, reaction.reaction, false, reaction.date, null, false, reaction.dateIsSeen, false);
}
@Override

View file

@ -12,10 +12,13 @@ import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.SystemClock;
@ -79,12 +82,16 @@ public class ShareDialogCell extends FrameLayout {
private boolean topicWasVisible;
private final int currentAccount = UserConfig.selectedAccount;
private final Theme.ResourcesProvider resourcesProvider;
public final Theme.ResourcesProvider resourcesProvider;
public static final int TYPE_SHARE = 0;
public static final int TYPE_CALL = 1;
public static final int TYPE_CREATE = 2;
public BackupImageView getImageView() {
return imageView;
}
public ShareDialogCell(Context context, int type, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
@ -144,11 +151,15 @@ public class ShareDialogCell extends FrameLayout {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp(currentType == TYPE_CREATE ? 95 : 103), MeasureSpec.EXACTLY));
}
protected String repostToCustomName() {
return LocaleController.getString(R.string.FwdMyStory);
}
public void setDialog(long uid, boolean checked, CharSequence name) {
if (uid == Long.MAX_VALUE) {
nameTextView.setText(LocaleController.getString(R.string.FwdMyStory));
nameTextView.setText(repostToCustomName());
if (repostStoryDrawable == null) {
repostStoryDrawable = new RepostStoryDrawable(imageView, resourcesProvider);
repostStoryDrawable = new RepostStoryDrawable(getContext(), imageView, true, resourcesProvider);
}
imageView.setImage(null, null, repostStoryDrawable, null);
} else if (DialogObject.isUserDialog(uid)) {
@ -321,41 +332,62 @@ public class ShareDialogCell extends FrameLayout {
}
}
private static class RepostStoryDrawable extends Drawable {
public static class RepostStoryDrawable extends Drawable {
private final LinearGradient gradient;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RLottieDrawable lottieDrawable;
private final Drawable drawable;
public RepostStoryDrawable(View view, Theme.ResourcesProvider resourcesProvider) {
public RepostStoryDrawable(Context context, View parentView, boolean animate, Theme.ResourcesProvider resourcesProvider) {
gradient = new LinearGradient(0, 0, dp(56), dp(56), new int[] {
Theme.getColor(Theme.key_stories_circle1, resourcesProvider),
Theme.getColor(Theme.key_stories_circle2, resourcesProvider)
}, new float[] { 0, 1 }, Shader.TileMode.CLAMP);
paint.setShader(gradient);
lottieDrawable = new RLottieDrawable(R.raw.story_repost, "story_repost", dp(42), dp(42), true, null);
lottieDrawable.setMasterParent(view);
AndroidUtilities.runOnUIThread(lottieDrawable::start, 450);
if (animate) {
lottieDrawable = new RLottieDrawable(R.raw.story_repost, "story_repost", dp(42), dp(42), true, null);
lottieDrawable.setMasterParent(parentView);
AndroidUtilities.runOnUIThread(lottieDrawable::start, 450);
drawable = null;
} else {
lottieDrawable = null;
drawable = context.getResources().getDrawable(R.drawable.large_repost_story).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
}
}
int alpha = 0xFF;
@Override
public void draw(@NonNull Canvas canvas) {
canvas.save();
canvas.translate(getBounds().left, getBounds().top);
canvas.drawCircle(getBounds().width() / 2f, getBounds().height() / 2f, getBounds().width() / 2f, paint);
AndroidUtilities.rectTmp.set(0, 0, getBounds().width(), getBounds().height());
paint.setAlpha(alpha);
float r2 = Math.min(getBounds().width(), getBounds().height()) / 2f * ((float) alpha / 0xFF);
canvas.drawRoundRect(AndroidUtilities.rectTmp, r2, r2, paint);
canvas.restore();
AndroidUtilities.rectTmp2.set(getBounds());
AndroidUtilities.rectTmp2.inset(dp(8), dp(8));
lottieDrawable.setBounds(AndroidUtilities.rectTmp2);
lottieDrawable.draw(canvas);
final int r = dp(lottieDrawable != null ? 20 : 15);
AndroidUtilities.rectTmp2.set(
getBounds().centerX() - r,
getBounds().centerY() - r,
getBounds().centerX() + r,
getBounds().centerY() + r
);
Drawable drawable = lottieDrawable == null ? this.drawable : lottieDrawable;
if (drawable != null) {
drawable.setBounds(AndroidUtilities.rectTmp2);
drawable.setAlpha(alpha);
drawable.draw(canvas);
}
}
@Override
public void setAlpha(int alpha) {
this.alpha = alpha;
}
@Override

View file

@ -8,6 +8,8 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
@ -33,6 +35,7 @@ import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.Switch;
import org.telegram.ui.FilterCreateActivity;
import org.telegram.ui.PeerColorActivity;
public class TextCell extends FrameLayout {
@ -94,11 +97,11 @@ public class TextCell extends FrameLayout {
valueTextView = new AnimatedTextView(context, false, false, true);
valueTextView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlue2 : Theme.key_windowBackgroundWhiteValueText, resourcesProvider));
valueTextView.setPadding(0, AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18));
valueTextView.setTextSize(AndroidUtilities.dp(16));
valueTextView.setPadding(0, dp(18), 0, dp(18));
valueTextView.setTextSize(dp(16));
valueTextView.setGravity(LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT);
valueTextView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
valueTextView.setTranslationY(AndroidUtilities.dp(-2));
valueTextView.setTranslationY(dp(-2));
addView(valueTextView);
valueSpoilersTextView = new SimpleTextView(context);
@ -166,7 +169,7 @@ public class TextCell extends FrameLayout {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = AndroidUtilities.dp(heightDp);
int height = dp(heightDp);
if (lastWidth != 0 && lastWidth != width && valueText != null) {
valueTextView.setText(TextUtils.ellipsize(valueText, valueTextView.getPaint(), AndroidUtilities.displaySize.x / 2.5f, TextUtils.TruncateAt.END), false);
@ -175,16 +178,16 @@ public class TextCell extends FrameLayout {
int valueWidth;
if (prioritizeTitleOverValue) {
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(103 + leftPadding) - textView.getTextWidth(), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
valueSpoilersTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(103 + leftPadding) - textView.getTextWidth(), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(width - dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - dp(71 + leftPadding), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - dp(103 + leftPadding) - textView.getTextWidth(), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
valueSpoilersTextView.measure(MeasureSpec.makeMeasureSpec(width - dp(103 + leftPadding) - textView.getTextWidth(), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
} else {
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(leftPadding), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
valueSpoilersTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(leftPadding), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - dp(leftPadding), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
valueSpoilersTextView.measure(MeasureSpec.makeMeasureSpec(width - dp(leftPadding), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
valueWidth = Math.max(valueTextView.width(), valueSpoilersTextView.getTextWidth());
textView.measure(MeasureSpec.makeMeasureSpec(Math.max(0, width - AndroidUtilities.dp(71 + leftPadding) - valueWidth), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding) - valueWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(Math.max(0, width - dp(71 + leftPadding) - valueWidth), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - dp(71 + leftPadding) - valueWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
}
if (imageView.getVisibility() == VISIBLE) {
imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
@ -193,7 +196,7 @@ public class TextCell extends FrameLayout {
valueImageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
}
if (checkBox != null) {
checkBox.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(37), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
checkBox.measure(MeasureSpec.makeMeasureSpec(dp(37), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(20), MeasureSpec.EXACTLY));
}
setMeasuredDimension(width, height + (needDivider ? 1 : 0));
}
@ -212,43 +215,43 @@ public class TextCell extends FrameLayout {
int width = right - left;
int viewTop = (height - Math.max(valueSpoilersTextView.getTextHeight(), valueTextView.getTextHeight())) / 2;
int viewLeft = LocaleController.isRTL ? AndroidUtilities.dp(leftPadding) : width - valueTextView.getMeasuredWidth() - AndroidUtilities.dp(leftPadding);
int viewLeft = LocaleController.isRTL ? dp(leftPadding) : width - valueTextView.getMeasuredWidth() - dp(leftPadding);
if (prioritizeTitleOverValue && !LocaleController.isRTL) {
viewLeft = width - valueTextView.getMeasuredWidth() - AndroidUtilities.dp(leftPadding);
viewLeft = width - valueTextView.getMeasuredWidth() - dp(leftPadding);
}
valueTextView.layout(viewLeft, viewTop, viewLeft + valueTextView.getMeasuredWidth(), viewTop + valueTextView.getMeasuredHeight());
viewLeft = LocaleController.isRTL ? AndroidUtilities.dp(leftPadding) : width - valueSpoilersTextView.getMeasuredWidth() - AndroidUtilities.dp(leftPadding);
viewLeft = LocaleController.isRTL ? dp(leftPadding) : width - valueSpoilersTextView.getMeasuredWidth() - dp(leftPadding);
valueSpoilersTextView.layout(viewLeft, viewTop, viewLeft + valueSpoilersTextView.getMeasuredWidth(), viewTop + valueSpoilersTextView.getMeasuredHeight());
if (LocaleController.isRTL) {
viewLeft = getMeasuredWidth() - textView.getMeasuredWidth() - AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? offsetFromImage : leftPadding);
viewLeft = getMeasuredWidth() - textView.getMeasuredWidth() - dp(imageView.getVisibility() == VISIBLE ? offsetFromImage : leftPadding);
} else {
viewLeft = AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? offsetFromImage : leftPadding);
viewLeft = dp(imageView.getVisibility() == VISIBLE ? offsetFromImage : leftPadding);
}
if (subtitleView.getVisibility() == View.VISIBLE) {
int margin = heightDp > 50 ? 4 : 2;
viewTop = (height - textView.getTextHeight() - subtitleView.getTextHeight() - AndroidUtilities.dp(margin)) / 2;
viewTop = (height - textView.getTextHeight() - subtitleView.getTextHeight() - dp(margin)) / 2;
textView.layout(viewLeft, viewTop, viewLeft + textView.getMeasuredWidth(), viewTop + textView.getMeasuredHeight());
viewTop = viewTop + textView.getTextHeight() + AndroidUtilities.dp(margin);
viewTop = viewTop + textView.getTextHeight() + dp(margin);
subtitleView.layout(viewLeft, viewTop, viewLeft + subtitleView.getMeasuredWidth(), viewTop + subtitleView.getMeasuredHeight());
} else {
viewTop = (height - textView.getTextHeight()) / 2;
textView.layout(viewLeft, viewTop, viewLeft + textView.getMeasuredWidth(), viewTop + textView.getMeasuredHeight());
}
if (imageView.getVisibility() == VISIBLE) {
viewTop = AndroidUtilities.dp(heightDp > 50 ? 0 : 2) + (height - imageView.getMeasuredHeight()) / 2 - imageView.getPaddingTop();
viewLeft = !LocaleController.isRTL ? AndroidUtilities.dp(imageLeft) : width - imageView.getMeasuredWidth() - AndroidUtilities.dp(imageLeft);
viewTop = dp(heightDp > 50 ? 0 : 2) + (height - imageView.getMeasuredHeight()) / 2 - imageView.getPaddingTop();
viewLeft = !LocaleController.isRTL ? dp(imageLeft) : width - imageView.getMeasuredWidth() - dp(imageLeft);
imageView.layout(viewLeft, viewTop, viewLeft + imageView.getMeasuredWidth(), viewTop + imageView.getMeasuredHeight());
}
if (valueImageView.getVisibility() == VISIBLE) {
viewTop = (height - valueImageView.getMeasuredHeight()) / 2;
viewLeft = LocaleController.isRTL ? AndroidUtilities.dp(23) : width - valueImageView.getMeasuredWidth() - AndroidUtilities.dp(23);
viewLeft = LocaleController.isRTL ? dp(23) : width - valueImageView.getMeasuredWidth() - dp(23);
valueImageView.layout(viewLeft, viewTop, viewLeft + valueImageView.getMeasuredWidth(), viewTop + valueImageView.getMeasuredHeight());
}
if (checkBox != null && checkBox.getVisibility() == VISIBLE) {
viewTop = (height - checkBox.getMeasuredHeight()) / 2;
viewLeft = LocaleController.isRTL ? AndroidUtilities.dp(22) : width - checkBox.getMeasuredWidth() - AndroidUtilities.dp(22);
viewLeft = LocaleController.isRTL ? dp(22) : width - checkBox.getMeasuredWidth() - dp(22);
checkBox.layout(viewLeft, viewTop, viewLeft + checkBox.getMeasuredWidth(), viewTop + checkBox.getMeasuredHeight());
}
}
@ -286,6 +289,7 @@ public class TextCell extends FrameLayout {
public void setText(String text, boolean divider) {
imageLeft = 21;
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(valueText = null, false);
imageView.setVisibility(GONE);
valueTextView.setVisibility(GONE);
@ -295,25 +299,32 @@ public class TextCell extends FrameLayout {
setWillNotDraw(!needDivider);
}
public void setTextAndIcon(String text, int resId, boolean divider) {
public void setLockLevel(boolean plus, int level) {
textView.setRightDrawable(new PeerColorActivity.LevelLock(getContext(), plus, level, resourcesProvider));
textView.setDrawablePadding(dp(6));
}
public void setTextAndIcon(CharSequence text, int resId, boolean divider) {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(valueText = null, false);
imageView.setImageResource(resId);
imageView.setVisibility(VISIBLE);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setPadding(0, dp(7), 0, 0);
needDivider = divider;
setWillNotDraw(!needDivider);
}
public void setTextAndColorfulIcon(String text, int resId, int color, boolean divider) {
public void setTextAndColorfulIcon(CharSequence text, int resId, int color, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(valueText = null, false);
setColorfulIcon(color, resId);
valueTextView.setVisibility(GONE);
@ -326,6 +337,7 @@ public class TextCell extends FrameLayout {
offsetFromImage = 68;
imageLeft = 18;
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(valueText = null, false);
imageView.setColorFilter(null);
if (drawable instanceof RLottieDrawable) {
@ -336,7 +348,7 @@ public class TextCell extends FrameLayout {
imageView.setVisibility(VISIBLE);
valueTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(6), 0, 0);
imageView.setPadding(0, dp(6), 0, 0);
needDivider = divider;
setWillNotDraw(!needDivider);
}
@ -357,6 +369,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(TextUtils.ellipsize(valueText = value, valueTextView.getPaint(), AndroidUtilities.displaySize.x / 2.5f, TextUtils.TruncateAt.END), animated);
valueTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setVisibility(GONE);
@ -373,6 +386,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(TextUtils.ellipsize(valueText = value, valueTextView.getPaint(), AndroidUtilities.displaySize.x / 2.5f, TextUtils.TruncateAt.END), animated);
valueTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setVisibility(GONE);
@ -389,6 +403,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueSpoilersTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setText(value);
valueTextView.setVisibility(GONE);
@ -396,7 +411,7 @@ public class TextCell extends FrameLayout {
imageView.setVisibility(VISIBLE);
imageView.setTranslationX(0);
imageView.setTranslationY(0);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setPadding(0, dp(7), 0, 0);
imageView.setImageResource(resId);
needDivider = divider;
setWillNotDraw(!needDivider);
@ -409,6 +424,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueSpoilersTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setText(value);
valueTextView.setVisibility(GONE);
@ -429,6 +445,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(TextUtils.ellipsize(valueText = value, valueTextView.getPaint(), AndroidUtilities.displaySize.x / 2.5f, TextUtils.TruncateAt.END), animated);
valueTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setVisibility(GONE);
@ -436,7 +453,7 @@ public class TextCell extends FrameLayout {
imageView.setVisibility(VISIBLE);
imageView.setTranslationX(0);
imageView.setTranslationY(0);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setPadding(0, dp(7), 0, 0);
imageView.setImageResource(resId);
needDivider = divider;
setWillNotDraw(!needDivider);
@ -445,7 +462,7 @@ public class TextCell extends FrameLayout {
}
}
public static CharSequence applyNewSpan(String str) {
public static CharSequence applyNewSpan(CharSequence str) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
spannableStringBuilder.append(" d");
FilterCreateActivity.NewSpan span = new FilterCreateActivity.NewSpan(10);
@ -457,17 +474,18 @@ public class TextCell extends FrameLayout {
public void setColorfulIcon(int color, int resId) {
offsetFromImage = getOffsetFromImage(true);
imageView.setVisibility(VISIBLE);
imageView.setPadding(AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2));
imageView.setTranslationX(AndroidUtilities.dp(LocaleController.isRTL ? 0 : -3));
imageView.setPadding(dp(2), dp(2), dp(2), dp(2));
imageView.setTranslationX(dp(LocaleController.isRTL ? 0 : -3));
imageView.setImageResource(resId);
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
imageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(9), color));
imageView.setBackground(Theme.createRoundRectDrawable(dp(9), color));
}
public void setTextAndCheck(CharSequence text, boolean checked, boolean divider) {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
imageView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
needDivider = divider;
@ -482,6 +500,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
@ -490,7 +509,7 @@ public class TextCell extends FrameLayout {
checkBox.setChecked(checked, false);
}
imageView.setVisibility(VISIBLE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setPadding(0, dp(7), 0, 0);
imageView.setImageResource(resId);
needDivider = divider;
setWillNotDraw(!needDivider);
@ -500,6 +519,7 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
@ -508,7 +528,7 @@ public class TextCell extends FrameLayout {
checkBox.setChecked(checked, false);
}
imageView.setVisibility(VISIBLE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setPadding(0, dp(7), 0, 0);
imageView.setImageDrawable(resDrawable);
needDivider = divider;
setWillNotDraw(!needDivider);
@ -518,13 +538,14 @@ public class TextCell extends FrameLayout {
imageLeft = 21;
offsetFromImage = getOffsetFromImage(false);
textView.setText(text);
textView.setRightDrawable(null);
valueTextView.setText(valueText = null, false);
valueImageView.setVisibility(VISIBLE);
valueImageView.setImageDrawable(drawable);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
imageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
imageView.setPadding(0, dp(7), 0, 0);
needDivider = divider;
setWillNotDraw(!needDivider);
if (checkBox != null) {
@ -543,7 +564,7 @@ public class TextCell extends FrameLayout {
if (paint == null) {
paint = Theme.dividerPaint;
}
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? (inDialogs ? 72 : 68) : 20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(imageView.getVisibility() == VISIBLE ? (inDialogs ? 72 : 68) : 20) : 0), getMeasuredHeight() - 1, paint);
canvas.drawLine(LocaleController.isRTL ? 0 : dp(imageView.getVisibility() == VISIBLE ? (inDialogs ? 72 : 68) : 20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? dp(imageView.getVisibility() == VISIBLE ? (inDialogs ? 72 : 68) : 20) : 0), getMeasuredHeight() - 1, paint);
}
}
@ -693,16 +714,16 @@ public class TextCell extends FrameLayout {
paint.setAlpha((int) (255 * alpha));
int cy = getMeasuredHeight() >> 1;
AndroidUtilities.rectTmp.set(
getMeasuredWidth() - AndroidUtilities.dp(21) - AndroidUtilities.dp(loadingSize),
cy - AndroidUtilities.dp(3),
getMeasuredWidth() - AndroidUtilities.dp(21),
cy + AndroidUtilities.dp(3)
getMeasuredWidth() - dp(21) - dp(loadingSize),
cy - dp(3),
getMeasuredWidth() - dp(21),
cy + dp(3)
);
if (LocaleController.isRTL) {
AndroidUtilities.rectTmp.left = getMeasuredWidth() - AndroidUtilities.rectTmp.left;
AndroidUtilities.rectTmp.right = getMeasuredWidth() - AndroidUtilities.rectTmp.right;
}
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(3), AndroidUtilities.dp(3), paint);
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(3), dp(3), paint);
invalidate();
}
valueTextView.setAlpha(1f - drawLoadingProgress);

View file

@ -385,10 +385,13 @@ public class TextCheckCell extends FrameLayout {
canvas.drawCircle(cx, cy, animatedRad, animationPaint);
}
if (needDivider) {
if (imageView != null) {
canvas.drawLine(LocaleController.isRTL ? 0 : padding, getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? padding : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
} else {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
Paint dividerPaint = resourcesProvider != null ? resourcesProvider.getPaint(Theme.key_paint_divider) : Theme.dividerPaint;
if (dividerPaint != null) {
if (imageView != null) {
canvas.drawLine(LocaleController.isRTL ? 0 : padding, getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? padding : 0), getMeasuredHeight() - 1, dividerPaint);
} else {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, dividerPaint);
}
}
}
}

View file

@ -16,6 +16,7 @@ import android.view.MotionEvent;
import android.view.ViewTreeObserver;
import android.widget.LinearLayout;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import org.telegram.messenger.AndroidUtilities;
@ -30,7 +31,9 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.INavigationLayout;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.ChatBackgroundDrawable;
import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
@ -38,6 +41,7 @@ import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Stories.recorder.StoryEntry;
public class ThemePreviewMessagesCell extends LinearLayout {
@ -340,10 +344,7 @@ public class ThemePreviewMessagesCell extends LinearLayout {
if (getMessageObject() != null && getMessageObject().overrideLinkColor >= 0) {
final int colorId = getMessageObject().overrideLinkColor;
final int color1, color2;
if (getMessageObject().overrideProfilePeerColor != null) {
color1 = getMessageObject().overrideProfilePeerColor.getAvatarColor1();
color2 = getMessageObject().overrideProfilePeerColor.getAvatarColor2();
} else if (colorId >= 14) {
if (colorId >= 14) {
MessagesController messagesController = MessagesController.getInstance(UserConfig.selectedAccount);
MessagesController.PeerColors peerColors = messagesController != null ? messagesController.peerColors : null;
MessagesController.PeerColor peerColor = peerColors != null ? peerColors.getColor(colorId) : null;
@ -443,9 +444,32 @@ public class ThemePreviewMessagesCell extends LinearLayout {
private Drawable overrideDrawable;
public void setOverrideBackground(Drawable drawable) {
overrideDrawable = drawable;
if (overrideDrawable != null) {
overrideDrawable.setCallback(this);
}
if (overrideDrawable instanceof ChatBackgroundDrawable) {
if (isAttachedToWindow()) {
((ChatBackgroundDrawable) overrideDrawable).onAttachedToWindow(this);
}
}
invalidate();
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (overrideDrawable instanceof ChatBackgroundDrawable) {
((ChatBackgroundDrawable) overrideDrawable).onAttachedToWindow(this);
}
}
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == overrideDrawable || who == oldBackgroundDrawable || super.verifyDrawable(who);
}
public boolean customAnimation;
private final AnimatedFloat overrideDrawableUpdate = new AnimatedFloat(this, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
@Override
protected void onDraw(Canvas canvas) {
@ -454,7 +478,7 @@ public class ThemePreviewMessagesCell extends LinearLayout {
invalidate();
}
if (newDrawable != backgroundDrawable && newDrawable != null) {
if (Theme.isAnimatingColor()) {
if (Theme.isAnimatingColor() || customAnimation) {
oldBackgroundDrawable = backgroundDrawable;
oldBackgroundGradientDisposable = backgroundGradientDisposable;
} else if (backgroundGradientDisposable != null) {
@ -462,15 +486,16 @@ public class ThemePreviewMessagesCell extends LinearLayout {
backgroundGradientDisposable = null;
}
backgroundDrawable = newDrawable;
overrideDrawableUpdate.set(0, true);
}
float themeAnimationValue = parentLayout.getThemeAnimationValue();
float themeAnimationValue = customAnimation ? overrideDrawableUpdate.set(1) : parentLayout.getThemeAnimationValue();
for (int a = 0; a < 2; a++) {
Drawable drawable = a == 0 ? oldBackgroundDrawable : backgroundDrawable;
if (drawable == null) {
continue;
}
int alpha;
if (a == 1 && oldBackgroundDrawable != null && parentLayout != null) {
if (a == 1 && oldBackgroundDrawable != null && (parentLayout != null || customAnimation)) {
alpha = (int) (255 * themeAnimationValue);
} else {
alpha = 255;
@ -510,6 +535,8 @@ public class ThemePreviewMessagesCell extends LinearLayout {
}
drawable.draw(canvas);
canvas.restore();
} else {
StoryEntry.drawBackgroundDrawable(canvas, drawable, getWidth(), getHeight());
}
if (a == 0 && oldBackgroundDrawable != null && themeAnimationValue >= 1.0f) {
if (oldBackgroundGradientDisposable != null) {
@ -539,6 +566,9 @@ public class ThemePreviewMessagesCell extends LinearLayout {
oldBackgroundGradientDisposable.dispose();
oldBackgroundGradientDisposable = null;
}
if (overrideDrawable instanceof ChatBackgroundDrawable) {
((ChatBackgroundDrawable) overrideDrawable).onDetachedFromWindow(this);
}
}
@Override

View file

@ -354,7 +354,7 @@ public class WallpaperCell extends FrameLayout {
int width = MeasureSpec.getSize(widthMeasureSpec);
int availableWidth = width - AndroidUtilities.dp(14 * 2 + 6 * (spanCount - 1));
int itemWidth = availableWidth / spanCount;
int height = currentType == WallpapersListActivity.TYPE_ALL ? AndroidUtilities.dp(180) : itemWidth;
int height = currentType == WallpapersListActivity.TYPE_ALL || currentType == WallpapersListActivity.TYPE_CHANNEL_PATTERNS || currentType == WallpapersListActivity.TYPE_CHANNEL_CUSTOM ? AndroidUtilities.dp(180) : itemWidth;
setMeasuredDimension(width, height + (isTop ? AndroidUtilities.dp(14) : 0) + (AndroidUtilities.dp(isBottom ? 14 : 6)));
for (int a = 0; a < spanCount; a++) {

View file

@ -2377,7 +2377,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
@Override
public boolean needPlayMessage(MessageObject messageObject, boolean muted) {
public boolean needPlayMessage(ChatMessageCell cell, MessageObject messageObject, boolean muted) {
if (messageObject.isVoice() || messageObject.isRoundVideo()) {
boolean result = MediaController.getInstance().playMessage(messageObject, muted);
MediaController.getInstance().setVoiceMessagesPlaylist(null, false);
@ -2674,6 +2674,10 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
@Override
public void didClickImage(ChatActionCell cell) {
MessageObject message = cell.getMessageObject();
if (message.type == MessageObject.TYPE_ACTION_WALLPAPER) {
presentFragment(new ChannelColorActivity(getDialogId()).setOnApplied(ChannelAdminLogActivity.this));
return;
}
PhotoViewer.getInstance().setParentActivity(ChannelAdminLogActivity.this);
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(message.photoThumbs, 640);
if (photoSize != null) {

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,491 @@
package org.telegram.ui;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.Easings;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RecyclerListView;
import java.util.Locale;
public class ChannelWallpaperActivity extends BaseFragment {
public final long dialogId;
public int currentLevel;
public TL_stories.TL_premium_boostsStatus boostsStatus;
public TLRPC.WallPaper galleryWallpaper;
public TLRPC.WallPaper currentWallpaper, selectedWallpaper;
public ChannelWallpaperActivity(long dialogId, TL_stories.TL_premium_boostsStatus boostsStatus) {
super();
this.dialogId = dialogId;
TLRPC.Chat chat = getMessagesController().getChat(-dialogId);
if (chat != null) {
currentLevel = chat.level;
}
this.boostsStatus = boostsStatus;
if (boostsStatus == null) {
MessagesController.getInstance(currentAccount).getBoostsController().getBoostsStats(dialogId, loadedBoostsStatus -> {
this.boostsStatus = loadedBoostsStatus;
if (boostsStatus != null) {
this.currentLevel = boostsStatus.level;
if (chat != null) {
chat.flags |= 1024;
chat.level = currentLevel;
}
}
});
} else {
currentLevel = boostsStatus.level;
}
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-dialogId);
if (chatFull != null) {
currentWallpaper = selectedWallpaper = chatFull.wallpaper;
if (ChatThemeController.isNotEmoticonWallpaper(selectedWallpaper)) {
galleryWallpaper = selectedWallpaper;
}
}
}
public void setSelectedWallpaper(TLRPC.WallPaper wallpaper, TLRPC.WallPaper galleryWallpaper) {
selectedWallpaper = wallpaper;
this.galleryWallpaper = galleryWallpaper;
}
private Utilities.Callback3<TLRPC.WallPaper, TLRPC.WallPaper, TLRPC.WallPaper> onSelectedWallpaperChange;
public void setOnSelectedWallpaperChange(Utilities.Callback3<TLRPC.WallPaper, TLRPC.WallPaper, TLRPC.WallPaper> listener) {
onSelectedWallpaperChange = listener;
}
public FrameLayout contentView;
public RecyclerListView listView;
public Adapter adapter;
public boolean isDark() {
return resourceProvider != null ? resourceProvider.isDark() : Theme.isCurrentThemeDark();
}
private RLottieDrawable sunDrawable;
private ActionBarMenuItem dayNightItem;
@Override
public View createView(Context context) {
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setTitle(LocaleController.getString(R.string.ChannelWallpaper));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
finishFragment();
} else if (id == 1) {
toggleTheme();
}
}
});
sunDrawable = new RLottieDrawable(R.raw.sun, "" + R.raw.sun, dp(28), dp(28), true, null);
sunDrawable.setPlayInDirectionOfCustomEndFrame(true);
if (!isDark()) {
sunDrawable.setCustomEndFrame(0);
sunDrawable.setCurrentFrame(0);
} else {
sunDrawable.setCurrentFrame(35);
sunDrawable.setCustomEndFrame(36);
}
sunDrawable.beginApplyLayerColors();
int color = Theme.getColor(Theme.key_chats_menuName, resourceProvider);
sunDrawable.setLayerColor("Sunny.**", color);
sunDrawable.setLayerColor("Path 6.**", color);
sunDrawable.setLayerColor("Path.**", color);
sunDrawable.setLayerColor("Path 5.**", color);
if (resourceProvider instanceof ChannelColorActivity.ThemeDelegate) {
dayNightItem = actionBar.createMenu().addItem(1, sunDrawable);
}
contentView = new FrameLayout(context);
updateRows();
listView = new RecyclerListView(context, resourceProvider);
listView.setAdapter(adapter = new Adapter());
listView.setLayoutManager(new LinearLayoutManager(context));
contentView.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
listView.setOnItemClickListener((view, position) -> {
if (position == removeRow) {
galleryWallpaper = null;
selectedWallpaper = null;
if (onSelectedWallpaperChange != null) {
onSelectedWallpaperChange.run(currentWallpaper, selectedWallpaper, galleryWallpaper);
}
View themesView = findChildAt(themesRow);
if (themesView instanceof ChannelColorActivity.ThemeChooser) {
((ChannelColorActivity.ThemeChooser) themesView).setGalleryWallpaper(galleryWallpaper);
}
updateRows();
} else if (position == galleryRow) {
ChatThemeBottomSheet.openGalleryForBackground(getParentActivity(), this, dialogId, resourceProvider, wallpaper -> {
galleryWallpaper = currentWallpaper = selectedWallpaper = wallpaper;
if (onSelectedWallpaperChange != null) {
onSelectedWallpaperChange.run(currentWallpaper, selectedWallpaper, galleryWallpaper);
}
finishFragment();
}, toggleThemeDelegate, boostsStatus);
}
});
DefaultItemAnimator itemAnimator = new DefaultItemAnimator();
itemAnimator.setDurations(350);
itemAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
itemAnimator.setDelayAnimations(false);
itemAnimator.setSupportsChangeAnimations(false);
listView.setItemAnimator(itemAnimator);
updateColors();
return fragmentView = contentView;
}
public View findChildAt(int position) {
for (int i = 0; i < listView.getChildCount(); ++i) {
View child = listView.getChildAt(i);
if (listView.getChildAdapterPosition(child) == position) {
return child;
}
}
return null;
}
public static final int VIEW_TYPE_BUTTON = 0;
public static final int VIEW_TYPE_INFO = 1;
public static final int VIEW_TYPE_THEMES = 2;
public int rowsCount = 0;
public int galleryRow = -1;
public int removeRow = -1;
public int infoRow = -1;
public int themesRow = -1;
public void updateRows() {
rowsCount = 0;
galleryRow = rowsCount++;
final int wasRemoveRow = removeRow;
if (galleryWallpaper != null) {
removeRow = rowsCount++;
} else {
removeRow = -1;
}
if (adapter != null) {
if (removeRow != -1 && wasRemoveRow == -1) {
adapter.notifyItemInserted(removeRow);
}
if (removeRow == -1 && wasRemoveRow != -1) {
adapter.notifyItemRemoved(wasRemoveRow);
}
}
infoRow = rowsCount++;
themesRow = rowsCount++;
}
public class Adapter extends RecyclerListView.SelectionAdapter {
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_BUTTON) {
TextCell textCell = new TextCell(getContext(), resourceProvider);
textCell.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
view = textCell;
} else if (viewType == VIEW_TYPE_THEMES) {
ChannelColorActivity.ThemeChooser themesWallpaper = new ChannelColorActivity.ThemeChooser(getContext(), true, currentAccount, resourceProvider);
themesWallpaper.setSelectedEmoticon(ChatThemeController.getWallpaperEmoticon(selectedWallpaper), false);
themesWallpaper.setGalleryWallpaper(galleryWallpaper);
themesWallpaper.setOnEmoticonSelected(emoticon -> {
if (emoticon == null) {
selectedWallpaper = galleryWallpaper;
themesWallpaper.setSelectedEmoticon(null, false);
if (onSelectedWallpaperChange != null) {
onSelectedWallpaperChange.run(currentWallpaper, selectedWallpaper, galleryWallpaper);
}
updateRows();
return;
}
ThemePreviewActivity themePreviewActivity = new ThemePreviewActivity(new WallpapersListActivity.EmojiWallpaper(emoticon), null) {
@Override
public boolean insideBottomSheet() {
return true;
}
};
themePreviewActivity.boostsStatus = boostsStatus;
themePreviewActivity.setOnSwitchDayNightDelegate(toggleThemeDelegate);
themePreviewActivity.setResourceProvider(resourceProvider);
themePreviewActivity.setInitialModes(false, false, .20f);
themePreviewActivity.setDialogId(dialogId);
themePreviewActivity.setDelegate(wallPaper -> {
selectedWallpaper = new TLRPC.TL_wallPaperNoFile();
selectedWallpaper.id = 0;
selectedWallpaper.flags |= 4;
selectedWallpaper.settings = new TLRPC.TL_wallPaperSettings();
selectedWallpaper.settings.emoticon = emoticon;
themesWallpaper.setSelectedEmoticon(emoticon, false);
if (onSelectedWallpaperChange != null) {
onSelectedWallpaperChange.run(currentWallpaper, selectedWallpaper, galleryWallpaper);
}
updateRows();
finishFragment();
});
BaseFragment.BottomSheetParams params = new BaseFragment.BottomSheetParams();
params.transitionFromLeft = true;
params.allowNestedScroll = false;
params.occupyNavigationBar = true;
showAsSheet(themePreviewActivity, params);
});
themesWallpaper.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
view = themesWallpaper;
} else {
view = new TextInfoPrivacyCell(getContext());
}
return new RecyclerListView.Holder(view);
}
@Override
public int getItemViewType(int position) {
if (position == galleryRow || position == removeRow) {
return VIEW_TYPE_BUTTON;
}
if (position == themesRow) {
return VIEW_TYPE_THEMES;
}
return VIEW_TYPE_INFO;
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position == galleryRow) {
((TextCell) holder.itemView).setTextAndIcon(LocaleController.getString(R.string.ChooseFromGallery2), R.drawable.msg_background, removeRow != -1);
((TextCell) holder.itemView).setColors(Theme.key_windowBackgroundWhiteBlueIcon, Theme.key_windowBackgroundWhiteBlueButton);
} else if (position == removeRow) {
((TextCell) holder.itemView).setTextAndIcon(LocaleController.getString(R.string.ChannelWallpaperRemove), R.drawable.msg_delete, false);
((TextCell) holder.itemView).setColors(Theme.key_text_RedRegular, Theme.key_text_RedRegular);
} else if (position == infoRow) {
((TextInfoPrivacyCell) holder.itemView).setText(LocaleController.getString(R.string.ChannelWallpaperInfo));
((TextInfoPrivacyCell) holder.itemView).setBackgroundColor(getThemedColor(Theme.key_windowBackgroundGray));
((TextInfoPrivacyCell) holder.itemView).setForeground(Theme.getThemedDrawableByKey(getContext(), R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow, resourceProvider));
} else if (position == themesRow) {
((ChannelColorActivity.ThemeChooser) holder.itemView).setGalleryWallpaper(galleryWallpaper);
}
}
@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
if (holder.itemView instanceof ChannelColorActivity.ThemeChooser) {
((ChannelColorActivity.ThemeChooser) holder.itemView).setGalleryWallpaper(galleryWallpaper);
}
super.onViewAttachedToWindow(holder);
}
@Override
public int getItemCount() {
return rowsCount;
}
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return holder.getItemViewType() == VIEW_TYPE_BUTTON;
}
}
public void updateColors() {
actionBar.setBackgroundColor(getThemedColor(Theme.key_actionBarDefault));
actionBar.setTitleColor(getThemedColor(Theme.key_actionBarDefaultTitle));
actionBar.setItemsColor(getThemedColor(Theme.key_actionBarDefaultIcon), false);
actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarDefaultSelector), false);
listView.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundGray));
adapter.notifyDataSetChanged();
AndroidUtilities.forEachViews(listView, this::updateColors);
setNavigationBarColor(getNavigationBarColor());
contentView.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
}
private void updateColors(View view) {
if (view instanceof TextInfoPrivacyCell) {
((TextInfoPrivacyCell) view).setBackgroundColor(getThemedColor(Theme.key_windowBackgroundGray));
((TextInfoPrivacyCell) view).setForeground(Theme.getThemedDrawableByKey(getContext(), R.drawable.greydivider, Theme.key_windowBackgroundGrayShadow, resourceProvider));
} else {
view.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
if (view instanceof TextCell) {
((TextCell) view).updateColors();
} else if (view instanceof ChannelColorActivity.ThemeChooser) {
((ChannelColorActivity.ThemeChooser) view).updateColors();
}
}
}
public ThemePreviewActivity.DayNightSwitchDelegate toggleThemeDelegate = new ThemePreviewActivity.DayNightSwitchDelegate() {
@Override
public boolean isDark() {
return ChannelWallpaperActivity.this.isDark();
}
@Override
public void switchDayNight(boolean animated) {
if (resourceProvider instanceof ChannelColorActivity.ThemeDelegate) {
((ChannelColorActivity.ThemeDelegate) resourceProvider).toggle();
}
setForceDark(isDark(), false);
updateColors();
}
@Override
public boolean supportsAnimation() {
return false;
}
};
private View changeDayNightView;
private float changeDayNightViewProgress;
private ValueAnimator changeDayNightViewAnimator;
@SuppressLint("NotifyDataSetChanged")
public void toggleTheme() {
FrameLayout decorView1 = (FrameLayout) getParentActivity().getWindow().getDecorView();
Bitmap bitmap = Bitmap.createBitmap(decorView1.getWidth(), decorView1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas bitmapCanvas = new Canvas(bitmap);
dayNightItem.setAlpha(0f);
decorView1.draw(bitmapCanvas);
dayNightItem.setAlpha(1f);
Paint xRefPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
xRefPaint.setColor(0xff000000);
xRefPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Paint bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bitmapPaint.setFilterBitmap(true);
int[] position = new int[2];
dayNightItem.getLocationInWindow(position);
float x = position[0];
float y = position[1];
float cx = x + dayNightItem.getMeasuredWidth() / 2f;
float cy = y + dayNightItem.getMeasuredHeight() / 2f;
float r = Math.max(bitmap.getHeight(), bitmap.getWidth()) + AndroidUtilities.navigationBarHeight;
Shader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
bitmapPaint.setShader(bitmapShader);
changeDayNightView = new View(getContext()) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isDark()) {
if (changeDayNightViewProgress > 0f) {
bitmapCanvas.drawCircle(cx, cy, r * changeDayNightViewProgress, xRefPaint);
}
canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
} else {
canvas.drawCircle(cx, cy, r * (1f - changeDayNightViewProgress), bitmapPaint);
}
canvas.save();
canvas.translate(x, y);
dayNightItem.draw(canvas);
canvas.restore();
}
};
changeDayNightView.setOnTouchListener((v, event) -> true);
changeDayNightViewProgress = 0f;
changeDayNightViewAnimator = ValueAnimator.ofFloat(0, 1f);
changeDayNightViewAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
boolean changedNavigationBarColor = false;
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
changeDayNightViewProgress = (float) valueAnimator.getAnimatedValue();
changeDayNightView.invalidate();
if (!changedNavigationBarColor && changeDayNightViewProgress > .5f) {
changedNavigationBarColor = true;
}
}
});
changeDayNightViewAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (changeDayNightView != null) {
if (changeDayNightView.getParent() != null) {
((ViewGroup) changeDayNightView.getParent()).removeView(changeDayNightView);
}
changeDayNightView = null;
}
changeDayNightViewAnimator = null;
super.onAnimationEnd(animation);
}
});
changeDayNightViewAnimator.setDuration(400);
changeDayNightViewAnimator.setInterpolator(Easings.easeInOutQuad);
changeDayNightViewAnimator.start();
decorView1.addView(changeDayNightView, new ViewGroup.LayoutParams(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
AndroidUtilities.runOnUIThread(() -> {
if (resourceProvider instanceof ChannelColorActivity.ThemeDelegate) {
((ChannelColorActivity.ThemeDelegate) resourceProvider).toggle();
}
setForceDark(isDark(), true);
updateColors();
});
}
public void setForceDark(boolean isDark, boolean playAnimation) {
if (playAnimation) {
sunDrawable.setCustomEndFrame(isDark ? sunDrawable.getFramesCount() : 0);
if (sunDrawable != null) {
sunDrawable.start();
}
} else {
int frame = isDark ? sunDrawable.getFramesCount() - 1 : 0;
sunDrawable.setCurrentFrame(frame, false, true);
sunDrawable.setCustomEndFrame(frame);
if (dayNightItem != null) {
dayNightItem.invalidate();
}
}
}
}

View file

@ -73,17 +73,17 @@ public class ChartHorizontalLinesData {
boolean skipFloatValues = step / k < 1;
for (int i = 0; i < n; i++) {
values[i] = newMinHeight + (int) (i * step);
valuesStr[i] = AndroidUtilities.formatWholeNumber(values[i], dif);
valuesStr[i] = AndroidUtilities.formatWholeNumber(values[i], 0);
if (k > 0) {
float v = (values[i] / k);
if (skipFloatValues) {
if (v - ((int) v) < 0.01f) {
valuesStr2[i] = AndroidUtilities.formatWholeNumber((int) v, (int) (dif / k));
valuesStr2[i] = AndroidUtilities.formatWholeNumber((int) v, 0);
} else {
valuesStr2[i] = "";
}
} else {
valuesStr2[i] = AndroidUtilities.formatWholeNumber((int) v, (int) (dif / k));
valuesStr2[i] = AndroidUtilities.formatWholeNumber((int) v, 0);
}
}
}

View file

@ -50,6 +50,7 @@ import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -199,122 +200,33 @@ import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.Cells.ContextLinkCell;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.MentionCell;
import org.telegram.ui.Cells.ShareDialogCell;
import org.telegram.ui.Cells.StickerCell;
import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.AttachBotIntroTopView;
import org.telegram.ui.Components.AudioPlayerAlert;
import org.telegram.ui.Components.AutoDeletePopupWrapper;
import org.telegram.ui.Components.BackButtonMenu;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.BlurBehindDrawable;
import org.telegram.ui.Components.BluredView;
import org.telegram.ui.Components.BlurredFrameLayout;
import org.telegram.ui.Components.BotCommandsMenuView;
import org.telegram.ui.Components.BotWebViewSheet;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ChatActivityEnterTopView;
import org.telegram.ui.Components.ChatActivityEnterView;
import org.telegram.ui.Components.ChatActivityInterface;
import org.telegram.ui.Components.ChatAttachAlert;
import org.telegram.ui.Components.ChatAttachAlertDocumentLayout;
import org.telegram.ui.Components.ChatAvatarContainer;
import org.telegram.ui.Components.ChatBigEmptyView;
import org.telegram.ui.Components.ChatGreetingsView;
import org.telegram.ui.Components.ChatNotificationsPopupWrapper;
import org.telegram.ui.Components.ChatScrimPopupContainerLayout;
import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.ChecksHintView;
import org.telegram.ui.Components.CircularProgressDrawable;
import org.telegram.ui.Components.ClippingImageView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.CounterView;
import org.telegram.ui.Components.CrossfadeDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.EditTextCaption;
import org.telegram.ui.Components.EmbedBottomSheet;
import org.telegram.ui.Components.EmojiPacksAlert;
import org.telegram.ui.Components.EmojiView;
import org.telegram.ui.Components.ExtendedGridLayoutManager;
import org.telegram.ui.Components.FireworksOverlay;
import org.telegram.ui.Components.*;
import org.telegram.ui.Components.FloatingDebug.FloatingDebugController;
import org.telegram.ui.Components.FloatingDebug.FloatingDebugProvider;
import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.FragmentContextView;
import org.telegram.ui.Components.GigagroupConvertAlert;
import org.telegram.ui.Components.HideViewAfterAnimation;
import org.telegram.ui.Components.HintView;
import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.ImportingAlert;
import org.telegram.ui.Components.InstantCameraView;
import org.telegram.ui.Components.InviteMembersBottomSheet;
import org.telegram.ui.Components.JoinGroupAlert;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.MediaActivity;
import org.telegram.ui.Components.MentionsContainerView;
import org.telegram.ui.Components.MessageBackgroundDrawable;
import org.telegram.ui.Components.MessageContainsEmojiButton;
import org.telegram.ui.Components.MessagePreviewView;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.NumberTextView;
import org.telegram.ui.Components.PhonebookShareAlert;
import org.telegram.ui.Components.PinnedLineView;
import org.telegram.ui.Components.PipRoundVideoView;
import org.telegram.ui.Components.PollVotesAlert;
import org.telegram.ui.Components.PopupSwipeBackLayout;
import org.telegram.ui.Components.Premium.GiftPremiumBottomSheet;
import org.telegram.ui.Components.Premium.LimitReachedBottomSheet;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.Premium.PremiumPreviewBottomSheet;
import org.telegram.ui.Components.Premium.boosts.BoostDialogs;
import org.telegram.ui.Components.Premium.boosts.GiftInfoBottomSheet;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.ReactedHeaderView;
import org.telegram.ui.Components.ReactedUsersListView;
import org.telegram.ui.Components.ReactionTabHolderView;
import org.telegram.ui.Components.Premium.boosts.PremiumPreviewGiftLinkBottomSheet;
import org.telegram.ui.Components.Reactions.ChatSelectionReactionMenuOverlay;
import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.ReactionsContainerLayout;
import org.telegram.ui.Components.RecyclerAnimationScrollHelper;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ReportAlert;
import org.telegram.ui.Components.SearchCounterView;
import org.telegram.ui.Components.ShareAlert;
import org.telegram.ui.Components.SharedMediaLayout;
import org.telegram.ui.Components.SizeNotifierFrameLayout;
import org.telegram.ui.Components.StickersAlert;
import org.telegram.ui.Components.SuggestEmojiView;
import org.telegram.ui.Components.TextSelectionHint;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.ThemeEditorView;
import org.telegram.ui.Components.TranscribeButton;
import org.telegram.ui.Components.TranslateAlert2;
import org.telegram.ui.Components.TranslateButton;
import org.telegram.ui.Components.TrendingStickersAlert;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanBotCommand;
import org.telegram.ui.Components.URLSpanMono;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.URLSpanUserMention;
import org.telegram.ui.Components.UndoView;
import org.telegram.ui.Components.UnreadCounterTextView;
import org.telegram.ui.Components.ViewHelper;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.Components.voip.CellFlickerDrawable;
import org.telegram.ui.Components.voip.VoIPHelper;
import org.telegram.ui.Delegates.ChatActivityMemberRequestsDelegate;
import org.telegram.ui.Stories.DialogStoriesCell;
import org.telegram.ui.Stories.StoriesListPlaceProvider;
import org.telegram.ui.Stories.StoriesUtilities;
import org.telegram.ui.Stories.recorder.PreviewView;
import org.telegram.ui.Stories.recorder.StoryEntry;
import org.telegram.ui.Stories.recorder.StoryRecorder;
import java.io.BufferedWriter;
import java.io.File;
@ -393,6 +305,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private ActionBarMenuItem.Item closeTopicItem;
private ActionBarMenuItem.Item openForumItem;
private ClippingImageView animatingImageView;
private ThanosEffect chatListThanosEffect;
private RecyclerListView chatListView;
private ChatListItemAnimator chatListItemAnimator;
private GridLayoutManagerFixed chatLayoutManager;
@ -920,8 +833,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private boolean openImport;
private float chatListViewPaddingTop;
private int chatListViewPaddingVisibleOffset;
public float chatListViewPaddingTop;
public int chatListViewPaddingVisibleOffset;
private int contentPaddingTop;
private float contentPanTranslation;
@ -965,6 +878,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
};
private ChatSelectionReactionMenuOverlay selectionReactionsOverlay;
private SecretVoicePlayer secretVoicePlayer;
private boolean isPauseOnThemePreview;
private ChatThemeBottomSheet chatThemeBottomSheet;
@ -1209,7 +1123,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}));
}
return items;
}
@ -1696,7 +1609,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatActivityEnterView.getEmojiView().onMessageSend();
}
if (!getMessagesController().premiumLocked && getMessagesController().transcribeAudioTrialWeeklyNumber <= 0 && !getMessagesController().didPressTranscribeButtonEnough() && !getUserConfig().isPremium() && !TextUtils.isEmpty(message) && messages != null) {
if (!getMessagesController().premiumFeaturesBlocked() && getMessagesController().transcribeAudioTrialWeeklyNumber <= 0 && !getMessagesController().didPressTranscribeButtonEnough() && !getUserConfig().isPremium() && !TextUtils.isEmpty(message) && messages != null) {
for (int i = 1; i < Math.min(5, messages.size()); ++i) {
MessageObject msg = messages.get(i);
if (msg != null && !msg.isOutOwner() && (msg.isVoice() || msg.isRoundVideo()) && msg.isContentUnread()) {
@ -1992,7 +1905,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
@Override
public void needStartRecordVideo(int state, boolean notify, int scheduleDate) {
public void needStartRecordVideo(int state, boolean notify, int scheduleDate, int ttl) {
checkInstantCameraView();
if (instantCameraView != null) {
if (state == 0) {
@ -2000,7 +1913,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatListView.stopScroll();
chatAdapter.updateRowsSafe();
} else if (state == 1 || state == 3 || state == 4) {
instantCameraView.send(state, notify, scheduleDate);
instantCameraView.send(state, notify, scheduleDate, ttl);
} else if (state == 2 || state == 5) {
instantCameraView.cancel(state == 2);
}
@ -2134,6 +2047,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
checkAdjustResize();
}
@Override
public boolean onceVoiceAvailable() {
return currentUser != null && !UserObject.isUserSelf(currentUser) && !currentUser.bot && currentEncryptedChat == null && chatMode == 0;
}
@Override
public ReplyQuote getReplyQuote() {
return replyingQuote;
@ -2561,7 +2479,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
themeDelegate = new ThemeDelegate();
if (themeDelegate.isThemeChangeAvailable()) {
if (themeDelegate.isThemeChangeAvailable(false)) {
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.needSetDayNightTheme);
}
@ -3566,7 +3484,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (currentChat != null && !isTopic) {
viewAsTopics = headerItem.lazilyAddSubItem(view_as_topics, R.drawable.msg_topics, LocaleController.getString("TopicViewAsTopics", R.string.TopicViewAsTopics));
}
if (themeDelegate.isThemeChangeAvailable()) {
if (themeDelegate.isThemeChangeAvailable(true)) {
headerItem.lazilyAddSubItem(change_colors, R.drawable.msg_colors, LocaleController.getString("SetWallpapers", R.string.SetWallpapers));
}
if (!isTopic) {
@ -3767,6 +3685,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
@Override
protected boolean allowSelectChildAtPosition(View child) {
if (child != null && child.getVisibility() == View.INVISIBLE) return false;
return super.allowSelectChildAtPosition(child);
}
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
saveScrollPosition();
@ -4625,6 +4549,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
for (int a = 0; a < count; a++) {
View child = getChildAt(a);
if (child.getVisibility() == View.INVISIBLE || child.getVisibility() == View.GONE) {
continue;
}
if (chatAdapter.isBot && child instanceof BotHelpCell) {
BotHelpCell botCell = (BotHelpCell) child;
float top = (getMeasuredHeight() - chatListViewPaddingTop - blurredViewBottomOffset) / 2 - child.getMeasuredHeight() / 2 + chatListViewPaddingTop;
@ -4756,7 +4683,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
View child = chatListView.getChildAt(i);
if (child instanceof ChatMessageCell) {
ChatMessageCell cell = (ChatMessageCell) child;
if (child.getY() > chatListView.getHeight() || child.getY() + child.getHeight() < 0) {
if (child.getY() > chatListView.getHeight() || child.getY() + child.getHeight() < 0 || cell.getVisibility() == View.GONE) {
continue;
}
MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
@ -4889,7 +4816,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
ChatActionCell actionCell = null;
float cilpTop = chatListViewPaddingTop - chatListViewPaddingVisibleOffset - AndroidUtilities.dp(4);
if (child.getY() > getMeasuredHeight() || child.getY() + child.getMeasuredHeight() < cilpTop) {
if (child.getY() > getMeasuredHeight() || child.getY() + child.getMeasuredHeight() < cilpTop || child.getVisibility() == View.INVISIBLE || child.getVisibility() == View.GONE) {
skipDraw = true;
}
@ -5031,7 +4958,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
ImageReceiver imageReceiver = cell.getAvatarImage();
if (imageReceiver != null) {
MessageObject.GroupedMessages groupedMessages = getValidGroupedMessage(message);
if (cell.getMessageObject().deleted) {
if (cell.getMessageObject().deleted && !cell.getMessageObject().deletedByThanos) {
if (child.getTranslationY() != 0) {
canvas.restore();
}
@ -5361,6 +5288,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
});
}
};
chatListItemAnimator.setOnSnapMessage(this::supportsThanosEffect, this::getChatThanosEffect);
}
chatLayoutManager = new GridLayoutManagerFixed(context, 1000, LinearLayoutManager.VERTICAL, true) {
@ -5662,6 +5590,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
chatListView.invalidate();
if (chatListThanosEffect != null) {
chatListThanosEffect.scroll(dx, dy);
}
scrollUp = dy < 0;
int firstVisibleItem = chatLayoutManager.findFirstVisibleItemPosition();
if (dy != 0 && (scrollByTouch && recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) || recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
@ -11211,6 +11142,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
textToCheck = charSequence;
}
final String firstUrl = urls == null || urls.isEmpty() ? null : urls.get(0).toString();
if (currentEncryptedChat != null && messagesController.secretWebpagePreview == 2) {
AndroidUtilities.runOnUIThread(() -> {
@ -11983,7 +11915,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
messageObjectToReply = messageObjectsToForward.get(0);
}
} else if (type == MessageObject.TYPE_GIVEAWAY) {
text = LocaleController.getString("BoostingGiveaway", R.string.BoostingGiveaway);;
text = LocaleController.getString("BoostingGiveaway", R.string.BoostingGiveaway);
} else if (type == MessageObject.TYPE_GIVEAWAY_RESULTS) {
text = LocaleController.getString("BoostingGiveawayResults", R.string.BoostingGiveawayResults);
} else if (type == MessageObject.TYPE_GEO) {
text = LocaleController.formatPluralString("PreviewForwardLocation", messageObjectsToForward.size());
} else if (type == MessageObject.TYPE_VIDEO) {
@ -13546,6 +13480,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
public class ChatActivityFragmentView extends SizeNotifierFrameLayout {
public ChatActivity getChatActivity() {
return ChatActivity.this;
}
public ChatActivityFragmentView(Context context, INavigationLayout parentLayout) {
super(context, parentLayout);
adjustPanLayoutHelper = new AdjustPanLayoutHelper(this) {
@ -14491,7 +14429,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int contentWidthSpec = View.MeasureSpec.makeMeasureSpec(widthSize, View.MeasureSpec.EXACTLY);
int contentHeightSpec = View.MeasureSpec.makeMeasureSpec(h, View.MeasureSpec.EXACTLY);
child.measure(contentWidthSpec, contentHeightSpec);
} else if (child == chatListView) {
} else if (child == chatListView || child == chatListThanosEffect) {
int contentWidthSpec = View.MeasureSpec.makeMeasureSpec(widthSize, View.MeasureSpec.EXACTLY);
int h = heightSize - listViewTopHeight - (inPreviewMode && Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight : 0) + blurredViewTopOffset + blurredViewBottomOffset;
if (keyboardSize > AndroidUtilities.dp(20) && getLayoutParams().height < 0) {
@ -14710,7 +14648,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
} else if (child == gifHintTextView || child == voiceHintTextView || child == mediaBanTooltip || child == emojiHintTextView) {
childTop -= inputFieldHeight;
} else if (child == chatListView || child == floatingDateView || child == infoTopView) {
} else if (child == chatListView || child == chatListThanosEffect || child == floatingDateView || child == infoTopView) {
childTop -= blurredViewTopOffset;
if (!inPreviewMode) {
childTop -= (inputFieldHeight - AndroidUtilities.dp(51));
@ -15569,7 +15507,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else if (chatMode == MODE_PINNED) {
avatarContainer.setTitle(LocaleController.formatPluralString("PinnedMessagesCount", getPinnedMessagesCount()));
} else if (currentChat != null) {
avatarContainer.setTitle(currentChat.title, currentChat.scam, currentChat.fake, currentChat.verified, false, null, animated);
avatarContainer.setTitle(currentChat.title, currentChat.scam, currentChat.fake, currentChat.verified, false, currentChat.emoji_status, animated);
} else if (currentUser != null) {
if (currentUser.self) {
avatarContainer.setTitle(LocaleController.getString("SavedMessages", R.string.SavedMessages));
@ -18825,7 +18763,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
if (chatActivityEnterView != null) {
chatActivityEnterView.setBotsCount(botsCount, hasBotsCommands, true);
hasBotWebView = getMessagesController().getUser(info.user_id).bot_menu_webview;
TLRPC.User bot = getMessagesController().getUser(info.user_id);
hasBotWebView = bot != null && bot.bot_menu_webview;
chatActivityEnterView.updateBotWebView(true);
}
}
@ -20802,6 +20741,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private void processDeletedMessages(ArrayList<Integer> markAsDeletedMessages, long channelId) {
ArrayList<Integer> removedIndexes = new ArrayList<>();
ArrayList<Integer> messagesIndexes = new ArrayList<>();
int loadIndex = 0;
if (ChatObject.isChannel(currentChat)) {
if (channelId == 0 && mergeDialogId != 0) {
@ -20902,6 +20842,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
MessageObject removed = messages.remove(index);
if (chatAdapter != null) {
removedIndexes.add(chatAdapter.messagesStartRow + index);
if (removed != null && removed.messageOwner != null && removed.messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENT) {
messagesIndexes.add(chatAdapter.messagesStartRow + index);
removed.deletedByThanos = LiteMode.isEnabled(LiteMode.FLAG_CHAT_THANOS);
}
}
if (removed.getGroupId() != 0) {
MessageObject.GroupedMessages groupedMessages = groupedMessagesMap.get(removed.getGroupId());
@ -21017,7 +20961,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
int prevLoadingUpRow = chatAdapter.loadingUpRow;
int prevLoadingDownRow = chatAdapter.loadingDownRow;
for (int a = 0, N = removedIndexes.size(); a < N; a++) {
chatAdapter.notifyItemRemoved(removedIndexes.get(a));
final int pos = removedIndexes.get(a);
chatAdapter.notifyItemRemoved(pos, messagesIndexes.contains(pos));
}
if (!isThreadChat() || messages.size() <= 3) {
removeUnreadPlane(false);
@ -21383,7 +21328,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public void onBecomeFullyHidden() {
if (!getMessagesController().premiumLocked && getMessagesController().transcribeAudioTrialWeeklyNumber <= 0 && !getMessagesController().didPressTranscribeButtonEnough() && !getUserConfig().isPremium() && messages != null) {
if (!getMessagesController().premiumFeaturesBlocked() && getMessagesController().transcribeAudioTrialWeeklyNumber <= 0 && !getMessagesController().didPressTranscribeButtonEnough() && !getUserConfig().isPremium() && messages != null) {
for (int i = 0; i < messages.size(); ++i) {
MessageObject msg = messages.get(i);
if (msg != null && !msg.isOutOwner() && (msg.isVoice() || msg.isRoundVideo()) && !msg.isUnread() && (msg.isContentUnread() || ChatObject.isChannelAndNotMegaGroup(currentChat))) {
@ -23174,7 +23119,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
boolean showTranslate = (
getUserConfig().isPremium() ?
getMessagesController().getTranslateController().isDialogTranslatable(getDialogId()) && !getMessagesController().getTranslateController().isTranslateDialogHidden(getDialogId()) :
!getMessagesController().premiumLocked && preferences.getInt("dialog_show_translate_count" + did, 5) <= 0
!getMessagesController().premiumFeaturesBlocked() && preferences.getInt("dialog_show_translate_count" + did, 5) <= 0
);
if (showRestartTopic) {
shownRestartTopic = true;
@ -24459,13 +24404,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
final int type = getMessageType(message);
if (single) {
boolean isGiveawayResultsMessage = false;
if (message.messageOwner.action instanceof TLRPC.TL_messageActionCustomAction) {
TLRPC.TL_messageActionCustomAction customAction = (TLRPC.TL_messageActionCustomAction) message.messageOwner.action;
if (customAction.message != null && customAction.message.contains("giveaway")) {
//fallback for old versions
isGiveawayResultsMessage = true;
}
} else if (message.messageOwner.action instanceof TLRPC.TL_messageActionGiveawayResults) {
if (message.messageOwner.action instanceof TLRPC.TL_messageActionGiveawayResults) {
isGiveawayResultsMessage = true;
}
if (message.messageOwner.action instanceof TLRPC.TL_messageActionPinMessage || isGiveawayResultsMessage) {
@ -24520,7 +24459,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return true;
}
} else if (message.messageOwner.action instanceof TLRPC.TL_messageActionSetChatTheme) {
showChatThemeBottomSheet();
if (currentChat == null || ChatObject.canChangeChatInfo(currentChat)) {
showChatThemeBottomSheet();
}
return true;
}
}
@ -24606,7 +24547,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
icons.add(R.drawable.msg_user_search);
}
if (!getUserConfig().isPremium() && !getMessagesController().premiumLocked && message.getDocument() != null && message.getDocument().size >= 150 * 1024 * 1024 && FileLoader.getInstance(currentAccount).isLoadingFile(FileLoader.getAttachFileName(message.getDocument()))) {
if (!getUserConfig().isPremium() && !getMessagesController().premiumFeaturesBlocked() && message.getDocument() != null && message.getDocument().size >= 150 * 1024 * 1024 && FileLoader.getInstance(currentAccount).isLoadingFile(FileLoader.getAttachFileName(message.getDocument()))) {
items.add(LocaleController.getString(R.string.PremiumSpeedPromo));
options.add(OPTION_SPEED_PROMO);
icons.add(R.drawable.msg_speed);
@ -24680,7 +24621,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
messageTextToTranslate = null;
}
if (message.isSponsored() && !getMessagesController().premiumLocked) {
if (message.isSponsored() && !getUserConfig().isPremium() && !getMessagesController().premiumFeaturesBlocked()) {
items.add(LocaleController.getString("HideAd", R.string.HideAd));
options.add(OPTION_HIDE_SPONSORED_MESSAGE);
icons.add(R.drawable.msg_block2);
@ -26056,7 +25997,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
if (stickerSets.size() > 0 && !getMessagesController().premiumLocked) {
if (stickerSets.size() > 0 && !getMessagesController().premiumFeaturesBlocked()) {
View gap = new FrameLayout(contentView.getContext());
gap.setBackgroundColor(getThemedColor(Theme.key_actionBarDefaultSubmenuSeparator));
popupLayout.addView(gap, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8));
@ -27617,7 +27558,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public boolean onBackPressed() {
if (closeStoryViewer()) {
if (secretVoicePlayer != null && secretVoicePlayer.isShown()) {
secretVoicePlayer.dismiss();
return false;
} else if (closeStoryViewer()) {
return false;
} else if (selectionReactionsOverlay != null && !selectionReactionsOverlay.onBackPressed()) {
return false;
@ -27856,7 +27800,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (messageObject.getDialogId() == mergeDialogId && startMessageObject.getDialogId() != mergeDialogId) {
continue;
}
if ((currentEncryptedChat == null && messageObject.getId() > messageId || currentEncryptedChat != null && messageObject.getId() < messageId) && (messageObject.isVoice() || messageObject.isRoundVideo()) && (!playingUnreadMedia || messageObject.isContentUnread() && !messageObject.isOut())) {
if ((currentEncryptedChat == null && messageObject.getId() > messageId || currentEncryptedChat != null && messageObject.getId() < messageId) && (messageObject.isVoice() || messageObject.isRoundVideo()) && !messageObject.isVoiceOnce() && !messageObject.isRoundOnce() && (!playingUnreadMedia || messageObject.isContentUnread() && !messageObject.isOut())) {
messageObjects.add(messageObject);
}
}
@ -29238,14 +29182,24 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
((ChatActionCell) view).setInvalidateColors(true);
((ChatActionCell) view).setDelegate(new ChatActionCell.ChatActionCellDelegate() {
@Override
public void didOpenPremiumGift(ChatActionCell cell, TLRPC.TL_premiumGiftOption giftOption, boolean animateConfetti) {
showDialog(new PremiumPreviewBottomSheet(ChatActivity.this, currentAccount, getCurrentUser(), new GiftPremiumBottomSheet.GiftTier(giftOption), themeDelegate)
.setAnimateConfetti(animateConfetti)
.setOutboundGift(cell.getMessageObject().isOut()));
public void didOpenPremiumGift(ChatActionCell cell, TLRPC.TL_premiumGiftOption giftOption, String slug, boolean animateConfetti) {
if (slug != null) {
initGiftProgressDialog(cell);
PremiumPreviewGiftLinkBottomSheet.show(slug, giftOption, getCurrentUser(), progressDialogCurrent);
} else {
showDialog(new PremiumPreviewBottomSheet(ChatActivity.this, currentAccount, getCurrentUser(), new GiftPremiumBottomSheet.GiftTier(giftOption), themeDelegate)
.setAnimateConfetti(animateConfetti)
.setOutboundGift(cell.getMessageObject().isOut()));
}
}
@Override
public void didOpenPremiumGiftChannel(ChatActionCell cell, String slug, boolean animateConfetti) {
initGiftProgressDialog(cell);
GiftInfoBottomSheet.show(getBaseFragment(), slug, progressDialogCurrent);
}
private void initGiftProgressDialog(ChatActionCell cell) {
if (progressDialogCurrent != null) {
progressDialogCurrent.cancel(true);
}
@ -29270,7 +29224,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
};
GiftInfoBottomSheet.show(getBaseFragment(), slug, progressDialogCurrent);
}
@Override
@ -29320,7 +29273,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
if (cell.hasButton()) {
ThemePreviewActivity.showFor(ChatActivity.this, message);
} else {
} else if (currentChat == null || ChatObject.canChangeChatInfo(currentChat)) {
showChatThemeBottomSheet();
}
return;
@ -30263,6 +30216,26 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
public void notifyItemRemoved(int position, boolean thanos) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("notify item removed " + position + (thanos ? " with thanos effect" : ""));
}
if (!fragmentBeginToShow) {
chatListView.setItemAnimator(null);
} else if (chatListView.getItemAnimator() != chatListItemAnimator) {
chatListView.setItemAnimator(chatListItemAnimator);
}
if (thanos && chatListItemAnimator != null && chatListView.getItemAnimator() == chatListItemAnimator) {
chatListItemAnimator.prepareThanos(chatListView.findViewHolderForAdapterPosition(position));
}
updateRowsInternal();
try {
super.notifyItemRemoved(position);
} catch (Exception e) {
FileLog.e(e);
}
}
@Override
public void notifyItemRangeRemoved(int positionStart, int itemCount) {
if (BuildVars.LOGS_ENABLED) {
@ -30555,7 +30528,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
arrayList = new ArrayList<>();
arrayList.add(messageObject);
}
showDialog(new ShareAlert(getContext(), ChatActivity.this, arrayList, null, null, ChatObject.isChannel(currentChat), null, null, false, false, false, themeDelegate) {
final boolean includeStory = getMessagesController().storiesEnabled() && StoryEntry.canRepostMessage(messageObject);
showDialog(new ShareAlert(getContext(), ChatActivity.this, arrayList, null, null, ChatObject.isChannel(currentChat), null, null, false, false, includeStory, themeDelegate) {
{ includeStoryFromMessage = includeStory; }
@Override
public void dismissInternal() {
super.dismissInternal();
@ -30565,6 +30540,50 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
@Override
protected void onShareStory(View cell) {
StoryRecorder.SourceView sourceView = null;
if (cell instanceof ShareDialogCell) {
sourceView = StoryRecorder.SourceView.fromShareCell((ShareDialogCell) cell);
}
final ArrayList<MessageObject> messageObjects = new ArrayList<>();
MessageObject.GroupedMessages groupedMessages = messageObject.getGroupId() != 0 ? groupedMessagesMap.get(messageObject.getGroupId()) : null;
if (groupedMessages != null) {
messageObjects.addAll(groupedMessages.messages);
} else {
messageObjects.add(messageObject);
}
StoryRecorder editor = StoryRecorder.getInstance(getParentActivity(), currentAccount);
editor.setOnPrepareCloseListener((t, close, sent, did) -> {
if (sent) {
AndroidUtilities.runOnUIThread(() -> {
String chatTitle = "";
if (did < 0) {
TLRPC.Chat chat = getMessagesController().getChat(-did);
if (chat != null) {
chatTitle = chat.title;
}
}
BulletinFactory.of(ChatActivity.this).createSimpleBulletin(R.raw.contact_check, AndroidUtilities.replaceTags(
TextUtils.isEmpty(chatTitle) ?
LocaleController.getString(R.string.RepostedToProfile) :
LocaleController.formatString(R.string.RepostedToChannelProfile, chatTitle)
)).show();
});
dismiss();
editor.replaceSourceView(null);
} else {
StoryRecorder.SourceView sourceView2 = null;
if (cell instanceof ShareDialogCell && cell.isAttachedToWindow()) {
sourceView2 = StoryRecorder.SourceView.fromShareCell((ShareDialogCell) cell);
}
editor.replaceSourceView(sourceView2);
}
AndroidUtilities.runOnUIThread(close);
});
editor.openRepost(sourceView, StoryEntry.repostMessage(messageObjects));
}
@Override
protected void onSend(LongSparseArray<TLRPC.Dialog> dids, int count, TLRPC.TL_forumTopic topic) {
createUndoView();
@ -30584,8 +30603,30 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
@Override
public boolean needPlayMessage(MessageObject messageObject, boolean muted) {
if (messageObject.isVoice() || messageObject.isRoundVideo()) {
public boolean needPlayMessage(ChatMessageCell cell, MessageObject messageObject, boolean muted) {
if (messageObject.isVoiceOnce()) {
if (secretVoicePlayer != null && secretVoicePlayer.isShown()) return false;
try {
AudioManager audioManager = (AudioManager) ApplicationLoader.applicationContext.getSystemService(Context.AUDIO_SERVICE);
int stream = AudioManager.STREAM_MUSIC;
int volume = audioManager.getStreamVolume(stream);
if (volume == 0) {
audioManager.adjustStreamVolume(stream, volume, AudioManager.FLAG_SHOW_UI);
if (!messageObject.isOutOwner()) {
BulletinFactory.of(ChatActivity.this).createImageBulletin(R.drawable.tooltip_sound, LocaleController.getString(R.string.VoiceOnceTurnOnSound)).show(true);
return false;
}
}
} catch (Exception ignore) {}
secretVoicePlayer = new SecretVoicePlayer(getContext());
secretVoicePlayer.setCell(
cell,
!messageObject.isOutOwner() ? sendSecretMessageRead(messageObject, true) : null,
!messageObject.isOutOwner() ? sendSecretMediaDelete(messageObject) : null
);
showDialog(secretVoicePlayer);
return false;
} else if (messageObject.isVoice() || messageObject.isRoundVideo()) {
boolean result = MediaController.getInstance().playMessage(messageObject, muted);
MediaController.getInstance().setVoiceMessagesPlaylist(result ? createVoiceMessagesPlaylist(messageObject, false) : null, false);
return result;
@ -31286,7 +31327,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public boolean didPressAnimatedEmoji(ChatMessageCell cell, AnimatedEmojiSpan span) {
if (getMessagesController().premiumLocked || span == null || span.standard) {
if (getMessagesController().premiumFeaturesBlocked() || span == null || span.standard) {
return false;
}
long documentId = span.getDocumentId();
@ -31350,6 +31391,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (uri == null) {
return;
}
if (!safe && Browser.isTelegraphUrl(url, false)) {
safe = true;
}
if (progressDialogCurrent != null) {
progressDialogCurrent.cancel(true);
}
@ -31842,14 +31886,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public void didPressGiveawayChatButton(ChatMessageCell cell, int pressedPos) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) cell.getMessageObject().messageOwner.media;
long channelId = giveaway.channels.get(pressedPos);
if (dialog_id != -channelId) {
presentFragment(ChatActivity.of(-channelId));
} else {
ViewGroup v = getChatListView();
AndroidUtilities.shakeViewSpring(v, 5);
BotWebViewVibrationEffect.APP_ERROR.vibrate();
if (cell.getMessageObject().messageOwner.media instanceof TLRPC.TL_messageMediaGiveaway) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) cell.getMessageObject().messageOwner.media;
long channelId = giveaway.channels.get(pressedPos);
if (dialog_id != -channelId) {
presentFragment(ChatActivity.of(-channelId));
} else {
ViewGroup v = getChatListView();
AndroidUtilities.shakeViewSpring(v, 5);
BotWebViewVibrationEffect.APP_ERROR.vibrate();
}
}
if (cell.getMessageObject().messageOwner.media instanceof TLRPC.TL_messageMediaGiveawayResults) {
TLRPC.TL_messageMediaGiveawayResults giveaway = (TLRPC.TL_messageMediaGiveawayResults) cell.getMessageObject().messageOwner.media;
long id = giveaway.winners.get(pressedPos);
presentFragment(ProfileActivity.of(id));
}
}
@ -32366,7 +32417,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{msgOutDrawable, msgOutMediaDrawable}, null, Theme.key_chat_outBubble));
if (!themeDelegate.isThemeChangeAvailable()) {
if (!themeDelegate.isThemeChangeAvailable(false)) {
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{msgOutDrawable, msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient1));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{msgOutDrawable, msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient2));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{msgOutDrawable, msgOutMediaDrawable}, null, Theme.key_chat_outBubbleGradient3));
@ -32540,7 +32591,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_psaHelpDrawable[0]}, null, Theme.key_chat_inViews));
themeDescriptions.add(new ThemeDescription(chatListView, 0, new Class[]{ChatMessageCell.class}, null, new Drawable[]{Theme.chat_psaHelpDrawable[1]}, null, Theme.key_chat_outViews));
if (!themeDelegate.isThemeChangeAvailable()) {
if (!themeDelegate.isThemeChangeAvailable(false)) {
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, Theme.avatarDrawables, null, Theme.key_avatar_text));
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, Theme.dialogs_countPaint, null, null, Theme.key_chats_unreadCounter));
themeDescriptions.add(new ThemeDescription(messagesSearchListView, 0, new Class[]{DialogCell.class}, null, new Paint[]{Theme.dialogs_namePaint[0], Theme.dialogs_namePaint[1], Theme.dialogs_searchNamePaint}, null, null, Theme.key_chats_name));
@ -33030,6 +33081,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
private void showChatThemeBottomSheet() {
if (currentChat != null) {
presentFragment(new ChannelColorActivity(getDialogId()).setOnApplied(ChatActivity.this));
return;
}
chatThemeBottomSheet = new ChatThemeBottomSheet(ChatActivity.this, themeDelegate);
chatListView.setOnInterceptTouchListener(event -> true);
setChildrenEnabled(contentView, false);
@ -33059,9 +33114,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (userInfo != null) {
emoticon = userInfo.theme_emoticon;
}
if (emoticon == null && chatInfo != null) {
emoticon = chatInfo.theme_emoticon;
}
// if (emoticon == null && chatInfo != null) {
// emoticon = chatInfo.theme_emoticon;
// }
setChatThemeEmoticon(emoticon);
});
}
@ -33077,13 +33132,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
themeDelegate.setCurrentTheme(result, themeDelegate.wallpaper,openAnimationStartTime != 0, null);
});
}
TLRPC.WallPaper wallPaper = null;
if (dialog_id >= 0) {
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialog_id);
if (userFull != null) {
wallPaper = userFull.wallpaper;
}
}
TLRPC.WallPaper wallPaper = chatThemeController.getDialogWallpaper(dialog_id);
themeDelegate.setCurrentTheme(themeDelegate.chatTheme, wallPaper, openAnimationStartTime != 0, null);
}
@ -33143,7 +33192,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
ThemeDelegate() {
isDark = Theme.getActiveTheme().isDark();
boolean setup = false;
if (isThemeChangeAvailable()) {
if (isThemeChangeAvailable(false)) {
chatTheme = ChatThemeController.getInstance(currentAccount).getDialogTheme(dialog_id);
wallpaper = ChatThemeController.getInstance(currentAccount).getDialogWallpaper(dialog_id);
if (chatTheme != null || wallpaper != null) {
@ -33257,8 +33306,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
return chatTheme != null || backgroundDrawable != null ? currentPaints.get(paintKey) : null;
}
public boolean isThemeChangeAvailable() {
return currentChat == null && currentEncryptedChat == null && !currentUser.bot && dialog_id >= 0;
public boolean isThemeChangeAvailable(boolean canEdit) {
return currentEncryptedChat == null && (
(!canEdit /*|| currentChat != null && ChatObject.isChannelAndNotMegaGroup(currentChat) && ChatObject.canChangeChatInfo(currentChat)*/) ||
currentChat == null && currentUser != null && !currentUser.bot
);
}
public EmojiThemes getCurrentTheme() {
@ -33287,7 +33339,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
String newEmoticon = chatTheme != null ? chatTheme.getEmoticon() : null;
String oldEmoticon = this.chatTheme != null ? this.chatTheme.getEmoticon() : null;
TLRPC.WallPaper oldWallpaper = this.wallpaper;
if (!force && (!isThemeChangeAvailable() || (TextUtils.equals(oldEmoticon, newEmoticon) && this.isDark == newIsDark && ChatThemeController.equals(newWallpaper, oldWallpaper)))) {
if (!force && (!isThemeChangeAvailable(false) || (TextUtils.equals(oldEmoticon, newEmoticon) && this.isDark == newIsDark && ChatThemeController.equals(newWallpaper, oldWallpaper)))) {
return;
}
@ -33323,6 +33375,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
animationSettings.applyTheme = false;
if (dialog_id < 0)
animationSettings.applyTrulyTheme = false;
animationSettings.afterStartDescriptionsAddedRunnable = () -> {
setupChatTheme(chatTheme, newWallpaper, animated, true);
initServiceMessageColors(backgroundDrawable);
@ -33422,7 +33476,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
currentColors = chatTheme.createColors(currentAccount, isDark ? 1 : 0);
}
if (wallPaper != null) {
if (!TextUtils.isEmpty(ChatThemeController.getWallpaperEmoticon(wallpaper))) {
backgroundDrawable = PreviewView.getBackgroundDrawable(backgroundDrawable, currentAccount, wallpaper, isDark);
} else if (wallPaper != null) {
backgroundDrawable = ChatBackgroundDrawable.getOrCreate(backgroundDrawable, wallPaper, isDark);
} else {
backgroundDrawable = getBackgroundDrawableFromTheme(chatTheme, prevPhase);
@ -33464,7 +33520,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
patternAlphaAnimator.start();
}
if (chatTheme == null) {
if (chatTheme == null && dialog_id >= 0) {
Theme.ThemeInfo activeTheme;
if (Theme.getActiveTheme().isDark() == isDark) {
activeTheme = Theme.getActiveTheme();
@ -34023,4 +34079,28 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
}
public boolean supportsThanosEffect() {
return ThanosEffect.supports() && LiteMode.isEnabled(LiteMode.FLAG_CHAT_THANOS);
}
public ThanosEffect getChatThanosEffect() {
if (!LiteMode.isEnabled(LiteMode.FLAG_CHAT_THANOS) || !ThanosEffect.supports()) {
return null;
}
if (chatListThanosEffect == null) {
if (getContext() == null || !ThanosEffect.supports() || chatListView == null || contentView == null) {
return null;
}
chatListThanosEffect = new ThanosEffect(getContext(), () -> {
ThanosEffect thisThanosEffect = chatListThanosEffect;
if (thisThanosEffect != null) {
chatListThanosEffect = null;
contentView.removeView(thisThanosEffect);
}
});
contentView.addView(chatListThanosEffect, 1 + contentView.indexOfChild(chatListView), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
return chatListThanosEffect;
}
}

View file

@ -154,7 +154,7 @@ public class ChatBackgroundDrawable extends Drawable {
}
}
} else {
if (wallPaper.settings.intensity < 0) {
if (wallPaper.settings == null || wallPaper.settings.intensity < 0) {
thumb = bitmapDrawableOf(new ColorDrawable(Color.BLACK));
} else {
if (wallPaper.settings.second_background_color == 0) { //one color

View file

@ -45,6 +45,7 @@ import android.widget.ScrollView;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChannelBoostsController;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.Emoji;
@ -888,11 +889,15 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
if (ChatObject.isChannelAndNotMegaGroup(currentChat) && ChatObject.canChangeChatInfo(currentChat)) {
colorCell = new PeerColorActivity.ChangeNameColorCell(currentAccount, true, context, getResourceProvider());
colorCell = new PeerColorActivity.ChangeNameColorCell(currentAccount, -currentChat.id, context, getResourceProvider());
colorCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
typeEditContainer.addView(colorCell, LayoutHelper.createLinear(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
colorCell.setOnClickListener(v -> {
presentFragment(new PeerColorActivity(-currentChat.id).setOnApplied(this));
presentFragment(new ChannelColorActivity(-currentChat.id).setOnApplied(this));
MessagesController.getInstance(currentAccount).getMainSettings().edit().putInt("boostingappearance",
MessagesController.getInstance(currentAccount).getMainSettings().getInt("boostingappearance", 0) + 1
).apply();
});
}
@ -1925,7 +1930,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
}
private void updateColorCell() {
public void updateColorCell() {
if (colorCell != null) {
colorCell.set(currentChat, (historyCell != null && historyCell.getVisibility() == View.VISIBLE) || (signCell != null && signCell.getVisibility() == View.VISIBLE) || (forumsCell != null && forumsCell.getVisibility() == View.VISIBLE));
}
@ -2034,11 +2039,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
} else {
finalString = LocaleController.getString("ReactionsAll", R.string.ReactionsAll);
}
if (isChannelAndNotMegaGroup) {
reactionsCell.setTextAndValueAndIcon(TextCell.applyNewSpan(LocaleController.getString("Reactions", R.string.Reactions)), finalString, animated, R.drawable.msg_reactions2, true);
} else {
reactionsCell.setTextAndValueAndIcon(LocaleController.getString("Reactions", R.string.Reactions), finalString, animated, R.drawable.msg_reactions2, true);
}
reactionsCell.setTextAndValueAndIcon(LocaleController.getString("Reactions", R.string.Reactions), finalString, animated, R.drawable.msg_reactions2, true);
}
@Override

View file

@ -263,6 +263,9 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
if (id == -1) {
finishFragment();
} else if (id == done_button) {
if (doneButtonDrawable != null && doneButtonDrawable.getProgress() > 0) {
return;
}
processDone();
}
}
@ -683,10 +686,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
private void processDone() {
AndroidUtilities.runOnUIThread(enableDoneLoading, 200);
if (currentChat.noforwards != isSaveRestricted) {
getMessagesController().toggleChatNoForwards(chatId, currentChat.noforwards = isSaveRestricted);
}
if (trySetUsername() && tryUpdateJoinSettings()) {
if (trySetUsername() && trySetRestrict() && tryUpdateJoinSettings()) {
finishFragment();
}
}
@ -1117,6 +1117,26 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
}
}
private boolean trySetRestrict() {
if (currentChat.noforwards != isSaveRestricted) {
if (!ChatObject.isChannel(currentChat)) {
updateDoneProgress(true);
getMessagesController().convertToMegaGroup(getParentActivity(), chatId, this, param -> {
if (param != 0) {
chatId = param;
currentChat = getMessagesController().getChat(param);
getMessagesController().toggleChatNoForwards(chatId, currentChat.noforwards = isSaveRestricted);
processDone();
}
});
return false;
} else {
getMessagesController().toggleChatNoForwards(chatId, currentChat.noforwards = isSaveRestricted);
}
}
return true;
}
private boolean trySetUsername() {
if (getParentActivity() == null) {
return false;
@ -1165,7 +1185,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
private boolean deactivatingLinks = false;
private boolean tryDeactivateAllLinks() {
if (!isPrivate || currentChat.usernames == null) {
if (!isPrivate || currentChat.usernames == null || currentChat.usernames.isEmpty()) {
return true;
}
if (deactivatingLinks) {
@ -1182,7 +1202,7 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
if (hasActive) {
TLRPC.TL_channels_deactivateAllUsernames req = new TLRPC.TL_channels_deactivateAllUsernames();
req.channel = MessagesController.getInputChannel(currentChat);
getConnectionsManager().sendRequest(req, (res, err) -> {
getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.TL_boolTrue) {
for (int i = 0; i < currentChat.usernames.size(); ++i) {
final TLRPC.TL_username username = currentChat.usernames.get(i);
@ -1193,7 +1213,9 @@ public class ChatEditTypeActivity extends BaseFragment implements NotificationCe
}
deactivatingLinks = false;
AndroidUtilities.runOnUIThread(this::processDone);
});
}));
} else {
deactivatingLinks = false;
}
return !hasActive;
}

View file

@ -5768,28 +5768,32 @@ public class AlertsCreator {
}
}
boolean isGiveawayAndOwner = false;
boolean isActiveGiveawayAndOwner = false;
String giveawayEndDate = null;
if (selectedMessage != null) {
isGiveawayAndOwner = selectedMessage.isGiveaway() && !selectedMessage.isForwarded();
if (isGiveawayAndOwner) {
isActiveGiveawayAndOwner = selectedMessage.isGiveaway() && !selectedMessage.isForwarded();
if (isActiveGiveawayAndOwner) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) selectedMessage.messageOwner.media;
giveawayEndDate = LocaleController.getInstance().formatterGiveawayMonthDayYear.format(new Date(giveaway.until_date * 1000L));
long untilDate = giveaway.until_date * 1000L;
giveawayEndDate = LocaleController.getInstance().formatterGiveawayMonthDayYear.format(new Date(untilDate));
isActiveGiveawayAndOwner = System.currentTimeMillis() < untilDate;
}
} else if (count == 1) {
for (int a = 1; a >= 0; a--) {
for (int b = 0; b < selectedMessages[a].size(); b++) {
MessageObject msg = selectedMessages[a].valueAt(b);
isGiveawayAndOwner = msg.isGiveaway() && !msg.isForwarded();
if (isGiveawayAndOwner) {
isActiveGiveawayAndOwner = msg.isGiveaway() && !msg.isForwarded();
if (isActiveGiveawayAndOwner) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) msg.messageOwner.media;
giveawayEndDate = LocaleController.getInstance().formatterGiveawayMonthDayYear.format(new Date(giveaway.until_date * 1000L));
long untilDate = giveaway.until_date * 1000L;
giveawayEndDate = LocaleController.getInstance().formatterGiveawayMonthDayYear.format(new Date(untilDate));
isActiveGiveawayAndOwner = System.currentTimeMillis() < untilDate;
}
}
}
}
if (isGiveawayAndOwner) {
if (isActiveGiveawayAndOwner) {
builder.setTitle(LocaleController.getString("BoostingGiveawayDeleteMsgTitle", R.string.BoostingGiveawayDeleteMsgTitle));
builder.setMessage(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingGiveawayDeleteMsgText", R.string.BoostingGiveawayDeleteMsgText, giveawayEndDate)));
builder.setNeutralButton(LocaleController.getString("Delete", R.string.Delete), deleteAction);

View file

@ -71,6 +71,7 @@ public class AnimatedEmojiDrawable extends Drawable {
public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW = 14;
public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 = 15;
public static final int CACHE_TYPE_ALERT_PREVIEW_STATIC_WITH_THUMB = 16;
public static final int CACHE_TYPE_EMOJI_CALL = 17;
public int rawDrawIndex;
@ -463,7 +464,7 @@ public class AnimatedEmojiDrawable extends Drawable {
sizedp = (int) ((Math.abs(Theme.chat_msgTextPaintEmoji[2].ascent()) + Math.abs(Theme.chat_msgTextPaintEmoji[2].descent())) * 1.15f / AndroidUtilities.density);
} else if (this.cacheType == STANDARD_LOTTIE_FRAME) {
sizedp = (int) ((Math.abs(Theme.chat_msgTextPaintEmoji[0].ascent()) + Math.abs(Theme.chat_msgTextPaintEmoji[0].descent())) * 1.15f / AndroidUtilities.density);
} else if (cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2) {
} else if (cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 || cacheType == CACHE_TYPE_EMOJI_CALL) {
sizedp = 100;
} else {
sizedp = 34;
@ -528,10 +529,10 @@ public class AnimatedEmojiDrawable extends Drawable {
if (cacheType == CACHE_TYPE_RENDERING_VIDEO) {
filter += "_d_nostream";
}
if (cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW && cacheType != STANDARD_LOTTIE_FRAME && (cacheType != CACHE_TYPE_MESSAGES_LARGE || SharedConfig.getDevicePerformanceClass() < SharedConfig.PERFORMANCE_CLASS_HIGH) && cacheType != CACHE_TYPE_RENDERING_VIDEO) {
if (cacheType != CACHE_TYPE_EMOJI_CALL && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW && cacheType != STANDARD_LOTTIE_FRAME && (cacheType != CACHE_TYPE_MESSAGES_LARGE || SharedConfig.getDevicePerformanceClass() < SharedConfig.PERFORMANCE_CLASS_HIGH) && cacheType != CACHE_TYPE_RENDERING_VIDEO) {
filter += "_pcache";
}
if (cacheType != CACHE_TYPE_MESSAGES && cacheType != CACHE_TYPE_MESSAGES_LARGE && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2) {
if (cacheType != CACHE_TYPE_EMOJI_CALL && cacheType != CACHE_TYPE_MESSAGES && cacheType != CACHE_TYPE_MESSAGES_LARGE && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2) {
filter += "_compress";
}
if (cacheType == STANDARD_LOTTIE_FRAME) {
@ -585,7 +586,11 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.setImage(ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, thumbLocation, null, thumbDrawable, document.size, null, document, 1);
}
} else {
imageReceiver.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
ImageLocation thumbLocation = null;
if (cacheType == CACHE_TYPE_EMOJI_CALL) {
thumbLocation = ImageLocation.getForDocument(thumb, document);
}
imageReceiver.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, thumbLocation, null, thumbDrawable, document.size, null, document, 1);
}
}
@ -622,6 +627,8 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.setAutoRepeatCount(2);
} else if (cacheType == CACHE_TYPE_FORUM_TOPIC_LARGE || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) {
imageReceiver.setAutoRepeatCount(1);
} else if (cacheType == CACHE_TYPE_EMOJI_CALL){
imageReceiver.setAutoRepeatCount(0);
}
}

View file

@ -30,6 +30,13 @@ public class BitmapShaderTools {
updateBounds();
}
public BitmapShaderTools(int width, int height) {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint.setShader(shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
updateBounds();
}
public Bitmap getBitmap() {
return bitmap;
}
@ -64,4 +71,12 @@ public class BitmapShaderTools {
AndroidUtilities.rectTmp.set(left, top, right, bottom);
setBounds(AndroidUtilities.rectTmp);
}
public void setMatrix(float offsetX, float offsetY, float scale, float degrees) {
matrix.reset();
matrix.postRotate(degrees, bitmap.getWidth() / 2f, bitmap.getHeight() / 2f);
matrix.postScale(scale, scale);
matrix.postTranslate(offsetX, offsetY);
shader.setLocalMatrix(matrix);
}
}

View file

@ -40,26 +40,26 @@ public class BlobDrawable {
private Path path = new Path();
public Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float[] radius;
private float[] angle;
private float[] radiusNext;
private float[] angleNext;
private float[] progress;
private float[] speed;
protected float[] radius;
protected float[] angle;
protected float[] radiusNext;
protected float[] angleNext;
protected float[] progress;
protected float[] speed;
private float[] pointStart = new float[4];
private float[] pointEnd = new float[4];
final Random random = new Random();
protected final Random random = new Random();
private final float N;
protected final float N;
private final float L;
public float cubicBezierK = 1f;
private final Matrix m = new Matrix();
private final int liteFlag;
protected final int liteFlag;
public BlobDrawable(int n) {
this(n, LiteMode.FLAG_CALLS_ANIMATIONS);
@ -85,7 +85,7 @@ public class BlobDrawable {
this.liteFlag = liteFlag;
}
private void generateBlob(float[] radius, float[] angle, int i) {
protected void generateBlob(float[] radius, float[] angle, int i) {
float angleDif = 360f / N * 0.05f;
float radDif = maxRadius - minRadius;
radius[i] = minRadius + Math.abs(((random.nextInt() % 100f) / 100f)) * radDif;

View file

@ -555,7 +555,10 @@ public class BlurringShader {
private int i = 0;
public void setFallbackBlur(Bitmap bitmap, int orientation) {
fallbackBitmap = thumbBlurer.getBitmap(bitmap, "" + i++, orientation, 0);
setFallbackBlur(bitmap, orientation, false);
}
public void setFallbackBlur(Bitmap bitmap, int orientation, boolean recycleAfter) {
fallbackBitmap = thumbBlurer.getBitmap(bitmap, "" + i++, orientation, 0, recycleAfter);
}
public void resetBitmap() {
@ -603,7 +606,7 @@ public class BlurringShader {
thumbBitmap = null;
}
public Bitmap getBitmap(Bitmap bitmap, String key, int orientation, int invert) {
public Bitmap getBitmap(Bitmap bitmap, String key, int orientation, int invert, boolean recycleAfter) {
if (bitmap == null) {
return null;
}
@ -666,6 +669,10 @@ public class BlurringShader {
} else {
resultBitmap.recycle();
}
if (recycleAfter) {
bitmap.recycle();
}
});
});
return thumbBitmap;
@ -675,14 +682,14 @@ public class BlurringShader {
if (imageReceiver == null) {
return null;
}
return getBitmap(imageReceiver.getBitmap(), imageReceiver.getImageKey(), imageReceiver.getOrientation(), imageReceiver.getInvert());
return getBitmap(imageReceiver.getBitmap(), imageReceiver.getImageKey(), imageReceiver.getOrientation(), imageReceiver.getInvert(), false);
}
public Bitmap getBitmap(ImageReceiver.BitmapHolder bitmapHolder) {
if (bitmapHolder == null) {
return null;
}
return getBitmap(bitmapHolder.bitmap, bitmapHolder.getKey(), bitmapHolder.orientation, 0);
return getBitmap(bitmapHolder.bitmap, bitmapHolder.getKey(), bitmapHolder.orientation, 0, false);
}
}
@ -698,6 +705,7 @@ public class BlurringShader {
public static final int BLUR_TYPE_EMOJI_VIEW = 7;
public static final int BLUR_TYPE_REPLY_BACKGROUND = 8;
public static final int BLUR_TYPE_REPLY_TEXT_XFER = 9;
public static final int BLUR_TYPE_ACTION_BACKGROUND = 10;
private final BlurManager manager;
private final View view;
@ -758,6 +766,10 @@ public class BlurringShader {
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.4f);
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.45f);
// AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, 1.4f);
} else if (type == BLUR_TYPE_ACTION_BACKGROUND) {
colorMatrix.setSaturation(1.6f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, wasDark ? .97f : .92f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, wasDark ? +.12f : -.06f);
}
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
oldPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
@ -829,6 +841,22 @@ public class BlurringShader {
updateBounds();
}
private boolean wasDark = false;
public StoryBlurDrawer adapt(boolean isDark) {
if (wasDark != isDark) {
wasDark = isDark;
if (type == BLUR_TYPE_ACTION_BACKGROUND) {
final ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(1.6f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, wasDark ? .97f : .92f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, wasDark ? +.12f : -.06f);
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
oldPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
}
}
return this;
}
@Nullable
public Paint getPaint(float alpha) {
return getPaint(alpha, 0, 0);
@ -913,6 +941,7 @@ public class BlurringShader {
View view = this.view;
do {
matrix.preScale(1f / view.getScaleX(), 1f / view.getScaleY(), view.getPivotX(), view.getPivotY());
matrix.preRotate(-view.getRotation(), view.getPivotX(), view.getPivotY());
matrix.preTranslate(-view.getX(), -view.getY());
if (view.getParent() instanceof View) {
view = (View) view.getParent();
@ -930,6 +959,7 @@ public class BlurringShader {
}
matrix.postTranslate(child.getX(), child.getY());
matrix.postScale(1f / child.getScaleX(), 1f / child.getScaleY(), child.getPivotX(), child.getPivotY());
matrix.postRotate(child.getRotation(), child.getPivotX(), child.getPivotY());
index++;
}
}

View file

@ -1200,7 +1200,11 @@ public class BotWebViewSheet extends Dialog implements NotificationCenter.Notifi
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didSetNewTheme);
swipeContainer.stickTo(swipeContainer.getHeight() + frameLayout.measureKeyboardHeight(), ()->{
super.dismiss();
try {
super.dismiss();
} catch (Exception e) {
FileLog.e(e);
}
if (callback != null) {
callback.run();
}

View file

@ -251,6 +251,9 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
headerShadowDrawable.setBounds(backgroundPaddingLeft, actionBar.getBottom(), parentView.getMeasuredWidth() - backgroundPaddingLeft, actionBar.getBottom() + headerShadowDrawable.getIntrinsicHeight());
headerShadowDrawable.setAlpha((int) (255 * actionBar.getAlpha() * shadowAlpha));
headerShadowDrawable.draw(canvas);
if (headerShadowDrawable.getAlpha() < 255) {
parentView.invalidate();
}
}
wasDrawn = true;
}

View file

@ -674,7 +674,11 @@ public class Bulletin {
}
protected void setBackground(int color) {
background = Theme.createRoundRectDrawable(AndroidUtilities.dp(10), color);
setBackground(color, 10);
}
public void setBackground(int color, int rounding) {
background = Theme.createRoundRectDrawable(AndroidUtilities.dp(rounding), color);
}
public final static FloatPropertyCompat<Layout> IN_OUT_OFFSET_Y = new FloatPropertyCompat<Layout>("offsetY") {
@ -1085,9 +1089,17 @@ public class Bulletin {
this.resourcesProvider = resourcesProvider;
}
private boolean wrapWidth;
public void setWrapWidth() {
wrapWidth = true;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
childrenMeasuredWidth = 0;
if (wrapWidth) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (button != null && MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.AT_MOST) {
setMeasuredDimension(childrenMeasuredWidth + button.getMeasuredWidth(), getMeasuredHeight());

View file

@ -41,6 +41,7 @@ import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.HintView2;
import java.util.ArrayList;
import java.util.List;
@ -189,6 +190,20 @@ public final class BulletinFactory {
return create(layout, text.length() < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG);
}
public Bulletin createImageBulletin(int iconRawId, CharSequence title) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
layout.setBackground(Theme.getColor(Theme.key_undo_background, resourcesProvider), 12);
layout.imageView.setImageResource(iconRawId);
layout.textView.setText(title);
layout.textView.setSingleLine(false);
layout.textView.setLines(2);
layout.textView.setMaxLines(4);
layout.textView.setMaxWidth(HintView2.cutInFancyHalf(layout.textView.getText(), layout.textView.getPaint()));
((ViewGroup.MarginLayoutParams) layout.textView.getLayoutParams()).rightMargin = AndroidUtilities.dp(12);
layout.setWrapWidth();
return create(layout, Bulletin.DURATION_PROLONG);
}
public Bulletin createSimpleLargeBulletin(int iconRawId, CharSequence title, CharSequence subtitle) {
final Bulletin.TwoLineLayout layout = new Bulletin.TwoLineLayout(getContext(), resourcesProvider);
layout.imageView.setImageResource(iconRawId);

View file

@ -303,7 +303,7 @@ public class CaptionPhotoViewer extends CaptionContainerView {
@Override
public void updateColors(Theme.ResourcesProvider resourcesProvider) {
super.updateColors(resourcesProvider);
timerDrawable.updateColors(0xffffffff, Theme.getColor(Theme.key_chat_editMediaButton, resourcesProvider));
timerDrawable.updateColors(0xffffffff, Theme.getColor(Theme.key_chat_editMediaButton, resourcesProvider), 0xffffffff);
}
@Override

View file

@ -59,9 +59,7 @@ import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.DynamicDrawableSpan;
import android.text.style.ImageSpan;
import android.util.Log;
import android.util.Property;
import android.util.TypedValue;
import android.view.ActionMode;
@ -115,7 +113,6 @@ import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BotWebViewVibrationEffect;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.CodeHighlighting;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
@ -126,7 +123,6 @@ import org.telegram.messenger.MediaController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.NotificationsController;
import org.telegram.messenger.R;
@ -137,7 +133,6 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.VideoEditedInfo;
import org.telegram.messenger.XiaomiUtilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.messenger.camera.CameraController;
import org.telegram.tgnet.ConnectionsManager;
@ -161,11 +156,13 @@ import org.telegram.ui.ContentPreviewViewer;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.GroupStickersActivity;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.MultiContactsSelectorBottomSheet;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.ProfileActivity;
import org.telegram.ui.StickersActivity;
import org.telegram.ui.TopicsFragment;
import org.telegram.ui.Stories.recorder.CaptionContainerView;
import org.telegram.ui.Stories.recorder.HintView2;
import java.io.File;
import java.io.FileOutputStream;
@ -199,6 +196,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private boolean sendButtonEnabled = true;
private TLRPC.UserFull userInfo;
public boolean voiceOnce;
public boolean onceVisible;
public void drawRecordedPannel(Canvas canvas) {
if (getAlpha() == 0 || recordedAudioPanel == null || recordedAudioPanel.getParent() == null || recordedAudioPanel.getVisibility() != View.VISIBLE) {
return;
@ -242,7 +242,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
void didPressAttachButton();
void needStartRecordVideo(int state, boolean notify, int scheduleDate);
void needStartRecordVideo(int state, boolean notify, int scheduleDate, int ttl);
void needChangeVideoPreviewState(int state, float seekProgress);
@ -323,6 +323,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
default void onKeyboardRequested() {
}
default boolean onceVoiceAvailable() {
return false;
}
}
public final static int RECORD_STATE_ENTER = 0;
@ -527,6 +531,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private AnimatorSet scheduledButtonAnimation;
@Nullable
private RecordCircle recordCircle;
private OnceButton onceButton;
private CloseProgressDrawable2 progressDrawable;
private Paint dotPaint;
private MediaActionDrawable playPauseDrawable;
@ -728,7 +733,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
@Override
public void run() {
if (delegate != null) {
delegate.needStartRecordVideo(0, true, 0);
delegate.needStartRecordVideo(0, true, 0, 0);
}
}
};
@ -855,6 +860,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
drawable.beginApplyLayerColors();
drawable.setLayerColor("Cup Red.**", dotColor);
drawable.setLayerColor("Box.**", dotColor);
drawable.setLayerColor("Line 1.**", background);
drawable.setLayerColor("Line 2.**", background);
drawable.setLayerColor("Line 3.**", background);
drawable.commitApplyLayerColors();
if (playPauseDrawable != null) {
playPauseDrawable.setColor(getThemedColor(Theme.key_chat_recordedVoicePlayPause));
@ -1009,9 +1017,147 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
};
public class OnceButton extends FrameLayout {
private HintView2 hintView;
private CaptionContainerView.PeriodDrawable periodDrawable;
private Paint lockBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public OnceButton(Context context) {
super(context);
periodDrawable = new CaptionContainerView.PeriodDrawable();
periodDrawable.setCallback(this);
periodDrawable.setValue(1, voiceOnce, false);
setWillNotDraw(false);
updateColors();
}
public void showHintView() {
hideHintView();
hintView = new HintView2(getContext(), HintView2.DIRECTION_RIGHT);
hintView.setJoint(1, 0);
hintView.setMultilineText(true);
hintView.setText(AndroidUtilities.replaceTags(LocaleController.getString(voiceOnce ? R.string.VoiceSetOnceHintEnabled : R.string.VoiceSetOnceHint)));
hintView.setMaxWidthPx(HintView2.cutInFancyHalf(hintView.getText(), hintView.getTextPaint()));
if (voiceOnce) {
hintView.setIcon(R.raw.fire_on);
} else {
MessagesController.getGlobalMainSettings().edit().putInt("voiceoncehint", MessagesController.getGlobalMainSettings().getInt("voiceoncehint", 0) + 1).apply();
}
addView(hintView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL, 0, 0, 54, 58));
final HintView2 thisHintView = hintView;
hintView.setOnHiddenListener(() -> {
removeView(thisHintView);
if (hintView == thisHintView) {
hintView = null;
}
});
hintView.show();
}
public void hideHintView() {
if (hintView != null) {
HintView2 oldHintView = hintView;
oldHintView.setOnHiddenListener(() -> removeView(oldHintView));
oldHintView.hide();
hintView = null;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(
widthMeasureSpec,
MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(194 + 48 + 12), MeasureSpec.EXACTLY)
);
}
private final RectF rectF = new RectF();
public final RectF onceRect = new RectF();
@Override
protected void onDraw(Canvas canvas) {
if (recordCircle == null) return;
int cx = getMeasuredWidth() - AndroidUtilities.dp2(26);
final float cy = AndroidUtilities.lerp(recordCircle.lockY + recordCircle.translationDy, getMeasuredHeight() - AndroidUtilities.dp(70 + 36), Math.max(recordCircle.exitTransition, Math.min(recordCircle.progressToSeekbarStep1, recordCircle.slideToCancelLockProgress)));
rectF.set(cx - AndroidUtilities.dpf2(18), cy, cx + AndroidUtilities.dpf2(18), cy + recordCircle.lockSize);
rectF.offset(0, getMeasuredHeight() - recordCircle.getMeasuredHeight());
onceVisible = delegate != null && delegate.onceVoiceAvailable() && !isInVideoMode;
if (onceVisible) {
final float onceOffset = AndroidUtilities.dpf2(AndroidUtilities.lerp(4, 12, recordCircle.moveProgress));
rectF.set(
rectF.left, rectF.top - AndroidUtilities.dpf2(36) - onceOffset, rectF.right, rectF.top - onceOffset
);
if (hintView != null) {
hintView.setJointPx(0, rectF.centerY());
hintView.invalidate();
}
onceRect.set(rectF);
canvas.save();
final float s = recordCircle.scale * (1f - recordCircle.exitTransition) * recordCircle.slideToCancelLockProgress * recordCircle.snapAnimationProgress;
canvas.scale(s, s, rectF.centerX(), rectF.centerY());
lockShadowDrawable.setBounds(
(int) (rectF.left - AndroidUtilities.dpf2(3)), (int) (rectF.top - AndroidUtilities.dpf2(3)),
(int) (rectF.right + AndroidUtilities.dpf2(3)), (int) (rectF.bottom + AndroidUtilities.dpf2(3))
);
lockShadowDrawable.draw(canvas);
canvas.drawRoundRect(rectF, AndroidUtilities.dpf2(18), AndroidUtilities.dpf2(18), lockBackgroundPaint);
periodDrawable.setBounds((int) rectF.left, (int) rectF.top, (int) rectF.right, (int) rectF.bottom);
periodDrawable.draw(canvas);
canvas.restore();
}
}
public void updateColors() {
periodDrawable.updateColors(
getThemedColor(Theme.key_chat_messagePanelVoiceLock),
getThemedColor(Theme.key_chat_messagePanelVoiceBackground),
0xFFFFFFFF
);
lockBackgroundPaint.setColor(getThemedColor(Theme.key_chat_messagePanelVoiceLockBackground));
}
private boolean pressed;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (onceVisible && (recordCircle != null && recordCircle.snapAnimationProgress > .1f)) {
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
return pressed = onceRect.contains(x, y);
} else if (pressed) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (onceRect.contains(x, y)) {
voiceOnce = !voiceOnce;
periodDrawable.setValue(1, voiceOnce, true);
if (voiceOnce) {
showHintView();
} else {
hideHintView();
}
invalidate();
}
}
return true;
}
}
return false;
}
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == periodDrawable || super.verifyDrawable(who);
}
}
public class RecordCircle extends View {
private float scale;
public float scale;
private float amplitude;
private float animateToAmplitude;
private float animateAmplitudeDiff;
@ -1023,7 +1169,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private boolean pressed;
private float transformToSeekbar;
private float exitTransition;
private float progressToSeekbarStep3;
public float progressToSeekbarStep3;
private float progressToSendButton;
public float iconScale;
@ -1057,8 +1203,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private int paintAlpha;
private float touchSlop;
private float slideToCancelProgress;
private float slideToCancelLockProgress;
public float slideToCancelProgress;
public float slideToCancelLockProgress;
private float progressToSeekbarStep1, progressToSeekbarStep2;
private int slideDelta;
private boolean canceledByGesture;
@ -1225,9 +1372,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (event.getAction() == MotionEvent.ACTION_UP) {
if (pauseRect.contains(x, y)) {
if (isInVideoMode()) {
delegate.needStartRecordVideo(3, true, 0);
delegate.needStartRecordVideo(3, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
MediaController.getInstance().stopRecording(2, true, 0);
MediaController.getInstance().stopRecording(2, true, 0, voiceOnce);
delegate.needStartRecordAudio(0);
}
if (slideText != null) {
@ -1270,6 +1417,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
slideDelta = (int) (-distance * (1f - slideToCancelProgress));
}
public float moveProgress;
public float lockY, lockSize;
public float translationDy;
@Override
protected void onDraw(Canvas canvas) {
if (skipDraw) {
@ -1364,6 +1515,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
circleAlpha = Math.max(0, 1f - (exitTransition - 0.6f) / 0.4f);
}
}
this.progressToSeekbarStep1 = progressToSeekbarStep1;
this.progressToSeekbarStep2 = progressToSeekbarStep2;
if (canceledByGesture && slideToCancelProgress > 0.7f) {
circleAlpha *= (1f - (slideToCancelProgress - 0.7f) / 0.3f);
@ -1396,7 +1549,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
replaceDrawable.setBounds(cx - replaceDrawable.getIntrinsicWidth() / 2, cy - replaceDrawable.getIntrinsicHeight() / 2, cx + replaceDrawable.getIntrinsicWidth() / 2, cy + replaceDrawable.getIntrinsicHeight() / 2);
}
float moveProgress = 1.0f - yAdd / AndroidUtilities.dp(57);
float moveProgress = this.moveProgress = 1.0f - yAdd / AndroidUtilities.dp(57);
float lockSize;
float lockY;
@ -1511,8 +1664,8 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
if (isSendButtonVisible()) {
lockSize = AndroidUtilities.dp(36);
lockY = AndroidUtilities.dp(60) + multilinTooltipOffset + AndroidUtilities.dpf2(30) * (1.0f - sc) - yAdd + AndroidUtilities.dpf2(14f) * moveProgress;
lockSize = this.lockSize = AndroidUtilities.dp(36);
lockY = this.lockY = AndroidUtilities.dp(60) + multilinTooltipOffset + AndroidUtilities.dpf2(30) * (1.0f - sc) - yAdd + AndroidUtilities.dpf2(14f) * moveProgress;
lockMiddleY = lockY + lockSize / 2f - AndroidUtilities.dpf2(8) + AndroidUtilities.dpf2(2);
lockTopY = lockY + lockSize / 2f - AndroidUtilities.dpf2(16) + AndroidUtilities.dpf2(2);
@ -1522,15 +1675,14 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
transformToPauseProgress = moveProgress;
} else {
lockSize = AndroidUtilities.dp(36) + (int) (AndroidUtilities.dp(14) * moveProgress);
lockY = AndroidUtilities.dp(60) + multilinTooltipOffset + (int) (AndroidUtilities.dp(30) * (1.0f - sc)) - (int) yAdd + (moveProgress) * idleProgress * -AndroidUtilities.dp(8);
lockSize = this.lockSize = AndroidUtilities.dp(36) + (int) (AndroidUtilities.dp(14) * moveProgress);
lockY = this.lockY = AndroidUtilities.dp(60) + multilinTooltipOffset + (int) (AndroidUtilities.dp(30) * (1.0f - sc)) - (int) yAdd + (moveProgress) * idleProgress * -AndroidUtilities.dp(8);
lockMiddleY = lockY + lockSize / 2f - AndroidUtilities.dpf2(8) + AndroidUtilities.dpf2(2) + AndroidUtilities.dpf2(2) * moveProgress;
lockTopY = lockY + lockSize / 2f - AndroidUtilities.dpf2(16) + AndroidUtilities.dpf2(2) + AndroidUtilities.dpf2(2) * moveProgress;
lockRotation = 9 * (1f - moveProgress);
snapAnimationProgress = 0;
}
if ((showTooltip && System.currentTimeMillis() - showTooltipStartTime > 200) || tooltipAlpha != 0f) {
if (moveProgress < 0.8f || isSendButtonVisible() || exitTransition != 0 || transformToSeekbar != 0) {
showTooltip = false;
@ -1623,10 +1775,15 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
float maxTranslationDy = AndroidUtilities.dpf2(72);
float dy = maxTranslationDy * translation - AndroidUtilities.dpf2(20) * (progressToSeekbarStep1) * (1f - translation) + maxTranslationDy * (1f - slideToCancelLockProgress);
float dy = (
maxTranslationDy * translation
- AndroidUtilities.dpf2(20) * (progressToSeekbarStep1) * (1f - translation)
+ maxTranslationDy * (1f - slideToCancelLockProgress)
);
if (dy > maxTranslationDy) {
dy = maxTranslationDy;
}
this.translationDy = dy;
canvas.translate(0, dy);
float s = scale * (1f - progressToSeekbarStep2) * (1f - exitProgress2) * slideToCancelLockProgress;
canvas.scale(s, s, cx, lockMiddleY);
@ -1689,6 +1846,14 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
drawingCircleRadius = radius;
}
@Override
public void invalidate() {
super.invalidate();
if (onceButton != null) {
onceButton.invalidate();
}
}
public void drawIcon(Canvas canvas, int cx, int cy, float alpha) {
Drawable drawable;
Drawable replaceDrawable = null;
@ -2228,12 +2393,12 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (!hasRecordVideo || calledRecordRunnable) {
startedDraggingX = -1;
if (hasRecordVideo && isInVideoMode()) {
delegate.needStartRecordVideo(1, true, 0);
delegate.needStartRecordVideo(1, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
if (recordingAudioVideo && isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider);
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate, false), () -> MediaController.getInstance().stopRecording(0, false, 0, false), resourcesProvider);
}
MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0);
MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0, voiceOnce);
delegate.needStartRecordAudio(0);
}
recordingAudioVideo = false;
@ -2267,10 +2432,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (recordCircle.slideToCancelProgress < 0.7f) {
if (hasRecordVideo && isInVideoMode()) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(2, true, 0);
delegate.needStartRecordVideo(2, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
delegate.needStartRecordAudio(0);
MediaController.getInstance().stopRecording(0, false, 0);
MediaController.getInstance().stopRecording(0, false, 0, voiceOnce);
}
recordingAudioVideo = false;
updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE);
@ -2293,10 +2458,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (alpha < 0.45) {
if (hasRecordVideo && isInVideoMode()) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(2, true, 0);
delegate.needStartRecordVideo(2, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
delegate.needStartRecordAudio(0);
MediaController.getInstance().stopRecording(0, false, 0);
MediaController.getInstance().stopRecording(0, false, 0, voiceOnce);
}
recordingAudioVideo = false;
updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE);
@ -2315,15 +2480,15 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
startedDraggingX = -1;
if (hasRecordVideo && isInVideoMode()) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(1, true, 0);
delegate.needStartRecordVideo(1, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else if (!sendVoiceEnabled) {
delegate.needShowMediaBanHint();
} else {
if (recordingAudioVideo && isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate), () -> MediaController.getInstance().stopRecording(0, false, 0), resourcesProvider);
AlertsCreator.createScheduleDatePickerDialog(parentActivity, parentFragment.getDialogId(), (notify, scheduleDate) -> MediaController.getInstance().stopRecording(1, notify, scheduleDate, false), () -> MediaController.getInstance().stopRecording(0, false, 0, false), resourcesProvider);
}
delegate.needStartRecordAudio(0);
MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0);
MediaController.getInstance().stopRecording(isInScheduleMode() ? 3 : 1, true, 0, voiceOnce);
}
recordingAudioVideo = false;
messageTransitionIsRunning = false;
@ -2375,10 +2540,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (alpha == 0) {
if (hasRecordVideo && isInVideoMode()) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(2, true, 0);
delegate.needStartRecordVideo(2, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
delegate.needStartRecordAudio(0);
MediaController.getInstance().stopRecording(0, false, 0);
MediaController.getInstance().stopRecording(0, false, 0, voiceOnce);
}
recordingAudioVideo = false;
updateRecordInterface(RECORD_STATE_CANCEL_BY_GESTURE);
@ -3096,7 +3261,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
private void resetRecordedState() {
if (videoToSendMessageObject != null) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(2, true, 0);
delegate.needStartRecordVideo(2, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
MessageObject playing = MediaController.getInstance().getPlayingMessageObject();
if (playing != null && playing == audioToSendMessageObject) {
@ -3471,6 +3636,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
private void createRecordCircle() {
createOnceButton();
if (recordCircle != null) {
return;
}
@ -3479,6 +3645,18 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
sizeNotifierLayout.addView(recordCircle, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
}
private void createOnceButton() {
if (onceButton != null) {
return;
}
if (delegate == null || !delegate.onceVoiceAvailable()) {
return;
}
onceButton = new OnceButton(getContext());
onceButton.setVisibility(GONE);
sizeNotifierLayout.addView(onceButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
}
private void showRestrictedHint() {
if (DialogObject.isChatDialog(dialog_id)) {
TLRPC.Chat chat = accountInstance.getMessagesController().getChat(-dialog_id);
@ -4570,7 +4748,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
checkBotMenu();
if (editingCaption && !captionLimitBulletinShown && !MessagesController.getInstance(currentAccount).premiumLocked && !UserConfig.getInstance(currentAccount).isPremium() && codePointCount > MessagesController.getInstance(currentAccount).captionLengthLimitDefault && codePointCount < MessagesController.getInstance(currentAccount).captionLengthLimitPremium) {
if (editingCaption && !captionLimitBulletinShown && !MessagesController.getInstance(currentAccount).premiumFeaturesBlocked() && !UserConfig.getInstance(currentAccount).isPremium() && codePointCount > MessagesController.getInstance(currentAccount).captionLengthLimitDefault && codePointCount < MessagesController.getInstance(currentAccount).captionLengthLimitPremium) {
captionLimitBulletinShown = true;
if (heightShouldBeChanged) {
AndroidUtilities.runOnUIThread(()->showCaptionLimitBulletin(), 300);
@ -4641,10 +4819,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
public void cancelRecordingAudioVideo() {
if (hasRecordVideo && isInVideoMode()) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(5, true, 0);
delegate.needStartRecordVideo(5, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
delegate.needStartRecordAudio(0);
MediaController.getInstance().stopRecording(0, false, 0);
MediaController.getInstance().stopRecording(0, false, 0, voiceOnce);
}
recordingAudioVideo = false;
updateRecordInterface(RECORD_STATE_CANCEL);
@ -5498,20 +5676,24 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
updateEmojiButtonParams();
recordPannelAnimation = new AnimatorSet();
recordPannelAnimation.playTogether(
ObjectAnimator.ofFloat(emojiButton, EMOJI_BUTTON_ALPHA, emojiButtonRestricted ? 0.5f : 1.0f),
ObjectAnimator.ofFloat(emojiButton, EMOJI_BUTTON_SCALE, 1.0f),
ObjectAnimator.ofFloat(recordDeleteImageView, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(recordDeleteImageView, View.SCALE_X, 0.0f),
ObjectAnimator.ofFloat(recordDeleteImageView, View.SCALE_Y, 0.0f),
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofFloat(emojiButton, EMOJI_BUTTON_ALPHA, emojiButtonRestricted ? 0.5f : 1.0f));
animators.add(ObjectAnimator.ofFloat(emojiButton, EMOJI_BUTTON_SCALE, 1.0f));
animators.add(ObjectAnimator.ofFloat(recordDeleteImageView, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(recordDeleteImageView, View.SCALE_X, 0.0f));
animators.add(ObjectAnimator.ofFloat(recordDeleteImageView, View.SCALE_Y, 0.0f));
ObjectAnimator.ofFloat(recordedAudioPanel, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(attachButton, View.ALPHA, 1.0f),
ObjectAnimator.ofFloat(attachButton, View.SCALE_X, 1.0f),
ObjectAnimator.ofFloat(attachButton, View.SCALE_Y, 1.0f),
ObjectAnimator.ofFloat(messageEditText, View.ALPHA, 1f),
ObjectAnimator.ofFloat(messageEditText, MESSAGE_TEXT_TRANSLATION_X, 0)
);
animators.add(ObjectAnimator.ofFloat(recordedAudioPanel, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(attachButton, View.ALPHA, 1.0f));
animators.add(ObjectAnimator.ofFloat(attachButton, View.SCALE_X, 1.0f));
animators.add(ObjectAnimator.ofFloat(attachButton, View.SCALE_Y, 1.0f));
animators.add(ObjectAnimator.ofFloat(messageEditText, View.ALPHA, 1f));
animators.add(ObjectAnimator.ofFloat(messageEditText, MESSAGE_TEXT_TRANSLATION_X, 0));
if (onceButton != null) {
animators.add(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 0));
onceButton.hideHintView();
}
recordPannelAnimation.playTogether(animators);
if (botCommandsMenuButton != null) {
botCommandsMenuButton.setAlpha(0f);
@ -5544,12 +5726,16 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
AnimatorSet exitAnimation = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>();
if (isInVideoMode()) {
exitAnimation.playTogether(
ObjectAnimator.ofFloat(videoTimelineView, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(videoTimelineView, View.TRANSLATION_X, -AndroidUtilities.dp(20)),
ObjectAnimator.ofFloat(messageEditText, MESSAGE_TEXT_TRANSLATION_X, 0)
);
animators.add(ObjectAnimator.ofFloat(videoTimelineView, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(videoTimelineView, View.TRANSLATION_X, -AndroidUtilities.dp(20)));
animators.add(ObjectAnimator.ofFloat(messageEditText, MESSAGE_TEXT_TRANSLATION_X, 0));
if (onceButton != null) {
animators.add(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 0.0f));
onceButton.hideHintView();
}
exitAnimation.playTogether(animators);
if (emojiButtonPaddingAlpha == 1f) {
exitAnimation.playTogether(ObjectAnimator.ofFloat(messageEditText, View.ALPHA, 1f));
} else {
@ -5571,16 +5757,19 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
messageEditTextAniamtor.setDuration(200);
exitAnimation.playTogether(messageEditTextAniamtor);
}
exitAnimation.playTogether(
ObjectAnimator.ofFloat(recordedAudioSeekBar, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(recordedAudioPlayButton, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(recordedAudioBackground, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(recordedAudioTimeTextView, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(recordedAudioSeekBar, View.TRANSLATION_X, -AndroidUtilities.dp(20)),
ObjectAnimator.ofFloat(recordedAudioPlayButton, View.TRANSLATION_X, -AndroidUtilities.dp(20)),
ObjectAnimator.ofFloat(recordedAudioBackground, View.TRANSLATION_X, -AndroidUtilities.dp(20)),
ObjectAnimator.ofFloat(recordedAudioTimeTextView, View.TRANSLATION_X, -AndroidUtilities.dp(20))
);
animators.add(ObjectAnimator.ofFloat(recordedAudioSeekBar, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(recordedAudioPlayButton, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(recordedAudioBackground, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(recordedAudioTimeTextView, View.ALPHA, 0.0f));
animators.add(ObjectAnimator.ofFloat(recordedAudioSeekBar, View.TRANSLATION_X, -AndroidUtilities.dp(20)));
animators.add(ObjectAnimator.ofFloat(recordedAudioPlayButton, View.TRANSLATION_X, -AndroidUtilities.dp(20)));
animators.add(ObjectAnimator.ofFloat(recordedAudioBackground, View.TRANSLATION_X, -AndroidUtilities.dp(20)));
animators.add(ObjectAnimator.ofFloat(recordedAudioTimeTextView, View.TRANSLATION_X, -AndroidUtilities.dp(20)));
if (onceButton != null) {
animators.add(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 0));
onceButton.hideHintView();
}
exitAnimation.playTogether(animators);
}
exitAnimation.setDuration(200);
@ -5655,6 +5844,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (recordPannelAnimation != null) {
recordPannelAnimation.start();
}
if (onceButton != null) {
onceButton.invalidate();
}
}
private void hideRecordedAudioPanelInternal() {
@ -5738,7 +5930,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
return;
}
if (videoToSendMessageObject != null) {
delegate.needStartRecordVideo(4, notify, scheduleDate);
delegate.needStartRecordVideo(4, notify, scheduleDate, voiceOnce ? 0x7FFFFFFF : 0);
hideRecordedAudioPanel(true);
checkSendButton(true);
return;
@ -5747,7 +5939,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (playing != null && playing == audioToSendMessageObject) {
MediaController.getInstance().cleanupPlayer(true, true);
}
SendMessagesHelper.SendMessageParams params = SendMessagesHelper.SendMessageParams.of(audioToSend, null, audioToSendPath, dialog_id, replyingMessageObject, getThreadMessage(), null, null, null, null, notify, scheduleDate, 0, null, null, false);
SendMessagesHelper.SendMessageParams params = SendMessagesHelper.SendMessageParams.of(audioToSend, null, audioToSendPath, dialog_id, replyingMessageObject, getThreadMessage(), null, null, null, null, notify, scheduleDate, voiceOnce ? 0x7FFFFFFF : 0, null, null, false);
applyStoryToSendMessageParams(params);
SendMessagesHelper.getInstance(currentAccount).sendMessage(params);
if (delegate != null) {
@ -5921,7 +6113,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} catch (Exception ignored) {}
}
if (!MessagesController.getInstance(currentAccount).premiumLocked && MessagesController.getInstance(currentAccount).captionLengthLimitPremium > codePointCount) {
if (!MessagesController.getInstance(currentAccount).premiumFeaturesBlocked() && MessagesController.getInstance(currentAccount).captionLengthLimitPremium > codePointCount) {
showCaptionLimitBulletin();
}
return;
@ -6916,6 +7108,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (recordInterfaceState == 1) {
return;
}
voiceOnce = false;
if (onceButton != null) {
onceButton.periodDrawable.setValue(1, false, false);
}
createRecordAudioPanel();
recordInterfaceState = 1;
if (emojiView != null) {
@ -6954,6 +7150,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
recordCircle.setVisibility(VISIBLE);
recordCircle.setAmplitude(0);
}
if (onceButton != null) {
onceButton.setVisibility(delegate != null && delegate.onceVoiceAvailable() ? VISIBLE : GONE);
}
if (recordDot != null) {
recordDot.resetAlpha();
@ -6987,6 +7186,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
ObjectAnimator.ofFloat(slideText, View.TRANSLATION_X, 0),
ObjectAnimator.ofFloat(slideText, View.ALPHA, 1)
);
if (onceButton != null) {
iconChanges.playTogether(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 1));
}
if (audioVideoSendButton != null) {
iconChanges.playTogether(ObjectAnimator.ofFloat(audioVideoSendButton, View.ALPHA, 0));
}
@ -7103,6 +7305,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
ObjectAnimator.ofFloat(messageEditText, MESSAGE_TEXT_TRANSLATION_X, 0),
ObjectAnimator.ofFloat(recordCircle, "slideToCancelProgress", 1f)
);
if (onceButton != null) {
runningAnimationAudio.playTogether(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 0));
onceButton.hideHintView();
}
if (botCommandsMenuButton != null) {
runningAnimationAudio.playTogether(
ObjectAnimator.ofFloat(botCommandsMenuButton, View.SCALE_Y, 1),
@ -7319,6 +7525,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
botCommandsMenuButton.setScaleX(0f);
botCommandsMenuButton.setScaleY(0f);
}
if (onceButton != null && onceVisible && MessagesController.getGlobalMainSettings().getInt("voiceoncehint", 0) < 3) {
onceButton.showHintView();
}
}
});
@ -7334,6 +7544,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
ObjectAnimator.ofFloat(recordDot, View.SCALE_Y, 0),
ObjectAnimator.ofFloat(recordDot, View.SCALE_X, 0)
);
if (onceButton != null) {
iconsAnimator.playTogether(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 0));
onceButton.hideHintView();
}
if (botCommandsMenuButton != null) {
iconsAnimator.playTogether(
@ -7481,6 +7695,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
ObjectAnimator.ofFloat(recordDot, View.SCALE_X, 0),
ObjectAnimator.ofFloat(audioVideoButtonContainer, View.ALPHA, 1.0f)
);
if (onceButton != null) {
iconsAnimator.playTogether(ObjectAnimator.ofFloat(onceButton, View.ALPHA, 0));
onceButton.hideHintView();
}
if (botCommandsMenuButton != null) {
iconsAnimator.playTogether(
ObjectAnimator.ofFloat(botCommandsMenuButton, View.SCALE_Y, 1),
@ -8164,7 +8382,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
}
public void updateGiftButton(boolean animated) {
boolean visible = !MessagesController.getInstance(currentAccount).premiumLocked && MessagesController.getInstance(currentAccount).giftAttachMenuIcon &&
boolean visible = !MessagesController.getInstance(currentAccount).premiumFeaturesBlocked() && MessagesController.getInstance(currentAccount).giftAttachMenuIcon &&
MessagesController.getInstance(currentAccount).giftTextFieldIcon && getParentFragment() != null && getParentFragment().getCurrentUser() != null &&
!BuildVars.IS_BILLING_UNAVAILABLE && !getParentFragment().getCurrentUser().self && !getParentFragment().getCurrentUser().premium &&
getParentFragment().getCurrentUserInfo() != null && !getParentFragment().getCurrentUserInfo().premium_gifts.isEmpty() && !isInScheduleMode() &&
@ -8759,6 +8977,21 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} else if (button instanceof TLRPC.TL_keyboardButtonRequestPeer) {
TLRPC.TL_keyboardButtonRequestPeer btn = (TLRPC.TL_keyboardButtonRequestPeer) button;
if (btn.peer_type != null && messageObject != null && messageObject.messageOwner != null) {
if (btn.peer_type instanceof TLRPC.TL_requestPeerTypeUser && btn.max_quantity > 1) {
MultiContactsSelectorBottomSheet.open(btn.max_quantity, ids -> {
if (ids != null && !ids.isEmpty()) {
TLRPC.TL_messages_sendBotRequestedPeer req = new TLRPC.TL_messages_sendBotRequestedPeer();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(messageObject.messageOwner.peer_id);
req.msg_id = messageObject.getId();
req.button_id = btn.button_id;
for (Long id : ids) {
req.requested_peers.add(MessagesController.getInstance(currentAccount).getInputPeer(id));
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, null);
}
});
return false;
}
Bundle args = new Bundle();
args.putBoolean("onlySelect", true);
args.putInt("dialogsType", DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER);
@ -8774,20 +9007,17 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
FileLog.e(e);
}
DialogsActivity fragment = new DialogsActivity(args);
fragment.setDelegate(new DialogsActivity.DialogsActivityDelegate() {
@Override
public boolean didSelectDialogs(DialogsActivity fragment, ArrayList<MessagesStorage.TopicKey> dids, CharSequence message, boolean param, TopicsFragment topicsFragment) {
if (dids != null && !dids.isEmpty()) {
TLRPC.TL_messages_sendBotRequestedPeer req = new TLRPC.TL_messages_sendBotRequestedPeer();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(messageObject.messageOwner.peer_id);
req.msg_id = messageObject.getId();
req.button_id = btn.button_id;
req.requested_peer = MessagesController.getInstance(currentAccount).getInputPeer(dids.get(0).dialogId);
ConnectionsManager.getInstance(currentAccount).sendRequest(req, null);
}
fragment.finishFragment();
return true;
fragment.setDelegate((dialogFragment, dids, message, param, topicsFragment) -> {
if (dids != null && !dids.isEmpty()) {
TLRPC.TL_messages_sendBotRequestedPeer req = new TLRPC.TL_messages_sendBotRequestedPeer();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(messageObject.messageOwner.peer_id);
req.msg_id = messageObject.getId();
req.button_id = btn.button_id;
req.requested_peers.add(MessagesController.getInstance(currentAccount).getInputPeer(dids.get(0).dialogId));
ConnectionsManager.getInstance(currentAccount).sendRequest(req, null);
}
dialogFragment.finishFragment();
return true;
});
parentFragment.presentFragment(fragment);
return false;
@ -10553,10 +10783,10 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
public void onCancelButtonPressed() {
if (hasRecordVideo && isInVideoMode()) {
CameraController.getInstance().cancelOnInitRunnable(onFinishInitCameraRunnable);
delegate.needStartRecordVideo(5, true, 0);
delegate.needStartRecordVideo(5, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
} else {
delegate.needStartRecordAudio(0);
MediaController.getInstance().stopRecording(0, false, 0);
MediaController.getInstance().stopRecording(0, false, 0, voiceOnce);
}
recordingAudioVideo = false;
updateRecordInterface(RECORD_STATE_CANCEL);
@ -10814,7 +11044,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (isInVideoMode()) {
if (t >= 59500 && !stoppedInternal) {
startedDraggingX = -1;
delegate.needStartRecordVideo(3, true, 0);
delegate.needStartRecordVideo(3, true, 0, voiceOnce ? 0x7FFFFFFF : 0);
stoppedInternal = true;
}
}

View file

@ -2557,7 +2557,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
sendButtonColorAnimator.setDuration(150).start();
}
// if (!captionLimitBulletinShown && !MessagesController.getInstance(currentAccount).premiumLocked && !UserConfig.getInstance(currentAccount).isPremium() && codepointCount > MessagesController.getInstance(currentAccount).captionLengthLimitDefault && codepointCount < MessagesController.getInstance(currentAccount).captionLengthLimitPremium) {
// if (!captionLimitBulletinShown && !MessagesController.getInstance(currentAccount).premiumFeaturesBlocked() && !UserConfig.getInstance(currentAccount).isPremium() && codepointCount > MessagesController.getInstance(currentAccount).captionLengthLimitDefault && codepointCount < MessagesController.getInstance(currentAccount).captionLengthLimitPremium) {
// captionLimitBulletinShown = true;
// showCaptionLimitBulletin(parentFragment);
// }
@ -2623,7 +2623,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
} catch (Exception ignored) {
}
if (!MessagesController.getInstance(currentAccount).premiumLocked && MessagesController.getInstance(currentAccount).captionLengthLimitPremium > codepointCount) {
if (!MessagesController.getInstance(currentAccount).premiumFeaturesBlocked() && MessagesController.getInstance(currentAccount).captionLengthLimitPremium > codepointCount) {
showCaptionLimitBulletin(parentFragment);
}
return;

View file

@ -33,6 +33,7 @@ import androidx.core.content.ContextCompat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
@ -487,6 +488,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
titleTextLargerCopyView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleTextLargerCopyView.setLeftDrawableTopPadding(-AndroidUtilities.dp(1.3f));
titleTextLargerCopyView.setRightDrawable(titleTextView.getRightDrawable());
titleTextLargerCopyView.setRightDrawable2(titleTextView.getRightDrawable2());
titleTextLargerCopyView.setRightDrawableOutside(titleTextView.getRightDrawableOutside());
titleTextLargerCopyView.setLeftDrawable(titleTextView.getLeftDrawable());
titleTextLargerCopyView.setText(titleTextView.getText());
@ -618,16 +620,17 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
private boolean rightDrawableIsScamOrVerified = false;
private String rightDrawableContentDescription = null;
private String rightDrawable2ContentDescription = null;
public void setTitleIcons(Drawable leftIcon, Drawable mutedIcon) {
titleTextView.setLeftDrawable(leftIcon);
if (!rightDrawableIsScamOrVerified) {
if (mutedIcon != null) {
rightDrawableContentDescription = LocaleController.getString("NotificationsMuted", R.string.NotificationsMuted);
rightDrawable2ContentDescription = LocaleController.getString("NotificationsMuted", R.string.NotificationsMuted);
} else {
rightDrawableContentDescription = null;
rightDrawable2ContentDescription = null;
}
titleTextView.setRightDrawable(mutedIcon);
titleTextView.setRightDrawable2(mutedIcon);
}
}
@ -644,9 +647,9 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (!(titleTextView.getRightDrawable() instanceof ScamDrawable)) {
ScamDrawable drawable = new ScamDrawable(11, scam ? 0 : 1);
drawable.setColor(getThemedColor(Theme.key_actionBarDefaultSubtitle));
titleTextView.setRightDrawable(drawable);
titleTextView.setRightDrawable2(drawable);
// titleTextView.setRightPadding(0);
rightDrawableContentDescription = LocaleController.getString("ScamMessage", R.string.ScamMessage);
rightDrawable2ContentDescription = LocaleController.getString("ScamMessage", R.string.ScamMessage);
rightDrawableIsScamOrVerified = true;
}
} else if (verified) {
@ -655,37 +658,34 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
Drawable verifiedCheck = getResources().getDrawable(R.drawable.verified_check).mutate();
verifiedCheck.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_profile_verifiedCheck), PorterDuff.Mode.MULTIPLY));
Drawable verifiedDrawable = new CombinedDrawable(verifiedBackground, verifiedCheck);
titleTextView.setRightDrawable(verifiedDrawable);
// titleTextView.setRightPadding(titleTextView.getPaddingRight());
titleTextView.setRightDrawable2(verifiedDrawable);
rightDrawableIsScamOrVerified = true;
rightDrawableContentDescription = LocaleController.getString("AccDescrVerified", R.string.AccDescrVerified);
} else if (premium) {
boolean isStatus = emojiStatus instanceof TLRPC.TL_emojiStatus || emojiStatus instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) emojiStatus).until > (int) (System.currentTimeMillis() / 1000);
// if (premiumIconHiddable) {
// titleTextView.setCanHideRightDrawable(!isStatus);
// }
rightDrawable2ContentDescription = LocaleController.getString("AccDescrVerified", R.string.AccDescrVerified);
} else if (titleTextView.getRightDrawable() instanceof ScamDrawable) {
titleTextView.setRightDrawable2(null);
rightDrawableIsScamOrVerified = false;
rightDrawable2ContentDescription = null;
}
if (premium || DialogObject.getEmojiStatusDocumentId(emojiStatus) != 0) {
if (titleTextView.getRightDrawable() instanceof AnimatedEmojiDrawable.WrapSizeDrawable &&
((AnimatedEmojiDrawable.WrapSizeDrawable) titleTextView.getRightDrawable()).getDrawable() instanceof AnimatedEmojiDrawable) {
((AnimatedEmojiDrawable) ((AnimatedEmojiDrawable.WrapSizeDrawable) titleTextView.getRightDrawable()).getDrawable()).removeView(titleTextView);
}
if (emojiStatus instanceof TLRPC.TL_emojiStatus) {
emojiStatusDrawable.set(((TLRPC.TL_emojiStatus) emojiStatus).document_id, animated);
} else if (emojiStatus instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) emojiStatus).until > (int) (System.currentTimeMillis() / 1000)) {
emojiStatusDrawable.set(((TLRPC.TL_emojiStatusUntil) emojiStatus).document_id, animated);
} else {
if (DialogObject.getEmojiStatusDocumentId(emojiStatus) != 0) {
emojiStatusDrawable.set(DialogObject.getEmojiStatusDocumentId(emojiStatus), animated);
} else if (premium) {
Drawable drawable = ContextCompat.getDrawable(ApplicationLoader.applicationContext, R.drawable.msg_premium_liststar).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_profile_verifiedBackground), PorterDuff.Mode.MULTIPLY));
emojiStatusDrawable.set(drawable, animated);
} else {
emojiStatusDrawable.set((Drawable) null, animated);
}
emojiStatusDrawable.setColor(getThemedColor(Theme.key_profile_verifiedBackground));
titleTextView.setRightDrawable(emojiStatusDrawable);
// titleTextView.setRightPadding(titleTextView.getPaddingRight());
rightDrawableIsScamOrVerified = true;
rightDrawableContentDescription = LocaleController.getString("AccDescrPremium", R.string.AccDescrPremium);
} else if (titleTextView.getRightDrawable() instanceof ScamDrawable) {
titleTextView.setRightDrawable(null);
// titleTextView.setRightPadding(0);
rightDrawableIsScamOrVerified = false;
rightDrawableContentDescription = LocaleController.getString("AccDescrPremium", R.string.AccDescrPremium);
} else {
titleTextView.setRightDrawable(null);
rightDrawableContentDescription = null;
}
}
@ -1146,6 +1146,10 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
sb.append(", ");
sb.append(rightDrawableContentDescription);
}
if (rightDrawable2ContentDescription != null) {
sb.append(", ");
sb.append(rightDrawable2ContentDescription);
}
sb.append("\n");
sb.append(subtitleTextView.getText());
info.setContentDescription(sb);

View file

@ -1,5 +1,7 @@
package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@ -20,6 +22,8 @@ import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
@ -51,10 +55,12 @@ import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.ResultCallback;
import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.BaseFragment;
@ -66,7 +72,9 @@ import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.DrawerProfileCell;
import org.telegram.ui.Cells.ThemesHorizontalListCell;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.Premium.LimitReachedBottomSheet;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.StatisticActivity;
import org.telegram.ui.ThemePreviewActivity;
import org.telegram.ui.WallpapersListActivity;
@ -101,6 +109,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
private final LinearSmoothScroller scroller;
private final View applyButton;
private AnimatedTextView applyTextView;
private AnimatedTextView applySubTextView;
private TextView chooseBackgroundTextView;
private ChatThemeItem selectedItem;
private boolean forceDark;
@ -113,7 +122,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
HintView hintView;
private boolean dataLoaded;
private EmojiThemes currentTheme;
ThemePreviewActivity overlayFragment;
BaseFragment overlayFragment;
public ChatAttachAlert chatAttachAlert;
private FrameLayout chatAttachButton;
private AnimatedTextView chatAttachButtonText;
@ -150,10 +159,10 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
titleView.setTextColor(getThemedColor(Theme.key_dialogTextBlack));
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titleView.setPadding(AndroidUtilities.dp(12), AndroidUtilities.dp(6), AndroidUtilities.dp(12), AndroidUtilities.dp(8));
titleView.setPadding(dp(12), dp(6), dp(12), dp(8));
backButtonView = new ImageView(getContext());
int padding = AndroidUtilities.dp(10);
int padding = dp(10);
backButtonView.setPadding(padding, padding, padding, padding);
backButtonDrawable = new BackDrawable(false);
backButtonView.setImageDrawable(backButtonDrawable);
@ -169,7 +178,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
rootLayout.addView(titleView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.START, 44, 0, 62, 0));
int drawableColor = getThemedColor(Theme.key_featuredStickers_addButton);
int drawableSize = AndroidUtilities.dp(28);
int drawableSize = dp(28);
darkThemeDrawable = new RLottieDrawable(R.raw.sun_outline, "" + R.raw.sun_outline, drawableSize, drawableSize, false, null);
forceDark = !Theme.getActiveTheme().isDark();
setForceDark(Theme.getActiveTheme().isDark(), false);
@ -213,7 +222,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
recyclerView.setItemAnimator(null);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setLayoutManager(layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
recyclerView.setPadding(AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12), 0);
recyclerView.setPadding(dp(12), 0, dp(12), 0);
recyclerView.setOnItemClickListener((view, position) -> {
if (adapter.items.get(position) == selectedItem || changeDayNightView != null) {
return;
@ -255,7 +264,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
rootLayout.addView(recyclerView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 104, Gravity.START, 0, 44, 0, 0));
applyButton = new View(getContext());
applyButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), getThemedColor(Theme.key_featuredStickers_addButton), getThemedColor(Theme.key_featuredStickers_addButtonPressed)));
applyButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(6), getThemedColor(Theme.key_featuredStickers_addButton), getThemedColor(Theme.key_featuredStickers_addButtonPressed)));
applyButton.setOnClickListener((view) -> applySelectedTheme());
rootLayout.addView(applyButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.START, 16, 162, 16, 16));
@ -284,10 +293,19 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
applyTextView.adaptWidth = false;
applyTextView.setGravity(Gravity.CENTER);
applyTextView.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText));
applyTextView.setTextSize(AndroidUtilities.dp(15));
applyTextView.setTextSize(dp(15));
applyTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
rootLayout.addView(applyTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.START, 16, 162, 16, 16));
applySubTextView = new AnimatedTextView(getContext(), true, true, true);
applySubTextView.getDrawable().setEllipsizeByGradient(true);
applySubTextView.adaptWidth = false;
applySubTextView.setGravity(Gravity.CENTER);
applySubTextView.setTextColor(getThemedColor(Theme.key_featuredStickers_buttonText));
applySubTextView.setTextSize(dp(12));
applySubTextView.setAlpha(0f);
applySubTextView.setTranslationY(dp(11));
rootLayout.addView(applySubTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.START, 16, 162, 16, 16));
if (currentWallpaper != null) {
cancelOrResetTextView = new TextView(getContext());
@ -315,7 +333,13 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
themeHintTextView.setGravity(Gravity.CENTER);
themeHintTextView.setLines(1);
themeHintTextView.setSingleLine(true);
themeHintTextView.setText(LocaleController.formatString("ChatThemeApplyHint", R.string.ChatThemeApplyHint, chatActivity.getCurrentUser().first_name));
String name = "";
if (chatActivity.getCurrentUser() != null) {
name = UserObject.getFirstName(chatActivity.getCurrentUser());
} else if (chatActivity.getCurrentChat() != null) {
name = chatActivity.getCurrentChat().title;
}
themeHintTextView.setText(LocaleController.formatString("ChatThemeApplyHint", R.string.ChatThemeApplyHint, name));
themeHintTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
rootLayout.addView(themeHintTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.START, 16, 214, 16, 12));
}
@ -326,11 +350,11 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
private void updateButtonColors() {
if (themeHintTextView != null) {
themeHintTextView.setTextColor(getThemedColor(Theme.key_dialogTextGray));
themeHintTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
themeHintTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
}
if (cancelOrResetTextView != null) {
cancelOrResetTextView.setTextColor(getThemedColor(Theme.key_text_RedRegular));
cancelOrResetTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(getThemedColor(Theme.key_text_RedRegular), (int) (0.3f * 255))));
cancelOrResetTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(getThemedColor(Theme.key_text_RedRegular), (int) (0.3f * 255))));
}
backButtonView.setBackground(Theme.createSelectorDrawable(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_dialogTextBlack), 30), 1));
backButtonDrawable.setColor(getThemedColor(Theme.key_dialogTextBlack));
@ -339,7 +363,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
darkThemeView.setBackground(Theme.createSelectorDrawable(ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), 30), 1));
chooseBackgroundTextView.setTextColor(getThemedColor(Theme.key_dialogTextBlue));
chooseBackgroundTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
chooseBackgroundTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
}
@ -357,7 +381,12 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}
private ColoredImageSpan lockSpan;
private void updateState(boolean animated) {
TLRPC.Chat chat = chatActivity.getCurrentChat();
if (chat != null) {
checkBoostsLevel();
}
if (!dataLoaded) {
backButtonDrawable.setRotation(1f, animated);
applyButton.setEnabled(false);
@ -365,6 +394,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
AndroidUtilities.updateViewVisibilityAnimated(cancelOrResetTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyButton, false, 1f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applySubTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(themeHintTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(progressView, true, 1f, true, animated);
} else {
@ -372,16 +402,30 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
if (hasChanges()) {
backButtonDrawable.setRotation(0, animated);
applyButton.setEnabled(true);
AndroidUtilities.updateViewVisibilityAnimated(chooseBackgroundTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(cancelOrResetTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyButton, true, 1f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyTextView, true, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(themeHintTextView, true, 0.9f, false, animated);
boolean showSubText = false;
if (selectedItem != null && selectedItem.chatTheme != null && selectedItem.chatTheme.showAsDefaultStub && selectedItem.chatTheme.wallpaper == null) {
applyTextView.setText(LocaleController.getString("ChatResetTheme", R.string.ChatResetTheme));
} else {
applyTextView.setText(LocaleController.getString("ChatApplyTheme", R.string.ChatApplyTheme));
if (chat != null && boostsStatus != null && boostsStatus.level < chatActivity.getMessagesController().channelWallpaperLevelMin) {
showSubText = true;
SpannableStringBuilder text = new SpannableStringBuilder("l");
if (lockSpan == null) {
lockSpan = new ColoredImageSpan(R.drawable.mini_switch_lock);
lockSpan.setTopOffset(1);
}
text.setSpan(lockSpan, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
text.append(" ").append(LocaleController.formatPluralString("ReactionLevelRequiredBtn", chatActivity.getMessagesController().channelWallpaperLevelMin));
applySubTextView.setText(text);
}
}
updateApplySubTextTranslation(showSubText, animated && applyTextView.getAlpha() > .8f);
AndroidUtilities.updateViewVisibilityAnimated(chooseBackgroundTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(cancelOrResetTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyButton, true, 1f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyTextView, true, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applySubTextView, showSubText, 0.9f, false, 0.7f, animated);
AndroidUtilities.updateViewVisibilityAnimated(themeHintTextView, true, 0.9f, false, animated);
} else {
backButtonDrawable.setRotation(1f, animated);
applyButton.setEnabled(false);
@ -389,11 +433,54 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
AndroidUtilities.updateViewVisibilityAnimated(cancelOrResetTextView, true, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyButton, false, 1f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applyTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(applySubTextView, false, 0.9f, false, animated);
AndroidUtilities.updateViewVisibilityAnimated(themeHintTextView, false, 0.9f, false, animated);
}
}
}
private boolean checkingBoostsLevel = false, checkedBoostsLevel = false;
private TL_stories.TL_premium_boostsStatus boostsStatus;
private void checkBoostsLevel() {
if (chatActivity == null || checkingBoostsLevel || checkedBoostsLevel || boostsStatus != null) {
return;
}
checkingBoostsLevel = true;
chatActivity.getMessagesController().getBoostsController().getBoostsStats(chatActivity.getDialogId(), boostsStatus -> {
this.boostsStatus = boostsStatus;
checkedBoostsLevel = true;
updateState(true);
checkingBoostsLevel = false;
});
}
private float subTextTranslation = 0;
private ValueAnimator subTextTranslationAnimator;
private void updateApplySubTextTranslation(boolean subtextShown, boolean animated) {
if (subTextTranslationAnimator != null) {
subTextTranslationAnimator.cancel();
subTextTranslationAnimator = null;
}
if (animated) {
subTextTranslationAnimator = ValueAnimator.ofFloat(subTextTranslation, subtextShown ? 1 : 0);
subTextTranslationAnimator.addUpdateListener(anm -> {
subTextTranslation = (float) anm.getAnimatedValue();
applyTextView.setTranslationY(-dp(7) * subTextTranslation);
});
subTextTranslationAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
subTextTranslation = subtextShown ? 1 : 0;
applyTextView.setTranslationY(-dp(7) * subTextTranslation);
}
});
subTextTranslationAnimator.start();
} else {
subTextTranslation = subtextShown ? 1 : 0;
applyTextView.setTranslationY(-dp(7) * subTextTranslation);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@ -433,7 +520,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
hintView = new HintView(getContext(), 9, chatActivity.getResourceProvider());
hintView.setVisibility(View.INVISIBLE);
hintView.setShowingDuration(5000);
hintView.setBottomOffset(-AndroidUtilities.dp(8));
hintView.setBottomOffset(-dp(8));
if (forceDark) {
hintView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("ChatThemeDaySwitchTooltip", R.string.ChatThemeDaySwitchTooltip)));
} else {
@ -538,7 +625,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
updateButtonColors();
if (chatAttachButton != null) {
chatAttachButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(0), getThemedColor(Theme.key_windowBackgroundWhite), ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
chatAttachButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(0), getThemedColor(Theme.key_windowBackgroundWhite), ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
}
if (chatAttachButtonText != null) {
chatAttachButtonText.setTextColor(getThemedColor(Theme.key_featuredStickers_addButton));
@ -550,8 +637,8 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
};
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
if (chatActivity.forceDisallowRedrawThemeDescriptions && overlayFragment != null) {
themeDescriptions.addAll(overlayFragment.getThemeDescriptionsInternal());
if (chatActivity.forceDisallowRedrawThemeDescriptions && overlayFragment instanceof ThemePreviewActivity) {
themeDescriptions.addAll(((ThemePreviewActivity) overlayFragment).getThemeDescriptionsInternal());
return themeDescriptions;
}
if (chatAttachAlert != null) {
@ -833,6 +920,35 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
private void applySelectedTheme() {
if (checkingBoostsLevel) {
return;
}
if (boostsStatus != null && boostsStatus.level < chatActivity.getMessagesController().channelWallpaperLevelMin) {
chatActivity.getMessagesController().getBoostsController().userCanBoostChannel(chatActivity.getDialogId(), boostsStatus, canApplyBoost -> {
if (getContext() == null) {
return;
}
LimitReachedBottomSheet limitReachedBottomSheet = new LimitReachedBottomSheet(chatActivity, getContext(), LimitReachedBottomSheet.TYPE_BOOSTS_FOR_WALLPAPER, currentAccount, resourcesProvider);
limitReachedBottomSheet.setCanApplyBoost(canApplyBoost);
limitReachedBottomSheet.setBoostsStats(boostsStatus, true);
limitReachedBottomSheet.setDialogId(chatActivity.getDialogId());
limitReachedBottomSheet.showStatisticButtonInLink(() -> {
TLRPC.Chat chat = chatActivity.getMessagesController().getChat(-chatActivity.getDialogId());
Bundle args = new Bundle();
args.putLong("chat_id", -chatActivity.getDialogId());
args.putBoolean("is_megagroup", chat.megagroup);
args.putBoolean("start_from_boosts", true);
TLRPC.ChatFull chatInfo = chatActivity.getMessagesController().getChatFull(-chatActivity.getDialogId());
if (chatInfo == null || !chatInfo.can_view_stats) {
args.putBoolean("only_boosts", true);
};
StatisticActivity fragment = new StatisticActivity(args);
showAsSheet(fragment);
});
limitReachedBottomSheet.show();
});
return;
}
Bulletin bulletin = null;
EmojiThemes newTheme = selectedItem.chatTheme;
if (selectedItem != null && newTheme != currentTheme) {
@ -1124,6 +1240,147 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}
public static void openGalleryForBackground(
Activity activity,
BaseFragment fragment,
long dialogId,
Theme.ResourcesProvider resourcesProvider,
Utilities.Callback<TLRPC.WallPaper> onSet,
ThemePreviewActivity.DayNightSwitchDelegate toggleTheme,
TL_stories.TL_premium_boostsStatus cachedBoostsStatus
) {
ChatAttachAlert chatAttachAlert = new ChatAttachAlert(activity, fragment, false, false, false, resourcesProvider);
chatAttachAlert.drawNavigationBar = true;
chatAttachAlert.setupPhotoPicker(LocaleController.getString("ChooseBackground", R.string.ChooseBackground));
chatAttachAlert.setDelegate(new ChatAttachAlert.ChatAttachViewDelegate() {
long start;
@Override
public boolean selectItemOnClicking() {
start = System.currentTimeMillis();
return true;
}
@Override
public void didPressedButton(int button, boolean arg, boolean notify, int scheduleDate, boolean forceDocument) {
try {
HashMap<Object, Object> photos = chatAttachAlert.getPhotoLayout().getSelectedPhotos();
if (!photos.isEmpty()) {
MediaController.PhotoEntry entry = (MediaController.PhotoEntry) photos.values().iterator().next();
String path;
if (entry.imagePath != null) {
path = entry.imagePath;
} else {
path = entry.path;
}
if (path != null) {
File currentWallpaperPath = new File(FileLoader.getDirectory(FileLoader.MEDIA_DIR_CACHE), Utilities.random.nextInt() + ".jpg");
Point screenSize = AndroidUtilities.getRealScreenSize();
Bitmap bitmap = ImageLoader.loadBitmap(path, null, screenSize.x, screenSize.y, true);
FileOutputStream stream = new FileOutputStream(currentWallpaperPath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 87, stream);
ThemePreviewActivity themePreviewActivity = new ThemePreviewActivity(new WallpapersListActivity.FileWallpaper("", currentWallpaperPath, currentWallpaperPath), bitmap) {
@Override
public boolean insideBottomSheet() {
return true;
}
};
themePreviewActivity.boostsStatus = cachedBoostsStatus;
themePreviewActivity.setResourceProvider(resourcesProvider);
themePreviewActivity.setOnSwitchDayNightDelegate(toggleTheme);
themePreviewActivity.setInitialModes(false, false, .20f);
themePreviewActivity.setDialogId(dialogId);
themePreviewActivity.setDelegate(wallPaper -> {
chatAttachAlert.dismissInternal();
if (onSet != null) {
onSet.run(wallPaper);
}
});
BaseFragment.BottomSheetParams params = new BaseFragment.BottomSheetParams();
params.transitionFromLeft = true;
params.allowNestedScroll = false;
params.occupyNavigationBar = true;
fragment.showAsSheet(themePreviewActivity, params);
chatAttachAlert.dismiss();
}
}
} catch (Throwable e) {
FileLog.e(e);
}
}
@Override
public void onWallpaperSelected(Object object) {
ThemePreviewActivity wallpaperActivity = new ThemePreviewActivity(object, null, true, false) {
@Override
public boolean insideBottomSheet() {
return true;
}
};
wallpaperActivity.boostsStatus = cachedBoostsStatus;
wallpaperActivity.setResourceProvider(resourcesProvider);
wallpaperActivity.setOnSwitchDayNightDelegate(toggleTheme);
wallpaperActivity.setDialogId(dialogId);
wallpaperActivity.setDelegate(wallPaper -> {
chatAttachAlert.dismissInternal();
if (onSet != null) {
onSet.run(wallPaper);
}
});
BaseFragment.BottomSheetParams params = new BaseFragment.BottomSheetParams();
params.transitionFromLeft = true;
params.allowNestedScroll = false;
params.occupyNavigationBar = true;
fragment.showAsSheet(wallpaperActivity, params);
}
});
chatAttachAlert.setMaxSelectedPhotos(1, false);
chatAttachAlert.init();
chatAttachAlert.getPhotoLayout().loadGalleryPhotos();
chatAttachAlert.show();
FrameLayout chatAttachButton = new FrameLayout(activity) {
Paint paint = new Paint();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp(48), MeasureSpec.EXACTLY));
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
paint.setColor(Theme.getColor(Theme.key_divider, resourcesProvider));
canvas.drawRect(0, 0, getMeasuredWidth(), 1, paint);
}
};
AnimatedTextView chatAttachButtonText = new AnimatedTextView(activity, true, true, true);
chatAttachButtonText.setTextSize(dp(14));
chatAttachButtonText.setText(LocaleController.getString(R.string.SetColorAsBackground));
chatAttachButtonText.setGravity(Gravity.CENTER);
chatAttachButtonText.setTextColor(Theme.getColor(Theme.key_featuredStickers_addButton, resourcesProvider));
chatAttachButton.addView(chatAttachButtonText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
chatAttachButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(0), Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider), ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_featuredStickers_addButton, resourcesProvider), (int) (0.3f * 255))));
chatAttachButton.setOnClickListener(v -> {
if (chatAttachAlert.getCurrentAttachLayout() == chatAttachAlert.getPhotoLayout()) {
chatAttachButtonText.setText(LocaleController.getString(R.string.ChooseBackgroundFromGallery));
chatAttachAlert.openColorsLayout();
// chatAttachAlert.colorsLayout.updateColors(forceDark);
} else {
chatAttachButtonText.setText(LocaleController.getString(R.string.SetColorAsBackground));
chatAttachAlert.showLayout(chatAttachAlert.getPhotoLayout());
}
// WallpapersListActivity wallpapersListActivity = new WallpapersListActivity(WallpapersListActivity.TYPE_ALL, chatActivity.getDialogId());
// chatActivity.presentFragment(wallpapersListActivity);
// chatAttachAlert.dismiss();
// dismiss();
});
chatAttachAlert.sizeNotifierFrameLayout.addView(chatAttachButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
}
private void openGalleryForBackground() {
chatAttachAlert = new ChatAttachAlert(chatActivity.getParentActivity(), chatActivity, false, false, false, chatActivity.getResourceProvider());
chatAttachAlert.drawNavigationBar = true;
@ -1161,9 +1418,10 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
return true;
}
};
themePreviewActivity.boostsStatus = boostsStatus;
themePreviewActivity.setInitialModes(false, false, .20f);
themePreviewActivity.setDialogId(chatActivity.getDialogId());
themePreviewActivity.setDelegate(() -> {
themePreviewActivity.setDelegate(wallPaper -> {
chatAttachAlert.dismissInternal();
dismiss();
});
@ -1183,8 +1441,9 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
return true;
}
};
wallpaperActivity.boostsStatus = boostsStatus;
wallpaperActivity.setDialogId(chatActivity.getDialogId());
wallpaperActivity.setDelegate(() -> {
wallpaperActivity.setDelegate(wallPaper -> {
chatAttachAlert.dismissInternal();
dismiss();
});
@ -1202,7 +1461,7 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), MeasureSpec.EXACTLY));
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp(48), MeasureSpec.EXACTLY));
}
@Override
@ -1213,12 +1472,12 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
};
chatAttachButtonText = new AnimatedTextView(getContext(), true, true, true);
chatAttachButtonText.setTextSize(AndroidUtilities.dp(14));
chatAttachButtonText.setTextSize(dp(14));
chatAttachButtonText.setText(LocaleController.getString("SetColorAsBackground", R.string.SetColorAsBackground));
chatAttachButtonText.setGravity(Gravity.CENTER);
chatAttachButtonText.setTextColor(getThemedColor(Theme.key_featuredStickers_addButton));
chatAttachButton.addView(chatAttachButtonText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
chatAttachButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(0), getThemedColor(Theme.key_windowBackgroundWhite), ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
chatAttachButton.setBackground(Theme.createSimpleSelectorRoundRectDrawable(dp(0), getThemedColor(Theme.key_windowBackgroundWhite), ColorUtils.setAlphaComponent(getThemedColor(Theme.key_featuredStickers_addButton), (int) (0.3f * 255))));
chatAttachButton.setOnClickListener(v -> {
if (chatAttachAlert.getCurrentAttachLayout() == chatAttachAlert.getPhotoLayout()) {
chatAttachButtonText.setText(LocaleController.getString("ChooseBackgroundFromGallery", R.string.ChooseBackgroundFromGallery));
@ -1261,6 +1520,27 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
}
}
private void showAsSheet(BaseFragment fragment) {
if (fragment == null) {
return;
}
BaseFragment.BottomSheetParams params = new BaseFragment.BottomSheetParams();
params.transitionFromLeft = true;
params.allowNestedScroll = false;
fragment.setResourceProvider(chatActivity.getResourceProvider());
params.onOpenAnimationFinished = () -> {
PhotoViewer.getInstance().closePhoto(false, false);
};
params.onPreFinished = () -> {
fixColorsAfterAnotherWindow();
};
params.onDismiss = () -> {
overlayFragment = null;
};
params.occupyNavigationBar = true;
chatActivity.showAsSheet(overlayFragment = fragment, params);
}
private void showAsSheet(ThemePreviewActivity themePreviewActivity) {
BaseFragment.BottomSheetParams params = new BaseFragment.BottomSheetParams();
params.transitionFromLeft = true;
@ -1274,6 +1554,11 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
return forceDark;
}
@Override
public boolean supportsAnimation() {
return true;
}
@Override
public void switchDayNight(boolean animated) {
forceDark = !forceDark;
@ -1316,5 +1601,12 @@ public class ChatThemeBottomSheet extends BottomSheet implements NotificationCen
public ChatThemeItem(EmojiThemes chatTheme) {
this.chatTheme = chatTheme;
}
public String getEmoticon() {
if (chatTheme == null || chatTheme.showAsDefaultStub) {
return null;
}
return chatTheme.getEmoticon();
}
}
}

View file

@ -14,7 +14,7 @@ public class DotDividerSpan extends ReplacementSpan {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
int color;
int topPadding;
private int size = 3;
private float size = 3;
@Override
public int getSize(@NonNull Paint paint, CharSequence charSequence, int i, int i1, @Nullable Paint.FontMetricsInt fontMetricsInt) {
@ -35,7 +35,7 @@ public class DotDividerSpan extends ReplacementSpan {
this.topPadding = topPadding;
}
public void setSize(int size) {
public void setSize(float size) {
this.size = size;
}
}

View file

@ -231,7 +231,7 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not
editText.setHintTextColor(getThemedColor(Theme.key_windowBackgroundWhiteHintText));
editText.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
editText.setHandlesColor(getThemedColor(Theme.key_chat_TextSelectionCursor));
editText.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(40) : 0, 0, LocaleController.isRTL ? 0 : AndroidUtilities.dp(40), AndroidUtilities.dp(8));
editText.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(40) : 0, 0, LocaleController.isRTL ? 0 : AndroidUtilities.dp(40), AndroidUtilities.dp(11));
addView(editText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.CENTER_VERTICAL, LocaleController.isRTL ? 11 : 0, 1, LocaleController.isRTL ? 0 : 11, 0));
} else if (style == STYLE_STORY || style == STYLE_PHOTOVIEWER) {
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
@ -276,7 +276,7 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not
if (style == STYLE_FRAGMENT) {
emojiIconDrawable.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_messagePanelIcons), PorterDuff.Mode.MULTIPLY));
emojiIconDrawable.setIcon(R.drawable.smiles_tab_smiles, false);
addView(emojiButton, LayoutHelper.createFrame(48, 48, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT), 0, 0, 0, 7));
addView(emojiButton, LayoutHelper.createFrame(48, 48, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT), 0, 0, 0, 5));
} else if (style == STYLE_STORY || style == STYLE_PHOTOVIEWER) {
emojiIconDrawable.setColorFilter(new PorterDuffColorFilter(0x8cffffff, PorterDuff.Mode.MULTIPLY));
emojiIconDrawable.setIcon(R.drawable.input_smile, false);
@ -367,10 +367,11 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not
public void setEnabled(boolean enabled) {
editText.setEnabled(enabled);
emojiButton.setVisibility(enabled ? VISIBLE : GONE);
int bottomPadding = AndroidUtilities.dp(currentStyle == STYLE_FRAGMENT ? 11 : 8);
if (enabled) {
editText.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(40) : 0, 0, LocaleController.isRTL ? 0 : AndroidUtilities.dp(40), AndroidUtilities.dp(8));
editText.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(40) : 0, 0, LocaleController.isRTL ? 0 : AndroidUtilities.dp(40), bottomPadding);
} else {
editText.setPadding(0, 0, 0, AndroidUtilities.dp(8));
editText.setPadding(0, 0, 0, bottomPadding);
}
}

View file

@ -5774,7 +5774,7 @@ public class EmojiView extends FrameLayout implements NotificationCenter.Notific
}
}
}
if (MessagesController.getInstance(currentAccount).premiumLocked) {
if (MessagesController.getInstance(currentAccount).premiumFeaturesBlocked()) {
for (int a = 0; a < favouriteStickers.size(); a++) {
if (MessageObject.isPremiumSticker(favouriteStickers.get(a))) {
favouriteStickers.remove(a);

View file

@ -1706,7 +1706,7 @@ public class FilterTabsView extends FrameLayout {
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumLocked && (!isEditing || (viewHolder.getAdapterPosition() == 0 && tabs.get(0).isDefault && !UserConfig.getInstance(UserConfig.selectedAccount).isPremium()))) {
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked() && (!isEditing || (viewHolder.getAdapterPosition() == 0 && tabs.get(0).isDefault && !UserConfig.getInstance(UserConfig.selectedAccount).isPremium()))) {
return makeMovementFlags(0, 0);
}
return makeMovementFlags(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT, 0);
@ -1714,7 +1714,7 @@ public class FilterTabsView extends FrameLayout {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumLocked && ((source.getAdapterPosition() == 0 || target.getAdapterPosition() == 0) && !UserConfig.getInstance(UserConfig.selectedAccount).isPremium())) {
if (MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked() && ((source.getAdapterPosition() == 0 || target.getAdapterPosition() == 0) && !UserConfig.getInstance(UserConfig.selectedAccount).isPremium())) {
return false;
}
adapter.swapElements(source.getAdapterPosition(), target.getAdapterPosition());

View file

@ -32,11 +32,13 @@ public class FireworksOverlay extends View {
private float speedCoef = 1.0f;
private int fallingDownCount;
private static Drawable[] heartDrawable;
private static Drawable[] starsDrawable;
private static final int particlesCount = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW ? 50 : 60;
private static final int fallParticlesCount = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW ? 20 : 30;
private boolean isFebruary14;
private boolean withStars;
private static int[] colors = new int[] {
private static int[] colors = new int[]{
0xff2CBCE8,
0xff9E04D0,
0xffFECB02,
@ -45,7 +47,7 @@ public class FireworksOverlay extends View {
0xff59B86C
};
private static int[] heartColors = new int[] {
private static int[] heartColors = new int[]{
0xffE2557B,
0xff5FCDF2,
0xffFFDA69,
@ -53,6 +55,14 @@ public class FireworksOverlay extends View {
0xffE376B0
};
private static int[] starsColors = new int[]{
0xff1e80ff,
0xff10c689,
0xffff5997,
0xffff9724,
0xff2fe1f9
};
static {
paint = new Paint[colors.length];
for (int a = 0; a < paint.length; a++) {
@ -85,15 +95,23 @@ public class FireworksOverlay extends View {
canvas.drawRoundRect(rect, AndroidUtilities.dp(2), AndroidUtilities.dp(2), paint[colorType]);
canvas.restore();
} else if (type == 2) {
Drawable drawable = heartDrawable[colorType];
int w = drawable.getIntrinsicWidth() / 2;
int h = drawable.getIntrinsicHeight() / 2;
drawable.setBounds((int) x - w, (int) y - h, (int) x + w, (int) y + h);
canvas.save();
canvas.rotate(rotation, x, y);
canvas.scale(typeSize / 6.0f, typeSize / 6.0f, x, y);
drawable.draw(canvas);
canvas.restore();
Drawable drawable = null;
if (starsDrawable != null) {
drawable = starsDrawable[colorType];
}
if (heartDrawable != null) {
drawable = heartDrawable[colorType];
}
if (drawable != null) {
int w = drawable.getIntrinsicWidth() / 2;
int h = drawable.getIntrinsicHeight() / 2;
drawable.setBounds((int) x - w, (int) y - h, (int) x + w, (int) y + h);
canvas.save();
canvas.rotate(rotation, x, y);
canvas.scale(typeSize / 6.0f, typeSize / 6.0f, x, y);
drawable.draw(canvas);
canvas.restore();
}
}
}
@ -170,16 +188,27 @@ public class FireworksOverlay extends View {
}
}
private void loadStarsDrawables() {
if (starsDrawable != null) {
return;
}
starsDrawable = new Drawable[starsColors.length];
for (int a = 0; a < starsDrawable.length; a++) {
starsDrawable[a] = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.msg_settings_premium).mutate();
starsDrawable[a].setColorFilter(new PorterDuffColorFilter(starsColors[a], PorterDuff.Mode.MULTIPLY));
}
}
private int getHeightForAnimation() {
if (getMeasuredHeight() == 0) {
return ((View)getParent()).getHeight();
return ((View) getParent()).getHeight();
}
return getMeasuredHeight();
}
private int getWidthForAnimation() {
if (getMeasuredWidth() == 0) {
return ((View)getParent()).getWidth();
return ((View) getParent()).getWidth();
}
return getMeasuredWidth();
}
@ -190,6 +219,9 @@ public class FireworksOverlay extends View {
if (isFebruary14 && particle.type == 0) {
particle.type = 2;
particle.colorType = (byte) Utilities.random.nextInt(heartColors.length);
} else if (withStars && Utilities.random.nextBoolean()) {
particle.type = 2;
particle.colorType = (byte) Utilities.random.nextInt(starsColors.length);
} else {
particle.colorType = (byte) Utilities.random.nextInt(colors.length);
}
@ -223,11 +255,10 @@ public class FireworksOverlay extends View {
return started;
}
public void start() {
public void start(boolean withStars) {
this.withStars = withStars;
particles.clear();
if (Build.VERSION.SDK_INT >= 18) {
setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
setLayerType(View.LAYER_TYPE_HARDWARE, null);
started = true;
startedFall = false;
fallingDownCount = 0;
@ -239,6 +270,8 @@ public class FireworksOverlay extends View {
isFebruary14 = month == 1 && (BuildVars.DEBUG_PRIVATE_VERSION || day == 14);
if (isFebruary14) {
loadHeartDrawables();
} else if (withStars) {
loadStarsDrawables();
}
for (int a = 0; a < particlesCount; a++) {
particles.add(createParticle(false));
@ -246,6 +279,10 @@ public class FireworksOverlay extends View {
invalidate();
}
public void start() {
start(false);
}
private void startFall() {
if (startedFall) {
return;

View file

@ -115,6 +115,9 @@ public class FolderBottomSheet extends BottomSheetWithRecyclerListView {
req.chatlist = new TL_chatlists.TL_inputChatlistDialogFilter();
req.chatlist.filter_id = filterId;
fragment.getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (fragment.getParentActivity() == null) {
return;
}
FolderBottomSheet sheet;
if (res instanceof TLRPC.Vector) {
ArrayList<Long> suggestions = new ArrayList<>();

View file

@ -650,7 +650,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
if (cameraThread != null) {
cameraThread.shutdown(0);
cameraThread.shutdown(0, 0);
cameraThread = null;
}
if (cameraSession != null) {
@ -765,7 +765,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
}
}
public void send(int state, boolean notify, int scheduleDate) {
public void send(int state, boolean notify, int scheduleDate, int ttl) {
if (textureView == null) {
return;
}
@ -803,7 +803,9 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
videoEditedInfo.encryptedFile = encryptedFile;
videoEditedInfo.key = key;
videoEditedInfo.iv = iv;
delegate.sendMedia(new MediaController.PhotoEntry(0, 0, 0, cameraFile.getAbsolutePath(), 0, true, 0, 0, 0), videoEditedInfo, notify, scheduleDate, false);
MediaController.PhotoEntry entry = new MediaController.PhotoEntry(0, 0, 0, cameraFile.getAbsolutePath(), 0, true, 0, 0, 0);
entry.ttl = ttl;
delegate.sendMedia(entry, videoEditedInfo, notify, scheduleDate, false);
if (scheduleDate != 0) {
startAnimation(false);
}
@ -828,7 +830,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
send = 1;
}
saveLastCameraBitmap();
cameraThread.shutdown(send);
cameraThread.shutdown(send, ttl);
cameraThread = null;
}
if (cancelled) {
@ -871,7 +873,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.recordStopped, recordingGuid, byGesture ? 0 : 6);
if (cameraThread != null) {
saveLastCameraBitmap();
cameraThread.shutdown(0);
cameraThread.shutdown(0, 0);
cameraThread = null;
}
if (cameraFile != null) {
@ -1562,7 +1564,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
case DO_SHUTDOWN_MESSAGE:
finish();
if (recording) {
videoEncoder.stopRecording(inputMessage.arg1);
videoEncoder.stopRecording(inputMessage.arg1, inputMessage.arg2);
}
Looper looper = Looper.myLooper();
if (looper != null) {
@ -1636,10 +1638,10 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
}
}
public void shutdown(int send) {
public void shutdown(int send, int ttl) {
Handler handler = getHandler();
if (handler != null) {
sendMessage(handler.obtainMessage(DO_SHUTDOWN_MESSAGE, send, 0), 0);
sendMessage(handler.obtainMessage(DO_SHUTDOWN_MESSAGE, send, ttl), 0);
}
}
@ -1682,7 +1684,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
encoder.prepareEncoder();
} catch (Exception e) {
FileLog.e(e);
encoder.handleStopRecording(0);
encoder.handleStopRecording(0, 0);
Looper.myLooper().quit();
}
break;
@ -1691,7 +1693,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (BuildVars.LOGS_ENABLED) {
FileLog.e("InstantCamera stop encoder");
}
encoder.handleStopRecording(inputMessage.arg1);
encoder.handleStopRecording(inputMessage.arg1, inputMessage.arg2);
break;
}
case MSG_VIDEOFRAME_AVAILABLE: {
@ -1777,6 +1779,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
private boolean ready;
private volatile boolean running;
private volatile int sendWhenDone;
private volatile int sendWhenDoneTTL;
private long skippedTime;
private boolean skippedFirst;
@ -1901,7 +1904,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
} catch (Exception e) {
FileLog.e(e);
}
handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, sendWhenDone, 0));
handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, sendWhenDone, sendWhenDoneTTL));
}
};
@ -1950,8 +1953,8 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
handler.sendMessage(handler.obtainMessage(MSG_START_RECORDING));
}
public void stopRecording(int send) {
handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, send, 0));
public void stopRecording(int send, int ttl) {
handler.sendMessage(handler.obtainMessage(MSG_STOP_RECORDING, send, ttl));
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
});
@ -2279,10 +2282,11 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
}
}
private void handleStopRecording(final int send) {
private void handleStopRecording(final int send, final int ttl) {
if (running) {
FileLog.d("InstantCamera handleStopRecording running=false");
sendWhenDone = send;
sendWhenDoneTTL = ttl;
running = false;
return;
}
@ -2374,13 +2378,17 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
if (send == 1) {
if (delegate.isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(delegate.getParentActivity(), delegate.getDialogId(), (notify, scheduleDate) -> {
delegate.sendMedia(new MediaController.PhotoEntry(0, 0, 0, videoFile.getAbsolutePath(), 0, true, 0, 0, 0), videoEditedInfo, notify, scheduleDate, false);
MediaController.PhotoEntry entry = new MediaController.PhotoEntry(0, 0, 0, videoFile.getAbsolutePath(), 0, true, 0, 0, 0);
entry.ttl = ttl;
delegate.sendMedia(entry, videoEditedInfo, notify, scheduleDate, false);
startAnimation(false);
}, () -> {
startAnimation(false);
}, resourcesProvider);
} else {
delegate.sendMedia(new MediaController.PhotoEntry(0, 0, 0, videoFile.getAbsolutePath(), 0, true, 0, 0, 0), videoEditedInfo, true, 0, false);
MediaController.PhotoEntry entry = new MediaController.PhotoEntry(0, 0, 0, videoFile.getAbsolutePath(), 0, true, 0, 0, 0);
entry.ttl = ttl;
delegate.sendMedia(entry, videoEditedInfo, true, 0, false);
}
} else {
videoPlayer = new VideoPlayer();

View file

@ -39,9 +39,9 @@ public class MediaActionDrawable extends Drawable {
public static final int ICON_UPDATE = 15;
private TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
public Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
public Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint paint3 = new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF rect = new RectF();
private ColorFilter colorFilter;
@ -274,7 +274,7 @@ public class MediaActionDrawable extends Drawable {
}
}
private void applyShaderMatrix(boolean path) {
public void applyShaderMatrix(boolean path) {
if (messageDrawable != null && messageDrawable.hasGradient() && !hasOverlayImage) {
android.graphics.Rect bounds = getBounds();
Shader shader = messageDrawable.getGradientShader();

View file

@ -30,7 +30,7 @@ public class MenuToItemOptions implements Menu {
@Override
public MenuItem add(int groupId, int itemId, int order, CharSequence title) {
if (premiumLock != null && FloatingToolbar.premiumOptions.contains(itemId) && MessagesController.getInstance(UserConfig.selectedAccount).premiumLocked) {
if (premiumLock != null && FloatingToolbar.premiumOptions.contains(itemId) && MessagesController.getInstance(UserConfig.selectedAccount).premiumFeaturesBlocked()) {
return null;
}
itemOptions.add(title, () -> onMenuClicked.run(itemId));

View file

@ -910,7 +910,7 @@ public class MessagePreviewView extends FrameLayout {
menu.addView(btn1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
if (!messagePreviewParams.noforwards) {
if (!messagePreviewParams.noforwards && !messagePreviewParams.hasSecretMessages) {
FrameLayout btn2 = new FrameLayout(context);
replyAnotherChatButton = new ActionBarMenuSubItem(context, true, false, false, resourcesProvider);
replyAnotherChatButton.setTextAndIcon(LocaleController.getString(R.string.ReplyToAnotherChat), R.drawable.msg_forward_replace);
@ -923,7 +923,7 @@ public class MessagePreviewView extends FrameLayout {
menu.addView(btn2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48));
}
if (!messagePreviewParams.isSecret) {
if (!messagePreviewParams.noforwards && !messagePreviewParams.hasSecretMessages) {
ActionBarPopupWindow.GapView gap2 = new ActionBarPopupWindow.GapView(context, resourcesProvider);
gap2.setTag(R.id.fit_width_tag, 1);
menu.addView(gap2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 8));

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