update to 9.4.0

This commit is contained in:
xaxtix 2023-02-03 23:11:36 +04:00
parent 2628a58147
commit 135e3cc766
433 changed files with 22076 additions and 6899 deletions

View File

@ -36,6 +36,7 @@ dependencies {
implementation 'com.google.android.gms:play-services-wearable:18.0.0'
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-wallet:19.1.0'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.stripe:stripe-android:2.0.2'
implementation 'com.google.mlkit:language-id:16.1.1'

View File

@ -18,7 +18,6 @@
<permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/AppNameBeta"

View File

@ -20,7 +20,6 @@
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/AppNameBeta"

View File

@ -18,7 +18,6 @@
<permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/AppName"

View File

@ -20,7 +20,6 @@
<permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:label="@string/AppName"

View File

@ -20,7 +20,6 @@
<permission android:name="${applicationId}.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher_sa"
android:roundIcon="@mipmap/ic_launcher_sa"
android:label="@string/AppName"

View File

@ -1057,7 +1057,7 @@ auth_Authorization *auth_Authorization::TLdeserialize(NativeByteBuffer *stream,
case 0x44747e9a:
result = new TL_auth_authorizationSignUpRequired();
break;
case 0x33fb7bb8:
case 0x2ea2c0d4:
result = new TL_auth_authorization();
break;
default:
@ -1086,9 +1086,15 @@ void TL_auth_authorizationSignUpRequired::serializeToStream(NativeByteBuffer *st
void TL_auth_authorization::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error) {
flags = stream->readInt32(&error);
if ((flags & 2) != 0) {
otherwise_relogin_days = stream->readInt32(&error);
}
if ((flags & 1) != 0) {
tmp_sessions = stream->readInt32(&error);
}
if ((flags & 4) != 0) {
future_auth_token = std::unique_ptr<ByteArray>(stream->readByteArray(&error));
}
user = std::unique_ptr<User>(User::TLdeserialize(stream, stream->readUint32(&error), instanceNum, error));
}

View File

@ -705,10 +705,12 @@ public:
class TL_auth_authorization : public auth_Authorization {
public:
static const uint32_t constructor = 0x33fb7bb8;
static const uint32_t constructor = 0x2ea2c0d4;
int32_t flags;
int32_t tmp_sessions;
int32_t otherwise_relogin_days;
std::unique_ptr<ByteArray> future_auth_token;
std::unique_ptr<User> user;
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);

View File

@ -891,10 +891,12 @@ void ConnectionsManager::onConnectionDataReceived(Connection *connection, Native
if (object != nullptr) {
if (datacenter->isHandshaking(connection->isMediaConnection)) {
if (LOGS_ENABLED) DEBUG_E("process handshake");
datacenter->processHandshakeResponse(connection->isMediaConnection, object, messageId);
} else {
processServerResponse(object, messageId, 0, 0, connection, 0, 0);
connection->addProcessedMessageId(messageId);
if (LOGS_ENABLED) DEBUG_E("connection(%p) received incorrect unencrypted message type", connection);
connection->reconnect();
return;
}
lastProtocolUsefullData = true;
connection->setHasUsefullData();

View File

@ -84,7 +84,9 @@
<application
android:name="org.telegram.messenger.ApplicationLoader"
android:allowBackup="false"
android:allowBackup="true"
android:restoreAnyVersion="true"
android:backupAgent=".BackupAgent"
android:hardwareAccelerated="@bool/useHardwareAcceleration"
android:largeHeap="true"
android:theme="@style/Theme.TMessages.Start"

View File

@ -12,7 +12,6 @@ dialogCheckboxSquareBackground=-14380561
chats_menuPhone=-1006632961
avatar_actionBarIconOrange=-8684677
chat_outViews=-1258291201
statisticChartLine_red=-2075818
avatar_actionBarSelectorCyan=-8684677
chat_secretTimerBackground=1375731712
chat_outViaBotNameText=-1
@ -33,7 +32,6 @@ player_time=-6511440
chat_outFileProgressSelected=-13332255
chat_outTimeSelectedText=-1056964609
chat_attachGalleryText=-13726231
statisticChartLine_lightblue=-10966803
switch2Track=-691072
chat_inContactNameText=-13487566
chats_menuPhoneCats=-1
@ -96,7 +94,6 @@ dialogLineProgressBackground=-3152133
chat_inReplyNameText=-13464859
chat_outAudioPerfomerSelectedText=-1
profile_title=-13224394
statisticChartLine_lightgreen=-7352519
avatar_actionBarIconRed=-8684677
chats_onlineCircle=-11810020
chat_outAudioSelectedProgress=-10907938
@ -123,10 +120,8 @@ dialogTextBlue3=-14839830
dialogTextBlue4=-15625752
actionBarTabActiveText=-13590803
chat_topPanelMessage=-8354167
statisticChartLine_golden=-1853657
calls_callReceivedGreenIcon=-13645978
chats_pinnedOverlay=100663296
statisticChartLine_green=-10369198
chat_emojiPanelBadgeBackground=-12276493
chat_inForwardedNameText=-13464859
chats_sentError=-65536
@ -175,7 +170,22 @@ picker_badge=-13261833
chat_outFileInfoSelectedText=-1056964609
chat_outAudioDurationSelectedText=-1056964609
avatar_actionBarSelectorPink=-8684677
statisticChartLine_lightblue=-10966803
statisticChartLine_blue=-13467675
statisticChartLine_golden=-1853657
statisticChartLine_green=-10369198
statisticChartLine_lightgreen=-7352519
statisticChartLine_red=-2075818
statisticChartLine_indigo=-8422925
statisticChartLine_orange=-881607
color_lightblue=-10966803
color_blue=-13467675
color_yellow=-1853657
color_green=-10369198
color_lightgreen=-7352519
color_red=-2075818
color_purple=-8422925
color_orange=-881607
chat_topPanelTitle=-281900315
chat_inAudioCacheSeekbar=1071179248
chat_outContactIcon=-13332255
@ -236,7 +246,6 @@ chat_outBubbleSelected=-13332255
avatar_backgroundInProfileBlue=-13330708
chat_lockIcon=-9211021
chat_inFileNameText=-14079703
statisticChartLine_blue=-13467675
chat_inInstantSelected=-13464859
chat_outFileInfoText=-1056964609
chat_outContactPhoneSelectedText=-1056964609
@ -286,7 +295,6 @@ chat_outAudioCacheSeekbar=738197503
chats_sentClock=2066650878
avatar_subtitleInProfileRed=-16777216
avatar_backgroundActionBarRed=-1
statisticChartLine_indigo=-8422925
dialogFloatingButton=-12081419
chats_archiveBackground=-11294989
chat_inPreviewInstantText=-15299362

View File

@ -2,7 +2,6 @@ chat_unreadMessagesStartText=-12348451
dialogTextBlue=-14510887
chat_inSentClockSelected=-7752511
chat_outViews=-259216707
statisticChartLine_red=-2075818
chat_outViaBotNameText=-14514998
profile_actionPressedBackground=-1710619
chat_inPreviewInstantSelectedText=-12940081
@ -15,7 +14,6 @@ actionBarWhiteSelector=268435456
chat_outTimeSelectedText=-8674358
chat_outFileProgressSelected=-3018241
chat_attachGalleryText=-13726231
statisticChartLine_lightblue=-10966803
chat_inContactNameText=-15654091
chats_menuPhoneCats=-2626311
chat_outPreviewLine=-12343577
@ -50,7 +48,6 @@ chat_outAudioProgress=-6239505
chat_inReplyLine=-348807706
dialogLineProgressBackground=-2035723
chat_inReplyNameText=-14643754
statisticChartLine_lightgreen=-7352519
chats_onlineCircle=-13192972
chat_outAudioSelectedProgress=-7484939
chat_inInstant=-14707230
@ -63,9 +60,7 @@ actionBarDefaultArchivedSelector=-10852240
dialogTextBlue2=-14510887
dialogTextBlue3=-15294488
dialogTextBlue4=-15294488
statisticChartLine_golden=-1853657
calls_callReceivedGreenIcon=-12475665
statisticChartLine_green=-10369198
chat_inForwardedNameText=-16220470
chats_actionBackground=-10376481
chat_outContactNameText=-14799042
@ -95,7 +90,22 @@ avatar_backgroundArchived=-4998207
chat_outFileInfoSelectedText=-8674358
chat_outAudioDurationSelectedText=-8674358
avatar_backgroundArchivedHidden=-10832396
statisticChartLine_lightblue=-10966803
statisticChartLine_blue=-13467675
statisticChartLine_indigo=-8422925
statisticChartLine_red=-2075818
statisticChartLine_lightgreen=-7352519
statisticChartLine_green=-10369198
statisticChartLine_golden=-1853657
statisticChartLine_orange=-881607
color_lightblue=-10966803
color_blue=-13467675
color_purple=-8422925
color_red=-2075818
color_lightgreen=-7352519
color_green=-10369198
color_yellow=-1853657
color_orange=-881607
chat_topPanelTitle=-13199648
chat_outContactIcon=-1
chat_inPreviewLine=-348675089
@ -128,7 +138,6 @@ chat_outFileBackground=-1295523081
dialogBadgeBackground=-13127439
chat_outBubbleSelected=-2690305
chat_inFileNameText=-15654091
statisticChartLine_blue=-13467675
chat_inInstantSelected=-14707230
chat_outFileInfoText=-7953740
chat_outContactPhoneSelectedText=-9725764
@ -159,7 +168,6 @@ chat_inViewsSelected=-7752511
chat_outMediaIcon=-1
chat_outAudioCacheSeekbar=-1029190425
chats_sentClock=-4670273
statisticChartLine_indigo=-8422925
chat_inPreviewInstantText=-14446113
chat_outLoaderSelected=-12277262
windowBackgroundWhiteGrayText2=-7565423

View File

@ -13,7 +13,6 @@ actionBarActionModeDefaultTop=-14536643
statisticChartHintLine=452984831
chats_menuPhone=-1816080163
chat_outViews=-7357217
statisticChartLine_red=-832444
chat_secretTimerBackground=-1239540194
avatar_actionBarSelectorCyan=-12758164
chat_outViaBotNameText=-7551233
@ -49,7 +48,6 @@ chat_inAudioPerfomerText=-8812393
statisticChartBackZoomColor=-12145938
player_button=-1
key_sheet_other=1140850687
statisticChartLine_lightblue=-12814100
chat_inContactNameText=-8796932
chats_menuPhoneCats=-8613724
chat_outPreviewLine=-6631937
@ -145,7 +143,6 @@ actionBarActionModeDefaultIcon=-1
windowBackgroundWhiteRedText4=-3187617
chat_goDownButtonIcon=-1
windowBackgroundWhiteRedText5=-1152913
statisticChartLine_lightgreen=-7352519
chat_outAudioSelectedProgress=-1
chat_messageTextOut=-328966
chat_inInstant=-8796932
@ -185,14 +182,12 @@ windowBackgroundWhiteGreenText=-10371737
actionBarTabActiveText=-9781249
chat_emojiPanelIcon=-9996665
chat_topPanelMessage=1859974399
statisticChartLine_golden=-2184161
statisticChartSignatureAlpha=-1946157057
chat_emojiPanelTrendingDescription=-8549479
calls_callReceivedGreenIcon=-12001930
chats_pinnedOverlay=150994943
windowBackgroundWhiteInputField=-12035217
avatar_backgroundRed=-1545110
statisticChartLine_green=-12729793
chat_emojiPanelIconSelector=-10177041
chat_emojiPanelBadgeBackground=-11291403
chat_inForwardedNameText=-8796932
@ -260,7 +255,22 @@ premiumGradientBackground2=-15394271
premiumStarGradient1=-15436801
premiumStarGradient2=-4167942
dialogTextHint=-8549479
statisticChartLine_blue=-11362305
statisticChartLine_indigo=-7906078
statisticChartLine_red=-832444
statisticChartLine_lightblue=-12814100
statisticChartLine_lightgreen=-7352519
statisticChartLine_golden=-2184161
statisticChartLine_green=-12729793
statisticChartLine_orange=-881607
color_blue=-11362305
color_purple=-7906078
color_red=-832444
color_lightblue=-12814100
color_lightgreen=-7352519
color_yellow=-2184161
color_green=-12729793
color_orange=-881607
chat_topPanelTitle=-9719066
chat_inAudioCacheSeekbar=-11443856
chat_outContactIcon=-1
@ -340,7 +350,6 @@ dialogBadgeBackground=-10177041
chat_outBubbleSelected=-11829841
avatar_backgroundInProfileBlue=-11232035
chat_inFileNameText=-1
statisticChartLine_blue=-11362305
inappPlayerPerformer=-1
chat_inInstantSelected=-5648402
chat_outFileInfoText=-7357217
@ -416,7 +425,6 @@ chats_sentClock=-11772054
chat_inAudioSeekbar=-11443856
avatar_subtitleInProfileRed=-7628894
avatar_backgroundActionBarRed=-14602949
statisticChartLine_indigo=-7906078
dialogSearchIcon=-8945521
chat_inPreviewInstantText=-8796932
chats_archiveBackground=-11036980

View File

@ -13,7 +13,6 @@ dialogCheckboxSquareBackground=-14380561
chats_menuPhone=-1006632961
avatar_actionBarIconOrange=-8684677
chat_outViews=-3676417
statisticChartLine_red=-2075818
avatar_actionBarSelectorCyan=-8684677
chat_secretTimerBackground=-12629421
chat_outViaBotNameText=-1
@ -34,7 +33,6 @@ chat_outFileProgressSelected=-14707997
chat_outTimeSelectedText=-3348225
chat_inFileProgressSelected=-1
chat_attachGalleryText=-13726231
statisticChartLine_lightblue=-10966803
switch2Track=-691072
chat_inContactNameText=-13487566
chats_menuPhoneCats=-1
@ -102,7 +100,6 @@ dialogLineProgressBackground=-3348999
chat_inReplyNameText=-13531425
chat_outAudioPerfomerSelectedText=-1
profile_title=-13224394
statisticChartLine_lightgreen=-6368184
avatar_actionBarIconRed=-8684677
chats_onlineCircle=-14047001
chat_outAudioSelectedProgress=-12155183
@ -131,11 +128,9 @@ dialogTextBlue4=-15625752
actionBarTabActiveText=-15755027
chat_topPanelMessage=-8419703
chat_stickerNameText=-1
statisticChartLine_golden=-1853657
calls_callReceivedGreenIcon=-13645978
chat_botButtonText=-13816531
chats_pinnedOverlay=100663296
statisticChartLine_green=-10369198
chat_stickerReplyNameText=-13923877
chat_emojiPanelBadgeBackground=-12081165
chat_inForwardedNameText=-13597734
@ -189,7 +184,22 @@ chat_outFileInfoSelectedText=-3676417
chat_outAudioDurationSelectedText=-3676417
avatar_backgroundArchivedHidden=-12208385
avatar_actionBarSelectorPink=-8684677
statisticChartLine_blue=-13467675
statisticChartLine_indigo=-8422925
statisticChartLine_red=-2075818
statisticChartLine_lightblue=-10966803
statisticChartLine_lightgreen=-6368184
statisticChartLine_golden=-1853657
statisticChartLine_green=-10369198
statisticChartLine_orange=-881607
color_blue=-13467675
color_purple=-8422925
color_red=-2075818
color_lightblue=-10966803
color_lightgreen=-6368184
color_yellow=-1853657
color_green=-10369198
color_orange=-881607
chat_topPanelTitle=-12478747
chat_inAudioCacheSeekbar=1071179248
chat_outContactIcon=-14707997
@ -255,7 +265,6 @@ chat_outBubbleSelected=-12418863
avatar_backgroundInProfileBlue=-13330708
chat_lockIcon=-13816531
chat_inFileNameText=-14079703
statisticChartLine_blue=-13467675
chat_inInstantSelected=-15234594
chat_outFileInfoText=-3676417
chat_inLocationIcon=-6379862
@ -310,7 +319,6 @@ chats_sentClock=2073474246
chat_inAudioSeekbar=-2762017
avatar_subtitleInProfileRed=-16777216
avatar_backgroundActionBarRed=-1
statisticChartLine_indigo=-8422925
dialogFloatingButton=-12081419
chats_archiveBackground=-11294989
chat_inPreviewInstantText=-15300135

View File

@ -12,7 +12,6 @@ actionBarActionModeDefaultTop=-14277082
statisticChartHintLine=452984831
chats_menuPhone=-1815557944
chat_outViews=-7357217
statisticChartLine_red=-832444
chat_secretTimerBackground=-1239540194
avatar_actionBarSelectorCyan=-12758164
chat_outViaBotNameText=-5448193
@ -49,7 +48,6 @@ chat_inAudioPerfomerText=-8749955
statisticChartBackZoomColor=-12145938
player_button=-1
key_sheet_other=1140850687
statisticChartLine_lightblue=-12814100
chat_inContactNameText=-8796932
chats_menuPhoneCats=-8224126
chat_outPreviewLine=-6631937
@ -149,7 +147,6 @@ actionBarActionModeDefaultIcon=-1
windowBackgroundWhiteRedText4=-3187617
chat_goDownButtonIcon=-1
windowBackgroundWhiteRedText5=-1152913
statisticChartLine_lightgreen=-7352519
chats_onlineCircle=-13130503
chat_outAudioSelectedProgress=-1
chat_messageTextOut=-328966
@ -195,7 +192,6 @@ windowBackgroundWhiteGreenText=-10371737
actionBarTabActiveText=-10698241
chat_emojiPanelIcon=-9539985
chat_topPanelMessage=1694498815
statisticChartLine_golden=-2184161
statisticChartSignatureAlpha=-1946157057
chat_emojiSearchIcon=-9211020
chat_emojiPanelTrendingDescription=-8553090
@ -204,7 +200,6 @@ chats_pinnedOverlay=201326591
windowBackgroundWhiteInputField=-11513776
avatar_backgroundRed=-2326437
avatar_background2Red=-2863816
statisticChartLine_green=-12729793
chat_emojiPanelIconSelector=-10177041
chat_emojiPanelBadgeBackground=-11291403
chat_inForwardedNameText=-8930052
@ -278,7 +273,22 @@ premiumGradientBackground2=-16645625
premiumStarGradient1=-2342678
premiumStarGradient2=-9992961
dialogTextHint=-8553091
statisticChartLine_blue=-11362305
statisticChartLine_indigo=-7906075
statisticChartLine_red=-832444
statisticChartLine_lightblue=-12814100
statisticChartLine_lightgreen=-7352519
statisticChartLine_golden=-2184161
statisticChartLine_green=-12729793
statisticChartLine_orange=-881607
color_blue=-11362305
color_purple=-7906075
color_red=-832444
color_lightblue=-12814100
color_lightgreen=-7352519
color_yellow=-2184161
color_green=-12729793
color_orange=-881607
chat_topPanelTitle=-10440716
chat_inAudioCacheSeekbar=-10461088
chat_outContactIcon=-1
@ -360,7 +370,6 @@ dialogBadgeBackground=-10177041
chat_outBubbleSelected=-11829841
avatar_backgroundInProfileBlue=-11232035
chat_inFileNameText=-1
statisticChartLine_blue=-11362305
inappPlayerPerformer=-1
chat_inInstantSelected=-5648402
chat_outFileInfoText=-7357217
@ -441,7 +450,6 @@ chats_sentClock=-9539986
chat_inAudioSeekbar=-11119018
avatar_subtitleInProfileRed=-7628894
avatar_backgroundActionBarRed=-14602949
statisticChartLine_indigo=-7906075
dialogSearchIcon=-8882056
chat_inPreviewInstantText=-8796932
chats_archiveBackground=-12219694

View File

@ -338,6 +338,10 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void onChangeAnimationUpdate(RecyclerView.ViewHolder holder) {
}
protected void beforeAnimateMoveImpl(final RecyclerView.ViewHolder holder) {
}
@ -346,6 +350,14 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
}
protected void beforeAnimateChangeImpl(final RecyclerView.ViewHolder oldHolder, final RecyclerView.ViewHolder newHolder) {
}
protected void afterAnimateChangeImpl(final RecyclerView.ViewHolder oldHolder, final RecyclerView.ViewHolder newHolder) {
}
protected void animateMoveImpl(final RecyclerView.ViewHolder holder, MoveInfo moveInfo) {
int fromX = moveInfo.fromX;
int fromY = moveInfo.fromY;
@ -445,6 +457,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
beforeAnimateChangeImpl(changeInfo.oldHolder, changeInfo.newHolder);
if (view != null) {
final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(getChangeRemoveDuration()).setStartDelay(getChangeDelay());
mChangeAnimations.add(changeInfo.oldHolder);
@ -457,6 +470,9 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
.scaleX(1f - animateByScale(view))
.scaleY(1f - animateByScale(view));
}
if (Build.VERSION.SDK_INT >= 19) {
oldViewAnim.setUpdateListener(animation1 -> onChangeAnimationUpdate(changeInfo.oldHolder));
}
oldViewAnim
.setInterpolator(getChangeInterpolator())
.setListener(new AnimatorListenerAdapter() {
@ -493,6 +509,9 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
if (animateByScale(newView) > 0) {
newViewAnimation.scaleX(1f).scaleY(1f);
}
if (Build.VERSION.SDK_INT >= 19) {
newViewAnimation.setUpdateListener(animation1 -> onChangeAnimationUpdate(changeInfo.newHolder));
}
newViewAnimation
.setListener(new AnimatorListenerAdapter() {
@Override
@ -512,6 +531,8 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
dispatchChangeFinished(changeInfo.newHolder, false);
mChangeAnimations.remove(changeInfo.newHolder);
dispatchFinishedWhenDone();
afterAnimateChangeImpl(changeInfo.oldHolder, changeInfo.newHolder);
}
}).start();
}

View File

@ -541,6 +541,27 @@ public class AndroidUtilities {
recycleBitmaps(Collections.singletonList(image));
}
public static boolean findClickableView(ViewGroup container, float x, float y) {
for (int i = 0; i < container.getChildCount(); i++) {
View child = container.getChildAt(i);
if (child.getVisibility() != View.VISIBLE) {
continue;
}
if (child.isClickable()) {
return true;
} else if (child instanceof ViewGroup && findClickableView((ViewGroup) child, x - child.getX(), y - child.getY())) {
return true;
}
}
return false;
}
public static void removeFromParent(View child) {
if (child.getParent() != null) {
((ViewGroup) child.getParent()).removeView(child);
}
}
private static class LinkSpec {
String url;
int start;
@ -2193,12 +2214,20 @@ public class AndroidUtilities {
if (!hasCallPermissions) {
return null;
}
String order;
Bundle selectionArgs;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
order = "date DESC";
} else {
order = "date DESC LIMIT 5";
}
try (Cursor cursor = ApplicationLoader.applicationContext.getContentResolver().query(
CallLog.Calls.CONTENT_URI,
new String[]{CallLog.Calls.NUMBER, CallLog.Calls.DATE},
CallLog.Calls.TYPE + " IN (" + CallLog.Calls.MISSED_TYPE + "," + CallLog.Calls.INCOMING_TYPE + "," + CallLog.Calls.REJECTED_TYPE + ")",
null,
"date DESC LIMIT 5")) {
order
)) {
while (cursor.moveToNext()) {
String number = cursor.getString(0);
long date = cursor.getLong(1);
@ -2926,7 +2955,9 @@ public class AndroidUtilities {
}
public static String formatFileSize(long size, boolean removeZero) {
if (size < 1024) {
if (size == 0) {
return String.format("%d KB", 0);
} else if (size < 1024) {
return String.format("%d B", size);
} else if (size < 1024 * 1024) {
float value = size / 1024.0f;
@ -2935,7 +2966,7 @@ public class AndroidUtilities {
} else {
return String.format("%.1f KB", value);
}
} else if (size < 1024 * 1024 * 1024) {
} else if (size < 1000 * 1024 * 1024) {
float value = size / 1024.0f / 1024.0f;
if (removeZero && (value - (int) value) * 10 == 0) {
return String.format("%d MB", (int) value);
@ -3633,7 +3664,7 @@ public class AndroidUtilities {
lineView.setBackgroundColor(Theme.getColor(Theme.key_divider));
linearLayout.addView(lineView, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1));
}
for (int a = 0; a < 5; a++) {
for (int a = 0; a < 6; a++) {
String text = null;
String detail = null;
if (a == 0) {
@ -3651,6 +3682,9 @@ public class AndroidUtilities {
} else if (a == 4) {
text = password;
detail = LocaleController.getString("UseProxyPassword", R.string.UseProxyPassword);
} else if (a == 5) {
text = LocaleController.getString(R.string.Checking);
detail = LocaleController.getString(R.string.ProxyStatus);
}
if (TextUtils.isEmpty(text)) {
continue;
@ -3660,8 +3694,22 @@ public class AndroidUtilities {
cell.getTextView().setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
cell.getValueTextView().setTextColor(Theme.getColor(Theme.key_dialogTextGray3));
linearLayout.addView(cell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (a == 2) {
break;
if (a == 5) {
try {
ConnectionsManager.getInstance(UserConfig.selectedAccount).checkProxy(address, Integer.parseInt(port), user, password, secret, time -> AndroidUtilities.runOnUIThread(() -> {
if (time == -1) {
cell.getTextView().setText(LocaleController.getString(R.string.Unavailable));
cell.getTextView().setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
} else {
cell.getTextView().setText(LocaleController.getString(R.string.Available) + ", " + LocaleController.formatString(R.string.Ping, time));
cell.getTextView().setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGreenText));
}
}));
} catch (NumberFormatException ignored) {
cell.getTextView().setText(LocaleController.getString(R.string.Unavailable));
cell.getTextView().setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteRedText4));
}
}
}
@ -4664,18 +4712,36 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static CharSequence replaceMultipleCharSequence(String what, CharSequence from, CharSequence obj) {
SpannableStringBuilder spannableStringBuilder;
if (from instanceof SpannableStringBuilder) {
spannableStringBuilder = (SpannableStringBuilder) from;
} else {
spannableStringBuilder = new SpannableStringBuilder(from);
}
int index = TextUtils.indexOf(from, what);
while (index >= 0) {
spannableStringBuilder.replace(index, index + what.length(), obj);
index = TextUtils.indexOf(spannableStringBuilder, what);
}
return spannableStringBuilder;
}
public static Bitmap makeBlurBitmap(View view) {
return makeBlurBitmap(view, 6f, 7);
}
public static Bitmap makeBlurBitmap(View view, float downscale, int maxRadius) {
if (view == null) {
return null;
}
int w = (int) (view.getWidth() / 6.0f);
int h = (int) (view.getHeight() / 6.0f);
int w = (int) (view.getWidth() / downscale);
int h = (int) (view.getHeight() / downscale);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.scale(1.0f / 6.0f, 1.0f / 6.0f);
canvas.scale(1.0f / downscale, 1.0f / downscale);
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite));
view.draw(canvas);
Utilities.stackBlurBitmap(bitmap, Math.max(7, Math.max(w, h) / 180));
Utilities.stackBlurBitmap(bitmap, Math.max(maxRadius, Math.max(w, h) / 180));
return bitmap;
}
@ -4808,4 +4874,54 @@ public class AndroidUtilities {
return output;
}
public static boolean isRTL(CharSequence text) {
if (text == null || text.length() <= 0) {
return false;
}
char c;
for (int i = 0; i < text.length(); ++i) {
c = text.charAt(i);
if (c >= 0x590 && c <= 0x6ff) {
return true;
}
}
return false;
}
private static Pattern uriParse;
private static Pattern getURIParsePattern() {
if (uriParse == null) {
uriParse = Pattern.compile("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"); // RFC 3986 B
}
return uriParse;
}
public static String getHostAuthority(String uri) {
if (uri == null) {
return null;
}
// CVE-2017-13274
Matcher matcher = getURIParsePattern().matcher(uri);
if (matcher.matches()) {
String authority = matcher.group(4);
if (authority != null) {
authority = authority.toLowerCase();
}
return authority;
}
return null;
}
public static String getHostAuthority(Uri uri) {
if (uri == null) {
return null;
}
return getHostAuthority(uri.toString());
}
public static boolean intersect1d(int x1, int x2, int y1, int y2) {
return Math.max(x1, x2) >= Math.min(y1, y2) && Math.max(y1, y2) >= Math.min(x1, x2);
}
}

View File

@ -278,6 +278,7 @@ public class ApplicationLoader extends Application {
AndroidUtilities.runOnUIThread(ApplicationLoader::startPushService);
LauncherIconController.tryFixLauncherIconIfNeeded();
ProxyRotationController.init();
}
public static void startPushService() {

View File

@ -0,0 +1,119 @@
package org.telegram.messenger;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.android.exoplayer2.util.Log;
import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLRPC;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
public class AuthTokensHelper {
public static ArrayList<TLRPC.TL_auth_loggedOut> getSavedLogOutTokens() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
if (count == 0) {
return null;
}
ArrayList<TLRPC.TL_auth_loggedOut> tokens = new ArrayList<>();
for (int i = 0; i < count; i++) {
String value = preferences.getString("log_out_token_" + i, "");
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
TLRPC.TL_auth_loggedOut token = TLRPC.TL_auth_loggedOut.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (token != null) {
tokens.add(token);
}
}
return tokens;
}
public static void saveLogOutTokens(ArrayList<TLRPC.TL_auth_loggedOut> tokens) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
ArrayList<TLRPC.TL_auth_loggedOut> activeTokens = new ArrayList<>();
preferences.edit().clear().apply();
int date = (int) (System.currentTimeMillis() / 1000L);
for (int i = 0; i < Math.min(20, tokens.size()); i++) {
activeTokens.add(tokens.get(i));
}
if (activeTokens.size() > 0) {
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("count", activeTokens.size());
for (int i = 0; i < activeTokens.size(); i++) {
SerializedData data = new SerializedData(activeTokens.get(i).getObjectSize());
activeTokens.get(i).serializeToStream(data);
editor.putString("log_out_token_" + i, Utilities.bytesToHex(data.toByteArray()));
}
editor.apply();
// BackupAgent.requestBackup(ApplicationLoader.applicationContext);
}
}
public static ArrayList<TLRPC.TL_auth_authorization> getSavedLogInTokens() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens_login", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
if (count == 0) {
return null;
}
ArrayList<TLRPC.TL_auth_authorization> tokens = new ArrayList<>();
for (int i = 0; i < count; i++) {
String value = preferences.getString("log_in_token_" + i, "");
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
TLRPC.auth_Authorization token = TLRPC.auth_Authorization.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (token instanceof TLRPC.TL_auth_authorization) {
tokens.add((TLRPC.TL_auth_authorization) token);
}
}
return tokens;
}
public static void saveLogInToken(TLRPC.TL_auth_authorization token) {
if (BuildVars.DEBUG_VERSION) {
FileLog.d("saveLogInToken " + new String(token.future_auth_token, StandardCharsets.UTF_8));
}
ArrayList<TLRPC.TL_auth_authorization> tokens = getSavedLogInTokens();
if (tokens == null) {
tokens = new ArrayList<>();
}
tokens.add(0, token);
saveLogInTokens(tokens);
}
private static void saveLogInTokens(ArrayList<TLRPC.TL_auth_authorization> tokens) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens_login", Context.MODE_PRIVATE);
ArrayList<TLRPC.TL_auth_authorization> activeTokens = new ArrayList<>();
preferences.edit().clear().apply();
for (int i = 0; i < Math.min(20, tokens.size()); i++) {
activeTokens.add(tokens.get(i));
}
if (activeTokens.size() > 0) {
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("count", activeTokens.size());
for (int i = 0; i < activeTokens.size(); i++) {
SerializedData data = new SerializedData(activeTokens.get(i).getObjectSize());
activeTokens.get(i).serializeToStream(data);
editor.putString("log_in_token_" + i, Utilities.bytesToHex(data.toByteArray()));
}
editor.apply();
BackupAgent.requestBackup(ApplicationLoader.applicationContext);
}
}
public static void addLogOutToken(TLRPC.TL_auth_loggedOut response) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
SerializedData data = new SerializedData(response.getObjectSize());
response.serializeToStream(data);
preferences.edit().putString("log_out_token_" + count, Utilities.bytesToHex(data.toByteArray())).putInt("count", count + 1).apply();
BackupAgent.requestBackup(ApplicationLoader.applicationContext);
}
}

View File

@ -0,0 +1,35 @@
package org.telegram.messenger;
import android.app.backup.BackupAgentHelper;
import android.app.backup.BackupDataInput;
import android.app.backup.BackupDataOutput;
import android.app.backup.BackupManager;
import android.app.backup.FullBackupDataOutput;
import android.app.backup.RestoreObserver;
import android.app.backup.SharedPreferencesBackupHelper;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
import org.telegram.tgnet.TLRPC;
import java.io.IOException;
import java.util.ArrayList;
public class BackupAgent extends BackupAgentHelper {
private static BackupManager backupManager;
@Override
public void onCreate() {
SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, "saved_tokens", "saved_tokens_login");
addHelper("prefs", helper);
}
public static void requestBackup(Context context) {
if (backupManager == null) {
backupManager = new BackupManager(context);
}
backupManager.dataChanged();
}
}

View File

@ -54,6 +54,8 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
private Map<String, Consumer<BillingResult>> resultListeners = new HashMap<>();
private List<String> requestingTokens = new ArrayList<>();
private String lastPremiumTransaction;
private String lastPremiumToken;
private Map<String, Integer> currencyExpMap = new HashMap<>();
@ -73,6 +75,14 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
.build();
}
public String getLastPremiumTransaction() {
return lastPremiumTransaction;
}
public String getLastPremiumToken() {
return lastPremiumToken;
}
public String formatCurrency(long amount, String currency) {
return formatCurrency(amount, currency, getCurrencyExp(currency));
}
@ -156,10 +166,10 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
}
public void launchBillingFlow(Activity activity, AccountInstance accountInstance, TLRPC.InputStorePaymentPurpose paymentPurpose, List<BillingFlowParams.ProductDetailsParams> productDetails) {
launchBillingFlow(activity, accountInstance, paymentPurpose, productDetails, false);
launchBillingFlow(activity, accountInstance, paymentPurpose, productDetails, null, false);
}
public void launchBillingFlow(Activity activity, AccountInstance accountInstance, TLRPC.InputStorePaymentPurpose paymentPurpose, List<BillingFlowParams.ProductDetailsParams> productDetails, boolean checkedConsume) {
public void launchBillingFlow(Activity activity, AccountInstance accountInstance, TLRPC.InputStorePaymentPurpose paymentPurpose, List<BillingFlowParams.ProductDetailsParams> productDetails, BillingFlowParams.SubscriptionUpdateParams subscriptionUpdateParams, boolean checkedConsume) {
if (!isReady() || activity == null) {
return;
}
@ -167,7 +177,7 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
if (paymentPurpose instanceof TLRPC.TL_inputStorePaymentGiftPremium && !checkedConsume) {
queryPurchases(BillingClient.ProductType.INAPP, (billingResult, list) -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Runnable callback = () -> launchBillingFlow(activity, accountInstance, paymentPurpose, productDetails, true);
Runnable callback = () -> launchBillingFlow(activity, accountInstance, paymentPurpose, productDetails, subscriptionUpdateParams, true);
AtomicInteger productsToBeConsumed = new AtomicInteger(0);
List<String> productsConsumed = new ArrayList<>();
@ -205,9 +215,12 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
return;
}
boolean ok = billingClient.launchBillingFlow(activity, BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetails)
.build()).getResponseCode() == BillingClient.BillingResponseCode.OK;
BillingFlowParams.Builder flowParams = BillingFlowParams.newBuilder()
.setProductDetailsParamsList(productDetails);
if (subscriptionUpdateParams != null) {
flowParams.setSubscriptionUpdateParams(subscriptionUpdateParams);
}
boolean ok = billingClient.launchBillingFlow(activity, flowParams.build()).getResponseCode() == BillingClient.BillingResponseCode.OK;
if (ok) {
for (BillingFlowParams.ProductDetailsParams params : productDetails) {
@ -240,7 +253,13 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
if (list == null) {
return;
}
lastPremiumTransaction = null;
for (Purchase purchase : list) {
if (purchase.getProducts().contains(PREMIUM_PRODUCT_ID)) {
lastPremiumTransaction = purchase.getOrderId();
lastPremiumToken = purchase.getPurchaseToken();
}
if (!requestingTokens.contains(purchase.getPurchaseToken())) {
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++) {
AccountInstance acc = AccountInstance.getInstance(i);

View File

@ -24,11 +24,13 @@ 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 = 3026;
public static String BUILD_VERSION_STRING = "9.3.3";
public static int BUILD_VERSION = 3098;
public static String BUILD_VERSION_STRING = "9.4.0";
public static int APP_ID = 4;
public static String APP_HASH = "014b35b6184100b085b0d0572f9b5103";
// SafetyNet key for Google Identity SDK, set it to empty to disable
public static String SAFETYNET_KEY = "AIzaSyDqt8P-7F7CPCseMkOiVRgb1LY8RN1bvH8";
public static String SMS_HASH = isStandaloneApp() ? "w0lkcmTZkKh" : (DEBUG_VERSION ? "O2P2z+/jBpJ" : "oLeq9AcOZkT");
public static String PLAYSTORE_APP_URL = "https://play.google.com/store/apps/details?id=org.telegram.messenger";
public static String GOOGLE_AUTH_CLIENT_ID = "760348033671-81kmi3pi84p11ub8hp9a1funsv0rn2p9.apps.googleusercontent.com";

View File

@ -38,6 +38,7 @@ public class ChatObject {
public static final int CHAT_TYPE_CHANNEL = 2;
public static final int CHAT_TYPE_USER = 3;
public static final int CHAT_TYPE_MEGAGROUP = 4;
public static final int CHAT_TYPE_FORUM = 5;
public static final int ACTION_PIN = 0;
public static final int ACTION_CHANGE_INFO = 1;
@ -46,6 +47,7 @@ public class ChatObject {
public static final int ACTION_ADD_ADMINS = 4;
public static final int ACTION_POST = 5;
public static final int ACTION_SEND = 6;
public static final int ACTION_SEND_TEXT = 22;
public static final int ACTION_SEND_MEDIA = 7;
public static final int ACTION_SEND_STICKERS = 8;
public static final int ACTION_EMBED_LINKS = 9;
@ -56,6 +58,15 @@ public class ChatObject {
public static final int ACTION_MANAGE_CALLS = 14;
public static final int ACTION_MANAGE_TOPICS = 15;
public static final int ACTION_SEND_PHOTO = 16;
public static final int ACTION_SEND_VIDEO = 17;
public static final int ACTION_SEND_MUSIC = 18;
public static final int ACTION_SEND_DOCUMENTS = 19;
public static final int ACTION_SEND_VOICE = 20;
public static final int ACTION_SEND_ROUND = 21;
public static final int ACTION_SEND_PLAIN = 22;
public static final int ACTION_SEND_GIFS = 23;
public final static int VIDEO_FRAME_NO_FRAME = 0;
public final static int VIDEO_FRAME_REQUESTING = 1;
public final static int VIDEO_FRAME_HAS_FRAME = 2;
@ -85,6 +96,61 @@ public class ChatObject {
return false;
}
public static boolean canSendAnyMedia(TLRPC.Chat currentChat) {
return canSendPhoto(currentChat) || canSendVideo(currentChat) || canSendRoundVideo(currentChat)|| canSendVoice(currentChat) || canSendDocument(currentChat) || canSendMusic(currentChat) || canSendStickers(currentChat);
}
public static String getAllowedSendString(TLRPC.Chat chat) {
StringBuilder stringBuilder = new StringBuilder();
if (ChatObject.canSendPhoto(chat)) {
stringBuilder.append(LocaleController.getString("SendMediaPermissionPhotos", R.string.SendMediaPermissionPhotos));
}
if (ChatObject.canSendVideo(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaPermissionVideos", R.string.SendMediaPermissionVideos));
}
if (ChatObject.canSendStickers(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaPermissionStickersGifs", R.string.SendMediaPermissionStickersGifs));
}
if (ChatObject.canSendMusic(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaPermissionMusic", R.string.SendMediaPermissionMusic));
}
if (ChatObject.canSendDocument(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaPermissionFiles", R.string.SendMediaPermissionFiles));
}
if (ChatObject.canSendVoice(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaPermissionVoice", R.string.SendMediaPermissionVoice));
}
if (ChatObject.canSendRoundVideo(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaPermissionRound", R.string.SendMediaPermissionRound));
}
if (ChatObject.canSendEmbed(chat)) {
if (stringBuilder.length() > 0) {
stringBuilder.append(", ");
}
stringBuilder.append(LocaleController.getString("SendMediaEmbededLinks", R.string.SendMediaEmbededLinks));
}
return stringBuilder.toString();
}
public static class Call {
public final static int RECORD_TYPE_AUDIO = 0,
RECORD_TYPE_VIDEO_PORTAIT = 1,
@ -1412,6 +1478,13 @@ public class ChatObject {
case ACTION_SEND_POLLS:
case ACTION_VIEW:
case ACTION_MANAGE_TOPICS:
case ACTION_SEND_PHOTO:
case ACTION_SEND_VIDEO:
case ACTION_SEND_MUSIC:
case ACTION_SEND_DOCUMENTS:
case ACTION_SEND_VOICE:
case ACTION_SEND_ROUND:
case ACTION_SEND_PLAIN:
return true;
}
return false;
@ -1459,14 +1532,31 @@ public class ChatObject {
return rights.view_messages;
case ACTION_MANAGE_TOPICS:
return rights.manage_topics;
case ACTION_SEND_PHOTO:
return rights.send_photos;
case ACTION_SEND_VIDEO:
return rights.send_videos;
case ACTION_SEND_MUSIC:
return rights.send_audios;
case ACTION_SEND_DOCUMENTS:
return rights.send_docs;
case ACTION_SEND_VOICE:
return rights.send_voices;
case ACTION_SEND_ROUND:
return rights.send_roundvideos;
case ACTION_SEND_PLAIN:
return rights.send_plain;
}
return false;
}
public static boolean isActionBannedByDefault(TLRPC.Chat chat, int action) {
if (getBannedRight(chat.banned_rights, action)) {
if (chat == null) {
return false;
}
if (getBannedRight(chat.banned_rights, action) && getBannedRight(chat.default_banned_rights, action)) {
return true;
}
return getBannedRight(chat.default_banned_rights, action);
}
@ -1628,8 +1718,31 @@ public class ChatObject {
return canUserDoAction(chat, ACTION_EMBED_LINKS);
}
public static boolean canSendMedia(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_MEDIA);
// public static boolean canSendMedia(TLRPC.Chat chat) {
// return canUserDoAction(chat, ACTION_SEND_MEDIA);
// }
public static boolean canSendPhoto(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_PHOTO);
}
public static boolean canSendVideo(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_VIDEO);
}
public static boolean canSendMusic(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_MUSIC);
}
public static boolean canSendDocument(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_DOCUMENTS);
}
public static boolean canSendVoice(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_VOICE);
}
public static boolean canSendRoundVideo(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_ROUND);
}
public static boolean canSendPolls(TLRPC.Chat chat) {
@ -1640,6 +1753,10 @@ public class ChatObject {
return canUserDoAction(chat, ACTION_SEND);
}
public static boolean canSendPlain(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_SEND_PLAIN);
}
public static boolean canPost(TLRPC.Chat chat) {
return canUserDoAction(chat, ACTION_POST);
}
@ -1760,6 +1877,13 @@ public class ChatObject {
currentBannedRights += bannedRights.change_info ? 1 : 0;
currentBannedRights += bannedRights.pin_messages ? 1 : 0;
currentBannedRights += bannedRights.manage_topics ? 1 : 0;
currentBannedRights += bannedRights.send_photos ? 1 : 0;
currentBannedRights += bannedRights.send_videos ? 1 : 0;
currentBannedRights += bannedRights.send_roundvideos ? 1 : 0;
currentBannedRights += bannedRights.send_voices ? 1 : 0;
currentBannedRights += bannedRights.send_audios ? 1 : 0;
currentBannedRights += bannedRights.send_docs ? 1 : 0;
currentBannedRights += bannedRights.send_plain ? 1 : 0;
currentBannedRights += bannedRights.until_date;
return currentBannedRights;
}
@ -1819,6 +1943,93 @@ public class ChatObject {
return !TextUtils.isEmpty(getPublicUsername(chat));
}
public static String getRestrictedErrorText(TLRPC.Chat chat, int action) {
if (action == ACTION_SEND_GIFS) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachGifRestricted", R.string.GlobalAttachGifRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachGifRestrictedForever", R.string.AttachGifRestrictedForever);
} else {
return LocaleController.formatString("AttachGifRestricted", R.string.AttachGifRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_STICKERS) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachStickersRestricted", R.string.GlobalAttachStickersRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachStickersRestrictedForever", R.string.AttachStickersRestrictedForever);
} else {
return LocaleController.formatString("AttachStickersRestricted", R.string.AttachStickersRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_PHOTO) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachPhotoRestricted", R.string.GlobalAttachPhotoRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachPhotoRestrictedForever", R.string.AttachPhotoRestrictedForever);
} else {
return LocaleController.formatString("AttachPhotoRestricted", R.string.AttachPhotoRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_VIDEO) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachVideoRestricted", R.string.GlobalAttachVideoRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachVideoRestrictedForever", R.string.AttachVideoRestrictedForever);
} else {
return LocaleController.formatString("AttachVideoRestricted", R.string.AttachVideoRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_DOCUMENTS) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachDocumentsRestricted", R.string.GlobalAttachDocumentsRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachDocumentsRestrictedForever", R.string.AttachDocumentsRestrictedForever);
} else {
return LocaleController.formatString("AttachDocumentsRestricted", R.string.AttachDocumentsRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_MEDIA) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachMediaRestricted", R.string.GlobalAttachMediaRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachMediaRestrictedForever", R.string.AttachMediaRestrictedForever);
} else {
return LocaleController.formatString("AttachMediaRestricted", R.string.AttachMediaRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_MUSIC) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachAudioRestricted", R.string.GlobalAttachAudioRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachAudioRestrictedForever", R.string.AttachAudioRestrictedForever);
} else {
return LocaleController.formatString("AttachAudioRestricted", R.string.AttachAudioRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_PLAIN) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachPlainRestricted", R.string.GlobalAttachPlainRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachPlainRestrictedForever", R.string.AttachPlainRestrictedForever);
} else {
return LocaleController.formatString("AttachPlainRestricted", R.string.AttachPlainRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_ROUND) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachRoundRestricted", R.string.GlobalAttachRoundRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachRoundRestrictedForever", R.string.AttachRoundRestrictedForever);
} else {
return LocaleController.formatString("AttachRoundRestricted", R.string.AttachRoundRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
} else if (action == ACTION_SEND_VOICE) {
if (chat == null || ChatObject.isActionBannedByDefault(chat, action)) {
return LocaleController.getString("GlobalAttachVoiceRestricted", R.string.GlobalAttachVoiceRestricted);
} else if (AndroidUtilities.isBannedForever(chat.banned_rights)) {
return LocaleController.formatString("AttachVoiceRestrictedForever", R.string.AttachVoiceRestrictedForever);
} else {
return LocaleController.formatString("AttachVoiceRestricted", R.string.AttachVoiceRestricted, LocaleController.formatDateForBan(chat.banned_rights.until_date));
}
}
return "";
}
public static class VideoParticipant {
public TLRPC.TL_groupCallParticipant participant;

View File

@ -762,7 +762,7 @@ public class ContactsController extends BaseController {
String lookup_key = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
String name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String phone = null;
if (contactsMap.get(lookup_key) != null || TextUtils.isEmpty(name)) {
if ((contactsMap != null && contactsMap.get(lookup_key) != null) || TextUtils.isEmpty(name)) {
continue;
}
pCur = cr.query(

View File

@ -1218,6 +1218,12 @@ public class DatabaseMigrationHelper {
version = 111;
}
if (version == 111) {
database.executeFast("CREATE TABLE emoji_groups(type INTEGER PRIMARY KEY, data BLOB)").stepThis().dispose();
database.executeFast("PRAGMA user_version = 112").stepThis().dispose();
version = 112;
}
return version;
}
}

View File

@ -116,7 +116,10 @@ public class DocumentObject {
int w = 512, h = 512;
for (int a = 0, N = document.attributes.size(); a < N; a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeImageSize) {
if (
attribute instanceof TLRPC.TL_documentAttributeImageSize ||
attribute instanceof TLRPC.TL_documentAttributeVideo
) {
w = attribute.w;
h = attribute.h;
break;

View File

@ -64,6 +64,15 @@ public class Emoji {
public static float emojiDrawingYOffset;
public static boolean emojiDrawingUseAlpha = true;
private static String[] DEFAULT_RECENT = new String[]{
"\uD83D\uDE02", "\uD83D\uDE18", "\u2764", "\uD83D\uDE0D", "\uD83D\uDE0A", "\uD83D\uDE01",
"\uD83D\uDC4D", "\u263A", "\uD83D\uDE14", "\uD83D\uDE04", "\uD83D\uDE2D", "\uD83D\uDC8B",
"\uD83D\uDE12", "\uD83D\uDE33", "\uD83D\uDE1C", "\uD83D\uDE48", "\uD83D\uDE09", "\uD83D\uDE03",
"\uD83D\uDE22", "\uD83D\uDE1D", "\uD83D\uDE31", "\uD83D\uDE21", "\uD83D\uDE0F", "\uD83D\uDE1E",
"\uD83D\uDE05", "\uD83D\uDE1A", "\uD83D\uDE4A", "\uD83D\uDE0C", "\uD83D\uDE00", "\uD83D\uDE0B",
"\uD83D\uDE06", "\uD83D\uDC4C", "\uD83D\uDE10", "\uD83D\uDE15"
};
private final static int MAX_RECENT_EMOJI_COUNT = 48;
static {
@ -663,6 +672,14 @@ public class Emoji {
emojiUseHistory.put(code, ++count);
}
public static void removeRecentEmoji(String code) {
emojiUseHistory.remove(code);
recentEmoji.remove(code);
if (emojiUseHistory.isEmpty() || recentEmoji.isEmpty()) {
addRecentEmoji(DEFAULT_RECENT[0]);
}
}
public static void sortEmoji() {
recentEmoji.clear();
for (HashMap.Entry<String, Integer> entry : emojiUseHistory.entrySet()) {
@ -756,15 +773,8 @@ public class Emoji {
}
if (emojiUseHistory.isEmpty()) {
if (!preferences.getBoolean("filled_default", false)) {
String[] newRecent = new String[]{
"\uD83D\uDE02", "\uD83D\uDE18", "\u2764", "\uD83D\uDE0D", "\uD83D\uDE0A", "\uD83D\uDE01",
"\uD83D\uDC4D", "\u263A", "\uD83D\uDE14", "\uD83D\uDE04", "\uD83D\uDE2D", "\uD83D\uDC8B",
"\uD83D\uDE12", "\uD83D\uDE33", "\uD83D\uDE1C", "\uD83D\uDE48", "\uD83D\uDE09", "\uD83D\uDE03",
"\uD83D\uDE22", "\uD83D\uDE1D", "\uD83D\uDE31", "\uD83D\uDE21", "\uD83D\uDE0F", "\uD83D\uDE1E",
"\uD83D\uDE05", "\uD83D\uDE1A", "\uD83D\uDE4A", "\uD83D\uDE0C", "\uD83D\uDE00", "\uD83D\uDE0B",
"\uD83D\uDE06", "\uD83D\uDC4C", "\uD83D\uDE10", "\uD83D\uDE15"};
for (int i = 0; i < newRecent.length; i++) {
emojiUseHistory.put(newRecent[i], newRecent.length - i);
for (int i = 0; i < DEFAULT_RECENT.length; i++) {
emojiUseHistory.put(DEFAULT_RECENT[i], DEFAULT_RECENT.length - i);
}
preferences.edit().putBoolean("filled_default", true).commit();
saveRecentEmoji();

View File

@ -0,0 +1,132 @@
package org.telegram.messenger;
import android.util.Pair;
import java.util.ArrayList;
import java.util.HashMap;
public abstract class Fetcher<Args, R> {
protected void getRemote(int currentAccount, Args arguments, long hash, Utilities.Callback3<Boolean, R, Long> onResult) {
// Implement this function
}
// Not specifying getLocal and setLocal would mean that data is cached only in RAM
protected void getLocal(int currentAccount, Args arguments, Utilities.Callback2<Long, R> onResult) {
// Implement this function
onResult.run(0L, null);
}
protected void setLocal(int currentAccount, Args arguments, R data, long hash) {
// Implement this function
}
private long requestRemotelyTimeout = 4 * 60 * 1000;
private HashMap<Pair<Integer, Args>, R> cachedResults;
private HashMap<Pair<Integer, Args>, ArrayList<Utilities.Callback<R>>> loadingCallbacks;
private HashMap<Pair<Integer, Args>, Long> lastRequestedRemotely;
public void fetch(int currentAccount, Args arguments, Utilities.Callback<R> onResult) {
final Pair<Integer, Args> key = new Pair<>(currentAccount, arguments);
if (isLoading(key)) {
saveCallback(key, onResult);
return;
}
R cached = getCachedResult(key);
if (cached != null && !shouldRequest(key)) {
if (onResult != null) {
onResult.run(cached);
}
return;
}
saveCallback(key, onResult);
getLocal(currentAccount, arguments, (hash, data) -> {
if (shouldRequest(key)) {
saveLastRequested(key);
getRemote(currentAccount, arguments, hash, (notModified, remoteData, newHash) -> {
if (notModified) {
cacheResult(key, data);
callCallbacks(key, data);
} else {
if (remoteData != null) {
setLocal(currentAccount, arguments, remoteData, newHash);
cacheResult(key, remoteData);
}
callCallbacks(key, remoteData);
}
});
} else {
cacheResult(key, data);
callCallbacks(key, data);
}
});
}
private R getCachedResult(Pair<Integer, Args> key) {
if (cachedResults == null) {
return null;
}
return cachedResults.get(key);
}
private void cacheResult(Pair<Integer, Args> key, R result) {
if (cachedResults == null) {
cachedResults = new HashMap<>();
}
cachedResults.put(key, result);
}
private void saveLastRequested(Pair<Integer, Args> key) {
if (lastRequestedRemotely == null) {
lastRequestedRemotely = new HashMap<>();
}
lastRequestedRemotely.put(key, System.currentTimeMillis());
}
private boolean shouldRequest(Pair<Integer, Args> key) {
Long lastRequested = lastRequestedRemotely != null ? lastRequestedRemotely.get(key) : null;
return lastRequested == null || System.currentTimeMillis() - lastRequested >= requestRemotelyTimeout;
}
private boolean isLoading(Pair<Integer, Args> key) {
return loadingCallbacks != null && loadingCallbacks.get(key) != null;
}
private void saveCallback(Pair<Integer, Args> key, Utilities.Callback<R> callback) {
if (callback == null) {
return;
}
if (loadingCallbacks == null) {
loadingCallbacks = new HashMap<>();
}
ArrayList<Utilities.Callback<R>> callbacks = loadingCallbacks.get(key);
if (callbacks == null) {
loadingCallbacks.put(key, callbacks = new ArrayList<>());
}
callbacks.add(callback);
}
private void callCallbacks(Pair<Integer, Args> key, R result) {
if (loadingCallbacks == null) {
return;
}
final ArrayList<Utilities.Callback<R>> callbacks = loadingCallbacks.get(key);
if (callbacks == null) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
for (Utilities.Callback<R> callback: callbacks) {
callback.run(result);
}
callbacks.clear();
});
loadingCallbacks.remove(key);
}
}

View File

@ -1412,7 +1412,11 @@ public class FileLoadOperation {
} else if (currentType == ConnectionsManager.FileTypePhoto) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_PHOTOS, 1);
} else if (currentType == ConnectionsManager.FileTypeFile) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
if (ext != null && (ext.toLowerCase().endsWith("mp3") || ext.toLowerCase().endsWith("m4a"))) {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_MUSIC, 1);
} else {
StatsController.getInstance(currentAccount).incrementReceivedItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
}
}
}
delegate.didFinishLoadingFile(FileLoadOperation.this, cacheFileFinal);
@ -2148,7 +2152,11 @@ public class FileLoadOperation {
} else if (currentType == ConnectionsManager.FileTypePhoto) {
StatsController.getInstance(currentAccount).incrementReceivedBytesCount(response.networkType, StatsController.TYPE_PHOTOS, response.getObjectSize() + 4);
} else if (currentType == ConnectionsManager.FileTypeFile) {
StatsController.getInstance(currentAccount).incrementReceivedBytesCount(response.networkType, StatsController.TYPE_FILES, response.getObjectSize() + 4);
if (ext != null && (ext.toLowerCase().endsWith("mp3") || ext.toLowerCase().endsWith("m4a"))) {
StatsController.getInstance(currentAccount).incrementReceivedBytesCount(response.networkType, StatsController.TYPE_MUSIC, response.getObjectSize() + 4);
} else {
StatsController.getInstance(currentAccount).incrementReceivedBytesCount(response.networkType, StatsController.TYPE_FILES, response.getObjectSize() + 4);
}
}
}
processRequestResult(requestInfo, error);

View File

@ -45,7 +45,7 @@ public class FileLoader extends BaseController {
String str = (String) parentObject;
if (str.startsWith("sent_")) {
if (sentPattern == null) {
sentPattern = Pattern.compile("sent_.*_([0-9]+)_([0-9]+)_([0-9]+)");
sentPattern = Pattern.compile("sent_.*_([0-9]+)_([0-9]+)_([0-9]+)_([0-9]+)");
}
try {
Matcher matcher = sentPattern.matcher(str);
@ -54,6 +54,7 @@ public class FileLoader extends BaseController {
fileMeta.messageId = Integer.parseInt(matcher.group(1));
fileMeta.dialogId = Long.parseLong(matcher.group(2));
fileMeta.messageType = Integer.parseInt(matcher.group(3));
fileMeta.messageSize = Long.parseLong(matcher.group(4));
return fileMeta;
}
} catch (Exception e) {
@ -66,11 +67,25 @@ public class FileLoader extends BaseController {
fileMeta.messageId = messageObject.getId();
fileMeta.dialogId = messageObject.getDialogId();
fileMeta.messageType = messageObject.type;
fileMeta.messageSize = messageObject.getSize();
return fileMeta;
}
return null;
}
public static TLRPC.VideoSize getVectorMarkupVideoSize(TLRPC.Photo photo) {
if (photo == null || photo.video_sizes == null) {
return null;
}
for (int i = 0; i < photo.video_sizes.size(); i++) {
TLRPC.VideoSize videoSize = photo.video_sizes.get(i);
if (videoSize instanceof TLRPC.TL_videoSizeEmojiMarkup || videoSize instanceof TLRPC.TL_videoSizeStickerMarkup) {
return videoSize;
}
}
return null;
}
private int getPriorityValue(int priorityType) {
if (priorityType == PRIORITY_STREAM) {
return Integer.MAX_VALUE;
@ -732,7 +747,6 @@ public class FileLoader extends BaseController {
storeDir = getDirectory(type);
boolean saveCustomPath = false;
if ((type == MEDIA_DIR_IMAGE || type == MEDIA_DIR_VIDEO) && canSaveToPublicStorage(parentObject)) {
File newDir;
if (type == MEDIA_DIR_IMAGE) {
@ -856,16 +870,27 @@ public class FileLoader extends BaseController {
}
private boolean canSaveToPublicStorage(Object parentObject) {
if (SharedConfig.saveToGalleryFlags == 0 || BuildVars.NO_SCOPED_STORAGE) {
if (BuildVars.NO_SCOPED_STORAGE) {
return false;
}
if (parentObject instanceof MessageObject) {
MessageObject messageObject = (MessageObject) parentObject;
FilePathDatabase.FileMeta metadata = getFileMetadataFromParent(currentAccount, parentObject);
MessageObject messageObject = null;
if (metadata != null) {
int flag;
long dialogId = messageObject.getDialogId();
if (messageObject.isRoundVideo() || messageObject.isVoice() || messageObject.isAnyKindOfSticker() || getMessagesController().isChatNoForwards(getMessagesController().getChat(-dialogId)) || messageObject.messageOwner.noforwards || DialogObject.isEncryptedDialog(dialogId)) {
long dialogId = metadata.dialogId;
if (getMessagesController().isChatNoForwards(getMessagesController().getChat(-dialogId)) || DialogObject.isEncryptedDialog(dialogId)) {
return false;
}
if (parentObject instanceof MessageObject) {
messageObject = (MessageObject) parentObject;
if (messageObject.isRoundVideo() || messageObject.isVoice() || messageObject.isAnyKindOfSticker() || messageObject.messageOwner.noforwards) {
return false;
}
} else {
if (metadata.messageType == MessageObject.TYPE_ROUND_VIDEO || metadata.messageType == MessageObject.TYPE_STICKER || metadata.messageType == MessageObject.TYPE_VOICE) {
return false;
}
}
if (dialogId >= 0) {
flag = SharedConfig.SAVE_TO_GALLERY_FLAG_PEER;
} else {
@ -876,7 +901,7 @@ public class FileLoader extends BaseController {
}
}
if ((SharedConfig.saveToGalleryFlags & flag) != 0) {
if (SaveToGallerySettingsHelper.needSave(flag, metadata, messageObject, currentAccount)) {
return true;
}
}
@ -1182,13 +1207,64 @@ public class FileLoader extends BaseController {
}
if (byMinSide) {
int currentSide = Math.min(obj.h, obj.w);
if (closestObject == null || side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE || obj instanceof TLRPC.TL_photoCachedSize || side > lastSide && lastSide < currentSide) {
if (
closestObject == null ||
side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE ||
obj instanceof TLRPC.TL_photoCachedSize || side > lastSide && lastSide < currentSide
) {
closestObject = obj;
lastSide = currentSide;
}
} else {
int currentSide = Math.max(obj.w, obj.h);
if (closestObject == null || side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE || obj instanceof TLRPC.TL_photoCachedSize || currentSide <= side && lastSide < currentSide) {
if (
closestObject == null ||
side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE ||
obj instanceof TLRPC.TL_photoCachedSize ||
currentSide <= side && lastSide < currentSide
) {
closestObject = obj;
lastSide = currentSide;
}
}
}
return closestObject;
}
public static TLRPC.VideoSize getClosestVideoSizeWithSize(ArrayList<TLRPC.VideoSize> sizes, int side) {
return getClosestVideoSizeWithSize(sizes, side, false);
}
public static TLRPC.VideoSize getClosestVideoSizeWithSize(ArrayList<TLRPC.VideoSize> sizes, int side, boolean byMinSide) {
return getClosestVideoSizeWithSize(sizes, side, byMinSide, false);
}
public static TLRPC.VideoSize getClosestVideoSizeWithSize(ArrayList<TLRPC.VideoSize> sizes, int side, boolean byMinSide, boolean ignoreStripped) {
if (sizes == null || sizes.isEmpty()) {
return null;
}
int lastSide = 0;
TLRPC.VideoSize closestObject = null;
for (int a = 0; a < sizes.size(); a++) {
TLRPC.VideoSize obj = sizes.get(a);
if (obj == null || obj instanceof TLRPC.TL_videoSizeEmojiMarkup || obj instanceof TLRPC.TL_videoSizeStickerMarkup) {
continue;
}
if (byMinSide) {
int currentSide = Math.min(obj.h, obj.w);
if (closestObject == null ||
side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE ||
side > lastSide && lastSide < currentSide) {
closestObject = obj;
lastSide = currentSide;
}
} else {
int currentSide = Math.max(obj.w, obj.h);
if (
closestObject == null ||
side > 100 && closestObject.location != null && closestObject.location.dc_id == Integer.MIN_VALUE ||
currentSide <= side && lastSide < currentSide
) {
closestObject = obj;
lastSide = currentSide;
}

View File

@ -445,5 +445,6 @@ public class FilePathDatabase {
public long dialogId;
public int messageId;
public int messageType;
public long messageSize;
}
}

View File

@ -535,7 +535,11 @@ public class FileUploadOperation {
} else if (currentType == ConnectionsManager.FileTypePhoto) {
StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_PHOTOS, requestSize);
} else if (currentType == ConnectionsManager.FileTypeFile) {
StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_FILES, requestSize);
if (uploadingFilePath != null && (uploadingFilePath.toLowerCase().endsWith("mp3") || uploadingFilePath.toLowerCase().endsWith("m4a"))) {
StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_MUSIC, requestSize);
} else {
StatsController.getInstance(currentAccount).incrementSentBytesCount(networkType, StatsController.TYPE_FILES, requestSize);
}
}
if (currentRequestIv != null) {
freeRequestIvs.add(currentRequestIv);
@ -590,7 +594,11 @@ public class FileUploadOperation {
} else if (currentType == ConnectionsManager.FileTypePhoto) {
StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_PHOTOS, 1);
} else if (currentType == ConnectionsManager.FileTypeFile) {
StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
if (uploadingFilePath != null && (uploadingFilePath.toLowerCase().endsWith("mp3") || uploadingFilePath.toLowerCase().endsWith("m4a"))) {
StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_MUSIC, 1);
} else {
StatsController.getInstance(currentAccount).incrementSentItemsCount(ApplicationLoader.getCurrentNetworkType(), StatsController.TYPE_FILES, 1);
}
}
} else if (currentUploadRequetsCount < maxRequestsCount) {
if (estimatedSize == 0 && !uploadFirstPartLater && !nextPartFirst) {

View File

@ -74,6 +74,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import java.util.zip.GZIPInputStream;
@ -86,6 +87,7 @@ import java.util.zip.GZIPInputStream;
* b - need blur image
* g - autoplay
* lastframe - return lastframe for Lottie animation
* lastreactframe - return lastframe for Lottie animation + some scale ReactionLastFrame magic
* firstframe - return firstframe for Lottie animation
*/
public class ImageLoader {
@ -870,6 +872,7 @@ public class ImageLoader {
boolean precache = false;
boolean limitFps = false;
boolean lastFrameBitmap = false;
boolean lastFrameReactionScaleBitmap = false;
boolean firstFrameBitmap = false;
int autoRepeat = 1;
int[] colors = null;
@ -896,6 +899,10 @@ public class ImageLoader {
if (cacheImage.filter.contains("lastframe")) {
lastFrameBitmap = true;
}
if (cacheImage.filter.contains("lastreactframe")) {
lastFrameBitmap = true;
lastFrameReactionScaleBitmap = true;
}
if (cacheImage.filter.contains("firstframe")) {
firstFrameBitmap = true;
}
@ -964,13 +971,17 @@ public class ImageLoader {
precache = false;
}
BitmapsCache.CacheOptions cacheOptions = null;
if (precache) {
if (precache || lastFrameBitmap || firstFrameBitmap) {
cacheOptions = new BitmapsCache.CacheOptions();
if (cacheImage.filter != null && cacheImage.filter.contains("compress")) {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
if (cacheImage.filter != null && cacheImage.filter.contains("flbk")) {
cacheOptions.fallback = true;
if (!lastFrameBitmap && !firstFrameBitmap) {
if (cacheImage.filter != null && cacheImage.filter.contains("compress")) {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
if (cacheImage.filter != null && cacheImage.filter.contains("flbk")) {
cacheOptions.fallback = true;
}
} else {
cacheOptions.firstFrame = true;
}
}
if (compressed) {
@ -980,7 +991,7 @@ public class ImageLoader {
}
}
if (lastFrameBitmap || firstFrameBitmap) {
loadLastFrame(lottieDrawable, h, w, lastFrameBitmap);
loadLastFrame(lottieDrawable, h, w, lastFrameBitmap, lastFrameReactionScaleBitmap);
} else {
lottieDrawable.setAutoRepeat(autoRepeat);
onPostExecute(lottieDrawable);
@ -995,6 +1006,8 @@ public class ImageLoader {
}
boolean limitFps = false;
boolean precache = false;
boolean fistFrame = false;
boolean notCreateStream = false;
if (cacheImage.filter != null) {
String[] args = cacheImage.filter.split("_");
if (args.length >= 2) {
@ -1008,20 +1021,28 @@ public class ImageLoader {
if ("pcache".equals(args[i])) {
precache = true;
}
if ("firstframe".equals(args[i])) {
fistFrame = true;
}
if ("nostream".equals(args[i])) {
notCreateStream = true;
}
}
if (fistFrame) {
notCreateStream = true;
}
}
BitmapsCache.CacheOptions cacheOptions = null;
if (precache && !fistFrame) {
cacheOptions = new BitmapsCache.CacheOptions();
if (cacheImage.filter != null && cacheImage.filter.contains("compress")) {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
}
if ((isAnimatedAvatar(cacheImage.filter) || AUTOPLAY_FILTER.equals(cacheImage.filter)) && !(cacheImage.imageLocation.document instanceof TLRPC.TL_documentEncrypted) && !precache) {
TLRPC.Document document = cacheImage.imageLocation.document instanceof TLRPC.Document ? cacheImage.imageLocation.document : null;
long size = document != null ? cacheImage.size : cacheImage.imageLocation.currentSize;
BitmapsCache.CacheOptions cacheOptions = null;
if (precache) {
cacheOptions = new BitmapsCache.CacheOptions();
if (cacheImage.filter != null && cacheImage.filter.contains("compress")) {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
}
boolean notCreateStream = cacheImage.filter != null && cacheImage.filter.contains("nostream");
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, false, notCreateStream ? 0 : size, notCreateStream ? null : document, document == null && !notCreateStream ? cacheImage.imageLocation : null, cacheImage.parentObject, seekTo, cacheImage.currentAccount, false, cacheOptions);
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, fistFrame, notCreateStream ? 0 : size, notCreateStream ? null : document, document == null && !notCreateStream ? cacheImage.imageLocation : null, cacheImage.parentObject, seekTo, cacheImage.currentAccount, false, cacheOptions);
fileDrawable.setIsWebmSticker(MessageObject.isWebM(document) || MessageObject.isVideoSticker(document) || isAnimatedAvatar(cacheImage.filter));
} else {
@ -1036,21 +1057,25 @@ public class ImageLoader {
h = (int) (h_filter * AndroidUtilities.density);
}
}
BitmapsCache.CacheOptions cacheOptions = null;
if (precache) {
cacheOptions = new BitmapsCache.CacheOptions();
if (cacheImage.filter != null && cacheImage.filter.contains("compress")) {
cacheOptions.compressQuality = BitmapsCache.COMPRESS_QUALITY_DEFAULT;
}
}
boolean createDecoder = cacheImage.filter != null && ("d".equals(cacheImage.filter) || cacheImage.filter.contains("_d"));
boolean notCreateStream = cacheImage.filter != null && cacheImage.filter.contains("nostream");
boolean createDecoder = fistFrame || (cacheImage.filter != null && ("d".equals(cacheImage.filter) || cacheImage.filter.contains("_d")));
fileDrawable = new AnimatedFileDrawable(cacheImage.finalFilePath, createDecoder, 0, notCreateStream ? null : cacheImage.imageLocation.document, null, null, seekTo, cacheImage.currentAccount, false, w, h, cacheOptions);
fileDrawable.setIsWebmSticker(MessageObject.isWebM(cacheImage.imageLocation.document) || MessageObject.isVideoSticker(cacheImage.imageLocation.document) || isAnimatedAvatar(cacheImage.filter));
}
fileDrawable.setLimitFps(limitFps);
Thread.interrupted();
onPostExecute(fileDrawable);
if (fistFrame) {
Bitmap bitmap = fileDrawable.getFrameAtTime(0, false);
fileDrawable.recycle();
Thread.interrupted();
if (bitmap == null) {
onPostExecute(null);
} else {
onPostExecute(new BitmapDrawable(bitmap));
}
} else {
fileDrawable.setLimitFps(limitFps);
Thread.interrupted();
onPostExecute(fileDrawable);
}
} else {
Long mediaId = null;
boolean mediaIsVideo = false;
@ -1548,10 +1573,10 @@ public class ImageLoader {
}
}
private void loadLastFrame(RLottieDrawable lottieDrawable, int w, int h, boolean lastFrame) {
private void loadLastFrame(RLottieDrawable lottieDrawable, int w, int h, boolean lastFrame, boolean reaction) {
Bitmap bitmap;
Canvas canvas;
if (lastFrame) {
if (lastFrame && reaction) {
bitmap = Bitmap.createBitmap((int) (w * ImageReceiver.ReactionLastFrame.LAST_FRAME_SCALE), (int) (h * ImageReceiver.ReactionLastFrame.LAST_FRAME_SCALE), Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
canvas.scale(2f, 2f, w * ImageReceiver.ReactionLastFrame.LAST_FRAME_SCALE / 2f, h * ImageReceiver.ReactionLastFrame.LAST_FRAME_SCALE / 2f);
@ -1560,32 +1585,29 @@ public class ImageLoader {
canvas = new Canvas(bitmap);
}
lottieDrawable.prepareForGenerateCache();
Bitmap currentBitmap = Bitmap.createBitmap(lottieDrawable.getIntrinsicWidth(), lottieDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
lottieDrawable.setGeneratingFrame(lastFrame ? lottieDrawable.getFramesCount() - 1 : 0);
lottieDrawable.getNextFrame(currentBitmap);
lottieDrawable.releaseForGenerateCache();
canvas.save();
if (!(lastFrame && reaction)) {
canvas.scale(currentBitmap.getWidth() / w, currentBitmap.getHeight() / h, w / 2f, h / 2f);
}
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setFilterBitmap(true);
BitmapDrawable bitmapDrawable = null;
if (lastFrame && reaction) {
canvas.drawBitmap(currentBitmap, (bitmap.getWidth() - currentBitmap.getWidth()) / 2f, (bitmap.getHeight() - currentBitmap.getHeight()) / 2f, paint);
bitmapDrawable = new ImageReceiver.ReactionLastFrame(bitmap);
} else {
canvas.drawBitmap(currentBitmap, 0, 0, paint);
bitmapDrawable = new BitmapDrawable(bitmap);
}
AndroidUtilities.runOnUIThread(() -> {
lottieDrawable.setOnFrameReadyRunnable(() -> {
lottieDrawable.setOnFrameReadyRunnable(null);
BitmapDrawable bitmapDrawable = null;
if (lottieDrawable.getBackgroundBitmap() != null || lottieDrawable.getRenderingBitmap() != null) {
Bitmap currentBitmap = lottieDrawable.getBackgroundBitmap() != null ? lottieDrawable.getBackgroundBitmap() : lottieDrawable.getRenderingBitmap();
canvas.save();
if (!lastFrame) {
canvas.scale(currentBitmap.getWidth() / w, currentBitmap.getHeight() / h, w / 2f, h / 2f);
}
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setFilterBitmap(true);
if (lastFrame) {
canvas.drawBitmap(currentBitmap, (bitmap.getWidth() - currentBitmap.getWidth()) / 2f, (bitmap.getHeight() - currentBitmap.getHeight()) / 2f, paint);
bitmapDrawable = new ImageReceiver.ReactionLastFrame(bitmap);
} else {
canvas.drawBitmap(currentBitmap, 0, 0, paint);
bitmapDrawable = new BitmapDrawable(bitmap);
}
}
onPostExecute(bitmapDrawable);
lottieDrawable.recycle();
});
lottieDrawable.setCurrentFrame(lastFrame ? lottieDrawable.getFramesCount() - 1 : 0, true, true);
});
lottieDrawable.recycle();
currentBitmap.recycle();
onPostExecute(bitmapDrawable);
}
private void onPostExecute(final Drawable drawable) {
@ -1736,7 +1758,7 @@ public class ImageLoader {
public void addImageReceiver(ImageReceiver imageReceiver, String key, String filter, int type, int guid) {
int index = imageReceiverArray.indexOf(imageReceiver);
if (index >= 0) {
if (index >= 0 && Objects.equals(imageReceiverArray.get(index).getImageKey(), key)) {
imageReceiverGuidsArray.set(index, guid);
return;
}
@ -2040,11 +2062,14 @@ public class ImageLoader {
public void fileDidLoaded(final String location, final File finalFile, Object parentObject, final int type) {
fileProgresses.remove(location);
AndroidUtilities.runOnUIThread(() -> {
if (SharedConfig.saveToGalleryFlags != 0 && finalFile != null && (location.endsWith(".mp4") || location.endsWith(".jpg"))) {
if (parentObject instanceof MessageObject) {
MessageObject messageObject = (MessageObject) parentObject;
long dialogId = messageObject.getDialogId();
if (finalFile != null && (location.endsWith(".mp4") || location.endsWith(".jpg"))) {
FilePathDatabase.FileMeta meta = FileLoader.getFileMetadataFromParent(currentAccount, parentObject);
if (meta != null) {
MessageObject messageObject = null;
if (parentObject instanceof MessageObject) {
messageObject = (MessageObject) parentObject;
}
long dialogId = meta.dialogId;
int flag;
if (dialogId >= 0) {
flag = SharedConfig.SAVE_TO_GALLERY_FLAG_PEER;
@ -2055,7 +2080,7 @@ public class ImageLoader {
flag = SharedConfig.SAVE_TO_GALLERY_FLAG_GROUP;
}
}
if ((SharedConfig.saveToGalleryFlags & flag) != 0) {
if (SaveToGallerySettingsHelper.needSave(flag, meta, messageObject, currentAccount)) {
AndroidUtilities.addMediaToGallery(finalFile.toString());
}
}
@ -2656,6 +2681,7 @@ public class ImageLoader {
final boolean shouldGenerateQualityThumb = imageReceiver.isShouldGenerateQualityThumb();
final int currentAccount = imageReceiver.getCurrentAccount();
final boolean currentKeyQuality = type == ImageReceiver.TYPE_IMAGE && imageReceiver.isCurrentKeyQuality();
final Runnable loadOperationRunnable = () -> {
boolean added = false;
if (thumb != 2) {
@ -3320,6 +3346,9 @@ public class ImageLoader {
}
private boolean useLottieMemCache(ImageLocation imageLocation, String key) {
if (key.endsWith("_firstframe") || key.endsWith("_lastframe")) {
return false;
}
return imageLocation != null && (MessageObject.isAnimatedStickerDocument(imageLocation.document, true) || imageLocation.imageType == FileLoader.IMAGE_TYPE_LOTTIE || MessageObject.isVideoSticker(imageLocation.document)) || isAnimatedAvatar(key);
}

View File

@ -118,7 +118,8 @@ public class ImageLocation {
public static final int TYPE_BIG = 0;
public static final int TYPE_SMALL = 1;
public static final int TYPE_STRIPPED = 2;
public static final int TYPE_VIDEO_THUMB = 3;
public static final int TYPE_VIDEO_SMALL = 3;
public static final int TYPE_VIDEO_BIG = 4;
public static ImageLocation getForUserOrChat(TLObject object, int type) {
if (object instanceof TLRPC.User) {
@ -133,19 +134,25 @@ public class ImageLocation {
if (user == null || user.access_hash == 0 || user.photo == null) {
return null;
}
if (type == TYPE_VIDEO_THUMB) {
if (type == TYPE_VIDEO_BIG || type == TYPE_VIDEO_SMALL) {
int currentAccount = UserConfig.selectedAccount;
if (MessagesController.getInstance(currentAccount).isPremiumUser(user) && user.photo.has_video) {
final TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (userFull != null && userFull.profile_photo != null && userFull.profile_photo.video_sizes != null && !userFull.profile_photo.video_sizes.isEmpty()) {
TLRPC.VideoSize videoSize = userFull.profile_photo.video_sizes.get(0);
for (int i = 0; i < userFull.profile_photo.video_sizes.size(); i++) {
if ("p".equals(userFull.profile_photo.video_sizes.get(i).type)) {
videoSize = userFull.profile_photo.video_sizes.get(i);
break;
if (type == TYPE_VIDEO_BIG) {
TLRPC.VideoSize videoSize = FileLoader.getClosestVideoSizeWithSize(userFull.profile_photo.video_sizes, 1000);
return ImageLocation.getForPhoto(videoSize, userFull.profile_photo);
} else {
TLRPC.VideoSize videoSize = FileLoader.getClosestVideoSizeWithSize(userFull.profile_photo.video_sizes, 100);
for (int i = 0; i < userFull.profile_photo.video_sizes.size(); i++) {
if ("p".equals(userFull.profile_photo.video_sizes.get(i).type)) {
videoSize = userFull.profile_photo.video_sizes.get(i);
break;
}
}
return ImageLocation.getForPhoto(videoSize, userFull.profile_photo);
}
return ImageLocation.getForPhoto(videoSize, userFull.profile_photo);
}
}
return null;

View File

@ -33,12 +33,14 @@ import androidx.annotation.Keep;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.AttachableDrawable;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.ClipRoundedDrawable;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LoadingStickerDrawable;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RecyclableDrawable;
import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import java.util.ArrayList;
@ -370,10 +372,10 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
setForUserOrChat(object, avatarDrawable, null);
}
public void setForUserOrChat(TLObject object, Drawable avatarDrawable, Object parentObject) {
setForUserOrChat(object, avatarDrawable, null, false);
setForUserOrChat(object, avatarDrawable, parentObject, false, 0);
}
public void setForUserOrChat(TLObject object, Drawable avatarDrawable, Object parentObject, boolean animationEnabled) {
public void setForUserOrChat(TLObject object, Drawable avatarDrawable, Object parentObject, boolean animationEnabled, int vectorType) {
if (parentObject == null) {
parentObject = object;
}
@ -381,29 +383,46 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
BitmapDrawable strippedBitmap = null;
boolean hasStripped = false;
ImageLocation videoLocation = null;
TLRPC.VideoSize vectorImageMarkup = null;
boolean isPremium = false;
if (object instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) object;
isPremium = user.premium;
if (user.photo != null) {
strippedBitmap = user.photo.strippedBitmap;
hasStripped = user.photo.stripped_thumb != null;
if (animationEnabled && MessagesController.getInstance(currentAccount).isPremiumUser(user) && user.photo.has_video && !SharedConfig.getLiteMode().enabled()) {
if (vectorType == VectorAvatarThumbDrawable.TYPE_STATIC) {
final TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (userFull != null) {
TLRPC.Photo photo = user.photo.personal ? userFull.personal_photo : userFull.profile_photo;
if (photo != null) {
vectorImageMarkup = FileLoader.getVectorMarkupVideoSize(photo);
}
}
}
if (vectorImageMarkup == null && animationEnabled && MessagesController.getInstance(currentAccount).isPremiumUser(user) && user.photo.has_video && !SharedConfig.getLiteMode().enabled()) {
final TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(user.id);
if (userFull == null) {
MessagesController.getInstance(currentAccount).loadFullUser(user, currentGuid, false);
} else {
TLRPC.Photo photo = userFull.profile_photo;
TLRPC.Photo photo = user.photo.personal ? userFull.personal_photo : userFull.profile_photo;
if (photo != null) {
ArrayList<TLRPC.VideoSize> videoSizes = photo.video_sizes;
if (videoSizes != null && !videoSizes.isEmpty()) {
TLRPC.VideoSize videoSize = videoSizes.get(0);
for (int i = 0; i < videoSizes.size(); i++) {
TLRPC.VideoSize videoSize1 = videoSizes.get(i);
if ("p".equals(videoSize1.type)) {
videoSize = videoSize1;
break;
vectorImageMarkup = FileLoader.getVectorMarkupVideoSize(photo);
if (vectorImageMarkup == null) {
ArrayList<TLRPC.VideoSize> videoSizes = photo.video_sizes;
if (videoSizes != null && !videoSizes.isEmpty()) {
TLRPC.VideoSize videoSize = FileLoader.getClosestVideoSizeWithSize(videoSizes, 100);
for (int i = 0; i < videoSizes.size(); i++) {
TLRPC.VideoSize videoSize1 = videoSizes.get(i);
if ("p".equals(videoSize1.type)) {
videoSize = videoSize1;
}
if (videoSize1 instanceof TLRPC.TL_videoSizeEmojiMarkup || videoSize1 instanceof TLRPC.TL_videoSizeStickerMarkup) {
vectorImageMarkup = videoSize1;
}
}
videoLocation = ImageLocation.getForPhoto(videoSize, photo);
}
videoLocation = ImageLocation.getForPhoto(videoSize, photo);
}
}
}
@ -416,18 +435,23 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
hasStripped = chat.photo.stripped_thumb != null;
}
}
ImageLocation location = ImageLocation.getForUserOrChat(object, ImageLocation.TYPE_SMALL);
String filter = "50_50";
if (videoLocation != null) {
setImage(videoLocation, "avatar", location, filter, null, null, strippedBitmap, 0, null, parentObject, 0);
animatedFileDrawableRepeatMaxCount = 3;
if (vectorImageMarkup != null && vectorType != 0) {
VectorAvatarThumbDrawable drawable = new VectorAvatarThumbDrawable(vectorImageMarkup, isPremium, vectorType);
setImageBitmap(drawable);
} else {
if (strippedBitmap != null) {
setImage(location, filter, strippedBitmap, null, parentObject, 0);
} else if (hasStripped) {
setImage(location, filter, ImageLocation.getForUserOrChat(object, ImageLocation.TYPE_STRIPPED), "50_50_b", avatarDrawable, parentObject, 0);
ImageLocation location = ImageLocation.getForUserOrChat(object, ImageLocation.TYPE_SMALL);
String filter = "50_50";
if (videoLocation != null) {
setImage(videoLocation, "avatar", location, filter, null, null, strippedBitmap, 0, null, parentObject, 0);
animatedFileDrawableRepeatMaxCount = 3;
} else {
setImage(location, filter, avatarDrawable, null, parentObject, 0);
if (strippedBitmap != null) {
setImage(location, filter, strippedBitmap, null, parentObject, 0);
} else if (hasStripped) {
setImage(location, filter, ImageLocation.getForUserOrChat(object, ImageLocation.TYPE_STRIPPED), "50_50_b", avatarDrawable, parentObject, 0);
} else {
setImage(location, filter, avatarDrawable, null, parentObject, 0);
}
}
}
@ -501,7 +525,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentParentObject = null;
currentCacheType = 0;
roundPaint.setShader(null);
staticThumbDrawable = thumb;
setStaticDrawable(thumb);
currentAlpha = 1.0f;
previousAlpha = 1f;
currentSize = 0;
@ -653,7 +677,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentExt = ext;
currentSize = size;
currentCacheType = cacheType;
staticThumbDrawable = thumb;
setStaticDrawable(thumb);
imageShader = null;
composeShader = null;
thumbShader = null;
@ -820,7 +844,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
thumbShader = null;
roundPaint.setShader(null);
staticThumbDrawable = bitmap;
setStaticDrawable(bitmap);
updateDrawableRadius(bitmap);
currentMediaLocation = null;
currentMediaFilter = null;
@ -870,6 +895,26 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
}
private void setStaticDrawable(Drawable bitmap) {
if (bitmap == staticThumbDrawable) {
return;
}
AttachableDrawable oldDrawable = null;
if (staticThumbDrawable instanceof AttachableDrawable) {
if (staticThumbDrawable.equals(bitmap)) {
return;
}
oldDrawable = (AttachableDrawable) staticThumbDrawable;
}
staticThumbDrawable = bitmap;
if (attachedToWindow && staticThumbDrawable instanceof AttachableDrawable) {
((AttachableDrawable) staticThumbDrawable).onAttachedToWindow(this);
}
if (attachedToWindow && oldDrawable != null) {
oldDrawable.onDetachedFromWindow(this);
}
}
private void setDrawableShader(Drawable drawable, BitmapShader shader) {
if (drawable == currentThumbDrawable || drawable == staticThumbDrawable) {
thumbShader = shader;
@ -965,9 +1010,12 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.stopAllHeavyOperations);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.startAllHeavyOperations);
}
if (staticThumbDrawable instanceof AttachableDrawable) {
((AttachableDrawable) staticThumbDrawable).onDetachedFromWindow(this);
}
if (staticThumbDrawable != null) {
staticThumbDrawable = null;
setStaticDrawable(null);
thumbShader = null;
roundPaint.setShader(null);
}
@ -1055,6 +1103,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
if (NotificationCenter.getGlobalInstance().isAnimationInProgress()) {
didReceivedNotification(NotificationCenter.stopAllHeavyOperations, currentAccount, 512);
}
if (staticThumbDrawable instanceof AttachableDrawable) {
((AttachableDrawable) staticThumbDrawable).onAttachedToWindow(this);
}
return false;
}
@ -1888,6 +1939,9 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
checkAlphaAnimation(animationNotReady && crossfadeWithThumb, backgroundThreadDrawHolder);
result = true;
} else if (staticThumbDrawable != null) {
if (staticThumbDrawable instanceof VectorAvatarThumbDrawable) {
((VectorAvatarThumbDrawable) staticThumbDrawable).setParent(this);
}
drawDrawable(canvas, staticThumbDrawable, (int) (overrideAlpha * 255), null, thumbOrientation, backgroundThreadDrawHolder);
checkAlphaAnimation(animationNotReady, backgroundThreadDrawHolder);
result = true;
@ -2134,7 +2188,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
}
public boolean hasNotThumb() {
return currentImageDrawable != null || currentMediaDrawable != null;
return currentImageDrawable != null || currentMediaDrawable != null || staticThumbDrawable instanceof VectorAvatarThumbDrawable;
}
public boolean hasStaticThumb() {
@ -2872,7 +2926,7 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
currentThumbDrawable = null;
thumbShader = null;
roundPaint.setShader(null);
staticThumbDrawable = thumb;
setStaticDrawable(thumb);
crossfadeWithThumb = true;
currentAlpha = 0f;
updateDrawableRadius(staticThumbDrawable);

View File

@ -442,7 +442,7 @@ public class LocaleController {
public LocaleInfo getBuiltinLanguageByPlural(String plural) {
Collection<LocaleInfo> values = languagesDict.values();
for (LocaleInfo l : values)
if (l.pathToFile != null && l.pathToFile.equals("remote") && l.pluralLangCode != null && l.pluralLangCode.equals(plural))
if (l.pathToFile != null && l.pathToFile.equals("remote") && !"en_raw".equals(l.shortName) && l.pluralLangCode != null && l.pluralLangCode.equals(plural))
return l;
return null;
}

View File

@ -352,6 +352,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public boolean isChatPreviewSpoilerRevealed;
public boolean isAttachSpoilerRevealed;
public TLRPC.VideoSize emojiMarkup;
public PhotoEntry(int bucketId, int imageId, long dateTaken, String path, int orientation, boolean isVideo, int width, int height, long size) {
this.bucketId = bucketId;

View File

@ -44,6 +44,8 @@ import androidx.core.content.pm.ShortcutInfoCompat;
import androidx.core.content.pm.ShortcutManagerCompat;
import androidx.core.graphics.drawable.IconCompat;
import com.android.billingclient.api.ProductDetails;
import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteDatabase;
import org.telegram.SQLite.SQLiteException;
@ -71,6 +73,7 @@ import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.URLSpanReplacement;
import org.telegram.ui.Components.URLSpanUserMention;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment;
import java.io.File;
import java.util.ArrayList;
@ -177,6 +180,8 @@ public class MediaDataController extends BaseController {
loadStickersByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME, false, true);
loadEmojiThemes();
loadRecentAndTopReactions(false);
loadAvatarConstructor(false);
loadAvatarConstructor(true);
ringtoneDataStore = new RingtoneDataStore(currentAccount);
}
@ -386,6 +391,70 @@ public class MediaDataController extends BaseController {
return premiumPromo;
}
public Integer getPremiumHintAnnualDiscount(boolean checkTransaction) {
if (checkTransaction && (!BillingController.getInstance().isReady() || BillingController.getInstance().getLastPremiumTransaction() == null) || premiumPromo == null) {
return null;
}
boolean found = false;
int discount = 0;
double currentPrice = 0;
for (TLRPC.TL_premiumSubscriptionOption option : premiumPromo.period_options) {
if (checkTransaction ? option.current && Objects.equals(option.transaction.replaceAll(PremiumPreviewFragment.TRANSACTION_PATTERN, "$1"), BillingController.getInstance().getLastPremiumTransaction()) : option.months == 1) {
found = true;
if (!BuildVars.useInvoiceBilling() && BillingController.PREMIUM_PRODUCT_DETAILS != null) {
ProductDetails.SubscriptionOfferDetails offerDetails = null;
for (ProductDetails.SubscriptionOfferDetails details : BillingController.PREMIUM_PRODUCT_DETAILS.getSubscriptionOfferDetails()) {
String period = details.getPricingPhases().getPricingPhaseList().get(0).getBillingPeriod();
if (option.months == 12 ? period.equals("P1Y") : period.equals(String.format(Locale.ROOT, "P%dM", option.months))) {
offerDetails = details;
break;
}
}
if (offerDetails == null) {
currentPrice = (double) option.amount / option.months;
} else {
currentPrice = (double) offerDetails.getPricingPhases().getPricingPhaseList().get(0).getPriceAmountMicros() / option.months;
}
} else {
currentPrice = (double) option.amount / option.months;
}
}
}
for (TLRPC.TL_premiumSubscriptionOption option : premiumPromo.period_options) {
if (found && option.months == 12) {
double amount;
if (!BuildVars.useInvoiceBilling() && BillingController.PREMIUM_PRODUCT_DETAILS != null) {
ProductDetails.SubscriptionOfferDetails offerDetails = null;
for (ProductDetails.SubscriptionOfferDetails details : BillingController.PREMIUM_PRODUCT_DETAILS.getSubscriptionOfferDetails()) {
String period = details.getPricingPhases().getPricingPhaseList().get(0).getBillingPeriod();
if (option.months == 12 ? period.equals("P1Y") : period.equals(String.format(Locale.ROOT, "P%dM", option.months))) {
offerDetails = details;
break;
}
}
if (offerDetails == null) {
amount = (double) option.amount / option.months;
} else {
amount = (double) offerDetails.getPricingPhases().getPricingPhaseList().get(0).getPriceAmountMicros() / option.months;
}
} else {
amount = (double) option.amount / option.months;
}
discount = (int) ((1.0 - amount / currentPrice) * 100);
}
}
if (!found || discount <= 0) {
return null;
}
return discount;
}
public TLRPC.TL_attachMenuBots getAttachMenuBots() {
return attachMenuBots;
}
@ -1109,7 +1178,7 @@ public class MediaDataController extends BaseController {
}
return cacheSet;
}
if (inputStickerSet instanceof TLRPC.TL_inputStickerSetID && hash != null) {
if (inputStickerSet instanceof TLRPC.TL_inputStickerSetID) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
TLRPC.TL_messages_stickerSet cachedSet = getCachedStickerSetInternal(inputStickerSet.id, hash);
AndroidUtilities.runOnUIThread(() -> {
@ -1191,7 +1260,7 @@ public class MediaDataController extends BaseController {
if (data != null) {
set = TLRPC.TL_messages_stickerSet.TLdeserialize(data, data.readInt32(false), false);
int cachedHash = cursor.intValue(1);
if (hash != null && hash != cachedHash) {
if (hash != null && hash != 0 && hash != cachedHash) {
return null;
}
}
@ -3715,12 +3784,14 @@ public class MediaDataController extends BaseController {
boolean isAnimated = false;
boolean isVideo = false;
boolean isVoice = false;
boolean isRound = false;
boolean isMusic = false;
boolean isSticker = false;
for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeVideo) {
isRound = attribute.round_message;
isVoice = attribute.round_message;
isVideo = !attribute.round_message;
} else if (attribute instanceof TLRPC.TL_documentAttributeAnimated) {
@ -3732,7 +3803,7 @@ public class MediaDataController extends BaseController {
isSticker = true;
}
}
if (isVoice) {
if (isVoice || isRound) {
return MEDIA_AUDIO;
} else if (isVideo && !isAnimated && !isSticker) {
return MEDIA_PHOTOVIDEO;
@ -3801,12 +3872,29 @@ public class MediaDataController extends BaseController {
}
getFileLoader().checkMediaExistance(objects);
AndroidUtilities.runOnUIThread(() -> {
int totalCount = res.count;
getMessagesController().putUsers(res.users, fromCache != 0);
getMessagesController().putChats(res.chats, fromCache != 0);
getNotificationCenter().postNotificationName(NotificationCenter.mediaDidLoad, dialogId, totalCount, objects, classGuid, type, topReached, min_id != 0, requestIndex);
});
Runnable notify = () -> {
AndroidUtilities.runOnUIThread(() -> {
int totalCount = res.count;
getMessagesController().putUsers(res.users, fromCache != 0);
getMessagesController().putChats(res.chats, fromCache != 0);
getNotificationCenter().postNotificationName(NotificationCenter.mediaDidLoad, dialogId, totalCount, objects, classGuid, type, topReached, min_id != 0, requestIndex);
});
};
if (getMessagesController().getTranslateController().isFeatureAvailable()) {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
for (int i = 0; i < objects.size(); ++i) {
MessageObject messageObject = objects.get(i);
TLRPC.Message message = getMessagesStorage().getMessageWithCustomParamsOnlyInternal(messageObject.getId(), messageObject.getDialogId());
messageObject.messageOwner.translatedToLanguage = message.translatedToLanguage;
messageObject.messageOwner.translatedText = message.translatedText;
messageObject.updateTranslation();
}
notify.run();
});
} else {
notify.run();
}
});
}
}
@ -7071,14 +7159,14 @@ public class MediaDataController extends BaseController {
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, boolean allowAnimated) {
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, false, null);
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, false, false, null);
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated) {
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, sync, allowAnimated, false, null);
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, sync, allowAnimated, false, false, null);
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated, boolean allowTopicIcons, Integer maxAnimatedPerEmoji) {
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, final CountDownLatch sync, boolean allowAnimated, boolean allowTopicIcons, boolean includeSingleEmoji, Integer maxAnimatedPerEmoji) {
if (callback == null) {
return;
}
@ -7116,6 +7204,29 @@ public class MediaDataController extends BaseController {
return;
}
if (includeSingleEmoji) {
final int[] emojiOnly = new int[1];
ArrayList<Emoji.EmojiSpanRange> ranges = Emoji.parseEmojis(keyword, emojiOnly);
if (emojiOnly[0] > 0) {
for (int i = 0; i < ranges.size(); ++i) {
String code = ranges.get(i).code.toString();
boolean foundDuplicate = false;
for (int j = 0; j < result.size(); ++j) {
if (TextUtils.equals(result.get(j).emoji, code)) {
foundDuplicate = true;
break;
}
}
if (!foundDuplicate) {
KeywordResult keywordResult = new KeywordResult();
keywordResult.emoji = code;
keywordResult.keyword = "";
result.add(keywordResult);
}
}
}
}
String key = keyword.toLowerCase();
for (int a = 0; a < 2; a++) {
if (a == 1) {
@ -7734,4 +7845,60 @@ public class MediaDataController extends BaseController {
}
return objects;
}
public TLRPC.TL_emojiList profileAvatarConstructorDefault;
public TLRPC.TL_emojiList groupAvatarConstructorDefault;
private void loadAvatarConstructor(boolean profile) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("avatar_constructor" + currentAccount, Context.MODE_PRIVATE);
String value;
long lastCheckTime;
if (profile) {
value = preferences.getString("profile", null);
lastCheckTime = preferences.getLong("profile_last_check", 0);
} else {
value = preferences.getString("group", null);
lastCheckTime = preferences.getLong("group_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);
if (profile) {
profileAvatarConstructorDefault = emojiList;
} else {
groupAvatarConstructorDefault = emojiList;
}
} catch (Throwable e) {
FileLog.e(e);
}
}
if (emojiList == null || (System.currentTimeMillis() - lastCheckTime) > 24 * 60 * 60 * 1000 || BuildVars.DEBUG_PRIVATE_VERSION) {
TLRPC.TL_account_getDefaultProfilePhotoEmojis req = new TLRPC.TL_account_getDefaultProfilePhotoEmojis();
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();
if (profile) {
profileAvatarConstructorDefault = (TLRPC.TL_emojiList) response;
editor.putString("profile", Utilities.bytesToHex(data.toByteArray()));
editor.putLong("profile_last_check", System.currentTimeMillis());
} else {
groupAvatarConstructorDefault = (TLRPC.TL_emojiList) response;
editor.putString("group", Utilities.bytesToHex(data.toByteArray()));
editor.putLong("group_last_check", System.currentTimeMillis());
}
editor.apply();
}
}));
}
}
}

View File

@ -14,7 +14,10 @@ public class MessageCustomParamsHelper {
!message.voiceTranscriptionRated &&
!message.voiceTranscriptionForce &&
message.voiceTranscriptionId == 0 &&
!message.premiumEffectWasPlayed;
!message.premiumEffectWasPlayed &&
message.originalLanguage == null &&
message.translatedToLanguage == null &&
message.translatedText == null;
}
public static void copyParams(TLRPC.Message fromMessage, TLRPC.Message toMessage) {
@ -25,6 +28,9 @@ public class MessageCustomParamsHelper {
toMessage.voiceTranscriptionRated = fromMessage.voiceTranscriptionRated;
toMessage.voiceTranscriptionId = fromMessage.voiceTranscriptionId;
toMessage.premiumEffectWasPlayed = fromMessage.premiumEffectWasPlayed;
toMessage.originalLanguage = fromMessage.originalLanguage;
toMessage.translatedToLanguage = fromMessage.translatedToLanguage;
toMessage.translatedText = fromMessage.translatedText;
}
@ -69,6 +75,10 @@ public class MessageCustomParamsHelper {
this.message = message;
flags += message.voiceTranscription != null ? 1 : 0;
flags += message.voiceTranscriptionForce ? 2 : 0;
flags += message.originalLanguage != null ? 4 : 0;
flags += message.translatedToLanguage != null ? 8 : 0;
flags += message.translatedText != null ? 16 : 0;
}
@Override
@ -85,6 +95,16 @@ public class MessageCustomParamsHelper {
stream.writeInt64(message.voiceTranscriptionId);
stream.writeBool(message.premiumEffectWasPlayed);
if ((flags & 4) != 0) {
stream.writeString(message.originalLanguage);
}
if ((flags & 8) != 0) {
stream.writeString(message.translatedToLanguage);
}
if ((flags & 16) != 0) {
message.translatedText.serializeToStream(stream);
}
}
@Override
@ -100,6 +120,16 @@ public class MessageCustomParamsHelper {
message.voiceTranscriptionId = stream.readInt64(exception);
message.premiumEffectWasPlayed = stream.readBool(exception);
if ((flags & 4) != 0) {
message.originalLanguage = stream.readString(exception);
}
if ((flags & 8) != 0) {
message.translatedToLanguage = stream.readString(exception);
}
if ((flags & 16) != 0) {
message.translatedText = TLRPC.TL_textWithEntities.TLdeserialize(stream, stream.readInt32(exception), exception);
}
}
}

View File

@ -56,6 +56,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.w3c.dom.Text;
import java.io.BufferedReader;
import java.io.File;
@ -114,6 +115,7 @@ public class MessageObject {
public Long emojiAnimatedStickerId;
public boolean isTopicMainMessage;
public boolean settingAvatar;
public TLRPC.VideoSize emojiMarkup;
private boolean emojiAnimatedStickerLoading;
public String emojiAnimatedStickerColor;
public CharSequence messageText;
@ -222,7 +224,6 @@ public class MessageObject {
public int textHeight;
public boolean hasRtl;
public float textXOffset;
public int linesCount;
public SendAnimationData sendAnimationData;
@ -1170,6 +1171,7 @@ public class MessageObject {
updateMessageText(users, chats, sUsers, sChats);
setType();
updateTranslation(false);
measureInlineBotButtons();
Calendar rightNow = new GregorianCalendar();
@ -1191,7 +1193,7 @@ public class MessageObject {
}
int[] emojiOnly = allowsBigEmoji() ? new int[1] : null;
messageText = Emoji.replaceEmoji(messageText, paint.getFontMetricsInt(), AndroidUtilities.dp(20), false, emojiOnly);
messageText = replaceAnimatedEmoji(messageText, messageOwner.entities, paint.getFontMetricsInt());
messageText = replaceAnimatedEmoji(messageText, paint.getFontMetricsInt());
if (emojiOnly != null && emojiOnly[0] > 1) {
replaceEmojiToLottieFrame(messageText, emojiOnly);
}
@ -2415,7 +2417,7 @@ public class MessageObject {
int[] emojiOnly = allowsBigEmoji() ? new int[1] : null;
messageText = Emoji.replaceEmoji(messageText, paint.getFontMetricsInt(), AndroidUtilities.dp(20), false, emojiOnly);
messageText = replaceAnimatedEmoji(messageText, messageOwner.entities, paint.getFontMetricsInt());
messageText = replaceAnimatedEmoji(messageText, paint.getFontMetricsInt());
if (emojiOnly != null && emojiOnly[0] > 1) {
replaceEmojiToLottieFrame(messageText, emojiOnly);
}
@ -2511,7 +2513,38 @@ public class MessageObject {
return name;
}
public boolean updateTranslation() {
return updateTranslation(true);
}
public boolean translated = false;
public boolean updateTranslation(boolean force) {
boolean replyUpdated = replyMessageObject != null && replyMessageObject.updateTranslation(force);
if (
TranslateController.isTranslatable(this) &&
MessagesController.getInstance(currentAccount).getTranslateController().isTranslatingDialog(getDialogId()) &&
messageOwner != null &&
messageOwner.translatedText != null &&
TextUtils.equals(MessagesController.getInstance(currentAccount).getTranslateController().getDialogTranslateTo(getDialogId()), messageOwner.translatedToLanguage)
) {
if (translated) {
return replyUpdated || false;
}
translated = true;
applyNewText(messageOwner.translatedText.text);
generateCaption();
return replyUpdated || true;
} else if (messageOwner != null && (force || translated)) {
translated = false;
applyNewText(messageOwner.message);
generateCaption();
return replyUpdated || true;
}
return replyUpdated || false;
}
public void applyNewText() {
translated = false;
applyNewText(messageOwner.message);
}
@ -2524,6 +2557,7 @@ public class MessageObject {
fromUser = MessagesController.getInstance(currentAccount).getUser(messageOwner.from_id.user_id);
}
messageText = text;
ArrayList<TLRPC.MessageEntity> entities = translated && messageOwner.translatedText != null ? messageOwner.translatedText.entities : messageOwner.entities;
TextPaint paint;
if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) {
paint = Theme.chat_msgGameTextPaint;
@ -2532,7 +2566,7 @@ public class MessageObject {
}
int[] emojiOnly = allowsBigEmoji() ? new int[1] : null;
messageText = Emoji.replaceEmoji(messageText, paint.getFontMetricsInt(), AndroidUtilities.dp(20), false, emojiOnly);
messageText = replaceAnimatedEmoji(messageText, messageOwner.entities, paint.getFontMetricsInt());
messageText = replaceAnimatedEmoji(messageText, entities, paint.getFontMetricsInt());
if (emojiOnly != null && emojiOnly[0] > 1) {
replaceEmojiToLottieFrame(messageText, emojiOnly);
}
@ -2668,7 +2702,7 @@ public class MessageObject {
}
mess = Emoji.replaceEmoji(mess, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
if (replyMessageObject != null && replyMessageObject.messageOwner != null) {
mess = replaceAnimatedEmoji(mess, replyMessageObject.messageOwner.entities, Theme.chat_msgTextPaint.getFontMetricsInt());
mess = replyMessageObject.replaceAnimatedEmoji(mess, Theme.chat_msgTextPaint.getFontMetricsInt());
}
MediaDataController.addTextStyleRuns(replyMessageObject, (Spannable) mess);
if (ellipsize) {
@ -3375,6 +3409,41 @@ public class MessageObject {
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionAttachMenuBotAllowed) {
messageText = LocaleController.getString(R.string.ActionAttachMenuBotAllowed);
} 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);
}
} 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);
}
}
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;
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null;
@ -3824,7 +3893,7 @@ public class MessageObject {
} else {
type = TYPE_ANIMATED_STICKER;
}
} else if (!isDice() && emojiOnlyCount >= 1 && !hasUnwrappedEmoji) {
} else if (isMediaEmpty() && !isDice() && emojiOnlyCount >= 1 && !hasUnwrappedEmoji) {
type = TYPE_EMOJIS;
} else if (isMediaEmpty()) {
type = TYPE_TEXT;
@ -3951,7 +4020,7 @@ public class MessageObject {
}
int[] emojiOnly = allowsBigEmoji() ? new int[1] : null;
messageText = Emoji.replaceEmoji(messageText, paint.getFontMetricsInt(), AndroidUtilities.dp(20), false, emojiOnly);
messageText = replaceAnimatedEmoji(messageText, messageOwner.entities, paint.getFontMetricsInt());
messageText = replaceAnimatedEmoji(messageText, paint.getFontMetricsInt());
if (emojiOnly != null && emojiOnly[0] > 1) {
replaceEmojiToLottieFrame(messageText, emojiOnly);
}
@ -4546,22 +4615,30 @@ public class MessageObject {
);
}
private boolean captionTranslated;
public void generateCaption() {
if (caption != null || isRoundVideo()) {
if (caption != null && translated == captionTranslated || isRoundVideo()) {
return;
}
String text = messageOwner.message;
ArrayList<TLRPC.MessageEntity> entities = messageOwner.entities;
if (hasExtendedMedia()) {
messageOwner.message = messageOwner.media.description;
text = messageOwner.message = messageOwner.media.description;
}
if (!isMediaEmpty() && !(getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) && !TextUtils.isEmpty(messageOwner.message)) {
caption = Emoji.replaceEmoji(messageOwner.message, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
caption = replaceAnimatedEmoji(caption, messageOwner.entities, Theme.chat_msgTextPaint.getFontMetricsInt());
if (captionTranslated = translated) {
text = messageOwner.translatedText.text;
entities = messageOwner.translatedText.entities;
}
if (!isMediaEmpty() && !(getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) && !TextUtils.isEmpty(text)) {
caption = Emoji.replaceEmoji(text, Theme.chat_msgTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);
caption = replaceAnimatedEmoji(caption, Theme.chat_msgTextPaint.getFontMetricsInt());
boolean hasEntities;
if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) {
hasEntities = false;
} else {
hasEntities = !messageOwner.entities.isEmpty();
hasEntities = !entities.isEmpty();
}
boolean useManualParse = !hasEntities && (
@ -4819,7 +4896,17 @@ public class MessageObject {
entities.add(entityItalic);
return addEntitiesToText(text, entities, isOutOwner(), true, photoViewer, useManualParse);
} else {
return addEntitiesToText(text, messageOwner.entities, isOutOwner(), true, photoViewer, useManualParse);
ArrayList<TLRPC.MessageEntity> entities;
if (translated) {
if (messageOwner.translatedText == null) {
entities = null;
} else {
entities = messageOwner.translatedText.entities;
}
} else {
entities = messageOwner.entities;
}
return addEntitiesToText(text, entities, isOutOwner(), true, photoViewer, useManualParse);
}
}
@ -4847,6 +4934,11 @@ public class MessageObject {
}
}
public Spannable replaceAnimatedEmoji(CharSequence text, Paint.FontMetricsInt fontMetricsInt) {
ArrayList<TLRPC.MessageEntity> entities = translated && messageOwner.translatedText != null ? messageOwner.translatedText.entities : messageOwner.entities;
return replaceAnimatedEmoji(text, entities, fontMetricsInt, false);
}
public static Spannable replaceAnimatedEmoji(CharSequence text, ArrayList<TLRPC.MessageEntity> entities, Paint.FontMetricsInt fontMetricsInt) {
return replaceAnimatedEmoji(text, entities, fontMetricsInt, false);
}
@ -4866,8 +4958,7 @@ public class MessageObject {
if (span != null) {
int start = spannable.getSpanStart(span);
int end = spannable.getSpanEnd(span);
if (entity.offset == start && entity.length == (end - start)) {
if (AndroidUtilities.intersect1d(entity.offset, entity.offset + entity.length, start, end)) {
spannable.removeSpan(span);
emojiSpans[j] = null;
}
@ -4903,7 +4994,7 @@ public class MessageObject {
Spannable spannable = (Spannable) text;
URLSpan[] spans = spannable.getSpans(0, text.length(), URLSpan.class);
boolean hasUrls = spans != null && spans.length > 0;
if (entities.isEmpty()) {
if (entities == null || entities.isEmpty()) {
return hasUrls;
}
@ -5224,11 +5315,13 @@ public class MessageObject {
textLayoutBlocks = new ArrayList<>();
textWidth = 0;
ArrayList<TLRPC.MessageEntity> entities = translated && messageOwner.translatedText != null ? messageOwner.translatedText.entities : messageOwner.entities;
boolean hasEntities;
if (messageOwner.send_state != MESSAGE_SEND_STATE_SENT) {
hasEntities = false;
} else {
hasEntities = !messageOwner.entities.isEmpty();
hasEntities = !entities.isEmpty();
}
boolean useManualParse = !hasEntities && (
@ -5305,7 +5398,7 @@ public class MessageObject {
}
textHeight = textLayout.getHeight();
linesCount = textLayout.getLineCount();
int linesCount = textLayout.getLineCount();
int linesPreBlock = totalAnimatedEmojiCount >= 50 ? LINES_PER_BLOCK_WITH_EMOJI : LINES_PER_BLOCK;
int blocksCount;

View File

@ -26,6 +26,7 @@ import android.os.SystemClock;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
@ -401,6 +402,8 @@ public class MessagesController extends BaseController implements NotificationCe
private LongSparseArray<Integer> emojiStatusUntilValues = new LongSparseArray<>();
private TopicsController topicsController;
private CacheByChatsController cacheByChatsController;
private TranslateController translateController;
public boolean uploadMarkupVideo;
public void getNextReactionMention(long dialogId, int topicId, int count, Consumer<Integer> callback) {
final MessagesStorage messagesStorage = getMessagesStorage();
@ -590,6 +593,10 @@ public class MessagesController extends BaseController implements NotificationCe
return topicsController;
}
public TranslateController getTranslateController() {
return translateController;
}
public boolean isForum(long dialogId) {
TLRPC.Chat chatLocal = getChat(-dialogId);
return chatLocal != null && chatLocal.forum;
@ -1008,6 +1015,10 @@ public class MessagesController extends BaseController implements NotificationCe
return localInstance;
}
public SharedPreferences getMainSettings() {
return mainPreferences;
}
public static SharedPreferences getNotificationsSettings(int account) {
return getInstance(account).notificationsPreferences;
}
@ -1152,6 +1163,7 @@ public class MessagesController extends BaseController implements NotificationCe
telegramAntispamUserId = mainPreferences.getLong("telegramAntispamUserId", -1);
telegramAntispamGroupSizeMin = mainPreferences.getInt("telegramAntispamGroupSizeMin", 100);
hiddenMembersGroupSizeMin = mainPreferences.getInt("hiddenMembersGroupSizeMin", 100);
uploadMarkupVideo = mainPreferences.getBoolean("uploadMarkupVideo", true);
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
Set<String> currencySet = mainPreferences.getStringSet("directPaymentsCurrency", null);
@ -1290,6 +1302,7 @@ public class MessagesController extends BaseController implements NotificationCe
topicsController = new TopicsController(num);
cacheByChatsController = new CacheByChatsController(num);
translateController = new TranslateController(this);
}
@ -1598,6 +1611,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
} else {
currentDialog.pinned = newDialog.pinned;
currentDialog.pinnedNum = newDialog.pinnedNum;
@ -1645,6 +1659,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
} else {
// if (newMsg == null || newMsg.messageOwner.date > oldMsg.messageOwner.date) {
@ -1682,6 +1697,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
}
}
@ -1802,13 +1818,29 @@ public class MessagesController extends BaseController implements NotificationCe
lockFiltersInternal();
}
public void updateEmojiStatus(TLRPC.EmojiStatus newStatus) {
TLRPC.TL_account_updateEmojiStatus req = new TLRPC.TL_account_updateEmojiStatus();
req.emoji_status = newStatus;
TLRPC.User user = getUserConfig().getCurrentUser();
if (user != null) {
user.emoji_status = req.emoji_status;
getNotificationCenter().postNotificationName(NotificationCenter.userEmojiStatusUpdated, user);
getMessagesController().updateEmojiStatusUntilUpdate(user.id, user.emoji_status);
}
getConnectionsManager().sendRequest(req, (res, err) -> {
if (!(res instanceof TLRPC.TL_boolTrue)) {
// TODO: reject
}
});
}
public void removeFilter(DialogFilter filter) {
dialogFilters.remove(filter);
dialogFiltersById.remove(filter.id);
getNotificationCenter().postNotificationName(NotificationCenter.dialogFiltersUpdated);
}
private void loadAppConfig() {
public void loadAppConfig() {
if (loadingAppConfig) {
return;
}
@ -1824,6 +1856,16 @@ public class MessagesController extends BaseController implements NotificationCe
for (int a = 0, N = object.value.size(); a < N; a++) {
TLRPC.TL_jsonObjectValue value = object.value.get(a);
switch (value.key) {
case "upload_markup_video": {
if (value.value instanceof TLRPC.TL_jsonBool) {
if (uploadMarkupVideo != ((TLRPC.TL_jsonBool) value.value).value) {
uploadMarkupVideo = ((TLRPC.TL_jsonBool) value.value).value;
editor.putBoolean("uploadMarkupVideo", uploadMarkupVideo);
changed = true;
}
}
break;
}
case "login_google_oauth_client_id": {
if (value.value instanceof TLRPC.TL_jsonString) {
String str = ((TLRPC.TL_jsonString) value.value).value;
@ -3450,6 +3492,7 @@ public class MessagesController extends BaseController implements NotificationCe
getLocationController().cleanup();
getMediaDataController().cleanup();
getColorPalette().cleanup();
getTranslateController().cleanup();
showFiltersTooltip = false;
@ -4433,6 +4476,7 @@ public class MessagesController extends BaseController implements NotificationCe
res.full_chat.inviterId = old.inviterId;
}
fullChats.put(chatId, res.full_chat);
getTranslateController().updateDialogFull(-chatId);
applyDialogNotificationsSettings(-chatId, 0, res.full_chat.notify_settings);
for (int a = 0; a < res.full_chat.bot_info.size(); a++) {
@ -4530,6 +4574,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
fullUsers.put(user.id, userFull);
getTranslateController().updateDialogFull(user.id);
loadingFullUsers.remove(user.id);
loadedFullUsers.put(user.id, System.currentTimeMillis());
String names = user.first_name + user.last_name + UserObject.getPublicUsername(user);
@ -5269,7 +5314,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (photo == null) {
TLRPC.TL_photos_updateProfilePhoto req = new TLRPC.TL_photos_updateProfilePhoto();
req.id = new TLRPC.TL_inputPhotoEmpty();
getUserConfig().getCurrentUser().photo = new TLRPC.TL_userProfilePhotoEmpty();
// getUserConfig().getCurrentUser().photo = new TLRPC.TL_userProfilePhotoEmpty();
TLRPC.User user = getUser(getUserConfig().getClientUserId());
if (user == null) {
user = getUserConfig().getCurrentUser();
@ -5277,39 +5322,49 @@ public class MessagesController extends BaseController implements NotificationCe
if (user == null) {
return;
}
user.photo = getUserConfig().getCurrentUser().photo;
getMessagesStorage().clearUserPhoto(user.id, user.photo.photo_id);
// user.photo = getUserConfig().getCurrentUser().photo;
getNotificationCenter().postNotificationName(NotificationCenter.mainUserInfoChanged);
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_ALL);
getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.TL_photos_photo photos_photo = (TLRPC.TL_photos_photo) response;
TLRPC.User user1 = getUser(getUserConfig().getClientUserId());
if (user1 == null) {
user1 = getUserConfig().getCurrentUser();
putUser(user1, false);
} else {
getUserConfig().setCurrentUser(user1);
}
if (user1 == null) {
return;
}
getMessagesStorage().clearUserPhotos(user1.id);
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(user1);
getMessagesStorage().putUsersAndChats(users, null, false, true);
if (photos_photo.photo instanceof TLRPC.TL_photo) {
user1.photo = new TLRPC.TL_userProfilePhoto();
user1.photo.has_video = !photos_photo.photo.video_sizes.isEmpty();
user1.photo.photo_id = photos_photo.photo.id;
user1.photo.photo_small = FileLoader.getClosestPhotoSizeWithSize(photos_photo.photo.sizes, 150).location;
user1.photo.photo_big = FileLoader.getClosestPhotoSizeWithSize(photos_photo.photo.sizes, 800).location;
user1.photo.dc_id = photos_photo.photo.dc_id;
} else {
user1.photo = new TLRPC.TL_userProfilePhotoEmpty();
}
AndroidUtilities.runOnUIThread(() -> {
TLRPC.TL_photos_photo photos_photo = (TLRPC.TL_photos_photo) response;
TLRPC.User user1 = getUser(getUserConfig().getClientUserId());
if (user1 == null) {
user1 = getUserConfig().getCurrentUser();
putUser(user1, false);
} else {
getUserConfig().setCurrentUser(user1);
}
if (user1 == null) {
return;
}
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(user1);
getMessagesStorage().putUsersAndChats(users, null, false, true);
if (photos_photo.photo instanceof TLRPC.TL_photo) {
user1.photo = new TLRPC.TL_userProfilePhoto();
user1.photo.has_video = !photos_photo.photo.video_sizes.isEmpty();
user1.photo.photo_id = photos_photo.photo.id;
user1.photo.photo_small = FileLoader.getClosestPhotoSizeWithSize(photos_photo.photo.sizes, 150).location;
user1.photo.photo_big = FileLoader.getClosestPhotoSizeWithSize(photos_photo.photo.sizes, 800).location;
user1.photo.dc_id = photos_photo.photo.dc_id;
} else {
user1.photo = new TLRPC.TL_userProfilePhotoEmpty();
}
TLRPC.UserFull userFull = getUserFull(getUserConfig().getClientUserId());
userFull.profile_photo = photos_photo.photo;
getMessagesStorage().updateUserInfo(userFull, false);
getUserConfig().getCurrentUser().photo = user1.photo;
putUser(user1, false);
getNotificationCenter().postNotificationName(NotificationCenter.mainUserInfoChanged);
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_ALL);
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_AVATAR);
getUserConfig().saveConfig(true);
});
}
@ -6336,6 +6391,7 @@ public class MessagesController extends BaseController implements NotificationCe
public void putChatFull(TLRPC.ChatFull chatFull) {
fullChats.put(chatFull.id, chatFull);
getTranslateController().updateDialogFull(-chatFull.id);
}
public void processChatInfo(long chatId, TLRPC.ChatFull info, ArrayList<TLRPC.User> usersArr, boolean fromCache, boolean force, boolean byChannelUsers, ArrayList<Integer> pinnedMessages, HashMap<Integer, MessageObject> pinnedMessagesMap, int totalPinnedCount, boolean pinnedEndReached) {
@ -6349,6 +6405,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (info != null) {
if (fullChats.get(chatId) == null) {
fullChats.put(chatId, info);
getTranslateController().updateDialogFull(-chatId);
}
putUsers(usersArr, fromCache);
if (info.stickerset != null) {
@ -6391,6 +6448,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (info != null) {
if (fullUsers.get(user.id) == null) {
fullUsers.put(user.id, info);
getTranslateController().updateDialogFull(user.id);
int index = blockePeers.indexOfKey(user.id);
if (info.blocked) {
@ -6964,6 +7022,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (promoDialog.last_message_date == 0) {
promoDialog.last_message_date = messageObject.messageOwner.date;
}
getTranslateController().checkDialogMessages(did);
}
sortDialogs(null);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload, true);
@ -7062,113 +7121,114 @@ public class MessagesController extends BaseController implements NotificationCe
newStrings.put(key, newPrintingStrings);
newTypes.put(key, newPrintingStringsTypes);
int type = 0;
CharSequence text = null;
if (key > 0 || isEncryptedChat || arr.size() == 1) {
PrintingUser pu = arr.get(0);
TLRPC.User user = getUser(pu.userId);
if (user == null) {
continue;
}
final boolean isGroup = key < 0 && !isEncryptedChat;
if (pu.action instanceof TLRPC.TL_sendMessageRecordAudioAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsRecordingAudio", R.string.IsRecordingAudio, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsRecordingAudio", R.string.IsRecordingAudio, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("RecordingAudio", R.string.RecordingAudio));
text = LocaleController.getString("RecordingAudio", R.string.RecordingAudio);
}
newPrintingStringsTypes.put(threadId, 1);
type = 1;
} else if (pu.action instanceof TLRPC.TL_sendMessageRecordRoundAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsRecordingRound", R.string.IsRecordingRound, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsRecordingRound", R.string.IsRecordingRound, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("RecordingRound", R.string.RecordingRound));
text = LocaleController.getString("RecordingRound", R.string.RecordingRound);
}
newPrintingStringsTypes.put(threadId, 4);
type = 4;
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadRoundAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSendingVideo", R.string.IsSendingVideo, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSendingVideo", R.string.IsSendingVideo, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SendingVideoStatus", R.string.SendingVideoStatus));
text = LocaleController.getString("SendingVideoStatus", R.string.SendingVideoStatus);
}
newPrintingStringsTypes.put(threadId, 4);
type = 4;
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadAudioAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSendingAudio", R.string.IsSendingAudio, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSendingAudio", R.string.IsSendingAudio, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SendingAudio", R.string.SendingAudio));
text = LocaleController.getString("SendingAudio", R.string.SendingAudio);
}
newPrintingStringsTypes.put(threadId, 2);
type = 2;
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadVideoAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSendingVideo", R.string.IsSendingVideo, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSendingVideo", R.string.IsSendingVideo, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SendingVideoStatus", R.string.SendingVideoStatus));
text = LocaleController.getString("SendingVideoStatus", R.string.SendingVideoStatus);
}
newPrintingStringsTypes.put(threadId, 2);
type = 2;
} else if (pu.action instanceof TLRPC.TL_sendMessageRecordVideoAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsRecordingVideo", R.string.IsRecordingVideo, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsRecordingVideo", R.string.IsRecordingVideo, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("RecordingVideoStatus", R.string.RecordingVideoStatus));
text = LocaleController.getString("RecordingVideoStatus", R.string.RecordingVideoStatus);
}
newPrintingStringsTypes.put(threadId, 2);
type = 2;
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadDocumentAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSendingFile", R.string.IsSendingFile, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSendingFile", R.string.IsSendingFile, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SendingFile", R.string.SendingFile));
text = LocaleController.getString("SendingFile", R.string.SendingFile);
}
newPrintingStringsTypes.put(threadId, 2);
type = 2;
} else if (pu.action instanceof TLRPC.TL_sendMessageUploadPhotoAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSendingPhoto", R.string.IsSendingPhoto, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSendingPhoto", R.string.IsSendingPhoto, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SendingPhoto", R.string.SendingPhoto));
text = LocaleController.getString("SendingPhoto", R.string.SendingPhoto);
}
newPrintingStringsTypes.put(threadId, 2);
type = 2;
} else if (pu.action instanceof TLRPC.TL_sendMessageGamePlayAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSendingGame", R.string.IsSendingGame, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSendingGame", R.string.IsSendingGame, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SendingGame", R.string.SendingGame));
text = LocaleController.getString("SendingGame", R.string.SendingGame);
}
newPrintingStringsTypes.put(threadId, 3);
type = 3;
} else if (pu.action instanceof TLRPC.TL_sendMessageGeoLocationAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSelectingLocation", R.string.IsSelectingLocation, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSelectingLocation", R.string.IsSelectingLocation, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SelectingLocation", R.string.SelectingLocation));
text = LocaleController.getString("SelectingLocation", R.string.SelectingLocation);
}
newPrintingStringsTypes.put(threadId, 0);
type = 0;
} else if (pu.action instanceof TLRPC.TL_sendMessageChooseContactAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsSelectingContact", R.string.IsSelectingContact, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsSelectingContact", R.string.IsSelectingContact, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("SelectingContact", R.string.SelectingContact));
text = LocaleController.getString("SelectingContact", R.string.SelectingContact);
}
newPrintingStringsTypes.put(threadId, 0);
type = 0;
} else if (pu.action instanceof TLRPC.TL_sendMessageEmojiInteractionSeen) {
String emoji = ((TLRPC.TL_sendMessageEmojiInteractionSeen) pu.action).emoticon;
String printingString;
if (key < 0 && !isEncryptedChat) {
printingString = LocaleController.formatString("IsEnjoyngAnimations", R.string.IsEnjoyngAnimations, getUserNameForTyping(user), emoji);
final String emoji = ((TLRPC.TL_sendMessageEmojiInteractionSeen) pu.action).emoticon;
if (isGroup) {
text = LocaleController.formatString("IsEnjoyngAnimations", R.string.IsEnjoyngAnimations, getUserNameForTyping(user), emoji);
} else {
printingString = LocaleController.formatString("EnjoyngAnimations", R.string.EnjoyngAnimations, emoji);
text = LocaleController.formatString("EnjoyngAnimations", R.string.EnjoyngAnimations, emoji);
}
newPrintingStrings.put(threadId, printingString);
newPrintingStringsTypes.put(threadId, 5);
type = 5;
} else if (pu.action instanceof TLRPC.TL_sendMessageChooseStickerAction) {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsChoosingSticker", R.string.IsChoosingSticker, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsChoosingSticker", R.string.IsChoosingSticker, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("ChoosingSticker", R.string.ChoosingSticker));
text = LocaleController.getString("ChoosingSticker", R.string.ChoosingSticker);
}
newPrintingStringsTypes.put(threadId, 5);
type = 5;
} else {
if (key < 0 && !isEncryptedChat) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsTypingGroup", R.string.IsTypingGroup, getUserNameForTyping(user)));
if (isGroup) {
text = LocaleController.formatString("IsTypingGroup", R.string.IsTypingGroup, getUserNameForTyping(user));
} else {
newPrintingStrings.put(threadId, LocaleController.getString("Typing", R.string.Typing));
text = LocaleController.getString("Typing", R.string.Typing);
}
newPrintingStringsTypes.put(threadId, 0);
type = 0;
}
} else {
int count = 0;
@ -7188,22 +7248,30 @@ public class MessagesController extends BaseController implements NotificationCe
}
if (label.length() != 0) {
if (count == 1) {
newPrintingStrings.put(threadId, LocaleController.formatString("IsTypingGroup", R.string.IsTypingGroup, label.toString()));
text = LocaleController.formatString("IsTypingGroup", R.string.IsTypingGroup, label.toString());
} else {
if (arr.size() > 2) {
String plural = LocaleController.getPluralString("AndMoreTypingGroup", arr.size() - 2);
try {
newPrintingStrings.put(threadId, String.format(plural, label.toString(), arr.size() - 2));
text = String.format(plural, label.toString(), arr.size() - 2);
} catch (Exception e) {
newPrintingStrings.put(threadId, "LOC_ERR: AndMoreTypingGroup");
text = "LOC_ERR: AndMoreTypingGroup";
}
} else {
newPrintingStrings.put(threadId, LocaleController.formatString("AreTypingGroup", R.string.AreTypingGroup, label.toString()));
text = LocaleController.formatString("AreTypingGroup", R.string.AreTypingGroup, label.toString());
}
}
newPrintingStringsTypes.put(threadId, 0);
type = 0;
}
}
if (text != null && ApplicationLoader.applicationContext != null) {
if (Theme.dialogs_messageNamePaint == null) {
Theme.createDialogsResources(ApplicationLoader.applicationContext);
}
text = Emoji.replaceEmoji(text, Theme.dialogs_messageNamePaint.getFontMetricsInt(), false);
newPrintingStrings.put(threadId, text);
newPrintingStringsTypes.put(threadId, type);
}
}
}
@ -8085,7 +8153,7 @@ public class MessagesController extends BaseController implements NotificationCe
getConnectionsManager().sendRequest(req, (response, error) -> {
if (error == null) {
TLRPC.messages_Dialogs dialogsRes = (TLRPC.messages_Dialogs) response;
processLoadedDialogs(dialogsRes, null, folderId, 0, count, 0, false, false, false);
processLoadedDialogs(dialogsRes, null, null, folderId, 0, count, 0, false, false, false);
if (onEmptyCallback != null && dialogsRes.dialogs.isEmpty()) {
AndroidUtilities.runOnUIThread(onEmptyCallback);
}
@ -8258,7 +8326,7 @@ public class MessagesController extends BaseController implements NotificationCe
dialogs.messages.addAll(res.messages);
dialogs.users.addAll(res.users);
dialogs.chats.addAll(res.chats);
processLoadedDialogs(dialogs, null, dialog.folder_id, 0, 1, DIALOGS_LOAD_TYPE_UNKNOWN, false, false, false);
processLoadedDialogs(dialogs, null, null, dialog.folder_id, 0, 1, DIALOGS_LOAD_TYPE_UNKNOWN, false, false, false);
}
}
if (newTaskId != 0) {
@ -8544,6 +8612,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
allDialogs.clear();
@ -8764,7 +8833,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
processLoadedDialogs(dialogsRes, null, 0, offsetId, 0, 0, false, true, false);
processLoadedDialogs(dialogsRes, null, null, 0, offsetId, 0, 0, false, true, false);
} catch (Exception e) {
FileLog.e(e);
AndroidUtilities.runOnUIThread(() -> migratingDialogs = false);
@ -8780,7 +8849,7 @@ public class MessagesController extends BaseController implements NotificationCe
private int DIALOGS_LOAD_TYPE_CHANNEL = 2;
private int DIALOGS_LOAD_TYPE_UNKNOWN = 3;
public void processLoadedDialogs(final TLRPC.messages_Dialogs dialogsRes, ArrayList<TLRPC.EncryptedChat> encChats, int folderId, int offset, int count, int loadType, boolean resetEnd, boolean migrate, boolean fromCache) {
public void processLoadedDialogs(final TLRPC.messages_Dialogs dialogsRes, ArrayList<TLRPC.EncryptedChat> encChats, ArrayList<TLRPC.UserFull> fullUsers, int folderId, int offset, int count, int loadType, boolean resetEnd, boolean migrate, boolean fromCache) {
Utilities.stageQueue.postRunnable(() -> {
if (!firstGettingTask) {
getNewDeleteTask(null, null);
@ -8794,6 +8863,13 @@ public class MessagesController extends BaseController implements NotificationCe
if (loadType == DIALOGS_LOAD_TYPE_CACHE && dialogsRes.dialogs.size() == 0) {
AndroidUtilities.runOnUIThread(() -> {
putUsers(dialogsRes.users, true);
if (fullUsers != null) {
for (int i = 0; i < fullUsers.size(); i++) {
long did = fullUsers.get(i).id;
this.fullUsers.put(did, fullUsers.get(i));
getTranslateController().updateDialogFull(did);
}
}
loadingDialogs.put(folderId, false);
if (resetEnd) {
dialogsEndReached.put(folderId, false);
@ -9040,6 +9116,13 @@ public class MessagesController extends BaseController implements NotificationCe
}
putUsers(dialogsRes.users, loadType == DIALOGS_LOAD_TYPE_CACHE);
putChats(dialogsRes.chats, loadType == DIALOGS_LOAD_TYPE_CACHE);
if (fullUsers != null) {
for (int i = 0; i < fullUsers.size(); i++) {
long did = fullUsers.get(i).id;
this.fullUsers.put(did, fullUsers.get(i));
getTranslateController().updateDialogFull(did);
}
}
if (encChats != null) {
for (int a = 0; a < encChats.size(); a++) {
@ -9090,6 +9173,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
} else {
if (loadType != DIALOGS_LOAD_TYPE_CACHE) {
currentDialog.notify_settings = value.notify_settings;
@ -9141,6 +9225,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
} else {
// if (newMsg == null && oldMs.getId() > 0 || newMsg != null && newMsg.messageOwner.date > oldMsg.messageOwner.date)
@ -9178,6 +9263,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
}
}
@ -9635,6 +9721,7 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.d("processDialogsUpdate new message not null");
}
}
getTranslateController().checkDialogMessages(key);
} else {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("processDialogsUpdate dialog not null");
@ -9694,6 +9781,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
if (fromCache && newMsgs == null) {
checkLastDialogMessage(value, null, 0);
@ -9740,6 +9828,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(key);
}
}
}
@ -10268,7 +10357,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (type == ChatObject.CHAT_TYPE_CHAT && !forImport) {
TLRPC.TL_messages_createChat req = new TLRPC.TL_messages_createChat();
req.title = title;
if (ttlPeriod > 0) {
if (ttlPeriod >= 0) {
req.ttl_period = ttlPeriod;
req.flags |= 1;
}
@ -10299,16 +10388,17 @@ public class MessagesController extends BaseController implements NotificationCe
}
});
}, ConnectionsManager.RequestFlagFailOnServerErrors);
} else if (forImport || type == ChatObject.CHAT_TYPE_CHANNEL || type == ChatObject.CHAT_TYPE_MEGAGROUP) {
} else if (forImport || type == ChatObject.CHAT_TYPE_CHANNEL || type == ChatObject.CHAT_TYPE_MEGAGROUP || type == ChatObject.CHAT_TYPE_FORUM) {
TLRPC.TL_channels_createChannel req = new TLRPC.TL_channels_createChannel();
req.title = title;
req.about = about != null ? about : "";
req.for_import = forImport;
if (forImport || type == ChatObject.CHAT_TYPE_MEGAGROUP) {
if (forImport || type == ChatObject.CHAT_TYPE_MEGAGROUP || type == ChatObject.CHAT_TYPE_FORUM) {
req.megagroup = true;
} else {
req.broadcast = true;
}
req.forum = type == ChatObject.CHAT_TYPE_FORUM;
if (location != null) {
req.geo_point = new TLRPC.TL_inputGeoPoint();
req.geo_point.lat = location.getLatitude();
@ -10962,12 +11052,12 @@ public class MessagesController extends BaseController implements NotificationCe
}, ConnectionsManager.RequestFlagInvokeAfter);
}
public void changeChatAvatar(long chatId, TLRPC.TL_inputChatPhoto oldPhoto, TLRPC.InputFile inputPhoto, TLRPC.InputFile inputVideo, double videoStartTimestamp, String videoPath, TLRPC.FileLocation smallSize, TLRPC.FileLocation bigSize, Runnable callback) {
public void changeChatAvatar(long chatId, TLRPC.TL_inputChatPhoto oldPhoto, TLRPC.InputFile inputPhoto, TLRPC.InputFile inputVideo, TLRPC.VideoSize emojiMarkup, double videoStartTimestamp, String videoPath, TLRPC.FileLocation smallSize, TLRPC.FileLocation bigSize, Runnable callback) {
TLObject request;
TLRPC.InputChatPhoto inputChatPhoto;
if (oldPhoto != null) {
inputChatPhoto = oldPhoto;
} else if (inputPhoto != null || inputVideo != null) {
} else if (inputPhoto != null || inputVideo != null || emojiMarkup != null) {
TLRPC.TL_inputChatUploadedPhoto uploadedPhoto = new TLRPC.TL_inputChatUploadedPhoto();
if (inputPhoto != null) {
uploadedPhoto.file = inputPhoto;
@ -10979,6 +11069,10 @@ public class MessagesController extends BaseController implements NotificationCe
uploadedPhoto.video_start_ts = videoStartTimestamp;
uploadedPhoto.flags |= 4;
}
if (emojiMarkup != null) {
uploadedPhoto.video_emoji_markup = emojiMarkup;
uploadedPhoto.flags |= 8;
}
inputChatPhoto = uploadedPhoto;
} else {
inputChatPhoto = new TLRPC.TL_inputChatPhotoEmpty();
@ -11039,6 +11133,7 @@ public class MessagesController extends BaseController implements NotificationCe
File src = new File(videoPath);
src.renameTo(destFile);
}
getMessagesStorage().addDialogPhoto(-chatId, photo);
}
}
processUpdates(updates, false);
@ -11047,6 +11142,7 @@ public class MessagesController extends BaseController implements NotificationCe
callback.run();
}
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_AVATAR);
getNotificationCenter().postNotificationName(NotificationCenter.reloadDialogPhotos);
});
}, ConnectionsManager.RequestFlagInvokeAfter);
}
@ -11076,13 +11172,8 @@ public class MessagesController extends BaseController implements NotificationCe
getConnectionsManager().cleanup(false);
AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_auth_loggedOut) {
TLRPC.TL_auth_loggedOut res = (TLRPC.TL_auth_loggedOut) response;
if (((TLRPC.TL_auth_loggedOut) response).future_auth_token != null) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
SerializedData data = new SerializedData(response.getObjectSize());
res.serializeToStream(data);
preferences.edit().putString("log_out_token_" + count, Utilities.bytesToHex(data.toByteArray())).putInt("count", count + 1).apply();
AuthTokensHelper.addLogOutToken((TLRPC.TL_auth_loggedOut) response);
}
}
});
@ -11125,44 +11216,6 @@ public class MessagesController extends BaseController implements NotificationCe
getContactsController().deleteUnknownAppAccounts();
}
public static ArrayList<TLRPC.TL_auth_loggedOut> getSavedLogOutTokens() {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
int count = preferences.getInt("count", 0);
if (count == 0) {
return null;
}
ArrayList<TLRPC.TL_auth_loggedOut> tokens = new ArrayList<>();
for (int i = 0; i < count; i++) {
String value = preferences.getString("log_out_token_" + i, "");
SerializedData serializedData = new SerializedData(Utilities.hexToBytes(value));
TLRPC.TL_auth_loggedOut token = TLRPC.TL_auth_loggedOut.TLdeserialize(serializedData, serializedData.readInt32(true), true);
if (token != null) {
tokens.add(token);
}
}
return tokens;
}
public static void saveLogOutTokens(ArrayList<TLRPC.TL_auth_loggedOut> tokens) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("saved_tokens", Context.MODE_PRIVATE);
ArrayList<TLRPC.TL_auth_loggedOut> activeTokens = new ArrayList<>();
preferences.edit().clear().apply();
int date = (int) (System.currentTimeMillis() / 1000L);
for (int i = 0; i < Math.min(20, tokens.size()); i++) {
activeTokens.add(tokens.get(i));
}
if (activeTokens.size() > 0) {
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("count", activeTokens.size());
for (int i = 0; i < activeTokens.size(); i++) {
SerializedData data = new SerializedData(activeTokens.get(i).getObjectSize());
activeTokens.get(i).serializeToStream(data);
editor.putString("log_out_token_" + i, Utilities.bytesToHex(data.toByteArray()));
}
editor.apply();
}
}
private boolean gettingAppChangelog;
@ -11478,7 +11531,7 @@ public class MessagesController extends BaseController implements NotificationCe
dialogs.messages.addAll(res.messages);
dialogs.users.addAll(res.users);
dialogs.chats.addAll(res.chats);
processLoadedDialogs(dialogs, null, dialog.folder_id, 0, 1, DIALOGS_LOAD_TYPE_CHANNEL, false, false, false);
processLoadedDialogs(dialogs, null, null, dialog.folder_id, 0, 1, DIALOGS_LOAD_TYPE_CHANNEL, false, false, false);
}
}
if (newTaskId != 0) {
@ -12458,6 +12511,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
}
getTranslateController().checkDialogMessages(dialog.id);
}
changed = true;
@ -14314,6 +14368,7 @@ public class MessagesController extends BaseController implements NotificationCe
boolean isDialogCreated = createdDialogIds.contains(message.dialog_id);
MessageObject obj = new MessageObject(currentAccount, message, usersDict, chatsDict, isDialogCreated, isDialogCreated);
getTranslateController().invalidateTranslation(obj);
LongSparseArray<ArrayList<MessageObject>> array;
if (editingMessages == null) {
@ -15047,7 +15102,7 @@ public class MessagesController extends BaseController implements NotificationCe
} else if (baseUpdate instanceof TLRPC.TL_updateChannelPinnedTopics) {
TLRPC.TL_updateChannelPinnedTopics update = (TLRPC.TL_updateChannelPinnedTopics) baseUpdate;
if ((update.flags & 1) > 0) {
if ((update.flags & 1) != 0) {
getTopicsController().applyPinnedOrder(update.channel_id, update.order);
} else {
getTopicsController().reloadTopics(update.channel_id, false);
@ -16283,6 +16338,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
dialogMessage.put(dialogId, arrayList);
getTranslateController().checkDialogMessages(dialogId);
changed = true;
if (filterDialogsChanged) {
@ -16325,6 +16381,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
}
dialogMessage.put(dialogId, arrayList);
getTranslateController().checkDialogMessages(dialogId);
if (lastMessage.messageOwner.peer_id.channel_id == 0) {
dialogMessagesByIds.put(lastMessage.getId(), lastMessage);
if (lastMessage.messageOwner.random_id != 0) {
@ -16344,6 +16401,10 @@ public class MessagesController extends BaseController implements NotificationCe
return changed;
}
public TLRPC.Dialog getDialog(long did) {
return dialogs_dict.get(did);
}
public void addDialogAction(long did, boolean clean) {
TLRPC.Dialog dialog = dialogs_dict.get(did);
if (dialog == null) {
@ -16412,7 +16473,11 @@ public class MessagesController extends BaseController implements NotificationCe
if (sortingDialogFilter == null) {
continue;
}
Collections.sort(allDialogs, dialogDateComparator);
try {
Collections.sort(allDialogs, dialogDateComparator);
} catch (Exception e) {
FileLog.e(e);
}
ArrayList<TLRPC.Dialog> dialogsByFilter = sortingDialogFilter.dialogs;
for (int a = 0, N = allDialogs.size(); a < N; a++) {
@ -16973,6 +17038,73 @@ public class MessagesController extends BaseController implements NotificationCe
});
}
public boolean matchesAdminRights(TLRPC.Chat chat, TLRPC.User user, TLRPC.TL_chatAdminRights rights) {
if (rights == null) {
return true;
}
TLRPC.TL_chatAdminRights userRights = getChatAdminRightsCached(chat, user);
return (
(!rights.change_info || userRights != null && userRights.change_info) &&
(!rights.post_messages || userRights != null && userRights.post_messages) &&
(!rights.edit_messages || userRights != null && userRights.edit_messages) &&
(!rights.delete_messages || userRights != null && userRights.delete_messages) &&
(!rights.ban_users || userRights != null && userRights.ban_users) &&
(!rights.invite_users || userRights != null && userRights.invite_users) &&
(!rights.pin_messages || userRights != null && userRights.pin_messages) &&
(!rights.add_admins || userRights != null && userRights.add_admins) &&
(!rights.anonymous || userRights != null && userRights.anonymous) &&
(!rights.manage_call || userRights != null && userRights.manage_call) &&
(!rights.other || userRights != null && userRights.other) &&
(!rights.manage_topics || userRights != null && userRights.manage_topics)
);
}
public TLRPC.TL_chatAdminRights getChatAdminRightsCached(TLRPC.Chat chat, TLRPC.User user) {
if (chat == null || user == null) {
return null;
}
if (UserObject.isUserSelf(user)) {
return chat.admin_rights;
}
final TLRPC.ChatFull chatFull = getChatFull(chat.id);
if (chatFull == null || chatFull.participants == null || chatFull.participants.participants == null) {
return null;
}
final ArrayList<TLRPC.ChatParticipant> participants = chatFull.participants.participants;
for (int i = 0; i < participants.size(); ++i) {
TLRPC.ChatParticipant participant = participants.get(i);
if (participant != null && participant.user_id == user.id) {
if (participant instanceof TLRPC.TL_chatChannelParticipant && ((TLRPC.TL_chatChannelParticipant) participant).channelParticipant != null) {
return ((TLRPC.TL_chatChannelParticipant) participant).channelParticipant.admin_rights;
}
return null;
}
}
return null;
}
public boolean isInChatCached(TLRPC.Chat chat, TLRPC.User user) {
if (chat == null || user == null) {
return false;
}
if (UserObject.isUserSelf(user)) {
return !ChatObject.isNotInChat(chat);
}
final TLRPC.ChatFull chatFull = getChatFull(chat.id);
if (chatFull == null || chatFull.participants == null || chatFull.participants.participants == null) {
return false;
}
final ArrayList<TLRPC.ChatParticipant> participants = chatFull.participants.participants;
for (int i = 0; i < participants.size(); ++i) {
TLRPC.ChatParticipant participant = participants.get(i);
if (participant != null && participant.user_id == user.id) {
return true;
}
}
return false;
}
public void checkIsInChat(boolean tryCacheFirst, TLRPC.Chat chat, TLRPC.User user, IsInChatCheckedCallback callback) {
if (chat == null || user == null) {
if (callback != null) {

View File

@ -15,6 +15,7 @@ import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
import android.util.Pair;
import android.util.SparseArray;
import android.util.SparseIntArray;
@ -34,6 +35,7 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.DialogsSearchAdapter;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.EditWidgetActivity;
import java.io.File;
@ -93,7 +95,7 @@ public class MessagesStorage extends BaseController {
}
}
private final static int LAST_DB_VERSION = 111;
private final static int LAST_DB_VERSION = 112;
private boolean databaseMigrationInProgress;
public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -447,6 +449,8 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE reaction_mentions_topics(message_id INTEGER, state INTEGER, dialog_id INTEGER, topic_id INTEGER, PRIMARY KEY(message_id, dialog_id, topic_id))").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS reaction_mentions_topics_did ON reaction_mentions_topics(dialog_id, topic_id);").stepThis().dispose();
database.executeFast("CREATE TABLE emoji_groups(type INTEGER PRIMARY KEY, data BLOB)").stepThis().dispose();
//version
database.executeFast("PRAGMA user_version = " + LAST_DB_VERSION).stepThis().dispose();
} else {
@ -502,9 +506,9 @@ public class MessagesStorage extends BaseController {
}
} catch (Exception e) {
FileLog.e(e);
if (BuildVars.DEBUG_PRIVATE_VERSION) {
throw new RuntimeException(e);
}
// if (BuildVars.DEBUG_PRIVATE_VERSION) {
// throw new RuntimeException(e);
// }
if (openTries < 3 && e.getMessage() != null && e.getMessage().contains("malformed")) {
if (openTries == 2) {
cleanupInternal(true);
@ -3917,68 +3921,82 @@ public class MessagesStorage extends BaseController {
return;
}
storageQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
try {
database.executeFast("DELETE FROM user_photos WHERE uid = " + did).stepThis().dispose();
state = database.executeFast("REPLACE INTO user_photos VALUES(?, ?, ?)");
for (int a = 0, N = photos.photos.size(); a < N; a++) {
TLRPC.Photo photo = photos.photos.get(a);
if (photo instanceof TLRPC.TL_photoEmpty) {
continue;
}
if (photo.file_reference == null) {
photo.file_reference = new byte[0];
}
state.requery();
int size = photo.getObjectSize();
if (messages != null) {
size += messages.get(a).getObjectSize();
}
NativeByteBuffer data = new NativeByteBuffer(size);
photo.serializeToStream(data);
if (messages != null) {
messages.get(a).serializeToStream(data);
}
state.bindLong(1, did);
state.bindLong(2, photo.id);
state.bindByteBuffer(3, data);
state.step();
data.reuse();
}
state.dispose();
state = null;
} catch (Exception e) {
FileLog.e(e);
} finally {
if (state != null) {
state.dispose();
}
}
putDialogPhotosInternal(did, photos, messages);
});
}
public void addDialogPhoto(long did, TLRPC.Photo photo) {
storageQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
try {
state = database.executeFast("REPLACE INTO user_photos VALUES(?, ?, ?)");
private void putDialogPhotosInternal(long did, TLRPC.photos_Photos photos, ArrayList<TLRPC.Message> messages) {
SQLitePreparedStatement state = null;
try {
database.executeFast("DELETE FROM user_photos WHERE uid = " + did).stepThis().dispose();
state = database.executeFast("REPLACE INTO user_photos VALUES(?, ?, ?)");
for (int a = 0, N = photos.photos.size(); a < N; a++) {
TLRPC.Photo photo = photos.photos.get(a);
if (photo instanceof TLRPC.TL_photoEmpty || photo == null) {
continue;
}
if (photo.file_reference == null) {
photo.file_reference = new byte[0];
}
state.requery();
int size = photo.getObjectSize();
if (messages != null && messages.get(a) != null) {
size += messages.get(a).getObjectSize();
}
NativeByteBuffer data = new NativeByteBuffer(size);
photo.serializeToStream(data);
if (messages != null && messages.get(a) != null) {
messages.get(a).serializeToStream(data);
}
state.bindLong(1, did);
state.bindLong(2, photo.id);
state.bindByteBuffer(3, data);
state.step();
data.reuse();
}
state.dispose();
state = null;
} catch (Exception e) {
FileLog.e(e);
} finally {
if (state != null) {
state.dispose();
state = null;
}
}
}
public void addDialogPhoto(long did, TLRPC.Photo photoToAdd) {
storageQueue.postRunnable(() -> {
SQLiteCursor cursor = null;
try {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM user_photos WHERE uid = %d ORDER BY rowid ASC", did));
TLRPC.photos_Photos res = new TLRPC.TL_photos_photos();
ArrayList<TLRPC.Message> messages = new ArrayList<>();
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.Photo photo = TLRPC.Photo.TLdeserialize(data, data.readInt32(false), false);
if (data.remaining() > 0) {
messages.add(TLRPC.Message.TLdeserialize(data, data.readInt32(false), false));
} else {
messages.add(null);
}
data.reuse();
res.photos.add(photo);
messages.add(null);
}
}
cursor.dispose();
cursor = null;
res.photos.add(0, photoToAdd);
putDialogPhotosInternal(did, res, messages);
} catch (Exception e) {
FileLog.e(e);
} finally {
if (state != null) {
state.dispose();
if (cursor != null) {
cursor.dispose();
}
}
});
@ -4260,7 +4278,7 @@ public class MessagesStorage extends BaseController {
SQLitePreparedStatement state = null;
try {
database.beginTransaction();
TLRPC.Message message = getMessageWithCustomParamsOnly(msgId, dialogId);
TLRPC.Message message = getMessageWithCustomParamsOnlyInternal(msgId, dialogId);
message.voiceTranscriptionOpen = saveFromMessage.voiceTranscriptionOpen;
message.voiceTranscriptionRated = saveFromMessage.voiceTranscriptionRated;
message.voiceTranscriptionFinal = saveFromMessage.voiceTranscriptionFinal;
@ -4308,7 +4326,7 @@ public class MessagesStorage extends BaseController {
SQLitePreparedStatement state = null;
try {
database.beginTransaction();
TLRPC.Message message = getMessageWithCustomParamsOnly(messageId, dialogId);
TLRPC.Message message = getMessageWithCustomParamsOnlyInternal(messageId, dialogId);
message.voiceTranscriptionFinal = isFinal;
message.voiceTranscriptionId = transcriptionId;
message.voiceTranscription = text;
@ -4348,7 +4366,7 @@ public class MessagesStorage extends BaseController {
SQLitePreparedStatement state = null;
try {
database.beginTransaction();
TLRPC.Message message = getMessageWithCustomParamsOnly(messageId, dialogId);
TLRPC.Message message = getMessageWithCustomParamsOnlyInternal(messageId, dialogId);
message.voiceTranscriptionOpen = saveFromMessage.voiceTranscriptionOpen;
message.voiceTranscriptionRated = saveFromMessage.voiceTranscriptionRated;
message.voiceTranscriptionFinal = saveFromMessage.voiceTranscriptionFinal;
@ -4397,7 +4415,7 @@ public class MessagesStorage extends BaseController {
SQLitePreparedStatement state = null;
try {
database.beginTransaction();
TLRPC.Message message = getMessageWithCustomParamsOnly(saveFromMessage.id, dialogId);
TLRPC.Message message = getMessageWithCustomParamsOnlyInternal(saveFromMessage.id, dialogId);
MessageCustomParamsHelper.copyParams(saveFromMessage, message);
for (int i = 0; i < 2; i++) {
@ -4436,7 +4454,7 @@ public class MessagesStorage extends BaseController {
});
}
private TLRPC.Message getMessageWithCustomParamsOnly(int messageId, long dialogId) {
public TLRPC.Message getMessageWithCustomParamsOnlyInternal(int messageId, long dialogId) {
TLRPC.Message message = new TLRPC.TL_message();
SQLiteCursor cursor = null;
try {
@ -5838,6 +5856,29 @@ public class MessagesStorage extends BaseController {
});
}
public ArrayList<TLRPC.UserFull> loadUserInfos(HashSet<Long> uids) {
ArrayList<TLRPC.UserFull> arrayList = new ArrayList<>();
try {
String ids = TextUtils.join(",", uids);
SQLiteCursor cursor = database.queryFinalized("SELECT info, pinned FROM user_settings WHERE uid IN(" + ids + ")");
while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
TLRPC.UserFull info = TLRPC.UserFull.TLdeserialize(data, data.readInt32(false), false);
info.pinned_msg_id = cursor.intValue(1);
arrayList.add(info);
data.reuse();
}
}
cursor.dispose();
cursor = null;
} catch (Exception e) {
FileLog.e(e);
}
return arrayList;
}
public void loadUserInfo(TLRPC.User user, boolean force, int classGuid, int fromMessageId) {
if (user == null) {
return;
@ -10705,7 +10746,7 @@ public class MessagesStorage extends BaseController {
state_download.bindInteger(2, type);
state_download.bindInteger(3, message.date);
state_download.bindByteBuffer(4, data);
state_download.bindString(5, "sent_" + (message.peer_id != null ? message.peer_id.channel_id : 0) + "_" + message.id + "_" + DialogObject.getPeerDialogId(message.peer_id) + "_" + messageObject.type);
state_download.bindString(5, "sent_" + (message.peer_id != null ? message.peer_id.channel_id : 0) + "_" + message.id + "_" + DialogObject.getPeerDialogId(message.peer_id) + "_" + messageObject.type + "_" + messageObject.getSize());
state_download.step();
data.reuse();
}
@ -13715,6 +13756,7 @@ public class MessagesStorage extends BaseController {
SQLiteCursor cursor = null;
try {
ArrayList<Long> usersToLoad = new ArrayList<>();
HashSet<Long> dialogUsers = new HashSet<>();
usersToLoad.add(getUserConfig().getClientUserId());
ArrayList<Long> chatsToLoad = new ArrayList<>();
ArrayList<Integer> encryptedToLoad = new ArrayList<>();
@ -13856,6 +13898,7 @@ public class MessagesStorage extends BaseController {
if (!usersToLoad.contains(dialogId)) {
usersToLoad.add(dialogId);
}
dialogUsers.add(dialogId);
} else if (DialogObject.isChatDialog(dialogId)) {
if (!chatsToLoad.contains(-dialogId)) {
chatsToLoad.add(-dialogId);
@ -13998,14 +14041,18 @@ public class MessagesStorage extends BaseController {
if (!usersToLoad.isEmpty()) {
getUsersInternal(TextUtils.join(",", usersToLoad), dialogs.users);
}
getMessagesController().processLoadedDialogs(dialogs, encryptedChats, folderId, offset, count, 1, false, false, true);
ArrayList<TLRPC.UserFull> fullUsers = null;
if (!dialogUsers.isEmpty()) {
fullUsers = loadUserInfos(dialogUsers);
}
getMessagesController().processLoadedDialogs(dialogs, encryptedChats, fullUsers, folderId, offset, count, 1, false, false, true);
} catch (Exception e) {
dialogs.dialogs.clear();
dialogs.users.clear();
dialogs.chats.clear();
encryptedChats.clear();
FileLog.e(e);
getMessagesController().processLoadedDialogs(dialogs, encryptedChats, folderId, 0, 100, 1, true, false, true);
getMessagesController().processLoadedDialogs(dialogs, encryptedChats, null, folderId, 0, 100, 1, true, false, true);
checkMalformed(e);
} finally {
if (cursor != null) {
@ -14040,6 +14087,41 @@ public class MessagesStorage extends BaseController {
}
}
public void updateDialogData(TLRPC.Dialog dialog) {
if (dialog == null) {
return;
}
storageQueue.postRunnable(() -> {
SQLiteCursor cursor = null;
SQLitePreparedStatement state = null;
try {
cursor = database.queryFinalized("SELECT data FROM dialogs WHERE did = " + dialog.id);
if (!cursor.next()) {
return;
}
state = database.executeFast("UPDATE dialogs SET data = ? WHERE did = ?");
NativeByteBuffer data = new NativeByteBuffer(dialog.getObjectSize());
dialog.serializeToStream(data);
state.bindByteBuffer(1, data);
state.bindLong(2, dialog.id);
state.step();
state.dispose();
state = null;
data.reuse();
} catch (Exception e) {
FileLog.e(e);
} finally {
if (cursor != null) {
cursor.dispose();
}
if (state != null) {
state.dispose();
}
}
});
}
private void putDialogsInternal(TLRPC.messages_Dialogs dialogs, int check) {
SQLitePreparedStatement state_messages = null;
SQLitePreparedStatement state_dialogs = null;
@ -14777,7 +14859,7 @@ public class MessagesStorage extends BaseController {
}
public void localSearch(int dialogsType, String query, ArrayList<Object> resultArray, ArrayList<CharSequence> resultArrayNames, ArrayList<TLRPC.User> encUsers, int folderId) {
public void localSearch(int dialogsType, String query, ArrayList<Object> resultArray, ArrayList<CharSequence> resultArrayNames, ArrayList<TLRPC.User> encUsers, ArrayList<Long> onlyDialogIds, int folderId) {
long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
SQLiteCursor cursor = null;
try {
@ -14816,23 +14898,30 @@ public class MessagesStorage extends BaseController {
dialogSearchResult.date = cursor.intValue(1);
dialogsResult.put(id, dialogSearchResult);
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER && (onlyDialogIds == null || !onlyDialogIds.contains(id))) {
continue;
}
if (!DialogObject.isEncryptedDialog(id)) {
if (DialogObject.isUserDialog(id)) {
if (dialogsType == 4 && id == selfUserId) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_USERS_ONLY && id == selfUserId) {
continue;
}
if (dialogsType != 2 && !usersToLoad.contains(id)) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY || dialogsType == DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY) {
continue;
}
if (dialogsType != DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO && !usersToLoad.contains(id)) {
usersToLoad.add(id);
}
} else {
if (dialogsType == 4) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_USERS_ONLY) {
continue;
}
if (!chatsToLoad.contains(-id)) {
chatsToLoad.add(-id);
}
}
} else if (dialogsType == 0 || dialogsType == 3) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT || dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD) {
int encryptedChatId = DialogObject.getEncryptedChatId(id);
if (!encryptedToLoad.contains(encryptedChatId)) {
encryptedToLoad.add(encryptedChatId);
@ -14892,6 +14981,9 @@ public class MessagesStorage extends BaseController {
if (data != null) {
TLRPC.User user = TLRPC.User.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER && (onlyDialogIds == null || !onlyDialogIds.contains(user.id))) {
continue;
}
DialogsSearchAdapter.DialogSearchResult dialogSearchResult = dialogsResult.get(user.id);
if (user.status != null) {
user.status.expires = cursor.intValue(1);
@ -14926,6 +15018,15 @@ public class MessagesStorage extends BaseController {
if (data != null) {
TLRPC.Chat chat = TLRPC.Chat.TLdeserialize(data, data.readInt32(false), false);
data.reuse();
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER && (onlyDialogIds == null || !onlyDialogIds.contains(-chat.id))) {
continue;
}
if (dialogsType == DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY && ChatObject.isChannelAndNotMegaGroup(chat)) {
continue;
}
if (dialogsType == DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY && !ChatObject.isChannelAndNotMegaGroup(chat)) {
continue;
}
if (!(chat == null || chat.deactivated || ChatObject.isChannel(chat) && ChatObject.isNotInChat(chat))) {
long dialog_id = -chat.id;
DialogsSearchAdapter.DialogSearchResult dialogSearchResult = dialogsResult.get(dialog_id);
@ -14942,7 +15043,7 @@ public class MessagesStorage extends BaseController {
cursor = null;
}
if (!encryptedToLoad.isEmpty()) {
if (!encryptedToLoad.isEmpty() && dialogsType != DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
cursor = getDatabase().queryFinalized(String.format(Locale.US, "SELECT q.data, u.name, q.user, q.g, q.authkey, q.ttl, u.data, u.status, q.layer, q.seq_in, q.seq_out, q.use_count, q.exchange_id, q.key_date, q.fprint, q.fauthkey, q.khash, q.in_seq_no, q.admin_id, q.mtproto_seq FROM enc_chats as q INNER JOIN users as u ON q.user = u.uid WHERE q.uid IN(%s)", TextUtils.join(",", encryptedToLoad)));
while (cursor.next()) {
String name = cursor.stringValue(1);
@ -15046,7 +15147,7 @@ public class MessagesStorage extends BaseController {
resultArrayNames.add(dialogSearchResult.name);
}
if (dialogsType != 2) {
if (dialogsType != DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO && dialogsType != DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER && dialogsType != DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY && dialogsType != DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY) {
cursor = getDatabase().queryFinalized("SELECT u.data, u.status, u.name, u.uid FROM users as u INNER JOIN contacts as c ON u.uid = c.uid");
while (cursor.next()) {
long uid = cursor.longValue(3);

View File

@ -72,6 +72,7 @@ public class NotificationCenter {
public static final int updateMessageMedia = totalEvents++;
public static final int replaceMessagesObjects = totalEvents++;
public static final int didSetPasscode = totalEvents++;
public static final int passcodeDismissed = totalEvents++;
public static final int twoStepPasswordChanged = totalEvents++;
public static final int didSetOrRemoveTwoStepPassword = totalEvents++;
public static final int didRemoveTwoStepPassword = totalEvents++;
@ -136,6 +137,11 @@ public class NotificationCenter {
public static final int recentEmojiStatusesUpdate = totalEvents++;
public static final int updateSearchSettings = totalEvents++;
public static final int messageTranslated = totalEvents++;
public static final int messageTranslating = totalEvents++;
public static final int dialogIsTranslatable = totalEvents++;
public static final int dialogTranslate = totalEvents++;
public static final int didGenerateFingerprintKeyPair = totalEvents++;
public static final int walletPendingTransactionsChanged = totalEvents++;
@ -231,6 +237,7 @@ public class NotificationCenter {
public static final int didSetNewWallpapper = totalEvents++;
public static final int proxySettingsChanged = totalEvents++;
public static final int proxyCheckDone = totalEvents++;
public static final int proxyChangedByRotation = totalEvents++;
public static final int liveLocationsChanged = totalEvents++;
public static final int newLocationAvailable = totalEvents++;
public static final int liveLocationsCacheChanged = totalEvents++;
@ -735,7 +742,7 @@ public class NotificationCenter {
@Override
public boolean remove(@Nullable Object o) {
if (set.remove(0)) {
if (set.remove(o)) {
return super.remove(o);
}
return false;

View File

@ -4084,6 +4084,7 @@ public class NotificationsController extends BaseController {
long selfUserId = getUserConfig().getClientUserId();
boolean waitingForPasscode = AndroidUtilities.needShowPasscode() || SharedConfig.isWaitingForPasscodeEnter;
boolean passcode = SharedConfig.passcodeHash.length() > 0;
int maxCount = 7;
LongSparseArray<Person> personCache = new LongSparseArray<>();
@ -4148,6 +4149,7 @@ public class NotificationsController extends BaseController {
} else {
chat = getMessagesController().getChat(-dialogId);
if (chat == null) {
canReply = false;
if (lastMessageObject.isFcmMessage()) {
isSupergroup = lastMessageObject.isSupergroup();
name = lastMessageObject.localName;
@ -4172,7 +4174,9 @@ public class NotificationsController extends BaseController {
name = topic.title + " in " + name;
}
}
if (canReply) {
canReply = ChatObject.canSendPlain(chat);
}
}
}
} else {
@ -4207,6 +4211,9 @@ public class NotificationsController extends BaseController {
photoPath = null;
canReply = false;
}
if (passcode) {
canReply = false;
}
if (photoPath != null) {
avatalFile = getFileLoader().getPathToAttach(photoPath, true);
@ -4521,6 +4528,7 @@ public class NotificationsController extends BaseController {
} else {
intent.putExtra("chatId", -dialogId);
}
FileLog.d("show extra notifications chatId " + dialogId + " topicId " + topicId);
if (topicId != 0) {
intent.putExtra("topicId", topicId);
}
@ -4596,7 +4604,7 @@ public class NotificationsController extends BaseController {
if (wearReplyAction != null) {
builder.addAction(wearReplyAction);
}
if (!waitingForPasscode) {
if (!passcode) {
builder.addAction(readAction);
}
if (sortedDialogs.size() == 1 && !TextUtils.isEmpty(summary)) {

View File

@ -0,0 +1,128 @@
package org.telegram.messenger;
import android.content.SharedPreferences;
import android.os.SystemClock;
import org.telegram.tgnet.ConnectionsManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class ProxyRotationController implements NotificationCenter.NotificationCenterDelegate {
private final static ProxyRotationController INSTANCE = new ProxyRotationController();
public final static int DEFAULT_TIMEOUT_INDEX = 1;
public final static List<Integer> ROTATION_TIMEOUTS = Arrays.asList(
5, 10, 15, 30, 60
);
private boolean isCurrentlyChecking;
private Runnable checkProxyAndSwitchRunnable = () -> {
isCurrentlyChecking = true;
int currentAccount = UserConfig.selectedAccount;
boolean startedCheck = false;
for (int i = 0; i < SharedConfig.proxyList.size(); i++) {
SharedConfig.ProxyInfo proxyInfo = SharedConfig.proxyList.get(i);
if (proxyInfo.checking || SystemClock.elapsedRealtime() - proxyInfo.availableCheckTime < 2 * 60 * 1000) {
continue;
}
startedCheck = true;
proxyInfo.checking = true;
proxyInfo.proxyCheckPingId = ConnectionsManager.getInstance(currentAccount).checkProxy(proxyInfo.address, proxyInfo.port, proxyInfo.username, proxyInfo.password, proxyInfo.secret, time -> AndroidUtilities.runOnUIThread(() -> {
proxyInfo.availableCheckTime = SystemClock.elapsedRealtime();
proxyInfo.checking = false;
if (time == -1) {
proxyInfo.available = false;
proxyInfo.ping = 0;
} else {
proxyInfo.ping = time;
proxyInfo.available = true;
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyCheckDone, proxyInfo);
}));
}
if (!startedCheck) {
isCurrentlyChecking = false;
switchToAvailable();
}
};
public static void init() {
INSTANCE.initInternal();
}
@SuppressWarnings("ComparatorCombinators")
private void switchToAvailable() {
isCurrentlyChecking = false;
if (!SharedConfig.proxyRotationEnabled) {
return;
}
List<SharedConfig.ProxyInfo> sortedList = new ArrayList<>(SharedConfig.proxyList);
Collections.sort(sortedList, (o1, o2) -> Long.compare(o1.ping, o2.ping));
for (SharedConfig.ProxyInfo info : sortedList) {
if (info == SharedConfig.currentProxy || info.checking || !info.available) {
continue;
}
SharedPreferences.Editor editor = MessagesController.getGlobalMainSettings().edit();
editor.putString("proxy_ip", info.address);
editor.putString("proxy_pass", info.password);
editor.putString("proxy_user", info.username);
editor.putInt("proxy_port", info.port);
editor.putString("proxy_secret", info.secret);
editor.putBoolean("proxy_enabled", true);
if (!info.secret.isEmpty()) {
editor.putBoolean("proxy_enabled_calls", false);
}
editor.apply();
SharedConfig.currentProxy = info;
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxySettingsChanged);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.proxyChangedByRotation);
ConnectionsManager.setProxySettings(true, SharedConfig.currentProxy.address, SharedConfig.currentProxy.port, SharedConfig.currentProxy.username, SharedConfig.currentProxy.password, SharedConfig.currentProxy.secret);
break;
}
}
private void initInternal() {
for (int i = 0; i < UserConfig.MAX_ACCOUNT_COUNT; i++) {
NotificationCenter.getInstance(i).addObserver(this, NotificationCenter.didUpdateConnectionState);
}
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.proxyCheckDone);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.proxySettingsChanged);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.proxyCheckDone) {
if (!SharedConfig.isProxyEnabled() || !SharedConfig.proxyRotationEnabled || SharedConfig.proxyList.size() <= 1 || !isCurrentlyChecking) {
return;
}
switchToAvailable();
} else if (id == NotificationCenter.proxySettingsChanged) {
AndroidUtilities.cancelRunOnUIThread(checkProxyAndSwitchRunnable);
} else if (id == NotificationCenter.didUpdateConnectionState && account == UserConfig.selectedAccount) {
if (!SharedConfig.isProxyEnabled() && !SharedConfig.proxyRotationEnabled || SharedConfig.proxyList.size() <= 1) {
return;
}
int state = ConnectionsManager.getInstance(account).getConnectionState();
if (state == ConnectionsManager.ConnectionStateConnectingToProxy) {
if (!isCurrentlyChecking) {
AndroidUtilities.runOnUIThread(checkProxyAndSwitchRunnable, ROTATION_TIMEOUTS.get(SharedConfig.proxyRotationTimeout) * 1000L);
}
} else {
AndroidUtilities.cancelRunOnUIThread(checkProxyAndSwitchRunnable);
}
}
}
}

View File

@ -3,6 +3,7 @@ package org.telegram.messenger;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;
import android.util.SparseBooleanArray;
import androidx.annotation.IntDef;
@ -286,8 +287,9 @@ public class PushListenerController {
chat_id = 0;
}
if (custom.has("topic_id")) {
topicId =custom.getInt("topic_id");
topicId = custom.getInt("topic_id");
}
FileLog.d( "recived push notification chatId " + chat_id + " custom topicId " + topicId);
if (custom.has("encryption_id")) {
dialogId = DialogObject.makeEncryptedDialogId(custom.getInt("encryption_id"));
}

View File

@ -0,0 +1,252 @@
package org.telegram.messenger;
import static org.telegram.messenger.SharedConfig.SAVE_TO_GALLERY_FLAG_CHANNELS;
import static org.telegram.messenger.SharedConfig.SAVE_TO_GALLERY_FLAG_GROUP;
import static org.telegram.messenger.SharedConfig.SAVE_TO_GALLERY_FLAG_PEER;
import android.app.Activity;
import android.content.SharedPreferences;
import android.util.LongSparseArray;
public class SaveToGallerySettingsHelper {
//shared settings
public static SharedSettings user;
public static SharedSettings groups;
public static SharedSettings channels;
public static String USERS_PREF_NAME = "users_save_gallery_exceptions";
public static String CHANNELS_PREF_NAME = "channels_save_gallery_exceptions";
public static String GROUPS_PREF_NAME = "groups_save_gallery_exceptions";
public static final long DEFAULT_VIDEO_LIMIT = 100 * 1024 * 1024;//100 MB
public static final long MAX_VIDEO_LIMIT = 4L * 1000 * 1024 * 1024;//100 MB
public static void load(SharedPreferences preferences) {
boolean saveToGalleryLegacy = preferences.getBoolean("save_gallery", false);
int saveToGalleryFlags;
if (saveToGalleryLegacy && BuildVars.NO_SCOPED_STORAGE) {
saveToGalleryFlags = SAVE_TO_GALLERY_FLAG_PEER + SAVE_TO_GALLERY_FLAG_CHANNELS + SAVE_TO_GALLERY_FLAG_GROUP;
} else {
saveToGalleryFlags = preferences.getInt("save_gallery_flags", -1);
}
//migration
if (saveToGalleryFlags != -1) {
preferences.edit().remove("save_gallery").remove("save_gallery_flags").apply();
user = new SharedSettings();
user.savePhoto = user.saveVideo = (saveToGalleryFlags & SAVE_TO_GALLERY_FLAG_PEER) != 0;
user.limitVideo = DEFAULT_VIDEO_LIMIT;
user.save("user", preferences);
groups = new SharedSettings();
groups.savePhoto = user.saveVideo = (saveToGalleryFlags & SAVE_TO_GALLERY_FLAG_GROUP) != 0;
groups.limitVideo = DEFAULT_VIDEO_LIMIT;
groups.save("groups", preferences);
channels = new SharedSettings();
channels.savePhoto = channels.saveVideo = (saveToGalleryFlags & SAVE_TO_GALLERY_FLAG_CHANNELS) != 0;
channels.limitVideo = DEFAULT_VIDEO_LIMIT;
channels.save("channels", preferences);
} else {
user = SharedSettings.read("user", preferences);
groups = SharedSettings.read("groups", preferences);
channels = SharedSettings.read("channels", preferences);
}
user.type = SAVE_TO_GALLERY_FLAG_PEER;
groups.type = SAVE_TO_GALLERY_FLAG_GROUP;
channels.type = SAVE_TO_GALLERY_FLAG_CHANNELS;
}
public static boolean needSave(int flag, FilePathDatabase.FileMeta metaData, MessageObject messageObject, int currentAccount) {
SharedSettings settings;
if (flag == SharedConfig.SAVE_TO_GALLERY_FLAG_PEER) {
settings = user;
} else if (flag == SharedConfig.SAVE_TO_GALLERY_FLAG_CHANNELS) {
settings = channels;
} else if (flag == SharedConfig.SAVE_TO_GALLERY_FLAG_GROUP) {
settings = groups;
} else {
return false;
}
return settings.needSave(metaData, messageObject, currentAccount);
}
public static LongSparseArray<DialogException> loadExceptions(SharedPreferences sharedPreferences) {
LongSparseArray<DialogException> exceptions = new LongSparseArray<>();
int count = sharedPreferences.getInt("count", 0);
for (int i = 0; i < count; i++) {
DialogException dialogException = new DialogException();
dialogException.dialogId = sharedPreferences.getLong(i + "_dialog_id", 0);
dialogException.savePhoto = sharedPreferences.getBoolean(i + "_photo", false);
dialogException.saveVideo = sharedPreferences.getBoolean(i + "_video", false);
dialogException.limitVideo = sharedPreferences.getLong(i + "_limitVideo", DEFAULT_VIDEO_LIMIT);
if (dialogException.dialogId != 0) {
exceptions.put(dialogException.dialogId, dialogException);
}
}
return exceptions;
}
public static void saveExceptions(SharedPreferences sharedPreferences, LongSparseArray<DialogException> exceptions) {
sharedPreferences.edit().clear().apply();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt("count", exceptions.size());
for (int i = 0; i < exceptions.size(); i++) {
DialogException dialogException = exceptions.valueAt(i);
editor.putLong(i + "_dialog_id", dialogException.dialogId);
editor.putBoolean(i + "_photo", dialogException.savePhoto);
editor.putBoolean(i + "_video", dialogException.saveVideo);
editor.putLong(i + "_limitVideo", dialogException.limitVideo);
}
editor.apply();
}
public static Settings getSettings(int type) {
if (type == SAVE_TO_GALLERY_FLAG_PEER) {
return user;
} else if (type == SAVE_TO_GALLERY_FLAG_GROUP) {
return groups;
} else if (type == SAVE_TO_GALLERY_FLAG_CHANNELS) {
return channels;
}
return null;
}
public static void saveSettings(int type) {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
if (type == SAVE_TO_GALLERY_FLAG_PEER) {
user.save("user", preferences);
} else if (type == SAVE_TO_GALLERY_FLAG_GROUP) {
groups.save("group", preferences);
} else if (type == SAVE_TO_GALLERY_FLAG_CHANNELS) {
channels.save("channels", preferences);
}
}
public static abstract class Settings {
public boolean savePhoto;
public boolean saveVideo;
public long limitVideo = 100 * 1024 * 1024; ///100 MB
public boolean enabled() {
return savePhoto || saveVideo;
}
public abstract CharSequence createDescription(int currentAccount);
public void toggle() {
if (enabled()) {
saveVideo = false;
savePhoto = false;
} else {
savePhoto = true;
saveVideo = true;
}
}
}
public static class SharedSettings extends Settings {
private int type;
private void save(String prefix, SharedPreferences sharedPreferences) {
sharedPreferences.edit()
.putBoolean(prefix + "_save_gallery_photo", savePhoto)
.putBoolean(prefix + "_save_gallery_video", saveVideo)
.putLong(prefix + "_save_gallery_limitVideo", limitVideo)
.apply();
}
private static SharedSettings read(String prefix, SharedPreferences preferences) {
SharedSettings settings = new SharedSettings();
settings.savePhoto = preferences.getBoolean(prefix + "_save_gallery_photo", false);
settings.saveVideo = preferences.getBoolean(prefix + "_save_gallery_video", false);
settings.limitVideo = preferences.getLong(prefix + "_save_gallery_limitVideo", DEFAULT_VIDEO_LIMIT);
return settings;
}
private boolean needSave(FilePathDatabase.FileMeta meta, MessageObject messageObject, int currentAccount) {
LongSparseArray<DialogException> exceptions = UserConfig.getInstance(currentAccount).getSaveGalleryExceptions(type);
DialogException exception = exceptions.get(meta.dialogId);
if (messageObject != null && messageObject.isOutOwner()) {
return false;
}
boolean isVideo = (messageObject != null && messageObject.isVideo()) || meta.messageType == MessageObject.TYPE_VIDEO;
long size = messageObject != null ? messageObject.getSize() : meta.messageSize;
boolean needSaveVideo = saveVideo;
boolean needSavePhoto = savePhoto;
long saveVideoLimit = limitVideo;
if (exception != null) {
needSaveVideo = exception.saveVideo;
needSavePhoto = exception.savePhoto;
saveVideoLimit = exception.limitVideo;
}
if (isVideo) {
if (needSaveVideo && (saveVideoLimit == -1 || size < saveVideoLimit)) {
return true;
}
} else {
if (needSavePhoto) {
return true;
}
}
return false;
}
public CharSequence createDescription(int currentAccount) {
StringBuilder builder = new StringBuilder();
if (enabled()) {
if (savePhoto) {
builder.append(LocaleController.getString("SaveToGalleryPhotos", R.string.SaveToGalleryPhotos));
}
if (saveVideo) {
if (builder.length() != 0) {
builder.append(", ");
}
builder.append(LocaleController.getString("SaveToGalleryVideos", R.string.SaveToGalleryVideos));
if (limitVideo > 0 && limitVideo < 4L * 1000 * 1024 * 1024) {
builder.append(" (").append(AndroidUtilities.formatFileSize(limitVideo, true)).append(")");
}
}
} else {
builder.append(LocaleController.getString("SaveToGalleryOff", R.string.SaveToGalleryOff));
}
LongSparseArray<DialogException> exceptions = UserConfig.getInstance(currentAccount).getSaveGalleryExceptions(type);
if (exceptions.size() != 0) {
if (builder.length() != 0) {
builder.append(", ");
}
builder.append(LocaleController.formatPluralString("Exception", exceptions.size(), exceptions.size()));
}
return builder;
}
}
public static class DialogException extends Settings {
public long dialogId;
public CharSequence createDescription(int currentAccount) {
StringBuilder builder = new StringBuilder();
if (enabled()) {
if (savePhoto) {
builder.append(LocaleController.getString("SaveToGalleryPhotos", R.string.SaveToGalleryPhotos));
}
if (saveVideo) {
if (builder.length() != 0) {
builder.append(", ");
}
if (limitVideo > 0 && limitVideo < 4L * 1000 * 1024 * 1024) {
builder.append(LocaleController.formatString("SaveToGalleryVideosUpTo", R.string.SaveToGalleryVideosUpTo, AndroidUtilities.formatFileSize(limitVideo, true)));
} else {
builder.append(LocaleController.formatString("SaveToGalleryVideos", R.string.SaveToGalleryVideos));
}
}
} else {
builder.append(LocaleController.getString("SaveToGalleryOff", R.string.SaveToGalleryOff));
}
return builder;
}
}
}

View File

@ -519,6 +519,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
public boolean forceImage;
public boolean updateStickersOrder;
public boolean hasMediaSpoilers;
public TLRPC.VideoSize emojiMarkup;
}
@SuppressLint("MissingPermission")
@ -1454,7 +1455,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
HashMap<String, String> params = null;
if (DialogObject.isEncryptedDialog(did) && messageObject.messageOwner.peer_id != null && (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo || messageObject.messageOwner.media.document instanceof TLRPC.TL_document)) {
params = new HashMap<>();
params.put("parentObject", "sent_" + messageObject.messageOwner.peer_id.channel_id + "_" + messageObject.getId() + "_" + messageObject.getDialogId() + "_" + messageObject.type);
params.put("parentObject", "sent_" + messageObject.messageOwner.peer_id.channel_id + "_" + messageObject.getId() + "_" + messageObject.getDialogId() + "_" + messageObject.type + "_" + messageObject.getSize());
}
if (messageObject.messageOwner.media.photo instanceof TLRPC.TL_photo) {
sendMessage((TLRPC.TL_photo) messageObject.messageOwner.media.photo, null, did, messageObject.replyMessageObject, null, messageObject.messageOwner.message, messageObject.messageOwner.entities, null, params, true, 0, messageObject.messageOwner.media.ttl_seconds, messageObject, false);
@ -1674,10 +1675,14 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
final TLRPC.Peer peer_id = getMessagesController().getPeer(peer);
boolean isSignature = false;
boolean canSendStickers = true;
boolean canSendMedia = true;
boolean canSendPhoto = true;
boolean canSendVideo = true;
boolean canSendDocument = true;
boolean canSendMusic = true;
boolean canSendPolls = true;
boolean canSendPreview = true;
boolean canSendVoiceMessages = true;
boolean canSendVoiceRound = true;
String rank = null;
long linkedToGroup = 0;
TLRPC.Chat chat;
@ -1690,7 +1695,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.UserFull userFull = getMessagesController().getUserFull(peer);
if (userFull != null) {
canSendVoiceMessages = !userFull.voice_messages_forbidden;
canSendVoiceRound = canSendVoiceMessages = !userFull.voice_messages_forbidden;
}
} else {
chat = getMessagesController().getChat(-peer);
@ -1709,9 +1714,14 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
rank = getMessagesController().getAdminRank(chat.id, myId);
}
canSendStickers = ChatObject.canSendStickers(chat);
canSendMedia = ChatObject.canSendMedia(chat);
canSendPhoto = ChatObject.canSendPhoto(chat);
canSendVideo = ChatObject.canSendVideo(chat);
canSendDocument = ChatObject.canSendDocument(chat);
canSendPreview = ChatObject.canSendEmbed(chat);
canSendPolls = ChatObject.canSendPolls(chat);
canSendVoiceRound = ChatObject.canSendRoundVideo(chat);
canSendVoiceMessages = ChatObject.canSendVoice(chat);
canSendMusic = ChatObject.canSendMusic(chat);
}
LongSparseArray<Long> groupsMap = new LongSparseArray<>();
@ -1739,9 +1749,19 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_STICKERS) ? 4 : 1;
}
continue;
} else if (!canSendMedia && (msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto || msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaDocument) && !mediaIsSticker) {
} else if (!canSendPhoto && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && !msgObj.isVideo() && !mediaIsSticker) {
if (sendResult == 0) {
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_MEDIA) ? 5 : 2;
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_PHOTO) ? 10 : 12;
}
continue;
} else if (!canSendMusic && msgObj.isMusic()) {
if (sendResult == 0) {
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_MUSIC) ? 19 : 20;
}
continue;
} else if (!canSendVideo && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && msgObj.isVideo() && !mediaIsSticker) {
if (sendResult == 0) {
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_VIDEO) ? 9 : 11;
}
continue;
} else if (!canSendPolls && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
@ -1750,13 +1770,30 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
continue;
} else if (!canSendVoiceMessages && MessageObject.isVoiceMessage(msgObj.messageOwner)) {
if (sendResult == 0) {
sendResult = 7;
if (chat != null) {
if (sendResult == 0) {
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_VOICE) ? 13 : 14;
}
} else {
if (sendResult == 0) {
sendResult = 7;
}
}
continue;
} else if (!canSendVoiceMessages && MessageObject.isRoundVideoMessage(msgObj.messageOwner)) {
} else if (!canSendVoiceRound && MessageObject.isRoundVideoMessage(msgObj.messageOwner)) {
if (chat != null) {
if (sendResult == 0) {
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_ROUND) ? 15 : 16;
}
} else {
if (sendResult == 0) {
sendResult = 8;
}
}
continue;
} else if (!canSendDocument && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && !mediaIsSticker) {
if (sendResult == 0) {
sendResult = 8;
sendResult = ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_DOCUMENTS) ? 17 : 18;
}
continue;
}
@ -2220,6 +2257,38 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return sendResult;
}
public static int canSendMessageToChat(TLRPC.Chat chat, MessageObject msgObj) {
boolean canSendStickers = ChatObject.canSendStickers(chat);
boolean canSendPhoto = ChatObject.canSendPhoto(chat);
boolean canSendVideo = ChatObject.canSendVideo(chat);
boolean canSendDocument = ChatObject.canSendDocument(chat);
boolean canSendPreview = ChatObject.canSendEmbed(chat);
boolean canSendPolls = ChatObject.canSendPolls(chat);
boolean canSendVoiceRound = ChatObject.canSendRoundVideo(chat);
boolean canSendVoiceMessages = ChatObject.canSendVoice(chat);
boolean canSendMusic = ChatObject.canSendMusic(chat);
boolean mediaIsSticker = (msgObj.isSticker() || msgObj.isAnimatedSticker() || msgObj.isGif() || msgObj.isGame());
if (!canSendStickers && mediaIsSticker) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_STICKERS) ? 4 : 1;
} else if (!canSendPhoto && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && !msgObj.isVideo() && !mediaIsSticker) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_PHOTO) ? 10 : 12;
} else if (!canSendMusic && msgObj.isMusic()) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_MUSIC) ? 19 : 20;
} else if (!canSendVideo && msgObj.isVideo() && !mediaIsSticker) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_VIDEO) ? 9 : 11;
} else if (!canSendPolls && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaPoll) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_POLLS) ? 6 : 3;
} else if (!canSendVoiceMessages && MessageObject.isVoiceMessage(msgObj.messageOwner)) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_VOICE) ? 13 : 14;
} else if (!canSendVoiceRound && MessageObject.isRoundVideoMessage(msgObj.messageOwner)) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_ROUND) ? 15 : 16;
} else if (!canSendDocument && msgObj.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && !mediaIsSticker) {
return ChatObject.isActionBannedByDefault(chat, ChatObject.ACTION_SEND_DOCUMENTS) ? 17 : 18;
}
return 0;
}
private void writePreviousMessageData(TLRPC.Message message, SerializedData data) {
if (message.media == null) {
TLRPC.TL_messageMediaEmpty media = new TLRPC.TL_messageMediaEmpty();
@ -5822,7 +5891,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
}
if (sentMessage.media instanceof TLRPC.TL_messageMediaPhoto && sentMessage.media.photo != null && newMsg.media instanceof TLRPC.TL_messageMediaPhoto && newMsg.media.photo != null) {
if (sentMessage.media.ttl_seconds == 0 && !newMsgObj.scheduled) {
getMessagesStorage().putSentFile(originalPath, sentMessage.media.photo, 0, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + MessageObject.TYPE_PHOTO);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.photo, 0, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + MessageObject.TYPE_PHOTO + "_" + newMsgObj.getSize());
}
if (newMsg.media.photo.sizes.size() == 1 && newMsg.media.photo.sizes.get(0).location instanceof TLRPC.TL_fileLocationUnavailable) {
@ -5883,14 +5952,14 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if ((isVideo || MessageObject.isGifMessage(sentMessage)) && MessageObject.isGifDocument(sentMessage.media.document) == MessageObject.isGifDocument(newMsg.media.document)) {
if (!newMsgObj.scheduled) {
MessageObject messageObject = new MessageObject(currentAccount, sentMessage, false, false);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 2, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + messageObject.type);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 2, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + messageObject.type + "_" + messageObject.getSize());
}
if (isVideo) {
sentMessage.attachPath = newMsg.attachPath;
}
} else if (!MessageObject.isVoiceMessage(sentMessage) && !MessageObject.isRoundVideoMessage(sentMessage) && !newMsgObj.scheduled) {
MessageObject messageObject = new MessageObject(currentAccount, sentMessage, false, false);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 1, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + messageObject.type);
getMessagesStorage().putSentFile(originalPath, sentMessage.media.document, 1, "sent_" + sentMessage.peer_id.channel_id + "_" + sentMessage.id + "_" + DialogObject.getPeerDialogId(sentMessage.peer_id) + "_" + messageObject.type + "_" + messageObject.getSize());
}
}
@ -7144,6 +7213,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_forumTopic topic = accountInstance.getMessagesController().getTopicsController().findTopic(-dialogId, topicId);
if (topic != null && topic.topicStartMessage != null) {
replyToMsg = new MessageObject(accountInstance.getCurrentAccount(), topic.topicStartMessage, false, false);
replyToMsg.isTopicMainMessage = true;
}
}
for (int a = 0; a < count; a++) {

View File

@ -41,9 +41,16 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
public class SharedConfig {
/**
* V2: Ping and check time serialized
*/
private final static int PROXY_SCHEMA_V2 = 2;
private final static int PROXY_CURRENT_SCHEMA_VERSION = PROXY_SCHEMA_V2;
public final static int PASSCODE_TYPE_PIN = 0,
PASSCODE_TYPE_PASSWORD = 1;
@ -125,7 +132,7 @@ public class SharedConfig {
private static final Object sync = new Object();
private static final Object localIdSync = new Object();
public static int saveToGalleryFlags;
// public static int saveToGalleryFlags;
public static int mapPreviewType = 2;
public static boolean chatBubbles = Build.VERSION.SDK_INT >= 30;
public static boolean autoplayGifs = true;
@ -142,7 +149,7 @@ public class SharedConfig {
public static boolean streamMkv = false;
public static boolean saveStreamMedia = true;
public static boolean smoothKeyboard = true;
public static boolean pauseMusicOnRecord = true;
public static boolean pauseMusicOnRecord = false;
public static boolean chatBlur = true;
public static boolean noiseSupression;
public static boolean noStatusBar = true;
@ -161,6 +168,8 @@ public class SharedConfig {
public static boolean fontSizeIsDefault;
public static int bubbleRadius = 17;
public static int ivFontSize = 16;
public static boolean proxyRotationEnabled;
public static int proxyRotationTimeout;
public static int messageSeenHintCount;
public static int emojiInteractionsHintCount;
public static int dayNightThemeSwitchHintCount;
@ -184,6 +193,8 @@ public class SharedConfig {
public static int fastScrollHintCount = 3;
public static boolean dontAskManageStorage;
public static boolean translateChats = true;
public static boolean isFloatingDebugActive;
public static LiteMode liteMode;
@ -205,23 +216,23 @@ public class SharedConfig {
public boolean available;
public long availableCheckTime;
public ProxyInfo(String a, int p, String u, String pw, String s) {
address = a;
port = p;
username = u;
password = pw;
secret = s;
if (address == null) {
address = "";
public ProxyInfo(String address, int port, String username, String password, String secret) {
this.address = address;
this.port = port;
this.username = username;
this.password = password;
this.secret = secret;
if (this.address == null) {
this.address = "";
}
if (password == null) {
password = "";
if (this.password == null) {
this.password = "";
}
if (username == null) {
username = "";
if (this.username == null) {
this.username = "";
}
if (secret == null) {
secret = "";
if (this.secret == null) {
this.secret = "";
}
}
@ -279,6 +290,8 @@ public class SharedConfig {
editor.putBoolean("forwardingOptionsHintShown", forwardingOptionsHintShown);
editor.putInt("lockRecordAudioVideoHint", lockRecordAudioVideoHint);
editor.putString("storageCacheDir", !TextUtils.isEmpty(storageCacheDir) ? storageCacheDir : "");
editor.putBoolean("proxyRotationEnabled", proxyRotationEnabled);
editor.putInt("proxyRotationTimeout", proxyRotationTimeout);
if (pendingAppUpdate != null) {
try {
@ -302,6 +315,7 @@ public class SharedConfig {
editor.putBoolean("hasEmailLogin", hasEmailLogin);
editor.putBoolean("useLNavigation", useLNavigation);
editor.putBoolean("floatingDebugActive", isFloatingDebugActive);
editor.putBoolean("record_via_sco", recordViaSco);
editor.apply();
} catch (Exception e) {
FileLog.e(e);
@ -345,6 +359,8 @@ public class SharedConfig {
passportConfigJson = preferences.getString("passportConfigJson", "");
passportConfigHash = preferences.getInt("passportConfigHash", 0);
storageCacheDir = preferences.getString("storageCacheDir", null);
proxyRotationEnabled = preferences.getBoolean("proxyRotationEnabled", false);
proxyRotationTimeout = preferences.getInt("proxyRotationTimeout", ProxyRotationController.DEFAULT_TIMEOUT_INDEX);
String authKeyString = preferences.getString("pushAuthKey", null);
if (!TextUtils.isEmpty(authKeyString)) {
pushAuthKey = Base64.decode(authKeyString, Base64.DEFAULT);
@ -399,13 +415,7 @@ public class SharedConfig {
}
preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
boolean saveToGalleryLegacy = preferences.getBoolean("save_gallery", false);
if (saveToGalleryLegacy && BuildVars.NO_SCOPED_STORAGE) {
saveToGalleryFlags = SAVE_TO_GALLERY_FLAG_PEER + SAVE_TO_GALLERY_FLAG_CHANNELS + SAVE_TO_GALLERY_FLAG_GROUP;
preferences.edit().remove("save_gallery").putInt("save_gallery_flags", saveToGalleryFlags).apply();
} else {
saveToGalleryFlags = preferences.getInt("save_gallery_flags", 0);
}
SaveToGallerySettingsHelper.load(preferences);
autoplayGifs = preferences.getBoolean("autoplay_gif", true);
autoplayVideo = preferences.getBoolean("autoplay_video", true);
mapPreviewType = preferences.getInt("mapPreviewType", 2);
@ -1036,17 +1046,17 @@ public class SharedConfig {
}
public static void toggleSaveToGalleryFlag(int flag) {
if ((saveToGalleryFlags & flag) != 0) {
saveToGalleryFlags &= ~flag;
} else {
saveToGalleryFlags |= flag;
}
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
preferences.edit().putInt("save_gallery_flags", saveToGalleryFlags).apply();
ImageLoader.getInstance().checkMediaPaths();
ImageLoader.getInstance().getCacheOutQueue().postRunnable(() -> {
checkSaveToGalleryFiles();
});
// if ((saveToGalleryFlags & flag) != 0) {
// saveToGalleryFlags &= ~flag;
// } else {
// saveToGalleryFlags |= flag;
// }
// SharedPreferences preferences = MessagesController.getGlobalMainSettings();
// preferences.edit().putInt("save_gallery_flags", saveToGalleryFlags).apply();
// ImageLoader.getInstance().checkMediaPaths();
// ImageLoader.getInstance().getCacheOutQueue().postRunnable(() -> {
// checkSaveToGalleryFiles();
// });
}
public static void toggleAutoplayGifs() {
@ -1256,17 +1266,46 @@ public class SharedConfig {
byte[] bytes = Base64.decode(list, Base64.DEFAULT);
SerializedData data = new SerializedData(bytes);
int count = data.readInt32(false);
for (int a = 0; a < count; a++) {
ProxyInfo info = new ProxyInfo(
data.readString(false),
data.readInt32(false),
data.readString(false),
data.readString(false),
data.readString(false));
proxyList.add(info);
if (currentProxy == null && !TextUtils.isEmpty(proxyAddress)) {
if (proxyAddress.equals(info.address) && proxyPort == info.port && proxyUsername.equals(info.username) && proxyPassword.equals(info.password)) {
currentProxy = info;
if (count == -1) { // V2 or newer
int version = data.readByte(false);
if (version == PROXY_SCHEMA_V2) {
count = data.readInt32(false);
for (int i = 0; i < count; i++) {
ProxyInfo info = new ProxyInfo(
data.readString(false),
data.readInt32(false),
data.readString(false),
data.readString(false),
data.readString(false));
info.ping = data.readInt64(false);
info.availableCheckTime = data.readInt64(false);
proxyList.add(info);
if (currentProxy == null && !TextUtils.isEmpty(proxyAddress)) {
if (proxyAddress.equals(info.address) && proxyPort == info.port && proxyUsername.equals(info.username) && proxyPassword.equals(info.password)) {
currentProxy = info;
}
}
}
} else {
FileLog.e("Unknown proxy schema version: " + version);
}
} else {
for (int a = 0; a < count; a++) {
ProxyInfo info = new ProxyInfo(
data.readString(false),
data.readInt32(false),
data.readString(false),
data.readString(false),
data.readString(false));
proxyList.add(info);
if (currentProxy == null && !TextUtils.isEmpty(proxyAddress)) {
if (proxyAddress.equals(info.address) && proxyPort == info.port && proxyUsername.equals(info.username) && proxyPassword.equals(info.password)) {
currentProxy = info;
}
}
}
}
@ -1279,16 +1318,33 @@ public class SharedConfig {
}
public static void saveProxyList() {
List<ProxyInfo> infoToSerialize = new ArrayList<>(proxyList);
Collections.sort(infoToSerialize, (o1, o2) -> {
long bias1 = SharedConfig.currentProxy == o1 ? -200000 : 0;
if (!o1.available) {
bias1 += 100000;
}
long bias2 = SharedConfig.currentProxy == o2 ? -200000 : 0;
if (!o2.available) {
bias2 += 100000;
}
return Long.compare(o1.ping + bias1, o2.ping + bias2);
});
SerializedData serializedData = new SerializedData();
int count = proxyList.size();
serializedData.writeInt32(-1);
serializedData.writeByte(PROXY_CURRENT_SCHEMA_VERSION);
int count = infoToSerialize.size();
serializedData.writeInt32(count);
for (int a = 0; a < count; a++) {
ProxyInfo info = proxyList.get(a);
ProxyInfo info = infoToSerialize.get(a);
serializedData.writeString(info.address != null ? info.address : "");
serializedData.writeInt32(info.port);
serializedData.writeString(info.username != null ? info.username : "");
serializedData.writeString(info.password != null ? info.password : "");
serializedData.writeString(info.secret != null ? info.secret : "");
serializedData.writeInt64(info.ping);
serializedData.writeInt64(info.availableCheckTime);
}
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
preferences.edit().putString("proxy_list", Base64.encodeToString(serializedData.toByteArray(), Base64.NO_WRAP)).commit();
@ -1309,6 +1365,10 @@ public class SharedConfig {
return proxyInfo;
}
public static boolean isProxyEnabled() {
return MessagesController.getGlobalMainSettings().getBoolean("proxy_enabled", false) && currentProxy != null;
}
public static void deleteProxy(ProxyInfo proxyInfo) {
if (currentProxy == proxyInfo) {
currentProxy = null;
@ -1340,7 +1400,7 @@ public class SharedConfig {
File videoPath = new File(telegramPath, "Telegram Video");
videoPath.mkdir();
if (saveToGalleryFlags != 0 || !BuildVars.NO_SCOPED_STORAGE) {
if (!BuildVars.NO_SCOPED_STORAGE) {
if (imagePath.isDirectory()) {
new File(imagePath, ".nomedia").delete();
}
@ -1484,6 +1544,14 @@ public class SharedConfig {
public static void setLastCheckedBackgroundActivity(long l) {
prefs.edit().putLong("last_checked", l).apply();
}
public static int getDismissedCount() {
return prefs.getInt("dismissed_count", 0);
}
public static void increaseDismissedCount() {
prefs.edit().putInt("dismissed_count", getDismissedCount() + 1).apply();
}
}
private static Boolean animationsEnabled;

View File

@ -27,7 +27,9 @@ public class StatsController extends BaseController {
public static final int TYPE_PHOTOS = 4;
public static final int TYPE_FILES = 5;
public static final int TYPE_TOTAL = 6;
private static final int TYPES_COUNT = 7;
public static final int TYPE_MUSIC = 7;
private static final int OLD_TYPES_COUNT = 7;
private static final int TYPES_COUNT = 8;
private byte[] buffer = new byte[8];
@ -87,7 +89,7 @@ public class StatsController extends BaseController {
try {
statsFile.seek(0);
for (int a = 0; a < 3; a++) {
for (int b = 0; b < TYPES_COUNT; b++) {
for (int b = 0; b < OLD_TYPES_COUNT; b++) {
statsFile.write(longToBytes(sentBytes[a][b]), 0, 8);
statsFile.write(longToBytes(receivedBytes[a][b]), 0, 8);
statsFile.write(intToBytes(sentItems[a][b]), 0, 4);
@ -96,6 +98,14 @@ public class StatsController extends BaseController {
statsFile.write(intToBytes(callsTotalTime[a]), 0, 4);
statsFile.write(longToBytes(resetStatsDate[a]), 0, 8);
}
for (int b = OLD_TYPES_COUNT; b < TYPES_COUNT; ++b) {
for (int a = 0; a < 3; ++a) {
statsFile.write(longToBytes(sentBytes[a][b]), 0, 8);
statsFile.write(longToBytes(receivedBytes[a][b]), 0, 8);
statsFile.write(intToBytes(sentItems[a][b]), 0, 4);
statsFile.write(intToBytes(receivedItems[a][b]), 0, 4);
}
}
statsFile.getFD().sync();
} catch (Exception ignore) {
@ -132,7 +142,7 @@ public class StatsController extends BaseController {
if (statsFile.length() > 0) {
boolean save = false;
for (int a = 0; a < 3; a++) {
for (int b = 0; b < TYPES_COUNT; b++) {
for (int b = 0; b < OLD_TYPES_COUNT; b++) {
statsFile.readFully(buffer, 0, 8);
sentBytes[a][b] = bytesToLong(buffer);
statsFile.readFully(buffer, 0, 8);
@ -151,6 +161,18 @@ public class StatsController extends BaseController {
resetStatsDate[a] = System.currentTimeMillis();
}
}
for (int b = OLD_TYPES_COUNT; b < TYPES_COUNT; ++b) {
for (int a = 0; a < 3; ++a) {
statsFile.readFully(buffer, 0, 8);
sentBytes[a][b] = bytesToLong(buffer);
statsFile.readFully(buffer, 0, 8);
receivedBytes[a][b] = bytesToLong(buffer);
statsFile.readFully(buffer, 0, 4);
sentItems[a][b] = bytesToInt(buffer);
statsFile.readFully(buffer, 0, 4);
receivedItems[a][b] = bytesToInt(buffer);
}
}
if (save) {
saveStats();
}
@ -222,14 +244,14 @@ public class StatsController extends BaseController {
public long getSentBytesCount(int networkType, int dataType) {
if (dataType == TYPE_MESSAGES) {
return sentBytes[networkType][TYPE_TOTAL] - sentBytes[networkType][TYPE_FILES] - sentBytes[networkType][TYPE_AUDIOS] - sentBytes[networkType][TYPE_VIDEOS] - sentBytes[networkType][TYPE_PHOTOS];
return sentBytes[networkType][TYPE_TOTAL] - sentBytes[networkType][TYPE_FILES] - sentBytes[networkType][TYPE_AUDIOS] - sentBytes[networkType][TYPE_VIDEOS] - sentBytes[networkType][TYPE_PHOTOS] - sentBytes[networkType][TYPE_MUSIC];
}
return sentBytes[networkType][dataType];
}
public long getReceivedBytesCount(int networkType, int dataType) {
if (dataType == TYPE_MESSAGES) {
return receivedBytes[networkType][TYPE_TOTAL] - receivedBytes[networkType][TYPE_FILES] - receivedBytes[networkType][TYPE_AUDIOS] - receivedBytes[networkType][TYPE_VIDEOS] - receivedBytes[networkType][TYPE_PHOTOS];
return receivedBytes[networkType][TYPE_TOTAL] - receivedBytes[networkType][TYPE_FILES] - receivedBytes[networkType][TYPE_AUDIOS] - receivedBytes[networkType][TYPE_VIDEOS] - receivedBytes[networkType][TYPE_PHOTOS] - receivedBytes[networkType][TYPE_MUSIC];
}
return receivedBytes[networkType][dataType];
}

View File

@ -204,10 +204,8 @@ public class TopicsController extends BaseController {
}
}
if (topicsToReload != null && loadType != LOAD_TYPE_LOAD_UNKNOWN) {
reloadTopics(chatId, topicsToReload);
reloadTopics(chatId, topicsToReload, null);
} else if (((loadType == LOAD_TYPE_PRELOAD && !fromCache) || loadType == LOAD_TYPE_LOAD_NEXT) && topics.size() >= totalCount && totalCount >= 0) {
endIsReached.put(chatId, 1);
getUserConfig().getPreferences().edit().putBoolean("topics_end_reached_" + chatId, true).apply();
@ -244,7 +242,6 @@ public class TopicsController extends BaseController {
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
if (topics != null) {
if (openedTopicsBuChatId.get(chatId, 0) > 0) {
// Comparator.comparingInt(o -> o.topMessage == null ? Integer.MAX_VALUE : -(o.pinned ? Integer.MAX_VALUE - o.pinnedOrder : o.topMessage.date))
Collections.sort(topics, (a, b) -> {
if (a.hidden != b.hidden) {
return a.hidden ? -1 : 1;
@ -351,7 +348,7 @@ public class TopicsController extends BaseController {
sortTopics(chatId);
}
if (topicsToReload != null) {
reloadTopics(chatId, topicsToReload);
reloadTopics(chatId, topicsToReload, null);
}
});
}
@ -359,7 +356,7 @@ public class TopicsController extends BaseController {
});
}
private void reloadTopics(long chatId, ArrayList<TLRPC.TL_forumTopic> topicsToReload) {
public void reloadTopics(long chatId, ArrayList<TLRPC.TL_forumTopic> topicsToReload, Runnable callback) {
TLRPC.TL_channels_getForumTopicsByID req = new TLRPC.TL_channels_getForumTopicsByID();
for (int i = 0; i < topicsToReload.size(); i++) {
req.topics.add(topicsToReload.get(i).id);
@ -379,6 +376,9 @@ public class TopicsController extends BaseController {
processTopics(chatId, topics.topics, messagesMap, false, LOAD_TYPE_LOAD_UNKNOWN, -1);
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0);
getMessagesStorage().saveTopics(-chatId, topicsByChatId.get(chatId), true, true);
if (callback != null) {
callback.run();
}
});
}
}));
@ -820,7 +820,7 @@ public class TopicsController extends BaseController {
for (int i = 0; i < topicsToReload.size(); i++) {
long dialogId = topicsToReload.keyAt(i);
ArrayList<TLRPC.TL_forumTopic> topics = topicsToReload.valueAt(i);
reloadTopics(-dialogId, topics);
reloadTopics(-dialogId, topics, null);
}
}
@ -872,14 +872,9 @@ public class TopicsController extends BaseController {
endIsReached.delete(chatId);
clearLoadingOffset(chatId);
TLRPC.Chat chat = getMessagesController().getChat(chatId);
if (chat != null && chat.forum) {
if (fromCache) {
preloadTopics(chatId);
} else {
loadTopics(chatId, false, LOAD_TYPE_PRELOAD);
}
loadTopics(chatId, fromCache, LOAD_TYPE_PRELOAD);
}
sortTopics(chatId);
});
@ -979,6 +974,27 @@ public class TopicsController extends BaseController {
}
}
public void loadTopic(long chatId, int topicId, Runnable runnable) {
getMessagesStorage().loadTopics(-chatId, topics -> {
AndroidUtilities.runOnUIThread(() -> {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("loaded from cache " + chatId + " topics_count=" + (topics == null ? 0 : topics.size()));
}
processTopics(chatId, topics, null, true, LOAD_TYPE_PRELOAD, -1);
sortTopics(chatId);
if (findTopic(chatId, topicId) != null) {
runnable.run();
} else {
ArrayList<TLRPC.TL_forumTopic> topicToReload = new ArrayList<>();
TLRPC.TL_forumTopic topic = new TLRPC.TL_forumTopic();
topic.id = topicId;
reloadTopics(chatId, topicToReload, runnable);
}
});
});
}
private class TopicsLoadOffset {
int lastMessageId;
int lastMessageDate;

View File

@ -0,0 +1,980 @@
package org.telegram.messenger;
import android.content.Context;
import android.content.res.Resources;
import android.icu.text.Collator;
import android.text.TextUtils;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InputMethodSubtype;
import androidx.annotation.Nullable;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.TranslateAlert2;
import org.telegram.ui.RestrictedLanguagesSelectActivity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
public class TranslateController extends BaseController {
public static final String UNKNOWN_LANGUAGE = "und";
private static final int REQUIRED_TOTAL_MESSAGES_CHECKED = 8;
private static final float REQUIRED_PERCENTAGE_MESSAGES_TRANSLATABLE = .60F;
private static final float REQUIRED_MIN_PERCENTAGE_MESSAGES_UNKNOWN = .65F;
private static final int MAX_SYMBOLS_PER_REQUEST = 25000;
private static final int MAX_MESSAGES_PER_REQUEST = 20;
private static final int GROUPING_TRANSLATIONS_TIMEOUT = 200;
private final Set<Long> translatingDialogs = new HashSet<>();
private final Set<Long> translatableDialogs = new HashSet<>();
private final HashMap<Long, TranslatableDecision> translatableDialogMessages = new HashMap<>();
private final HashMap<Long, String> translateDialogLanguage = new HashMap<>();
private final HashMap<Long, String> detectedDialogLanguage = new HashMap<>();
private final HashMap<Long, HashMap<Integer, MessageObject>> keptReplyMessageObjects = new HashMap<>();
private final Set<Long> hideTranslateDialogs = new HashSet<>();
class TranslatableDecision {
Set<Integer> certainlyTranslatable = new HashSet<>();
Set<Integer> unknown = new HashSet<>();
Set<Integer> certainlyNotTranslatable = new HashSet<>();
}
private MessagesController messagesController;
public TranslateController(MessagesController messagesController) {
super(messagesController.currentAccount);
this.messagesController = messagesController;
AndroidUtilities.runOnUIThread(this::loadTranslatingDialogsCached, 150);
}
public boolean isFeatureAvailable() {
return UserConfig.getInstance(currentAccount).isPremium() && isChatTranslateEnabled();
}
public boolean isChatTranslateEnabled() {
return MessagesController.getMainSettings(currentAccount).getBoolean("translate_chat_button", true);
}
public boolean isContextTranslateEnabled() {
return MessagesController.getMainSettings(currentAccount).getBoolean("translate_button", MessagesController.getGlobalMainSettings().getBoolean("translate_button", false));
}
public void setContextTranslateEnabled(boolean enable) {
MessagesController.getMainSettings(currentAccount).edit().putBoolean("translate_button", enable).apply();
}
public static boolean isTranslatable(MessageObject messageObject) {
return (
messageObject != null && messageObject.messageOwner != null &&
!messageObject.isOutOwner() &&
(
messageObject.type == MessageObject.TYPE_TEXT ||
messageObject.type == MessageObject.TYPE_VIDEO ||
messageObject.type == MessageObject.TYPE_PHOTO ||
messageObject.type == MessageObject.TYPE_VOICE ||
messageObject.type == MessageObject.TYPE_FILE ||
messageObject.type == MessageObject.TYPE_MUSIC
) && !TextUtils.isEmpty(messageObject.messageOwner.message)
);
}
public boolean isDialogTranslatable(long dialogId) {
return (
isFeatureAvailable() &&
!DialogObject.isEncryptedDialog(dialogId) &&
getUserConfig().getClientUserId() != dialogId &&
/* DialogObject.isChatDialog(dialogId) &&*/
translatableDialogs.contains(dialogId)
);
}
public boolean isTranslateDialogHidden(long dialogId) {
if (hideTranslateDialogs.contains(dialogId)) {
return true;
}
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-dialogId);
if (chatFull != null) {
return chatFull.translations_disabled;
}
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId);
if (userFull != null) {
return userFull.translations_disabled;
}
return false;
}
public boolean isTranslatingDialog(long dialogId) {
return isFeatureAvailable() && translatingDialogs.contains(dialogId);
}
public void toggleTranslatingDialog(long dialogId) {
toggleTranslatingDialog(dialogId, !isTranslatingDialog(dialogId));
}
public boolean toggleTranslatingDialog(long dialogId, boolean value) {
boolean currentValue = isTranslatingDialog(dialogId), notified = false;
if (value && !currentValue) {
translatingDialogs.add(dialogId);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, true);
notified = true;
} else if (!value && currentValue) {
translatingDialogs.remove((Long) dialogId);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, false);
cancelTranslations(dialogId);
notified = true;
}
saveTranslatingDialogsCache();
return notified;
}
private int hash(MessageObject messageObject) {
if (messageObject == null) {
return 0;
}
return Objects.hash(messageObject.getDialogId(), messageObject.getId());
}
private String currentLanguage() {
String lang = LocaleController.getInstance().getCurrentLocaleInfo().pluralLangCode;
if (lang != null) {
lang = lang.split("_")[0];
}
return lang;
}
public String getDialogTranslateTo(long dialogId) {
String lang = translateDialogLanguage.get(dialogId);
if (lang == null) {
lang = TranslateAlert2.getToLanguage();
if (lang == null || lang.equals(getDialogDetectedLanguage(dialogId))) {
lang = currentLanguage();
}
}
if ("nb".equals(lang)) {
lang = "no";
}
return lang;
}
public void setDialogTranslateTo(long dialogId, String language) {
if (TextUtils.equals(getDialogTranslateTo(dialogId), language)) {
return;
}
boolean wasTranslating = isTranslatingDialog(dialogId);
if (wasTranslating) {
AndroidUtilities.runOnUIThread(() -> {
synchronized (TranslateController.this) {
translateDialogLanguage.put(dialogId, language);
translatingDialogs.add(dialogId);
saveTranslatingDialogsCache();
}
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, true);
}, 150);
} else {
synchronized (TranslateController.this) {
translateDialogLanguage.put(dialogId, language);
}
}
cancelTranslations(dialogId);
synchronized (this) {
translatingDialogs.remove(dialogId);
}
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, false);
TranslateAlert2.setToLanguage(language);
}
public void updateDialogFull(long dialogId) {
if (!isFeatureAvailable() || !isDialogTranslatable(dialogId)) {
return;
}
final boolean wasHidden = hideTranslateDialogs.contains(dialogId);
boolean hidden = false;
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-dialogId);
if (chatFull != null) {
hidden = chatFull.translations_disabled;
} else {
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId);
if (userFull != null) {
hidden = userFull.translations_disabled;
}
}
synchronized (this) {
if (hidden) {
hideTranslateDialogs.add(dialogId);
} else {
hideTranslateDialogs.remove(dialogId);
}
}
if (wasHidden != hidden) {
saveTranslatingDialogsCache();
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, isTranslatingDialog(dialogId));
}
}
public void setHideTranslateDialog(long dialogId, boolean hide) {
setHideTranslateDialog(dialogId, hide, false);
}
public void setHideTranslateDialog(long dialogId, boolean hide, boolean doNotNotify) {
TLRPC.TL_messages_togglePeerTranslations req = new TLRPC.TL_messages_togglePeerTranslations();
req.peer = getMessagesController().getInputPeer(dialogId);
req.disabled = hide;
getConnectionsManager().sendRequest(req, null);
TLRPC.ChatFull chatFull = getMessagesController().getChatFull(-dialogId);
if (chatFull != null) {
chatFull.translations_disabled = hide;
getMessagesStorage().updateChatInfo(chatFull, true);
}
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId);
if (userFull != null) {
userFull.translations_disabled = hide;
getMessagesStorage().updateUserInfo(userFull, true);
}
synchronized (this) {
if (hide) {
hideTranslateDialogs.add(dialogId);
} else {
hideTranslateDialogs.remove(dialogId);
}
}
saveTranslatingDialogsCache();
if (!doNotNotify) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, isTranslatingDialog(dialogId));
}
}
private static List<String> languagesOrder = Arrays.asList(
"en", "ar", "zh", "fr", "de", "it", "ja", "ko", "pt", "ru", "es", "uk"
);
private static List<String> allLanguages = Arrays.asList(
"af", "sq", "am", "ar", "hy", "az", "eu", "be", "bn", "bs", "bg", "ca", "ceb", "zh", "co", "hr", "cs", "da", "nl", "en", "eo", "et", "fi", "fr", "fy", "gl", "ka", "de", "el", "gu", "ht", "ha", "haw", "he", "iw", "hi", "hmn", "hu", "is", "ig", "id", "ga", "it", "ja", "jv", "kn", "kk", "km", "rw", "ko", "ku", "ky", "lo", "la", "lv", "lt", "lb", "mk", "mg", "ms", "ml", "mt", "mi", "mr", "mn", "my", "ne", "no", "ny", "or", "ps", "fa", "pl", "pt", "pa", "ro", "ru", "sm", "gd", "sr", "st", "sn", "sd", "si", "sk", "sl", "so", "es", "su", "sw", "sv", "tl", "tg", "ta", "tt", "te", "th", "tr", "tk", "uk", "ur", "ug", "uz", "vi", "cy", "xh", "yi", "yo", "zu"
);
public static class Language {
public String code;
public String displayName;
}
public static ArrayList<Language> getLanguages() {
ArrayList<Language> result = new ArrayList<>();
for (int i = 0; i < allLanguages.size(); ++i) {
Language language = new Language();
language.code = allLanguages.get(i);
language.displayName = TranslateAlert2.capitalFirst(TranslateAlert2.languageName(language.code));
if (language.displayName == null) {
continue;
}
result.add(language);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
Collator collator = Collator.getInstance(Locale.getDefault());
Collections.sort(result, (lng1, lng2) -> collator.compare(lng1.displayName, lng2.displayName));
} else {
Collections.sort(result, Comparator.comparing(lng -> lng.displayName));
}
return result;
}
private static LinkedHashSet<String> suggestedLanguageCodes = null;
public static void invalidateSuggestedLanguageCodes() {
suggestedLanguageCodes = null;
}
public static void analyzeSuggestedLanguageCodes() {
LinkedHashSet<String> langs = new LinkedHashSet<>();
try {
langs.add(LocaleController.getInstance().getCurrentLocaleInfo().pluralLangCode);
} catch (Exception e1) {
FileLog.e(e1);
}
try {
langs.add(Resources.getSystem().getConfiguration().locale.getLanguage());
} catch (Exception e2) {
FileLog.e(e2);
}
try {
langs.addAll(RestrictedLanguagesSelectActivity.getRestrictedLanguages());
} catch (Exception e3) {
FileLog.e(e3);
}
try {
InputMethodManager imm = (InputMethodManager) ApplicationLoader.applicationContext.getSystemService(Context.INPUT_METHOD_SERVICE);
List<InputMethodInfo> ims = imm.getEnabledInputMethodList();
for (InputMethodInfo method : ims) {
List<InputMethodSubtype> submethods = imm.getEnabledInputMethodSubtypeList(method, true);
for (InputMethodSubtype submethod : submethods) {
if ("keyboard".equals(submethod.getMode())) {
String currentLocale = submethod.getLocale();
if (currentLocale != null && currentLocale.contains("_")) {
currentLocale = currentLocale.split("_")[0];
}
if (TranslateAlert2.languageName(currentLocale) != null) {
langs.add(currentLocale);
}
}
}
}
} catch (Exception e4) {
FileLog.e(e4);
}
suggestedLanguageCodes = langs;
}
public static ArrayList<Language> getSuggestedLanguages(String except) {
ArrayList<Language> result = new ArrayList<>();
if (suggestedLanguageCodes == null) {
analyzeSuggestedLanguageCodes();
if (suggestedLanguageCodes == null) {
return result;
}
}
Iterator<String> i = suggestedLanguageCodes.iterator();
while (i.hasNext()) {
final String code = i.next();
if (TextUtils.equals(code, except) || "no".equals(except) && "nb".equals(code) || "nb".equals(except) && "no".equals(code)) {
continue;
}
Language language = new Language();
language.code = code;
language.displayName = TranslateAlert2.capitalFirst(TranslateAlert2.languageName(language.code));
if (language.displayName == null) {
continue;
}
result.add(language);
}
return result;
}
public static ArrayList<LocaleController.LocaleInfo> getLocales() {
HashMap<String, LocaleController.LocaleInfo> languages = LocaleController.getInstance().languagesDict;
ArrayList<LocaleController.LocaleInfo> locales = new ArrayList<>(languages.values());
for (int i = 0; i < locales.size(); ++i) {
LocaleController.LocaleInfo locale = locales.get(i);
if (locale == null || locale.shortName != null && locale.shortName.endsWith("_raw") || !"remote".equals(locale.pathToFile)) {
locales.remove(i);
i--;
}
}
final LocaleController.LocaleInfo currentLocale = LocaleController.getInstance().getCurrentLocaleInfo();
Comparator<LocaleController.LocaleInfo> comparator = (o, o2) -> {
if (o == currentLocale) {
return -1;
} else if (o2 == currentLocale) {
return 1;
}
final int index1 = languagesOrder.indexOf(o.pluralLangCode);
final int index2 = languagesOrder.indexOf(o2.pluralLangCode);
if (index1 >= 0 && index2 >= 0) {
return index1 - index2;
} else if (index1 >= 0) {
return -1;
} else if (index2 >= 0) {
return 1;
}
if (o.serverIndex == o2.serverIndex) {
return o.name.compareTo(o2.name);
}
if (o.serverIndex > o2.serverIndex) {
return 1;
} else if (o.serverIndex < o2.serverIndex) {
return -1;
}
return 0;
};
Collections.sort(locales, comparator);
return locales;
}
public void checkRestrictedLanguagesUpdate() {
synchronized (this) {
translatableDialogMessages.clear();
ArrayList<Long> toNotify = new ArrayList<>();
HashSet<String> languages = RestrictedLanguagesSelectActivity.getRestrictedLanguages();
for (long dialogId : translatableDialogs) {
String language = detectedDialogLanguage.get(dialogId);
if (language != null && languages.contains(language)) {
cancelTranslations(dialogId);
translatingDialogs.remove(dialogId);
toNotify.add(dialogId);
}
}
translatableDialogs.clear();
saveTranslatingDialogsCache();
for (long dialogId : toNotify) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogTranslate, dialogId, false);
}
}
}
@Nullable
public String getDialogDetectedLanguage(long dialogId) {
return detectedDialogLanguage.get(dialogId);
}
public void checkTranslation(MessageObject messageObject, boolean onScreen) {
checkTranslation(messageObject, onScreen, false);
}
private void checkTranslation(MessageObject messageObject, boolean onScreen, boolean keepReply) {
if (!isFeatureAvailable()) {
return;
}
if (messageObject == null || messageObject.messageOwner == null) {
return;
}
long dialogId = messageObject.getDialogId();
if (!keepReply && messageObject.replyMessageObject != null) {
checkTranslation(messageObject.replyMessageObject, onScreen, true);
}
if (!isTranslatable(messageObject)) {
return;
}
if (!isTranslatingDialog(dialogId)) {
checkLanguage(messageObject);
return;
}
final String language = getDialogTranslateTo(dialogId);
MessageObject potentialReplyMessageObject;
if (!keepReply && (messageObject.messageOwner.translatedText == null || !language.equals(messageObject.messageOwner.translatedToLanguage)) && (potentialReplyMessageObject = findReplyMessageObject(dialogId, messageObject.getId())) != null) {
messageObject.messageOwner.translatedToLanguage = potentialReplyMessageObject.messageOwner.translatedToLanguage;
messageObject.messageOwner.translatedText = potentialReplyMessageObject.messageOwner.translatedText;
messageObject = potentialReplyMessageObject;
}
if (onScreen && isTranslatingDialog(dialogId)) {
final MessageObject finalMessageObject = messageObject;
if (finalMessageObject.messageOwner.translatedText == null || !language.equals(finalMessageObject.messageOwner.translatedToLanguage)) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.messageTranslating, finalMessageObject);
pushToTranslate(finalMessageObject, language, (text, lang) -> {
finalMessageObject.messageOwner.translatedToLanguage = lang;
finalMessageObject.messageOwner.translatedText = text;
if (keepReply) {
keepReplyMessage(finalMessageObject);
}
getMessagesStorage().updateMessageCustomParams(dialogId, finalMessageObject.messageOwner);
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.messageTranslated, finalMessageObject);
ArrayList<MessageObject> dialogMessages = messagesController.dialogMessage.get(dialogId);
if (dialogMessages != null) {
for (int i = 0; i < dialogMessages.size(); ++i) {
MessageObject dialogMessage = dialogMessages.get(i);
if (dialogMessage != null && dialogMessage.getId() == finalMessageObject.getId()) {
dialogMessage.messageOwner.translatedToLanguage = lang;
dialogMessage.messageOwner.translatedText = text;
if (dialogMessage.updateTranslation()) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.updateInterfaces, 0);
}
break;
}
}
}
});
} else if (keepReply) {
keepReplyMessage(messageObject);
}
}
}
public void invalidateTranslation(MessageObject messageObject) {
if (!isFeatureAvailable()) {
return;
}
if (messageObject == null || messageObject.messageOwner == null) {
return;
}
final long dialogId = messageObject.getDialogId();
messageObject.messageOwner.translatedToLanguage = null;
messageObject.messageOwner.translatedText = null;
getMessagesStorage().updateMessageCustomParams(dialogId, messageObject.messageOwner);
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.messageTranslated, messageObject, isTranslatingDialog(dialogId));
});
}
public void checkDialogMessages(long dialogId) {
if (!isFeatureAvailable()) {
return;
}
getMessagesStorage().getStorageQueue().postRunnable(() -> {
final ArrayList<MessageObject> dialogMessages = messagesController.dialogMessage.get(dialogId);
if (dialogMessages == null) {
return;
}
ArrayList<TLRPC.Message> customProps = new ArrayList<>();
for (int i = 0; i < dialogMessages.size(); ++i) {
MessageObject dialogMessage = dialogMessages.get(i);
if (dialogMessage == null || dialogMessage.messageOwner == null) {
customProps.add(null);
continue;
}
customProps.add(getMessagesStorage().getMessageWithCustomParamsOnlyInternal(dialogMessage.getId(), dialogMessage.getDialogId()));
}
AndroidUtilities.runOnUIThread(() -> {
boolean updated = false;
for (int i = 0; i < Math.min(customProps.size(), dialogMessages.size()); ++i) {
MessageObject dialogMessage = dialogMessages.get(i);
TLRPC.Message props = customProps.get(i);
if (dialogMessage == null || dialogMessage.messageOwner == null || props == null) {
continue;
}
dialogMessage.messageOwner.translatedText = props.translatedText;
dialogMessage.messageOwner.translatedToLanguage = props.translatedToLanguage;
if (dialogMessage.updateTranslation(false)) {
updated = true;
}
}
if (updated) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.updateInterfaces, 0);
}
});
});
}
public void cleanup() {
cancelAllTranslations();
resetTranslatingDialogsCache();
translatingDialogs.clear();
translatableDialogs.clear();
translatableDialogMessages.clear();
translateDialogLanguage.clear();
detectedDialogLanguage.clear();
keptReplyMessageObjects.clear();
hideTranslateDialogs.clear();
loadingTranslations.clear();
}
private ArrayList<Integer> pendingLanguageChecks = new ArrayList<>();
private void checkLanguage(MessageObject messageObject) {
if (!LanguageDetector.hasSupport()) {
return;
}
if (!isTranslatable(messageObject) || messageObject.messageOwner == null || TextUtils.isEmpty(messageObject.messageOwner.message)) {
return;
}
if (messageObject.messageOwner.originalLanguage != null) {
checkDialogTranslatable(messageObject);
return;
}
final long dialogId = messageObject.getDialogId();
final int hash = hash(messageObject);
if (isDialogTranslatable(dialogId)) {
return;
}
if (pendingLanguageChecks.contains(hash)) {
return;
}
pendingLanguageChecks.add(hash);
LanguageDetector.detectLanguage(messageObject.messageOwner.message, lng -> AndroidUtilities.runOnUIThread(() -> {
String detectedLanguage = lng;
if (detectedLanguage == null) {
detectedLanguage = UNKNOWN_LANGUAGE;
}
messageObject.messageOwner.originalLanguage = detectedLanguage;
getMessagesStorage().updateMessageCustomParams(dialogId, messageObject.messageOwner);
pendingLanguageChecks.remove((Integer) hash);
checkDialogTranslatable(messageObject);
}), err -> AndroidUtilities.runOnUIThread(() -> {
messageObject.messageOwner.originalLanguage = UNKNOWN_LANGUAGE;
getMessagesStorage().updateMessageCustomParams(dialogId, messageObject.messageOwner);
pendingLanguageChecks.remove((Integer) hash);
}));
}
private void checkDialogTranslatable(MessageObject messageObject) {
if (messageObject == null || messageObject.messageOwner == null) {
return;
}
final long dialogId = messageObject.getDialogId();
TranslatableDecision translatableMessages = translatableDialogMessages.get(dialogId);
if (translatableMessages == null) {
translatableDialogMessages.put(dialogId, translatableMessages = new TranslatableDecision());
}
final boolean isUnknown = isTranslatable(messageObject) && (
messageObject.messageOwner.originalLanguage == null ||
UNKNOWN_LANGUAGE.equals(messageObject.messageOwner.originalLanguage)
);
final boolean translatable = (
isTranslatable(messageObject) &&
messageObject.messageOwner.originalLanguage != null &&
!UNKNOWN_LANGUAGE.equals(messageObject.messageOwner.originalLanguage) &&
!RestrictedLanguagesSelectActivity.getRestrictedLanguages().contains(messageObject.messageOwner.originalLanguage) &&
!TextUtils.equals(getDialogTranslateTo(dialogId), messageObject.messageOwner.originalLanguage)
);
if (isUnknown) {
translatableMessages.unknown.add(messageObject.getId());
} else {
(translatable ? translatableMessages.certainlyTranslatable : translatableMessages.certainlyNotTranslatable).add(messageObject.getId());
}
if (!isUnknown) {
detectedDialogLanguage.put(dialogId, messageObject.messageOwner.originalLanguage);
}
final int translatableCount = translatableMessages.certainlyTranslatable.size();
final int unknownCount = translatableMessages.unknown.size();
final int notTranslatableCount = translatableMessages.certainlyNotTranslatable.size();
final int totalCount = translatableCount + unknownCount + notTranslatableCount;
if (
totalCount >= REQUIRED_TOTAL_MESSAGES_CHECKED &&
(translatableCount / (float) (translatableCount + notTranslatableCount)) >= REQUIRED_PERCENTAGE_MESSAGES_TRANSLATABLE &&
(unknownCount / (float) totalCount) < REQUIRED_MIN_PERCENTAGE_MESSAGES_UNKNOWN
) {
translatableDialogs.add(dialogId);
translatableDialogMessages.remove((Long) dialogId);
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.dialogIsTranslatable, dialogId);
}, 450);
}
}
private final Set<Integer> loadingTranslations = new HashSet<>();
private final HashMap<Long, ArrayList<PendingTranslation>> pendingTranslations = new HashMap<>();
private static class PendingTranslation {
Runnable runnable;
ArrayList<Integer> messageIds = new ArrayList<>();
ArrayList<TLRPC.TL_textWithEntities> messageTexts = new ArrayList<>();
ArrayList<Utilities.Callback2<TLRPC.TL_textWithEntities, String>> callbacks = new ArrayList<>();
String language;
int symbolsCount;
int reqId = -1;
}
private void pushToTranslate(
MessageObject message,
String language,
Utilities.Callback2<TLRPC.TL_textWithEntities, String> callback
) {
if (message == null || callback == null) {
return;
}
long dialogId = message.getDialogId();
PendingTranslation pendingTranslation;
synchronized (this) {
ArrayList<PendingTranslation> dialogPendingTranslations = pendingTranslations.get(dialogId);
if (dialogPendingTranslations == null) {
pendingTranslations.put(dialogId, dialogPendingTranslations = new ArrayList<>());
}
if (dialogPendingTranslations.isEmpty()) {
dialogPendingTranslations.add(pendingTranslation = new PendingTranslation());
} else {
pendingTranslation = dialogPendingTranslations.get(dialogPendingTranslations.size() - 1);
}
if (pendingTranslation.messageIds.contains(message.getId())) {
return;
}
int messageSymbolsCount = 0;
if (message.messageOwner != null && message.messageOwner.message != null) {
messageSymbolsCount = message.messageOwner.message.length();
} else if (message.caption != null) {
messageSymbolsCount = message.caption.length();
} else if (message.messageText != null) {
messageSymbolsCount = message.messageText.length();
}
if (pendingTranslation.symbolsCount + messageSymbolsCount >= MAX_SYMBOLS_PER_REQUEST ||
pendingTranslation.messageIds.size() + 1 >= MAX_MESSAGES_PER_REQUEST) {
dialogPendingTranslations.add(pendingTranslation = new PendingTranslation());
}
if (pendingTranslation.runnable != null) {
AndroidUtilities.cancelRunOnUIThread(pendingTranslation.runnable);
}
loadingTranslations.add(message.getId());
pendingTranslation.messageIds.add(message.getId());
TLRPC.TL_textWithEntities source = null;
if (message.messageOwner != null) {
source = new TLRPC.TL_textWithEntities();
source.text = message.messageOwner.message;
source.entities = message.messageOwner.entities;
}
pendingTranslation.messageTexts.add(source);
pendingTranslation.callbacks.add(callback);
pendingTranslation.language = language;
pendingTranslation.symbolsCount += messageSymbolsCount;
final PendingTranslation pendingTranslation1 = pendingTranslation;
pendingTranslation.runnable = () -> {
synchronized (TranslateController.this) {
ArrayList<PendingTranslation> dialogPendingTranslations1 = pendingTranslations.get(dialogId);
if (dialogPendingTranslations1 != null) {
dialogPendingTranslations1.remove(pendingTranslation1);
if (dialogPendingTranslations1.isEmpty()) {
pendingTranslations.remove(dialogId);
}
}
}
TLRPC.TL_messages_translateText req = new TLRPC.TL_messages_translateText();
req.flags |= 1;
req.peer = getMessagesController().getInputPeer(dialogId);
req.id = pendingTranslation1.messageIds;
req.to_lang = pendingTranslation1.language;
final int reqId = getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
final ArrayList<Integer> ids;
final ArrayList<Utilities.Callback2<TLRPC.TL_textWithEntities, String>> callbacks;
final ArrayList<TLRPC.TL_textWithEntities> texts;
synchronized (TranslateController.this) {
ids = pendingTranslation1.messageIds;
callbacks = pendingTranslation1.callbacks;
texts = pendingTranslation1.messageTexts;
}
if (res instanceof TLRPC.TL_messages_translateResult) {
ArrayList<TLRPC.TL_textWithEntities> translated = ((TLRPC.TL_messages_translateResult) res).result;
final int count = Math.min(callbacks.size(), translated.size());
for (int i = 0; i < count; ++i) {
callbacks.get(i).run(TranslateAlert2.preprocess(texts.get(i), translated.get(i)), pendingTranslation1.language);
}
} else if (err != null && "TO_LANG_INVALID".equals(err.text)) {
toggleTranslatingDialog(dialogId, false);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_ERROR, LocaleController.getString("TranslationFailedAlert2", R.string.TranslationFailedAlert2));
} else {
for (int i = 0; i < callbacks.size(); ++i) {
callbacks.get(i).run(null, pendingTranslation1.language);
}
}
synchronized (TranslateController.this) {
for (int i = 0; i < ids.size(); ++i) {
loadingTranslations.remove(ids.get(i));
}
}
}));
synchronized (TranslateController.this) {
pendingTranslation1.reqId = reqId;
}
};
AndroidUtilities.runOnUIThread(pendingTranslation.runnable, GROUPING_TRANSLATIONS_TIMEOUT);
}
}
public boolean isTranslating(MessageObject messageObject) {
synchronized (this) {
return messageObject != null && isTranslatingDialog(messageObject.getDialogId()) && loadingTranslations.contains(messageObject.getId());
}
}
public boolean isTranslating(MessageObject messageObject, MessageObject.GroupedMessages group) {
if (messageObject == null) {
return false;
}
if (!isTranslatingDialog(messageObject.getDialogId())) {
return false;
}
synchronized (this) {
if (loadingTranslations.contains(messageObject.getId())) {
return true;
}
if (group != null) {
for (MessageObject message : group.messages) {
if (loadingTranslations.contains(message.getId())) {
return true;
}
}
}
}
return false;
}
public void cancelAllTranslations() {
synchronized (this) {
for (ArrayList<PendingTranslation> translations : pendingTranslations.values()) {
if (translations != null) {
for (PendingTranslation pendingTranslation : translations) {
AndroidUtilities.cancelRunOnUIThread(pendingTranslation.runnable);
if (pendingTranslation.reqId != -1) {
getConnectionsManager().cancelRequest(pendingTranslation.reqId, true);
for (Integer messageId : pendingTranslation.messageIds) {
loadingTranslations.remove(messageId);
}
}
}
}
}
}
}
public void cancelTranslations(long dialogId) {
synchronized (this) {
ArrayList<PendingTranslation> translations = pendingTranslations.get(dialogId);
if (translations != null) {
for (PendingTranslation pendingTranslation : translations) {
AndroidUtilities.cancelRunOnUIThread(pendingTranslation.runnable);
if (pendingTranslation.reqId != -1) {
getConnectionsManager().cancelRequest(pendingTranslation.reqId, true);
for (Integer messageId : pendingTranslation.messageIds) {
loadingTranslations.remove(messageId);
}
}
}
pendingTranslations.remove((Long) dialogId);
}
}
}
private void keepReplyMessage(MessageObject messageObject) {
if (messageObject == null) {
return;
}
HashMap<Integer, MessageObject> map = keptReplyMessageObjects.get(messageObject.getDialogId());
if (map == null) {
keptReplyMessageObjects.put(messageObject.getDialogId(), map = new HashMap<>());
}
map.put(messageObject.getId(), messageObject);
}
public MessageObject findReplyMessageObject(long dialogId, int messageId) {
HashMap<Integer, MessageObject> map = keptReplyMessageObjects.get(dialogId);
if (map == null) {
return null;
}
return map.get(messageId);
}
private void clearAllKeptReplyMessages(long dialogId) {
keptReplyMessageObjects.remove(dialogId);
}
private void loadTranslatingDialogsCached() {
if (!isFeatureAvailable()) {
return;
}
String translatingDialogsCache = messagesController.getMainSettings().getString("translating_dialog_languages2", null);
if (translatingDialogsCache == null) {
return;
}
String[] dialogs = translatingDialogsCache.split(";");
HashSet<String> restricted = RestrictedLanguagesSelectActivity.getRestrictedLanguages();
for (int i = 0; i < dialogs.length; ++i) {
String[] keyval = dialogs[i].split("=");
if (keyval.length < 2) {
continue;
}
long did = Long.parseLong(keyval[0]);
String[] langs = keyval[1].split(">");
if (langs.length != 2) {
continue;
}
String from = langs[0], to = langs[1];
if ("null".equals(from)) from = null;
if ("null".equals(to)) to = null;
if (from != null) {
detectedDialogLanguage.put(did, from);
if (!restricted.contains(from)) {
translatingDialogs.add(did);
translatableDialogs.add(did);
}
if (to != null) {
translateDialogLanguage.put(did, to);
}
}
}
Set<String> hidden = messagesController.getMainSettings().getStringSet("hidden_translation_at", null);
if (hidden != null) {
Iterator<String> i = hidden.iterator();
while (i.hasNext()) {
try {
hideTranslateDialogs.add(Long.parseLong(i.next()));
} catch (Exception e) {
FileLog.e(e);
}
}
}
}
private void saveTranslatingDialogsCache() {
StringBuilder langset = new StringBuilder();
Iterator<Long> i = translatingDialogs.iterator();
boolean first = true;
while (i.hasNext()) {
try {
long did = i.next();
if (!first) {
langset.append(";");
}
if (first) {
first = false;
}
String lang = detectedDialogLanguage.get(did);
if (lang == null) {
lang = "null";
}
String tolang = getDialogTranslateTo(did);
if (tolang == null) {
tolang = "null";
}
langset.append(did).append("=").append(lang).append(">").append(tolang);
} catch (Exception e) {}
}
Set<String> hidden = new HashSet<>();
i = hideTranslateDialogs.iterator();
while (i.hasNext()) {
try {
hidden.add("" + i.next());
} catch (Exception e) {
FileLog.e(e);
}
}
MessagesController.getMainSettings(currentAccount).edit().putString("translating_dialog_languages2", langset.toString()).putStringSet("hidden_translation_at", hidden).apply();
}
private void resetTranslatingDialogsCache() {
MessagesController.getMainSettings(currentAccount).edit().remove("translating_dialog_languages2").remove("hidden_translation_at").apply();
}
}

View File

@ -12,6 +12,9 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.os.SystemClock;
import android.util.Base64;
import android.util.LongSparseArray;
import android.util.SparseArray;
import android.util.SparseLongArray;
import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLRPC;
@ -78,6 +81,10 @@ public class UserConfig extends BaseController {
public volatile byte[] savedPasswordHash;
public volatile byte[] savedSaltedPassword;
public volatile long savedPasswordTime;
LongSparseArray<SaveToGallerySettingsHelper.DialogException> userSaveGalleryExceptions;
LongSparseArray<SaveToGallerySettingsHelper.DialogException> chanelSaveGalleryExceptions;
LongSparseArray<SaveToGallerySettingsHelper.DialogException> groupsSaveGalleryExceptions;
private static volatile UserConfig[] Instance = new UserConfig[UserConfig.MAX_ACCOUNT_COUNT];
public static UserConfig getInstance(int num) {
@ -415,6 +422,48 @@ public class UserConfig extends BaseController {
}
}
public LongSparseArray<SaveToGallerySettingsHelper.DialogException> getSaveGalleryExceptions(int type) {
if (type == SharedConfig.SAVE_TO_GALLERY_FLAG_PEER) {
if (userSaveGalleryExceptions == null) {
userSaveGalleryExceptions = SaveToGallerySettingsHelper.loadExceptions(ApplicationLoader.applicationContext.getSharedPreferences(SaveToGallerySettingsHelper.USERS_PREF_NAME + "_" + currentAccount, Context.MODE_PRIVATE));
}
return userSaveGalleryExceptions;
} else if (type == SharedConfig.SAVE_TO_GALLERY_FLAG_GROUP) {
if (groupsSaveGalleryExceptions == null) {
groupsSaveGalleryExceptions = SaveToGallerySettingsHelper.loadExceptions(ApplicationLoader.applicationContext.getSharedPreferences(SaveToGallerySettingsHelper.GROUPS_PREF_NAME + "_" + currentAccount, Context.MODE_PRIVATE));
}
return groupsSaveGalleryExceptions;
} else if (type == SharedConfig.SAVE_TO_GALLERY_FLAG_CHANNELS) {
if (chanelSaveGalleryExceptions == null) {
chanelSaveGalleryExceptions = SaveToGallerySettingsHelper.loadExceptions(ApplicationLoader.applicationContext.getSharedPreferences(SaveToGallerySettingsHelper.CHANNELS_PREF_NAME + "_" + currentAccount, Context.MODE_PRIVATE));
}
return chanelSaveGalleryExceptions;
}
return null;
}
public void updateSaveGalleryExceptions(int type, LongSparseArray<SaveToGallerySettingsHelper.DialogException> exceptions) {
if (type == SharedConfig.SAVE_TO_GALLERY_FLAG_PEER) {
userSaveGalleryExceptions = exceptions;
SaveToGallerySettingsHelper.saveExceptions(
ApplicationLoader.applicationContext.getSharedPreferences(SaveToGallerySettingsHelper.USERS_PREF_NAME + "_" + currentAccount, Context.MODE_PRIVATE),
userSaveGalleryExceptions
);
} else if (type == SharedConfig.SAVE_TO_GALLERY_FLAG_GROUP) {
groupsSaveGalleryExceptions = exceptions;
SaveToGallerySettingsHelper.saveExceptions(
ApplicationLoader.applicationContext.getSharedPreferences(SaveToGallerySettingsHelper.GROUPS_PREF_NAME + "_" + currentAccount, Context.MODE_PRIVATE),
groupsSaveGalleryExceptions
);
} else if (type == SharedConfig.SAVE_TO_GALLERY_FLAG_CHANNELS) {
chanelSaveGalleryExceptions = exceptions;
SaveToGallerySettingsHelper.saveExceptions(
ApplicationLoader.applicationContext.getSharedPreferences(SaveToGallerySettingsHelper.CHANNELS_PREF_NAME + "_" + currentAccount, Context.MODE_PRIVATE),
chanelSaveGalleryExceptions
);
}
}
public void clearConfig() {
getPreferences().edit().clear().apply();
@ -516,16 +565,7 @@ public class UserConfig extends BaseController {
}
public Long getEmojiStatus() {
if (currentUser == null) {
return null;
}
if (currentUser.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
return ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).document_id;
}
if (currentUser.emoji_status instanceof TLRPC.TL_emojiStatus) {
return ((TLRPC.TL_emojiStatus) currentUser.emoji_status).document_id;
}
return null;
return UserObject.getEmojiStatusDocumentId(currentUser);
}

View File

@ -111,4 +111,26 @@ public class UserObject {
public static boolean hasFallbackPhoto(TLRPC.UserFull userInfo) {
return userInfo != null && userInfo.fallback_photo != null && !(userInfo.fallback_photo instanceof TLRPC.TL_photoEmpty);
}
public static Long getEmojiStatusDocumentId(TLRPC.User user) {
if (user == null) {
return null;
}
return getEmojiStatusDocumentId(user.emoji_status);
}
public static Long getEmojiStatusDocumentId(TLRPC.EmojiStatus emojiStatus) {
if (emojiStatus == null) {
return null;
}
if (emojiStatus instanceof TLRPC.TL_emojiStatus)
return ((TLRPC.TL_emojiStatus) emojiStatus).document_id;
if (emojiStatus instanceof TLRPC.TL_emojiStatusUntil) {
TLRPC.TL_emojiStatusUntil untilStatus = (TLRPC.TL_emojiStatusUntil) emojiStatus;
if (untilStatus.until > (int) (System.currentTimeMillis() / 1000)) {
return untilStatus.document_id;
}
}
return null;
}
}

View File

@ -510,10 +510,18 @@ public class Utilities {
public void run(T arg);
}
public static interface CallbackReturn<Arg, ReturnType> {
public ReturnType run(Arg arg);
}
public static interface Callback2<T, T2> {
public void run(T arg, T2 arg2);
}
public static interface Callback3<T, T2, T3> {
public void run(T arg, T2 arg2, T3 arg3);
}
public static <Key, Value> Value getOrDefault(HashMap<Key, Value> map, Key key, Value defaultValue) {
Value v = map.get(key);
if (v == null) {
@ -521,4 +529,34 @@ public class Utilities {
}
return v;
}
public static void doCallbacks(Utilities.Callback<Runnable> ...actions) {
doCallbacks(0, actions);
}
private static void doCallbacks(int i, Utilities.Callback<Runnable> ...actions) {
if (actions != null && actions.length > i) {
actions[i].run(() -> doCallbacks(i + 1, actions));
}
}
public static void raceCallbacks(Runnable onFinish, Utilities.Callback<Runnable> ...actions) {
if (actions == null || actions.length == 0) {
if (onFinish != null) {
onFinish.run();
}
return;
}
final int[] finished = new int[] { 0 };
Runnable checkFinish = () -> {
finished[0]++;
if (finished[0] == actions.length) {
if (onFinish != null) {
onFinish.run();
}
}
};
for (int i = 0; i < actions.length; ++i) {
actions[i].run(checkFinish);
}
}
}

View File

@ -103,6 +103,7 @@ public class VideoEditedInfo {
public int textAlign;
public int viewWidth;
public int viewHeight;
public float roundRadius;
public float scale;
public float textViewWidth;
@ -122,6 +123,7 @@ public class VideoEditedInfo {
public View view;
public Canvas canvas;
public AnimatedFileDrawable animatedFileDrawable;
public Canvas roundRadiusCanvas;
public MediaEntity() {

View File

@ -26,6 +26,7 @@ import org.telegram.messenger.BuildVars;
import org.telegram.messenger.CustomTabsCopyReceiver;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.ShareBroadcastReceiver;
@ -248,7 +249,7 @@ public class Browser {
boolean internalUri = isInternalUri(uri, forceBrowser);
if (tryTelegraph) {
try {
String host = uri.getHost().toLowerCase();
String host = AndroidUtilities.getHostAuthority(uri);
if (isTelegraphUrl(host, true) || uri.toString().toLowerCase().contains("telegram.org/faq") || uri.toString().toLowerCase().contains("telegram.org/privacy")) {
final AlertDialog[] progressDialog = new AlertDialog[] {
new AlertDialog(context, AlertDialog.ALERT_TYPE_SPINNER)
@ -307,7 +308,7 @@ public class Browser {
FileLog.e(e);
}
}
String host = uri.getHost() != null ? uri.getHost().toLowerCase() : "";
String host = AndroidUtilities.getHostAuthority(uri.toString().toLowerCase());
if (AccountInstance.getInstance(currentAccount).getMessagesController().autologinDomains.contains(host)) {
String token = "autologin_token=" + URLEncoder.encode(AccountInstance.getInstance(UserConfig.selectedAccount).getMessagesController().autologinToken, "UTF-8");
String url = uri.toString();
@ -375,6 +376,13 @@ public class Browser {
}
if (forceBrowser[0] || allActivities == null || allActivities.isEmpty()) {
if (MessagesController.getInstance(currentAccount).authDomains.contains(host)) {
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ApplicationLoader.applicationContext.startActivity(intent);
return;
}
Intent share = new Intent(ApplicationLoader.applicationContext, ShareBroadcastReceiver.class);
share.setAction(Intent.ACTION_SEND);
@ -441,9 +449,16 @@ public class Browser {
}
public static boolean isInternalUri(Uri uri, boolean all, boolean[] forceBrowser) {
String host = uri.getHost();
String host = AndroidUtilities.getHostAuthority(uri);
host = host != null ? host.toLowerCase() : "";
if (MessagesController.getInstance(UserConfig.selectedAccount).authDomains.contains(host)) {
if (forceBrowser != null) {
forceBrowser[0] = true;
}
return false;
}
Matcher prefixMatcher = LaunchActivity.PREFIX_T_ME_PATTERN.matcher(host);
if (prefixMatcher.find()) {
uri = Uri.parse("https://t.me/" + prefixMatcher.group(1) + (TextUtils.isEmpty(uri.getPath()) ? "" : "/" + uri.getPath()) + (TextUtils.isEmpty(uri.getQuery()) ? "" : "?" + uri.getQuery()));

View File

@ -42,7 +42,6 @@ public class BitmapsCache {
ArrayList<FrameOffset> frameOffsets = new ArrayList<>();
final boolean useSharedBuffers;
static ConcurrentHashMap<Thread, byte[]> sharedBuffers = new ConcurrentHashMap();
static volatile boolean cleanupScheduled;
@ -111,6 +110,9 @@ public class BitmapsCache {
fileExist = false;
file.delete();
} else {
if (cachedFile != randomAccessFile) {
closeCachedFile();
}
cachedFile = randomAccessFile;
}
}
@ -179,6 +181,9 @@ public class BitmapsCache {
if (count > 0) {
fillFrames(randomAccessFile, count);
randomAccessFile.seek(0);
if (cachedFile != randomAccessFile) {
closeCachedFile();
}
cachedFile = randomAccessFile;
fileExist = true;
return;
@ -345,6 +350,7 @@ public class BitmapsCache {
this.frameOffsets.clear();
this.frameOffsets.addAll(frameOffsets);
closeCachedFile();
cachedFile = new RandomAccessFile(file, "r");
cacheCreated = true;
fileExist = true;
@ -460,6 +466,9 @@ public class BitmapsCache {
bufferTmp = getBuffer(selectedFrame);
randomAccessFile.readFully(bufferTmp, 0, selectedFrame.frameSize);
if (!recycled) {
if (cachedFile != randomAccessFile) {
closeCachedFile();
}
cachedFile = randomAccessFile;
} else {
cachedFile = null;
@ -495,6 +504,16 @@ public class BitmapsCache {
return FRAME_RESULT_NO_FRAME;
}
private void closeCachedFile() {
if (cachedFile != null) {
try {
cachedFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private byte[] getBuffer(FrameOffset selectedFrame) {
boolean useSharedBuffers = this.useSharedBuffers && Thread.currentThread().getName().startsWith(DispatchQueuePoolBackground.THREAD_PREFIX);
byte[] bufferTmp;
@ -539,6 +558,10 @@ public class BitmapsCache {
return frameOffsets.size();
}
public boolean isCreated() {
return cacheCreated && fileExist;
}
private class FrameOffset {
final int index;
int frameSize;
@ -642,6 +665,7 @@ public class BitmapsCache {
public static class CacheOptions {
public int compressQuality = 100;
public boolean fallback = false;
public boolean firstFrame;
}
private static class CacheGeneratorSharedTools {

View File

@ -47,10 +47,10 @@ public class PhotoUtilities {
INavigationLayout layout = baseFragment.getParentLayout();
int currentAccount = baseFragment.getCurrentAccount();
ImageUpdater imageUpdater = new ImageUpdater(true);
ImageUpdater imageUpdater = new ImageUpdater(true, ImageUpdater.FOR_TYPE_USER, true);
imageUpdater.parentFragment = baseFragment;
imageUpdater.processEntry(entry);
imageUpdater.setDelegate((photo, video, videoStartTimestamp, videoPath, bigSize, smallSize, isVideo) -> AndroidUtilities.runOnUIThread(() -> {
imageUpdater.setDelegate((photo, video, videoStartTimestamp, videoPath, bigSize, smallSize, isVideo, emojiMarkup) -> AndroidUtilities.runOnUIThread(() -> {
TLRPC.TL_photos_uploadProfilePhoto req = new TLRPC.TL_photos_uploadProfilePhoto();
if (photo != null) {
req.file = photo;
@ -62,6 +62,10 @@ public class PhotoUtilities {
req.video_start_ts = videoStartTimestamp;
req.flags |= 4;
}
if (emojiMarkup != null) {
req.video_emoji_markup = emojiMarkup;
req.flags |= 16;
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_photos_photo) {
TLRPC.TL_photos_photo photos_photo = (TLRPC.TL_photos_photo) response;

View File

@ -354,7 +354,9 @@ public class MediaCodecVideoConvertor {
}
avatarStartTime = 0;
//this encoder work with bitrate better, prevent case when result video max 2MB
encoderName = "OMX.google.h264.encoder";
if (originalBitrate >= 15_000_000) {
encoderName = "OMX.google.h264.encoder";
}
} else if (bitrate <= 0) {
bitrate = 921600;
}
@ -822,7 +824,7 @@ public class MediaCodecVideoConvertor {
long timeLeft = System.currentTimeMillis() - time;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("compression completed time=" + timeLeft + " needCompress=" + needCompress + " w=" + resultWidth + " h=" + resultHeight + " bitrate=" + bitrate);
FileLog.d("compression completed time=" + timeLeft + " needCompress=" + needCompress + " w=" + resultWidth + " h=" + resultHeight + " bitrate=" + bitrate + " file size=" + cacheFile.length());
}
return error;

View File

@ -14,6 +14,10 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.graphics.Typeface;
import android.opengl.GLES11Ext;
@ -52,6 +56,7 @@ import org.telegram.ui.Components.FilterShaders;
import org.telegram.ui.Components.Paint.Views.EditTextOutline;
import org.telegram.ui.Components.Paint.Views.PaintTextOptionsView;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.Rect;
import java.io.File;
import java.io.RandomAccessFile;
@ -143,6 +148,8 @@ public class TextureRenderer {
private boolean isPhoto;
private boolean firstFrame = true;
Path path;
Paint xRefPaint;
public TextureRenderer(MediaController.SavedFilterState savedFilterState, String image, String paint, ArrayList<VideoEditedInfo.MediaEntity> entities, MediaController.CropState cropState, int w, int h, int originalWidth, int originalHeight, int rotation, float fps, boolean photo) {
isPhoto = photo;
@ -404,6 +411,7 @@ public class TextureRenderer {
VideoEditedInfo.MediaEntity entity = mediaEntities.get(a);
if (entity.ptr != 0) {
RLottieDrawable.getFrame(entity.ptr, (int) entity.currentFrame, stickerBitmap, 512, 512, stickerBitmap.getRowBytes(), true);
applyRoundRadius(entity, stickerBitmap);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0);
entity.currentFrame += entity.framesPerDraw;
@ -420,15 +428,21 @@ public class TextureRenderer {
currentFrame--;
}
Bitmap frameBitmap = entity.animatedFileDrawable.getBackgroundBitmap();
if (stickerCanvas == null && stickerBitmap != null) {
stickerCanvas = new Canvas(stickerBitmap);
}
if (stickerBitmap != null && frameBitmap != null) {
stickerBitmap.eraseColor(Color.TRANSPARENT);
stickerCanvas.drawBitmap(frameBitmap, 0, 0, null);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
if (frameBitmap != null) {
if (stickerCanvas == null && stickerBitmap != null) {
stickerCanvas = new Canvas(stickerBitmap);
if (stickerBitmap.getHeight() != frameBitmap.getHeight() || stickerBitmap.getWidth() != frameBitmap.getWidth()) {
stickerCanvas.scale(stickerBitmap.getWidth() / (float) frameBitmap.getWidth(), stickerBitmap.getHeight() / (float) frameBitmap.getHeight());
}
}
if (stickerBitmap != null) {
stickerBitmap.eraseColor(Color.TRANSPARENT);
stickerCanvas.drawBitmap(frameBitmap, 0, 0, null);
applyRoundRadius(entity, stickerBitmap);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
}
}
} else if (entity.view != null && entity.canvas != null && entity.bitmap != null) {
entity.bitmap.eraseColor(Color.TRANSPARENT);
@ -438,6 +452,7 @@ public class TextureRenderer {
EditTextEffects editTextEffects = (EditTextEffects) entity.view;
editTextEffects.incrementFrames(currentFrame - lastFrame);
entity.view.draw(entity.canvas);
applyRoundRadius(entity, entity.bitmap);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, entity.bitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
@ -453,6 +468,29 @@ public class TextureRenderer {
GLES20.glFinish();
}
private void applyRoundRadius(VideoEditedInfo.MediaEntity entity, Bitmap stickerBitmap) {
if (stickerBitmap == null || entity == null || entity.roundRadius == 0) {
return;
}
if (entity.roundRadiusCanvas == null) {
entity.roundRadiusCanvas = new Canvas(stickerBitmap);
}
if (path == null) {
path = new Path();
}
if (xRefPaint == null) {
xRefPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
xRefPaint.setColor(0xff000000);
xRefPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
float rad = Math.min(stickerBitmap.getWidth(), stickerBitmap.getHeight()) * entity.roundRadius;
path.rewind();
RectF rect = new RectF(0, 0, stickerBitmap.getWidth(), stickerBitmap.getHeight());
path.addRoundRect(rect, rad, rad, Path.Direction.CCW);
path.toggleInverseFillType();
entity.roundRadiusCanvas.drawPath(path, xRefPaint);
}
private void drawTexture(boolean bind, int texture) {
drawTexture(bind, texture, -10000, -10000, -10000, -10000, 0, false);
}

File diff suppressed because it is too large Load Diff

View File

@ -391,14 +391,6 @@ public class ActionBarMenuItem extends FrameLayout {
popupWindow.dismiss();
}
});
if (popupLayout.getSwipeBack() != null) {
popupLayout.getSwipeBack().setOnClickListener(view -> {
if (popupWindow != null) {
popupWindow.dismiss();
}
});
}
}
public void removeAllSubItems() {

View File

@ -43,14 +43,18 @@ public class ActionBarMenuSubItem extends FrameLayout {
}
public ActionBarMenuSubItem(Context context, boolean needCheck, boolean top, boolean bottom) {
this(context, needCheck, top, bottom, null);
this(context, needCheck ? 1 : 0, top, bottom, null);
}
public ActionBarMenuSubItem(Context context, boolean top, boolean bottom, Theme.ResourcesProvider resourcesProvider) {
this(context, false, top, bottom, resourcesProvider);
this(context, 0, top, bottom, resourcesProvider);
}
public ActionBarMenuSubItem(Context context, boolean needCheck, boolean top, boolean bottom, Theme.ResourcesProvider resourcesProvider) {
this(context, needCheck ? 1 : 0, top, bottom, resourcesProvider);
}
public ActionBarMenuSubItem(Context context, int needCheck, boolean top, boolean bottom, Theme.ResourcesProvider resourcesProvider) {
super(context);
this.resourcesProvider = resourcesProvider;
@ -78,12 +82,17 @@ public class ActionBarMenuSubItem extends FrameLayout {
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));
if (needCheck) {
if (needCheck > 0) {
checkView = new CheckBox2(context, 26, resourcesProvider);
checkView.setDrawUnchecked(false);
checkView.setColor(null, null, Theme.key_radioBackgroundChecked);
checkView.setDrawBackgroundAsArc(-1);
addView(checkView, LayoutHelper.createFrame(26, LayoutHelper.MATCH_PARENT, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)));
if (needCheck == 1) {
addView(checkView, LayoutHelper.createFrame(26, LayoutHelper.MATCH_PARENT, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT)));
} else {
addView(checkView, LayoutHelper.createFrame(26, LayoutHelper.MATCH_PARENT, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT)));
textView.setPadding(LocaleController.isRTL ? AndroidUtilities.dp(34) : 0, 0, LocaleController.isRTL ? 0 : AndroidUtilities.dp(34), 0);
}
}
}
@ -206,7 +215,7 @@ public class ActionBarMenuSubItem extends FrameLayout {
subtextView.setSingleLine(true);
subtextView.setGravity(Gravity.LEFT);
subtextView.setEllipsize(TextUtils.TruncateAt.END);
subtextView.setTextColor(0xff7C8286);
subtextView.setTextColor(getThemedColor(Theme.key_groupcreate_sectionText));
subtextView.setVisibility(GONE);
subtextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
subtextView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(43), 0, LocaleController.isRTL ? AndroidUtilities.dp(43) : 0, 0);

View File

@ -668,6 +668,10 @@ public class ActionBarPopupWindow extends PopupWindow {
}
private void init() {
View contentView = getContentView();
if (contentView instanceof ActionBarPopupWindowLayout && ((ActionBarPopupWindowLayout) contentView).getSwipeBack() != null) {
((ActionBarPopupWindowLayout) contentView).getSwipeBack().setOnClickListener(e -> dismiss());
}
if (superListenerField != null) {
try {
mSuperScrollListener = (ViewTreeObserver.OnScrollChangedListener) superListenerField.get(this);

View File

@ -94,7 +94,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
private BitmapDrawable[] shadow = new BitmapDrawable[2];
private boolean[] shadowVisibility = new boolean[2];
private AnimatorSet[] shadowAnimation = new AnimatorSet[2];
private int customViewOffset = 20;
private int customViewOffset = 12;
private String dialogButtonColorKey = Theme.key_dialogButton;
@ -277,7 +277,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
if (progressStyle != ALERT_TYPE_SPINNER || blurredBackground) {
shadowDrawable = context.getResources().getDrawable(R.drawable.popup_fixed_alert3).mutate();
backgroundColor = getThemedColor(Theme.key_dialogBackground);
blurOpacity = progressStyle == ALERT_TYPE_SPINNER ? 0.55f : (AndroidUtilities.computePerceivedBrightness(backgroundColor) < 0.721f ? 0.80f : 0.92f);
blurOpacity = progressStyle == ALERT_TYPE_SPINNER ? 0.55f : (AndroidUtilities.computePerceivedBrightness(backgroundColor) < 0.721f ? 0.80f : 0.97f);
shadowDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY));
shadowDrawable.getPadding(backgroundPaddings);
}
@ -380,7 +380,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
availableHeight -= topImageView.getMeasuredHeight();
}
if (topView != null) {
int w = width - AndroidUtilities.dp(16);
int w = width;
int h;
if (aspectRatio == 0) {
float scale = w / 936.0f;
@ -781,10 +781,6 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
}
if (!TextUtils.isEmpty(message)) {
messageTextView.setText(message);
if (customView != null) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) messageTextView.getLayoutParams();
params.topMargin = AndroidUtilities.dp(16);
}
messageTextView.setVisibility(View.VISIBLE);
} else {
messageTextView.setVisibility(View.GONE);

View File

@ -76,6 +76,7 @@ public class BottomSheet extends Dialog {
public boolean drawNavigationBar;
public boolean drawDoubleNavigationBar;
public boolean scrollNavBar;
protected boolean waitingKeyboard;
protected boolean useSmoothKeyboard;
@ -167,13 +168,14 @@ public class BottomSheet extends Dialog {
private OnDismissListener onHideListener;
protected Theme.ResourcesProvider resourcesProvider;
protected boolean isPortrait;
public boolean pauseAllHeavyOperations = true;
public void setDisableScroll(boolean b) {
disableScroll = b;
}
private ValueAnimator keyboardContentAnimator;
protected boolean smoothKeyboardAnimationEnabled;
public boolean smoothKeyboardAnimationEnabled;
private boolean openNoDelay;
private float hideSystemVerticalInsetsProgress;
@ -564,11 +566,18 @@ public class BottomSheet extends Dialog {
child.layout(childLeft, childTop, childLeft + width, childTop + height);
}
}
if (layoutCount == 0 && startAnimationRunnable != null) {
if (layoutCount == 0 && startAnimationRunnable != null && !waitingKeyboard) {
AndroidUtilities.cancelRunOnUIThread(startAnimationRunnable);
startAnimationRunnable.run();
startAnimationRunnable = null;
}
if (waitingKeyboard && keyboardVisible) {
if (startAnimationRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(startAnimationRunnable);
startAnimationRunnable.run();
}
waitingKeyboard = false;
}
keyboardChanged = false;
}
@ -1206,6 +1215,10 @@ public class BottomSheet extends Dialog {
if (Build.VERSION.SDK_INT >= 18) {
layoutCount = 2;
containerView.setTranslationY((Build.VERSION.SDK_INT >= 21 ? AndroidUtilities.statusBarHeight * (1f - hideSystemVerticalInsetsProgress) : 0) + containerView.getMeasuredHeight() + (scrollNavBar ? getBottomInset() : 0));
long delay = openNoDelay ? 0 : 150;
if (waitingKeyboard) {
delay = 500;
}
AndroidUtilities.runOnUIThread(startAnimationRunnable = new Runnable() {
@Override
public void run() {
@ -1215,7 +1228,7 @@ public class BottomSheet extends Dialog {
startAnimationRunnable = null;
startOpenAnimation();
}
}, openNoDelay ? 0 : 150);
}, delay);
} else {
startOpenAnimation();
}
@ -1345,7 +1358,7 @@ public class BottomSheet extends Dialog {
navigationBarAnimation
);
currentSheetAnimation.setDuration(400);
currentSheetAnimation.setStartDelay(20);
currentSheetAnimation.setStartDelay(waitingKeyboard ? 0 : 20);
currentSheetAnimation.setInterpolator(openInterpolator);
currentSheetAnimation.addListener(new AnimatorListenerAdapter() {
@Override
@ -1366,7 +1379,9 @@ public class BottomSheet extends Dialog {
getWindow().setAttributes(params);
}
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 512);
if (pauseAllHeavyOperations) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 512);
}
}
@Override
@ -1377,7 +1392,9 @@ public class BottomSheet extends Dialog {
}
}
});
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
if (pauseAllHeavyOperations) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
}
currentSheetAnimation.start();
}
}

View File

@ -95,6 +95,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
private boolean rightDrawableOutside;
private boolean ellipsizeByGradient, ellipsizeByGradientLeft;
private Boolean forceEllipsizeByGradientLeft;
private int ellipsizeByGradientWidthDp = 16;
private int paddingRight;
@ -192,15 +193,24 @@ public class SimpleTextView extends View implements Drawable.Callback {
}
public void setEllipsizeByGradient(boolean value) {
setEllipsizeByGradient(value, null);
}
public void setEllipsizeByGradient(int value) {
setEllipsizeByGradient(value, null);
}
public void setEllipsizeByGradient(boolean value, Boolean forceLeft) {
if (scrollNonFitText == value) {
return;
}
ellipsizeByGradient = value;
this.forceEllipsizeByGradientLeft = forceLeft;
updateFadePaints();
}
public void setEllipsizeByGradient(int value) {
setEllipsizeByGradient(true);
public void setEllipsizeByGradient(int value, Boolean forceLeft) {
setEllipsizeByGradient(true, forceLeft);
ellipsizeByGradientWidthDp = value;
updateFadePaints();
}
@ -219,7 +229,12 @@ public class SimpleTextView extends View implements Drawable.Callback {
fadePaintBack.setShader(new LinearGradient(0, 0, AndroidUtilities.dp(6), 0, new int[]{0, 0xffffffff}, new float[]{0f, 1f}, Shader.TileMode.CLAMP));
fadePaintBack.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
boolean ellipsizeLeft = getAlignment() == Layout.Alignment.ALIGN_NORMAL && LocaleController.isRTL || getAlignment() == Layout.Alignment.ALIGN_OPPOSITE && !LocaleController.isRTL;
boolean ellipsizeLeft;
if (forceEllipsizeByGradientLeft != null) {
ellipsizeLeft = forceEllipsizeByGradientLeft;
} else {
ellipsizeLeft = getAlignment() == Layout.Alignment.ALIGN_NORMAL && LocaleController.isRTL || getAlignment() == Layout.Alignment.ALIGN_OPPOSITE && !LocaleController.isRTL;
}
if ((fadeEllpsizePaint == null || fadeEllpsizePaintWidth != AndroidUtilities.dp(ellipsizeByGradientWidthDp) || ellipsizeByGradientLeft != ellipsizeLeft) && ellipsizeByGradient) {
if (fadeEllpsizePaint == null) {
fadeEllpsizePaint = new Paint();

View File

@ -9,6 +9,7 @@
package org.telegram.ui.ActionBar;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.dpf2;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
@ -143,6 +144,11 @@ public class Theme {
public static final int MSG_OUT_COLOR_BLACK = 0xff212121;
public static final int MSG_OUT_COLOR_WHITE = 0xffffffff;
public static final int default_shadow_color = ColorUtils.setAlphaComponent(Color.BLACK, 27);
public static void applyDefaultShadow(Paint paint) {
paint.setShadowLayer(dpf2(1), 0, dpf2(0.33f), default_shadow_color);
}
public static class BackgroundDrawableSettings {
@ -4007,6 +4013,17 @@ public class Theme {
public final static String key_statisticChartLine_cyan = "statisticChartLine_cyan";
public final static String key_statisticChartLineEmpty = "statisticChartLineEmpty";
public final static String key_color_lightblue = "color_lightblue";
public final static String key_color_blue = "color_blue";
public final static String key_color_green = "color_green";
public final static String key_color_lightgreen = "color_lightgreen";
public final static String key_color_red = "color_red";
public final static String key_color_orange = "color_orange";
public final static String key_color_yellow = "color_yellow";
public final static String key_color_purple = "color_purple";
public final static String key_color_cyan = "color_cyan";
public final static String[] keys_colors = { key_color_lightblue, key_color_blue, key_color_green, key_color_lightgreen, key_color_red, key_color_orange, key_color_yellow, key_color_purple, key_color_cyan };
public static final String key_chat_outReactionButtonBackground = "chat_outReactionButtonBackground";
public static final String key_chat_inReactionButtonBackground = "chat_inReactionButtonBackground";
public static final String key_chat_outReactionButtonText = "chat_outReactionButtonText";
@ -4848,6 +4865,16 @@ public class Theme {
defaultColors.put(key_statisticChartLineEmpty, 0xFFEEEEEE);
defaultColors.put(key_actionBarTipBackground, 0xFF446F94);
defaultColors.put(key_color_blue, 0xff327FE5);
defaultColors.put(key_color_green, 0xff61C752);
defaultColors.put(key_color_red, 0xffE05356);
defaultColors.put(key_color_yellow, 0xffEBA52D);
defaultColors.put(key_color_lightblue, 0xff58A8ED);
defaultColors.put(key_color_lightgreen, 0xff8FCF39);
defaultColors.put(key_color_orange, 0xffF28C39);
defaultColors.put(key_color_purple, 0xff9F79E8);
defaultColors.put(key_color_cyan, 0xff40D0CA);
defaultColors.put(key_voipgroup_checkMenu, 0xff6BB6F9);
defaultColors.put(key_voipgroup_muteButton, 0xff77E55C);
defaultColors.put(key_voipgroup_muteButton2, 0xff7DDCAA);
@ -5101,9 +5128,19 @@ public class Theme {
fallbackKeys.put(key_avatar_background2Blue, key_avatar_backgroundBlue);
fallbackKeys.put(key_avatar_background2Pink, key_avatar_backgroundPink);
fallbackKeys.put(key_statisticChartLine_orange, key_color_orange);
fallbackKeys.put(key_statisticChartLine_blue, key_color_blue);
fallbackKeys.put(key_statisticChartLine_red, key_color_red);
fallbackKeys.put(key_statisticChartLine_lightblue, key_color_lightblue);
fallbackKeys.put(key_statisticChartLine_golden, key_color_yellow);
fallbackKeys.put(key_statisticChartLine_purple, key_color_purple);
fallbackKeys.put(key_statisticChartLine_indigo, key_color_purple);
fallbackKeys.put(key_statisticChartLine_cyan, key_color_cyan);
themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_background));
themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_background2));
themeAccentExclusionKeys.addAll(Arrays.asList(keys_avatar_nameInMessage));
themeAccentExclusionKeys.addAll(Arrays.asList(keys_colors));
themeAccentExclusionKeys.add(key_chat_attachFileBackground);
themeAccentExclusionKeys.add(key_chat_attachGalleryBackground);
themeAccentExclusionKeys.add(key_chat_attachFileText);

View File

@ -39,6 +39,7 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
@ -48,8 +49,10 @@ import org.telegram.ui.Cells.ArchiveHintCell;
import org.telegram.ui.Cells.DialogCell;
import org.telegram.ui.Cells.DialogMeUrlCell;
import org.telegram.ui.Cells.DialogsEmptyCell;
import org.telegram.ui.Cells.DialogsRequestedEmptyCell;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.ProfileSearchCell;
import org.telegram.ui.Cells.RequestPeerRequirementsCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
@ -83,7 +86,9 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
VIEW_TYPE_NEW_CHAT_HINT = 11,
VIEW_TYPE_TEXT = 12,
VIEW_TYPE_CONTACTS_FLICKER = 13,
VIEW_TYPE_HEADER_2 = 14;
VIEW_TYPE_HEADER_2 = 14,
VIEW_TYPE_REQUIREMENTS = 15,
VIEW_TYPE_REQUIRED_EMPTY = 16;
private Context mContext;
private ArchiveHintCell archiveHintCell;
@ -119,7 +124,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
private boolean isTransitionSupport;
private boolean fromDiffUtils;
public DialogsAdapter(DialogsActivity fragment, Context context, int type, int folder, boolean onlySelect, ArrayList<Long> selected, int account) {
private TLRPC.RequestPeerType requestPeerType;
public boolean isEmpty;
public DialogsAdapter(DialogsActivity fragment, Context context, int type, int folder, boolean onlySelect, ArrayList<Long> selected, int account, TLRPC.RequestPeerType requestPeerType) {
mContext = context;
parentFragment = fragment;
dialogsType = type;
@ -136,6 +144,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
if (folder == 0) {
this.preloader = new DialogsPreloader();
}
this.requestPeerType = requestPeerType;
}
public void setRecyclerListView(RecyclerListView recyclerListView) {
@ -156,9 +165,9 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
if (showArchiveHint) {
position -= 2;
} else if (dialogsType == 11 || dialogsType == 13) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS || dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY) {
position -= 2;
} else if (dialogsType == 12) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_USERS) {
position -= 1;
}
return position;
@ -368,7 +377,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
public void updateHasHints() {
hasHints = folderId == 0 && dialogsType == 0 && !isOnlySelect && !MessagesController.getInstance(currentAccount).hintDialogs.isEmpty();
hasHints = folderId == 0 && dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT && !isOnlySelect && !MessagesController.getInstance(currentAccount).hintDialogs.isEmpty();
}
public void updateList(RecyclerListView recyclerListView, boolean hasHiddenArchive, float tabsTranslation) {
@ -451,7 +460,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
int viewType = holder.getItemViewType();
return viewType != VIEW_TYPE_FLICKER && viewType != VIEW_TYPE_EMPTY && viewType != VIEW_TYPE_DIVIDER &&
viewType != VIEW_TYPE_SHADOW && viewType != VIEW_TYPE_HEADER && viewType != VIEW_TYPE_ARCHIVE &&
viewType != VIEW_TYPE_LAST_EMPTY && viewType != VIEW_TYPE_NEW_CHAT_HINT && viewType != VIEW_TYPE_CONTACTS_FLICKER;
viewType != VIEW_TYPE_LAST_EMPTY && viewType != VIEW_TYPE_NEW_CHAT_HINT && viewType != VIEW_TYPE_CONTACTS_FLICKER &&
viewType != VIEW_TYPE_REQUIREMENTS && viewType != VIEW_TYPE_REQUIRED_EMPTY;
}
@Override
@ -459,7 +469,8 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
View view;
switch (viewType) {
case VIEW_TYPE_DIALOG:
if (dialogsType == 2) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO ||
dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
view = new ProfileSearchCell(mContext);
} else {
DialogCell dialogCell = new DialogCell(parentFragment, mContext, true, false, currentAccount, null);
@ -469,6 +480,12 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
dialogCell.setIsTransitionSupport(isTransitionSupport);
view = dialogCell;
}
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
}
break;
case VIEW_TYPE_REQUIREMENTS:
view = new RequestPeerRequirementsCell(mContext);
break;
case VIEW_TYPE_FLICKER:
case VIEW_TYPE_CONTACTS_FLICKER:
@ -524,6 +541,14 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
case VIEW_TYPE_EMPTY:
view = new DialogsEmptyCell(mContext);
break;
case VIEW_TYPE_REQUIRED_EMPTY:
view = new DialogsRequestedEmptyCell(mContext) {
@Override
protected void onButtonClick() {
onCreateGroupForThisClick();
}
};
break;
case VIEW_TYPE_USER:
view = new UserCell(mContext, 8, 0, false);
break;
@ -611,12 +636,19 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
case VIEW_TYPE_TEXT:
default: {
view = new TextCell(mContext);
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
view.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
}
}
}
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, viewType == 5 ? RecyclerView.LayoutParams.MATCH_PARENT : RecyclerView.LayoutParams.WRAP_CONTENT));
return new RecyclerListView.Holder(view);
}
public void onCreateGroupForThisClick() {
}
public int lastDialogsEmptyType = -1;
public int dialogsEmptyType() {
@ -637,10 +669,11 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
case VIEW_TYPE_DIALOG: {
TLRPC.Dialog dialog = (TLRPC.Dialog) getItem(i);
TLRPC.Dialog nextDialog = (TLRPC.Dialog) getItem(i + 1);
if (dialogsType == 2) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO || dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
ProfileSearchCell cell = (ProfileSearchCell) holder.itemView;
long oldDialogId = cell.getDialogId();
TLObject object = null;
TLRPC.Chat chat = null;
CharSequence title = null;
CharSequence subtitle;
@ -657,6 +690,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
if (chat != null) {
object = chat;
title = chat.title;
if (ChatObject.isChannel(chat) && !chat.megagroup) {
if (chat.participants_count != 0) {
@ -683,15 +717,27 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
} else {
subtitle = "";
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialog.id);
if (user != null) {
object = user;
title = UserObject.getUserName(user);
if (!UserObject.isReplyUser(user)) {
if (user.bot) {
subtitle = LocaleController.getString("Bot", R.string.Bot);
} else {
subtitle = LocaleController.formatUserStatus(currentAccount, user);
}
}
}
}
cell.useSeparator = nextDialog != null;
cell.setData(chat, null, title, subtitle, isRecent, false);
cell.setData(object, null, title, subtitle, isRecent, false);
cell.setChecked(selectedDialogs.contains(cell.getDialogId()), oldDialogId == cell.getDialogId());
} else {
DialogCell cell = (DialogCell) holder.itemView;
cell.useSeparator = nextDialog != null;
cell.fullSeparator = dialog.pinned && nextDialog != null && !nextDialog.pinned;
if (dialogsType == 0) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT) {
if (AndroidUtilities.isTablet()) {
cell.setDialogSelected(dialog.id == openedDialogId);
}
@ -734,6 +780,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
break;
}
case VIEW_TYPE_REQUIRED_EMPTY: {
((DialogsRequestedEmptyCell) holder.itemView).set(requestPeerType);
break;
}
case VIEW_TYPE_ME_URL: {
DialogMeUrlCell cell = (DialogMeUrlCell) holder.itemView;
cell.setRecentMeUrl((TLRPC.RecentMeUrl) getItem(i));
@ -747,7 +797,11 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
case VIEW_TYPE_HEADER: {
HeaderCell cell = (HeaderCell) holder.itemView;
if (dialogsType == 11 || dialogsType == 12 || dialogsType == 13) {
if (
dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS ||
dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_USERS ||
dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY
) {
if (i == 0) {
cell.setText(LocaleController.getString("ImportHeader", R.string.ImportHeader));
} else {
@ -792,11 +846,24 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
case VIEW_TYPE_TEXT: {
TextCell cell = (TextCell) holder.itemView;
cell.setColors(Theme.key_windowBackgroundWhiteBlueText4, Theme.key_windowBackgroundWhiteBlueText4);
cell.setTextAndIcon(LocaleController.getString("CreateGroupForImport", R.string.CreateGroupForImport), R.drawable.msg_groups_create, dialogsCount != 0);
if (requestPeerType != null) {
if (requestPeerType instanceof TLRPC.TL_requestPeerTypeBroadcast) {
cell.setTextAndIcon(LocaleController.getString("CreateChannelForThis", R.string.CreateChannelForThis), R.drawable.msg_channel_create, true);
} else {
cell.setTextAndIcon(LocaleController.getString("CreateGroupForThis", R.string.CreateGroupForThis), R.drawable.msg_groups_create, true);
}
} else {
cell.setTextAndIcon(LocaleController.getString("CreateGroupForImport", R.string.CreateGroupForImport), R.drawable.msg_groups_create, dialogsCount != 0);
}
cell.setIsInDialogs();
cell.setOffsetFromImage(75);
break;
}
case VIEW_TYPE_REQUIREMENTS: {
RequestPeerRequirementsCell cell = (RequestPeerRequirementsCell) holder.itemView;
cell.set(requestPeerType);
break;
}
}
if (i >= dialogsCount + 1) {
holder.itemView.setAlpha(1f);
@ -1098,6 +1165,7 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
MessagesController messagesController = MessagesController.getInstance(currentAccount);
ArrayList<TLRPC.Dialog> array = parentFragment.getDialogsArray(currentAccount, dialogsType, folderId, dialogsListFrozen);
dialogsCount = array.size();
isEmpty = false;
if (!hasHints && dialogsType == 0 && folderId == 0 && messagesController.isDialogsEndReached(folderId) && !forceUpdatingContacts) {
if (messagesController.getAllFoldersDialogsCount() <= 10 && ContactsController.getInstance(currentAccount).doneLoadingContacts && !ContactsController.getInstance(currentAccount).contacts.isEmpty()) {
@ -1121,6 +1189,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
}
if (requestPeerType != null) {
itemInternals.add(new ItemInternal(VIEW_TYPE_REQUIREMENTS));
}
boolean stopUpdate = false;
if (collapsedView || isTransitionSupport) {
for (int k = 0; k < array.size(); k++) {
@ -1134,13 +1206,15 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
}
if (dialogsCount == 0 && forceUpdatingContacts) {
itemInternals.add(new ItemInternal(VIEW_TYPE_EMPTY));
isEmpty = true;
itemInternals.add(new ItemInternal(requestPeerType == null ? VIEW_TYPE_EMPTY : VIEW_TYPE_REQUIRED_EMPTY));
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
itemInternals.add(new ItemInternal(VIEW_TYPE_CONTACTS_FLICKER));
} else if (onlineContacts != null) {
if (dialogsCount == 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_EMPTY));
isEmpty = true;
itemInternals.add(new ItemInternal(requestPeerType == null ? VIEW_TYPE_EMPTY : VIEW_TYPE_REQUIRED_EMPTY));
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
} else {
@ -1165,16 +1239,20 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
} else if (showArchiveHint) {
itemInternals.add(new ItemInternal(VIEW_TYPE_ARCHIVE));
itemInternals.add(new ItemInternal(VIEW_TYPE_SHADOW));
} else if (dialogsType == 11 || dialogsType == 13) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS || dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
itemInternals.add(new ItemInternal(VIEW_TYPE_TEXT));
} else if (dialogsType == 12) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_USERS) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER));
}
if ((requestPeerType instanceof TLRPC.TL_requestPeerTypeBroadcast || requestPeerType instanceof TLRPC.TL_requestPeerTypeChat) && dialogsCount > 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_TEXT));
}
if (!stopUpdate) {
for (int k = 0; k < array.size(); k++) {
if (dialogsType == 2 && array.get(k) instanceof DialogsActivity.DialogsHeader) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO && array.get(k) instanceof DialogsActivity.DialogsHeader) {
itemInternals.add(new ItemInternal(VIEW_TYPE_HEADER_2, array.get(k)));
} else {
itemInternals.add(new ItemInternal(VIEW_TYPE_DIALOG, array.get(k)));
@ -1185,9 +1263,10 @@ public class DialogsAdapter extends RecyclerListView.SelectionAdapter implements
if (!forceShowEmptyCell && dialogsType != 7 && dialogsType != 8 && !MessagesController.getInstance(currentAccount).isDialogsEndReached(folderId)) {
itemInternals.add(new ItemInternal(VIEW_TYPE_FLICKER));
} else if (dialogsCount == 0) {
itemInternals.add(new ItemInternal(VIEW_TYPE_EMPTY));
isEmpty = true;
itemInternals.add(new ItemInternal(requestPeerType == null ? VIEW_TYPE_EMPTY : VIEW_TYPE_REQUIRED_EMPTY));
} else {
if (folderId == 0 && dialogsCount > 10 && dialogsType == 0) {
if (folderId == 0 && dialogsCount > 10 && dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT) {
itemInternals.add(new ItemInternal(VIEW_TYPE_NEW_CHAT_HINT));
}
itemInternals.add(new ItemInternal(VIEW_TYPE_LAST_EMPTY));

View File

@ -53,6 +53,7 @@ import org.telegram.ui.Cells.TopicSearchCell;
import org.telegram.ui.Components.FlickerLoadingView;
import org.telegram.ui.Components.ForegroundColorSpanThemable;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.FilteredSearchView;
import java.util.ArrayList;
@ -109,6 +110,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private long lastShowMoreUpdate;
public View showMoreHeader;
private Runnable cancelShowMoreAnimation;
private ArrayList<Long> filterDialogIds;
private int currentAccount = UserConfig.selectedAccount;
@ -124,6 +126,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private int folderId;
private ArrayList<ContactEntry> allContacts;
public void setFilterDialogIds(ArrayList<Long> filterDialogIds) {
this.filterDialogIds = filterDialogIds;
}
public boolean isSearching() {
return waitingResponseCount > 0;
}
@ -312,6 +318,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return;
}
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
return;
}
final long dialogId = delegate.getSearchForumDialogId();
final TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
@ -432,6 +442,15 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchAdapterHelper.mergeResults(searchResult, filtered2RecentSearchObjects);
}
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
waitingResponseCount--;
if (delegate != null) {
delegate.searchStateChanged(waitingResponseCount > 0, true);
delegate.runResultsEnterAnimation();
}
return;
}
final TLRPC.TL_messages_searchGlobal req = new TLRPC.TL_messages_searchGlobal();
req.limit = 20;
req.q = query;
@ -547,7 +566,14 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
private boolean resentSearchAvailable() {
return dialogsType != 2 && dialogsType != 4 && dialogsType != 5 && dialogsType != 6 && dialogsType != 11;
return (
dialogsType != DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO &&
dialogsType != DialogsActivity.DIALOGS_TYPE_USERS_ONLY &&
dialogsType != DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY &&
dialogsType != DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY &&
dialogsType != DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS &&
dialogsType != DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER
);
}
public boolean isSearchWas() {
@ -559,6 +585,9 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
}
public void loadRecentSearch() {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
return;
}
loadRecentSearch(currentAccount, dialogsType, (arrayList, hashMap) -> {
DialogsSearchAdapter.this.setRecentSearch(arrayList, hashMap);
});
@ -581,7 +610,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
boolean add = false;
if (DialogObject.isEncryptedDialog(did)) {
if (dialogsType == 0 || dialogsType == 3) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT || dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD) {
int encryptedChatId = DialogObject.getEncryptedChatId(did);
if (!encryptedToLoad.contains(encryptedChatId)) {
encryptedToLoad.add(encryptedChatId);
@ -792,7 +821,8 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
ArrayList<CharSequence> resultArrayNames = new ArrayList<>();
ArrayList<TLRPC.User> encUsers = new ArrayList<>();
ArrayList<ContactsController.Contact> contacts = new ArrayList<>();
MessagesStorage.getInstance(currentAccount).localSearch(dialogsType, q, resultArray, resultArrayNames, encUsers, -1);
MessagesStorage.getInstance(currentAccount).localSearch(dialogsType, q, resultArray, resultArrayNames, encUsers, filterDialogIds, -1);
// if (allContacts == null) {
// allContacts = new ArrayList<>();
// for (ContactsController.Contact contact : ContactsController.getInstance(currentAccount).phoneBookContacts) {
@ -947,7 +977,21 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
searchResultNames.clear();
searchResultHashtags.clear();
searchAdapterHelper.mergeResults(null, null);
searchAdapterHelper.queryServerSearch(null, true, true, dialogsType != 11, dialogsType != 11, dialogsType == 2 || dialogsType == 11, 0, dialogsType == 0, 0, 0, delegate != null ? delegate.getSearchForumDialogId() : 0);
if (dialogsType != DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
searchAdapterHelper.queryServerSearch(
null,
true,
true,
dialogsType != DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS,
dialogsType != DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS,
dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO || dialogsType == DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS,
0,
dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT,
0,
0,
delegate != null ? delegate.getSearchForumDialogId() : 0
);
}
searchWas = false;
lastSearchId = 0;
waitingResponseCount = 0;
@ -956,9 +1000,11 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (delegate != null) {
delegate.searchStateChanged(false, true);
}
searchTopics(null);
searchMessagesInternal(null, 0);
searchForumMessagesInternal(null, 0);
if (dialogsType != DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
searchTopics(null);
searchMessagesInternal(null, 0);
searchForumMessagesInternal(null, 0);
}
notifyDataSetChanged();
localTipDates.clear();
localTipArchive = false;
@ -1000,17 +1046,33 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
Utilities.searchQueue.postRunnable(searchRunnable = () -> {
searchRunnable = null;
searchDialogsInternal(query, searchId);
if (dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
waitingResponseCount -= 2;
return;
}
AndroidUtilities.runOnUIThread(searchRunnable2 = () -> {
searchRunnable2 = null;
if (searchId != lastSearchId) {
return;
}
if (needMessagesSearch != 2) {
searchAdapterHelper.queryServerSearch(query, true, dialogsType != 4, true, dialogsType != 4 && dialogsType != 11, dialogsType == 2 || dialogsType == 1, 0, dialogsType == 0, 0, searchId, delegate != null ? delegate.getSearchForumDialogId() : 0);
if (needMessagesSearch != 2 && dialogsType != DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY && dialogsType != DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY) {
searchAdapterHelper.queryServerSearch(
query,
true,
dialogsType != DialogsActivity.DIALOGS_TYPE_USERS_ONLY,
true,
dialogsType != DialogsActivity.DIALOGS_TYPE_USERS_ONLY && dialogsType != DialogsActivity.DIALOGS_TYPE_IMPORT_HISTORY_GROUPS,
dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO || dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_SHARE,
0,
dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT,
0,
searchId,
delegate != null ? delegate.getSearchForumDialogId() : 0
);
} else {
waitingResponseCount -= 2;
}
if (needMessagesSearch == 0) {
if (needMessagesSearch == 0 || dialogsType == DialogsActivity.DIALOGS_TYPE_BOT_REQUEST_PEER) {
waitingResponseCount--;
} else {
searchTopics(text);

View File

@ -167,7 +167,7 @@ import org.telegram.ui.Components.TextPaintMarkSpan;
import org.telegram.ui.Components.TextPaintSpan;
import org.telegram.ui.Components.TextPaintUrlSpan;
import org.telegram.ui.Components.TextPaintWebpageUrlSpan;
import org.telegram.ui.Components.TranslateAlert;
import org.telegram.ui.Components.TranslateAlert2;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.WebPlayerView;
@ -1211,7 +1211,14 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}
BottomSheet.Builder builder = new BottomSheet.Builder(parentActivity);
builder.setTitle(urlFinal);
String formattedUrl = urlFinal;
try {
formattedUrl = URLDecoder.decode(urlFinal.replaceAll("\\+", "%2b"), "UTF-8");
} catch (Exception e) {
FileLog.e(e);
}
builder.setTitle(formattedUrl);
builder.setTitleMultipleLines(true);
builder.setItems(new CharSequence[]{LocaleController.getString("Open", R.string.Open), LocaleController.getString("Copy", R.string.Copy)}, (dialog, which) -> {
if (parentActivity == null) {
return;
@ -2648,22 +2655,24 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
pressedEnd = end;
}
}
if (pressedLink != null) {
links.removeLink(pressedLink);
}
pressedLink = new LinkSpanDrawable<TextPaintUrlSpan>(selectedLink, null, x, y);
pressedLink.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection) & 0x33ffffff);
links.addLink(pressedLink, pressedLinkOwnerLayout);
try {
LinkPath path = pressedLink.obtainNewPath();
path.setCurrentLayout(layout, pressedStart, 0);
TextPaint textPaint = selectedLink.getTextPaint();
int shift = textPaint != null ? textPaint.baselineShift : 0;
path.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
layout.getSelectionPath(pressedStart, pressedEnd, path);
parentView.invalidate();
} catch (Exception e) {
FileLog.e(e);
if (pressedLink == null || pressedLink.getSpan() != selectedLink) {
if (pressedLink != null) {
links.removeLink(pressedLink);
}
pressedLink = new LinkSpanDrawable(selectedLink, null, x, y);
pressedLink.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteLinkSelection) & 0x33ffffff);
links.addLink(pressedLink, pressedLinkOwnerLayout);
try {
LinkPath path = pressedLink.obtainNewPath();
path.setCurrentLayout(layout, pressedStart, 0);
TextPaint textPaint = selectedLink.getTextPaint();
int shift = textPaint != null ? textPaint.baselineShift : 0;
path.setBaselineShift(shift != 0 ? shift + AndroidUtilities.dp(shift > 0 ? 5 : -2) : 0);
layout.getSelectionPath(pressedStart, pressedEnd, path);
parentView.invalidate();
} catch (Exception e) {
FileLog.e(e);
}
}
}
}
@ -3671,10 +3680,8 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
boolean isLightNavigation = navigationBrightness >= 0.721f;
if (isLightNavigation && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
uiFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
navigationBarPaint.setColor(navigationColor);
} else if (!isLightNavigation) {
navigationBarPaint.setColor(navigationColor);
}
navigationBarPaint.setColor(navigationColor);
windowLayoutParams.systemUiVisibility = uiFlags;
if (Build.VERSION.SDK_INT >= 21) {
@ -3688,9 +3695,9 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
textSelectionHelper = new TextSelectionHelper.ArticleTextSelectionHelper();
textSelectionHelper.setParentView(listView[0]);
if (MessagesController.getGlobalMainSettings().getBoolean("translate_button", false)) {
if (MessagesController.getInstance(currentAccount).getTranslateController().isContextTranslateEnabled()) {
textSelectionHelper.setOnTranslate((text, fromLang, toLang, onAlertDismiss) -> {
TranslateAlert.showAlert(parentActivity, parentFragment, currentAccount, fromLang, toLang, text, false, null, onAlertDismiss);
TranslateAlert2.showAlert(parentActivity, parentFragment, currentAccount, fromLang, toLang, text, null, false, null, onAlertDismiss);
});
}
textSelectionHelper.layoutManager = layoutManager[0];

View File

@ -122,7 +122,7 @@ public class BubbleActivity extends BasePermissionsActivity implements INavigati
passcodeView.onShow(true, false);
SharedConfig.isWaitingForPasscodeEnter = true;
drawerLayoutContainer.setAllowOpenDrawer(false, false);
passcodeView.setDelegate(() -> {
passcodeView.setDelegate(view -> {
SharedConfig.isWaitingForPasscodeEnter = false;
if (passcodeSaveIntent != null) {
handleIntent(passcodeSaveIntent, passcodeSaveIntentIsNew, passcodeSaveIntentIsRestore, true, passcodeSaveIntentAccount, passcodeSaveIntentState);
@ -130,6 +130,8 @@ public class BubbleActivity extends BasePermissionsActivity implements INavigati
}
drawerLayoutContainer.setAllowOpenDrawer(true, false);
actionBarLayout.showLastFragment();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.passcodeDismissed, view);
});
}

View File

@ -81,11 +81,11 @@ public class CacheChatsExceptionsFragment extends BaseFragment {
args.putBoolean("onlySelect", true);
args.putBoolean("checkCanWrite", false);
if (currentType == CacheControlActivity.KEEP_MEDIA_TYPE_GROUP) {
args.putInt("dialogsType", 6);
args.putInt("dialogsType", DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY);
} else if (currentType == CacheControlActivity.KEEP_MEDIA_TYPE_CHANNEL) {
args.putInt("dialogsType", 5);
args.putInt("dialogsType", DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY);
} else {
args.putInt("dialogsType", 4);
args.putInt("dialogsType", DialogsActivity.DIALOGS_TYPE_USERS_ONLY);
}
args.putBoolean("allowGlobalSearch", false);
DialogsActivity activity = new DialogsActivity(args);
@ -123,6 +123,7 @@ public class CacheChatsExceptionsFragment extends BaseFragment {
int finalP = p;
showPopupFor(newException);
}
return true;
});
presentFragment(activity);
} else if (items.get(position).viewType == VIEW_TYPE_CHAT) {

View File

@ -170,7 +170,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
private CacheChartHeader cacheChartHeader;
private ClearCacheButtonInternal clearCacheButton;
private volatile boolean canceled = false;
public static volatile boolean canceled = false;
private View bottomSheetView;
private BottomSheet bottomSheet;
@ -208,9 +208,105 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
}
private static long lastTotalSizeCalculatedTime;
private static Long lastTotalSizeCalculated;
private static Long lastDeviceTotalSize, lastDeviceTotalFreeSize;
public static void calculateTotalSize(Utilities.Callback<Long> onDone) {
if (onDone == null) {
return;
}
if (lastTotalSizeCalculated != null) {
onDone.run(lastTotalSizeCalculated);
if (System.currentTimeMillis() - lastTotalSizeCalculatedTime < 5000) {
return;
}
}
Utilities.globalQueue.postRunnable(() -> {
canceled = false;
long cacheSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), 5);
long cacheTempSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), 4);
long photoSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_IMAGE), 0);
photoSize += getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_IMAGE_PUBLIC), 0);
long videoSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_VIDEO), 0);
videoSize += getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_VIDEO_PUBLIC), 0);
long documentsSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_DOCUMENT), 1);
documentsSize += getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_FILES), 1);
long musicSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_DOCUMENT), 2);
musicSize += getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_FILES), 2);
long stickersCacheSize = getDirectorySize(new File(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), "acache"), 0);
stickersCacheSize += getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_CACHE), 3);
long audioSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_AUDIO), 0);
final long totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize;
lastTotalSizeCalculatedTime = System.currentTimeMillis();
if (!canceled) {
AndroidUtilities.runOnUIThread(() -> {
onDone.run(totalSize);
});
}
});
}
public static void getDeviceTotalSize(Utilities.Callback2<Long, Long> onDone) {
if (lastDeviceTotalSize != null && lastDeviceTotalFreeSize != null) {
if (onDone != null) {
onDone.run(lastDeviceTotalSize, lastDeviceTotalFreeSize);
}
return;
}
File path;
if (Build.VERSION.SDK_INT >= 19) {
ArrayList<File> storageDirs = AndroidUtilities.getRootDirs();
String dir = (path = storageDirs.get(0)).getAbsolutePath();
if (!TextUtils.isEmpty(SharedConfig.storageCacheDir)) {
for (int a = 0, N = storageDirs.size(); a < N; a++) {
File file = storageDirs.get(a);
if (file.getAbsolutePath().startsWith(SharedConfig.storageCacheDir)) {
path = file;
break;
}
}
}
} else {
path = new File(SharedConfig.storageCacheDir);
}
try {
StatFs stat = new StatFs(path.getPath());
long blockSize;
long blockSizeExternal;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
blockSize = stat.getBlockSizeLong();
} else {
blockSize = stat.getBlockSize();
}
long availableBlocks;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
availableBlocks = stat.getAvailableBlocksLong();
} else {
availableBlocks = stat.getAvailableBlocks();
}
long blocksTotal;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
blocksTotal = stat.getBlockCountLong();
} else {
blocksTotal = stat.getBlockCount();
}
lastDeviceTotalSize = blocksTotal * blockSize;
lastDeviceTotalFreeSize = availableBlocks * blockSize;
if (onDone != null) {
onDone.run(lastDeviceTotalSize, lastDeviceTotalFreeSize);
}
return;
} catch (Exception e) {
FileLog.e(e);
}
}
@Override
public boolean onFragmentCreate() {
super.onFragmentCreate();
canceled = false;
getNotificationCenter().addObserver(this, NotificationCenter.didClearDatabase);
databaseSize = MessagesStorage.getInstance(currentAccount).getDatabaseSize();
loadingDialogs = true;
@ -256,7 +352,11 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
stickersCacheSize += cacheEmojiSize;
audioSize = getDirectorySize(FileLoader.checkDirectory(FileLoader.MEDIA_DIR_AUDIO), 0);
totalSize = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize;
if (canceled) {
return;
}
totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize;
lastTotalSizeCalculatedTime = System.currentTimeMillis();
File path;
if (Build.VERSION.SDK_INT >= 19) {
@ -302,14 +402,13 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
FileLog.e(e);
}
long minDuration = System.currentTimeMillis() - fragmentCreateTime > 45 ? 600 : 0;
AndroidUtilities.runOnUIThread(() -> {
resumeDelayedFragmentAnimation();
calculating = false;
updateRows(true);
updateChart();
}, Math.max(1, minDuration - (System.currentTimeMillis() - fragmentCreateTime)));
});
loadDialogEntities();
});
@ -339,11 +438,11 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
if (System.currentTimeMillis() - fragmentCreateTime < 80) {
cacheChart.loadingFloat.set(0, true);
}
cacheChart.setSegments(totalSize, segments);
cacheChart.setSegments(totalSize, true, segments);
} else if (calculating) {
cacheChart.setSegments(-1);
cacheChart.setSegments(-1, true);
} else {
cacheChart.setSegments(0);
cacheChart.setSegments(0, true);
}
}
if (clearCacheButton != null && !calculating) {
@ -530,14 +629,14 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
private String formatPercent(float k, boolean minimize) {
float p = Math.round(k * 100f);
if (minimize && p < 0.1f) {
if (minimize && k < 0.001f) {
return String.format("<%.1f%%", 0.1f);
}
if (p % 1 == 0) {
return ((int) p) + "%";
final float p = Math.round(k * 100f);
if (minimize && p <= 0) {
return String.format("<%d%%", 1);
}
return String.format("%.1f%%", p);
return String.format("%d%%", (int) p);
}
private CharSequence getCheckBoxTitle(CharSequence header, int percent) {
@ -545,7 +644,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
private CharSequence getCheckBoxTitle(CharSequence header, int percent, boolean addArrow) {
String percentString = percent <= 0 ? String.format("<%.1f%%", 0.1f) : String.format("%d%%", percent);
String percentString = percent <= 0 ? String.format("<%.1f%%", 1f) : String.format("%d%%", percent);
SpannableString percentStr = new SpannableString(percentString);
percentStr.setSpan(new RelativeSizeSpan(.834f), 0, percentStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
percentStr.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, percentStr.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -700,7 +799,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
canceled = true;
}
private long getDirectorySize(File dir, int documentsMusicType) {
private static long getDirectorySize(File dir, int documentsMusicType) {
if (dir == null || canceled) {
return 0;
}
@ -841,7 +940,8 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
}
final boolean imagesClearedFinal = imagesCleared;
totalSize = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize;
totalSize = lastTotalSizeCalculated = cacheSize + cacheTempSize + videoSize + audioSize + photoSize + documentsSize + musicSize + stickersCacheSize;
lastTotalSizeCalculatedTime = System.currentTimeMillis();
Arrays.fill(selected, true);
File path = Environment.getDataDirectory();
@ -888,8 +988,10 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
getMediaDataController().ringtoneDataStore.checkRingtoneSoundsLoaded();
cacheRemovedTooltip.setInfoText(LocaleController.formatString("CacheWasCleared", R.string.CacheWasCleared, AndroidUtilities.formatFileSize(finalClearedSize)));
cacheRemovedTooltip.showWithAction(0, UndoView.ACTION_CACHE_WAS_CLEARED, null, null);
AndroidUtilities.runOnUIThread(() -> {
cacheRemovedTooltip.setInfoText(LocaleController.formatString("CacheWasCleared", R.string.CacheWasCleared, AndroidUtilities.formatFileSize(finalClearedSize)));
cacheRemovedTooltip.showWithAction(0, UndoView.ACTION_CACHE_WAS_CLEARED, null, null);
}, 150);
MediaDataController.getInstance(currentAccount).chekAllMedia(true);
loadDialogEntities();
@ -1436,7 +1538,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
LocaleController.getString("StorageCleared", R.string.StorageCleared)
);
if (hasCache) {
if (percent < 0.1f) {
if (percent < 0.01f) {
subtitle[1].setText(LocaleController.formatString("StorageUsageTelegramLess", R.string.StorageUsageTelegramLess, formatPercent(percent)));
} else {
subtitle[1].setText(LocaleController.formatString("StorageUsageTelegram", R.string.StorageUsageTelegram, formatPercent(percent)));
@ -1640,7 +1742,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
@Override
protected void dispatchDraw(Canvas canvas) {
final int margin = AndroidUtilities.dp(8);
int x = (getMeasuredWidth() - margin - valueTextView.getCurrentWidth() + textView.getCurrentWidth()) / 2;
int x = (getMeasuredWidth() - margin - (int) valueTextView.getCurrentWidth() + (int) textView.getCurrentWidth()) / 2;
if (LocaleController.isRTL) {
super.dispatchDraw(canvas);
@ -2140,14 +2242,11 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
}
String value = CacheByChatsController.getKeepMediaString(cacheByChatsController.getKeepMedia(keepMediaType));
if (itemInners.get(position).keepMediaType == KEEP_MEDIA_TYPE_USER) {
textCell2.setTextAndValue(LocaleController.getString("PrivateChats", R.string.PrivateChats), value, true, true);
textCell2.setColorfulIcon(getThemedColor(Theme.key_statisticChartLine_lightblue), R.drawable.msg_filled_menu_users);
textCell2.setTextAndValueAndColorfulIcon(LocaleController.getString("PrivateChats", R.string.PrivateChats), value, true, R.drawable.msg_filled_menu_users, getThemedColor(Theme.key_statisticChartLine_lightblue), true);
} else if (itemInners.get(position).keepMediaType == KEEP_MEDIA_TYPE_GROUP) {
textCell2.setTextAndValue(LocaleController.getString("GroupChats", R.string.GroupChats), value, true, true);
textCell2.setColorfulIcon(getThemedColor(Theme.key_statisticChartLine_green), R.drawable.msg_filled_menu_groups);
textCell2.setTextAndValueAndColorfulIcon(LocaleController.getString("GroupChats", R.string.GroupChats), value, true, R.drawable.msg_filled_menu_groups, getThemedColor(Theme.key_statisticChartLine_green), true);
} else if (itemInners.get(position).keepMediaType == KEEP_MEDIA_TYPE_CHANNEL) {
textCell2.setTextAndValue(LocaleController.getString("CacheChannels", R.string.CacheChannels), value, true, false);
textCell2.setColorfulIcon(getThemedColor(Theme.key_statisticChartLine_golden), R.drawable.msg_filled_menu_channels);
textCell2.setTextAndValueAndColorfulIcon(LocaleController.getString("CacheChannels", R.string.CacheChannels), value, true, R.drawable.msg_filled_menu_channels, getThemedColor(Theme.key_statisticChartLine_golden), true);
}
textCell2.setSubtitle(subtitle);
break;

View File

@ -100,7 +100,7 @@ public class CachedMediaLayout extends FrameLayout implements NestedSizeNotifier
int CacheTabChats;
allPages[PAGE_TYPE_CHATS] = new Page(LocaleController.getString("Chats", R.string.Chats), PAGE_TYPE_CHATS, new DialogsAdapter());
allPages[PAGE_TYPE_MEDIA] = new Page(LocaleController.getString("Media", R.string.Media), PAGE_TYPE_MEDIA, new MediaAdapter());
allPages[PAGE_TYPE_MEDIA] = new Page(LocaleController.getString("MediaTab", R.string.MediaTab), PAGE_TYPE_MEDIA, new MediaAdapter());
allPages[PAGE_TYPE_DOCUMENTS] = new Page(LocaleController.getString("Files", R.string.Files), PAGE_TYPE_DOCUMENTS, new DocumentsAdapter());
allPages[PAGE_TYPE_MUSIC] = new Page(LocaleController.getString("Music", R.string.Music), PAGE_TYPE_MUSIC, new MusicAdapter());
// allPages[PAGE_TYPE_VOICE] = new Page(LocaleController.getString("Voice", R.string.Voice), PAGE_TYPE_VOICE, new VoiceAdapter());
@ -750,7 +750,7 @@ public class CachedMediaLayout extends FrameLayout implements NestedSizeNotifier
holder.itemView.setTag(file);
long date = file.file.lastModified();
cell.setTextAndValueAndTypeAndThumb(file.messageType == MessageObject.TYPE_ROUND_VIDEO ? LocaleController.getString("AttachRound", R.string.AttachRound) : file.file.getName(), LocaleController.formatDateAudio(date, true), Utilities.getExtension(file.file.getName()), null, 0, divider);
cell.setTextAndValueAndTypeAndThumb(file.messageType == MessageObject.TYPE_ROUND_VIDEO ? LocaleController.getString("AttachRound", R.string.AttachRound) : file.file.getName(), LocaleController.formatDateAudio(date / 1000, true), Utilities.getExtension(file.file.getName()), null, 0, divider);
if (!animated) {
cell.setPhoto(file.file.getPath());
}
@ -992,7 +992,7 @@ public class CachedMediaLayout extends FrameLayout implements NestedSizeNotifier
super(context);
checkBox = new CheckBox2(context, 21);
checkBox.setDrawBackgroundAsArc(14);
checkBox.setColor(Theme.key_radioBackground, Theme.key_radioBackground, Theme.key_checkboxCheck);
checkBox.setColor(Theme.key_checkbox, Theme.key_radioBackground, Theme.key_checkboxCheck);
addView(checkBox, LayoutHelper.createFrame(24, 24, Gravity.LEFT | Gravity.CENTER_VERTICAL, 18, 0, 0, 0));
View checkBoxClickableView = new View(getContext());
checkBoxClickableView.setOnClickListener(v -> {

View File

@ -9,6 +9,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -59,6 +60,7 @@ import org.telegram.ui.Components.HintView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.SharedMediaLayout;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import java.time.YearMonth;
import java.util.ArrayList;
@ -122,6 +124,9 @@ public class CalendarActivity extends BaseFragment {
private int calendarType;
private Path path = new Path();
private SpoilerEffect mediaSpoilerEffect = new SpoilerEffect();
public CalendarActivity(Bundle args, int photosVideosTypeFilter, int selectedDate) {
super(args);
this.photosVideosTypeFilter = photosVideosTypeFilter;
@ -923,6 +928,7 @@ public class CalendarActivity extends BaseFragment {
PeriodDay periodDay = messagesByDays.get(key);
MessageObject messageObject = periodDay.messageObject;
if (messageObject != null) {
boolean hasMediaSpoilers = messageObject.hasMediaSpoilers();
if (messageObject.isVideo()) {
TLRPC.Document document = messageObject.getDocument();
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 50);
@ -932,9 +938,9 @@ public class CalendarActivity extends BaseFragment {
}
if (thumb != null) {
if (messageObject.strippedThumb != null) {
receiver.setImage(ImageLocation.getForDocument(qualityThumb, document), "44_44", messageObject.strippedThumb, null, messageObject, 0);
receiver.setImage(ImageLocation.getForDocument(qualityThumb, document), hasMediaSpoilers ? "5_5_b" : "44_44", messageObject.strippedThumb, null, messageObject, 0);
} else {
receiver.setImage(ImageLocation.getForDocument(qualityThumb, document), "44_44", ImageLocation.getForDocument(thumb, document), "b", (String) null, messageObject, 0);
receiver.setImage(ImageLocation.getForDocument(qualityThumb, document), hasMediaSpoilers ? "5_5_b" : "44_44", ImageLocation.getForDocument(thumb, document), "b", (String) null, messageObject, 0);
}
}
} else if (messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaPhoto && messageObject.messageOwner.media.photo != null && !messageObject.photoThumbs.isEmpty()) {
@ -945,9 +951,9 @@ public class CalendarActivity extends BaseFragment {
currentPhotoObjectThumb = null;
}
if (messageObject.strippedThumb != null) {
receiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "44_44", null, null, messageObject.strippedThumb, currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
receiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), hasMediaSpoilers ? "5_5_b" : "44_44", null, null, messageObject.strippedThumb, currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
} else {
receiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), "44_44", ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), "b", currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
receiver.setImage(ImageLocation.getForObject(currentPhotoObject, messageObject.photoThumbsObject), hasMediaSpoilers ? "5_5_b" : "44_44", ImageLocation.getForObject(currentPhotoObjectThumb, messageObject.photoThumbsObject), "b", currentPhotoObject != null ? currentPhotoObject.size : 0, null, messageObject, messageObject.shouldEncryptPhotoOrVideo() ? 2 : 1);
}
} else {
if (messageObject.strippedThumb != null) {
@ -1060,6 +1066,24 @@ public class CalendarActivity extends BaseFragment {
imagesByDays.get(i).setImageCoords(cx - (AndroidUtilities.dp(44) - pad) / 2f, cy - (AndroidUtilities.dp(44) - pad) / 2f, AndroidUtilities.dp(44) - pad, AndroidUtilities.dp(44) - pad);
imagesByDays.get(i).draw(canvas);
if (messagesByDays.get(i) != null && messagesByDays.get(i).messageObject != null && messagesByDays.get(i).messageObject.hasMediaSpoilers()) {
float rad = (AndroidUtilities.dp(44) - pad) / 2f;
path.rewind();
path.addCircle(cx, cy, rad, Path.Direction.CW);
canvas.save();
canvas.clipPath(path);
int sColor = Color.WHITE;
mediaSpoilerEffect.setColor(ColorUtils.setAlphaComponent(sColor, (int) (Color.alpha(sColor) * 0.325f * day.enterAlpha)));
mediaSpoilerEffect.setBounds((int) (cx - rad), (int) (cy - rad), (int) (cx + rad), (int) (cy + rad));
mediaSpoilerEffect.draw(canvas);
invalidate();
canvas.restore();
}
blackoutPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (day.enterAlpha * 80)));
canvas.drawCircle(cx, cy, (AndroidUtilities.dp(44) - pad) / 2f, blackoutPaint);
day.wasDrawn = true;

View File

@ -502,9 +502,11 @@ public class AboutLinkCell extends FrameLayout {
@Override
public void end(boolean replacing) {
if (thisLoading != null) {
links.removeLoading(thisLoading, true);
}
AndroidUtilities.runOnUIThread(() -> {
if (thisLoading != null) {
links.removeLoading(thisLoading, true);
}
}, replacing ? 0 : 350);
}
} : null;
if (pressedLink instanceof URLSpanNoUnderline) {

View File

@ -12,6 +12,7 @@ import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
@ -24,6 +25,8 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader;
@ -40,6 +43,7 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.LinkSpanDrawable;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanNoUnderline;
@ -58,8 +62,8 @@ public class BotHelpCell extends View {
private int textY;
public boolean wasDraw;
private ClickableSpan pressedLink;
private LinkPath urlPath = new LinkPath();
private LinkSpanDrawable<ClickableSpan> pressedLink;
private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this);
private BotHelpCellDelegate delegate;
private Theme.ResourcesProvider resourcesProvider;
@ -84,6 +88,9 @@ public class BotHelpCell extends View {
imageReceiver.setInvalidateAll(true);
imageReceiver.setCrossfadeWithOldImage(true);
imageReceiver.setCrossfadeDuration(300);
selectorDrawable = Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), selectorDrawableRadius = SharedConfig.bubbleRadius, SharedConfig.bubbleRadius);
selectorDrawable.setCallback(this);
}
public void setDelegate(BotHelpCellDelegate botHelpCellDelegate) {
@ -94,6 +101,7 @@ public class BotHelpCell extends View {
if (pressedLink != null) {
pressedLink = null;
}
links.clear();
invalidate();
}
@ -195,6 +203,13 @@ public class BotHelpCell extends View {
}
}
public CharSequence getText() {
if (textLayout == null) {
return null;
}
return textLayout.getText();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
@ -217,15 +232,18 @@ public class BotHelpCell extends View {
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0) {
resetPressedLink();
pressedLink = link[0];
pressedLink = new LinkSpanDrawable<ClickableSpan>(link[0], resourcesProvider, x2, y2);
result = true;
try {
int start = buffer.getSpanStart(pressedLink);
urlPath.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(pressedLink), urlPath);
int start = buffer.getSpanStart(link[0]);
LinkPath path = pressedLink.obtainNewPath();
path.setCurrentLayout(textLayout, start, 0);
textLayout.getSelectionPath(start, buffer.getSpanEnd(link[0]), path);
} catch (Exception e) {
FileLog.e(e);
}
links.addLink(pressedLink);
invalidate();
} else {
resetPressedLink();
}
@ -238,21 +256,20 @@ public class BotHelpCell extends View {
}
} else if (pressedLink != null) {
try {
if (pressedLink instanceof URLSpanNoUnderline) {
String url = ((URLSpanNoUnderline) pressedLink).getURL();
ClickableSpan span = pressedLink.getSpan();
if (span instanceof URLSpanNoUnderline) {
String url = ((URLSpanNoUnderline) span).getURL();
if (url.startsWith("@") || url.startsWith("#") || url.startsWith("/")) {
if (delegate != null) {
delegate.didPressUrl(url);
}
}
} else {
if (pressedLink instanceof URLSpan) {
if (delegate != null) {
delegate.didPressUrl(((URLSpan) pressedLink).getURL());
}
} else {
pressedLink.onClick(this);
} else if (span instanceof URLSpan) {
if (delegate != null) {
delegate.didPressUrl(((URLSpan) span).getURL());
}
} else if (span != null) {
span.onClick(this);
}
} catch (Exception e) {
FileLog.e(e);
@ -264,6 +281,23 @@ public class BotHelpCell extends View {
resetPressedLink();
}
}
if (selectorDrawable != null) {
if (!result && y > 0 && event.getAction() == MotionEvent.ACTION_DOWN && isClickable()) {
selectorDrawable.setState(new int[]{android.R.attr.state_pressed, android.R.attr.state_enabled});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
selectorDrawable.setHotspot(event.getX(), event.getY());
}
invalidate();
result = true;
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
selectorDrawable.setState(new int[]{});
invalidate();
if (!result && event.getAction() == MotionEvent.ACTION_UP) {
performClick();
}
result = true;
}
}
return result || super.onTouchEvent(event);
}
@ -272,6 +306,9 @@ public class BotHelpCell extends View {
setMeasuredDimension(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), height + AndroidUtilities.dp(8));
}
private Drawable selectorDrawable;
private int selectorDrawableRadius;
@Override
protected void onDraw(Canvas canvas) {
int x = (getWidth() - width) / 2;
@ -294,6 +331,15 @@ public class BotHelpCell extends View {
drawable.setBounds(x, 0, width + x, height);
drawable.draw(canvas);
if (selectorDrawable != null) {
if (selectorDrawableRadius != SharedConfig.bubbleRadius) {
selectorDrawableRadius = SharedConfig.bubbleRadius;
Theme.setMaskDrawableRad(selectorDrawable, selectorDrawableRadius, selectorDrawableRadius);
}
selectorDrawable.setBounds(x + AndroidUtilities.dp(2), AndroidUtilities.dp(2), width + x - AndroidUtilities.dp(2), height - AndroidUtilities.dp(2));
selectorDrawable.draw(canvas);
}
imageReceiver.setImageCoords(x + imagePadding, imagePadding, width - imagePadding * 2, photoHeight - imagePadding);
imageReceiver.draw(canvas);
@ -301,8 +347,8 @@ public class BotHelpCell extends View {
Theme.chat_msgTextPaint.linkColor = getThemedColor(Theme.key_chat_messageLinkIn);
canvas.save();
canvas.translate(textX = AndroidUtilities.dp(isPhotoVisible ? 14 : 11) + x, textY = AndroidUtilities.dp(11) + y);
if (pressedLink != null) {
canvas.drawPath(urlPath, Theme.chat_urlPaint);
if (links.draw(canvas)) {
invalidate();
}
if (textLayout != null) {
textLayout.draw(canvas);
@ -349,4 +395,9 @@ public class BotHelpCell extends View {
Drawable drawable = resourcesProvider != null ? resourcesProvider.getDrawable(drawableKey) : null;
return drawable != null ? drawable : Theme.getThemeDrawable(drawableKey);
}
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == selectorDrawable || super.verifyDrawable(who);
}
}

View File

@ -14,6 +14,7 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Build;
import android.text.Layout;
@ -125,6 +126,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
private boolean canDrawInParent;
private View invalidateWithParent;
public void setInvalidateWithParent(View viewToInvalidate) {
invalidateWithParent = viewToInvalidate;
}
public interface ChatActionCellDelegate {
default void didClickImage(ChatActionCell cell) {
@ -397,37 +403,37 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
hasReplyMessage = messageObject.replyMessageObject != null;
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
previousWidth = 0;
imageReceiver.setAutoRepeatCount(0);
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
imageReceiver.setRoundRadius((int) (stickerSize / 2f));
imageReceiver.setAllowStartLottieAnimation(true);
imageReceiver.setDelegate(null);
TLRPC.TL_messageActionSuggestProfilePhoto action = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action;
TLRPC.VideoSize videoSize = FileLoader.getClosestVideoSizeWithSize(action.photo.video_sizes, 1000);
ImageLocation videoLocation;
if (action.photo.video_sizes != null && !action.photo.video_sizes.isEmpty()) {
videoLocation = ImageLocation.getForPhoto(action.photo.video_sizes.get(0), action.photo);
videoLocation = ImageLocation.getForPhoto(videoSize, action.photo);
} else {
videoLocation = null;
}
TLRPC.Photo photo = messageObject.messageOwner.action.photo;
TLRPC.VideoSize videoSize = null;
TLRPC.PhotoSize strippedPhotoSize = null;
for (int a = 0, N = messageObject.photoThumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = messageObject.photoThumbs.get(a);
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
strippedPhotoSize = photoSize;
break;
if (messageObject.strippedThumb == null) {
for (int a = 0, N = messageObject.photoThumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = messageObject.photoThumbs.get(a);
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
strippedPhotoSize = photoSize;
break;
}
}
}
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 1000);
if (photoSize != null) {
if (!photo.video_sizes.isEmpty()) {
videoSize = photo.video_sizes.get(0);
}
if (videoSize != null) {
imageReceiver.setImage(videoLocation, ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForPhoto(photoSize, photo), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", null, 0, null, messageObject, 0);
imageReceiver.setImage(videoLocation, ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForPhoto(photoSize, photo), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", messageObject.strippedThumb, 0, null, messageObject, 0);
} else {
imageReceiver.setImage(ImageLocation.getForPhoto(photoSize, photo), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", null, 0, null, messageObject, 0);
imageReceiver.setImage(ImageLocation.getForPhoto(photoSize, photo), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", messageObject.strippedThumb, 0, null, messageObject, 0);
}
}
@ -527,17 +533,20 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imageReceiver.setAllowStartLottieAnimation(true);
imageReceiver.setDelegate(null);
imageReceiver.setRoundRadius(AndroidUtilities.roundMessageSize / 2);
imageReceiver.setAutoRepeatCount(1);
long id = messageObject.getDialogId();
avatarDrawable.setInfo(id, null, null);
if (messageObject.messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
imageReceiver.setImage(null, null, avatarDrawable, null, messageObject, 0);
} else {
TLRPC.PhotoSize strippedPhotoSize = null;
for (int a = 0, N = messageObject.photoThumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = messageObject.photoThumbs.get(a);
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
strippedPhotoSize = photoSize;
break;
if (messageObject.strippedThumb == null) {
for (int a = 0, N = messageObject.photoThumbs.size(); a < N; a++) {
TLRPC.PhotoSize photoSize = messageObject.photoThumbs.get(a);
if (photoSize instanceof TLRPC.TL_photoStrippedSize) {
strippedPhotoSize = photoSize;
break;
}
}
}
TLRPC.PhotoSize photoSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 640);
@ -545,7 +554,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
TLRPC.Photo photo = messageObject.messageOwner.action.photo;
TLRPC.VideoSize videoSize = null;
if (!photo.video_sizes.isEmpty() && SharedConfig.autoplayGifs) {
videoSize = photo.video_sizes.get(0);
videoSize = FileLoader.getClosestVideoSizeWithSize(photo.video_sizes, 1000);
if (!messageObject.mediaExists && !DownloadController.getInstance(currentAccount).canDownloadMedia(DownloadController.AUTODOWNLOAD_TYPE_VIDEO, videoSize.size)) {
currentVideoLocation = ImageLocation.getForPhoto(videoSize, photo);
String fileName = FileLoader.getAttachFileName(videoSize);
@ -554,9 +563,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
}
if (videoSize != null) {
imageReceiver.setImage(ImageLocation.getForPhoto(videoSize, photo), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", avatarDrawable, 0, null, messageObject, 1);
imageReceiver.setImage(ImageLocation.getForPhoto(videoSize, photo), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", messageObject.strippedThumb, 0, null, messageObject, 1);
} else {
imageReceiver.setImage(ImageLocation.getForObject(photoSize, messageObject.photoThumbsObject), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", avatarDrawable, 0, null, messageObject, 1);
imageReceiver.setImage(ImageLocation.getForObject(photoSize, messageObject.photoThumbsObject), "150_150", ImageLocation.getForObject(strippedPhotoSize, messageObject.photoThumbsObject), "50_50_b", messageObject.strippedThumb, 0, null, messageObject, 1);
}
} else {
imageReceiver.setImageBitmap(avatarDrawable);
@ -844,6 +853,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else {
paint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText);
}
paint.linkColor = paint.getColor();
textLayout = new StaticLayout(text, paint, maxWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
spoilersPool.addAll(spoilers);
@ -1511,4 +1521,28 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private boolean isButtonLayout(MessageObject messageObject) {
return messageObject != null && (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO);
}
@Override
public void invalidate() {
super.invalidate();
if (invalidateWithParent != null) {
invalidateWithParent.invalidate();
}
}
@Override
public void invalidate(Rect dirty) {
super.invalidate(dirty);
if (invalidateWithParent != null) {
invalidateWithParent.invalidate();
}
}
@Override
public void invalidate(int l, int t, int r, int b) {
super.invalidate(l, t, r, b);
if (invalidateWithParent != null) {
invalidateWithParent.invalidate();
}
}
}

View File

@ -53,6 +53,7 @@ import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.util.Property;
import android.util.SparseArray;
import android.util.StateSet;
@ -155,6 +156,7 @@ import org.telegram.ui.Components.URLSpanBotCommand;
import org.telegram.ui.Components.URLSpanBrowser;
import org.telegram.ui.Components.URLSpanMono;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import org.telegram.ui.Components.VideoForwardDrawable;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PhotoViewer;
@ -242,7 +244,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhoto = null;
}
avatarDrawable.setInfo(currentUser);
avatarImage.setForUserOrChat(currentUser, avatarDrawable, null, true);
avatarImage.setForUserOrChat(currentUser, avatarDrawable, null, true, VectorAvatarThumbDrawable.TYPE_SMALL);
} else if (currentChat != null) {
if (currentChat.photo != null) {
currentPhoto = currentChat.photo.photo_small;
@ -1052,6 +1054,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private float replyTouchX, replyTouchY;
private TLRPC.PhotoSize currentReplyPhoto;
private AnimatedFloat translationLoadingFloat;
private LinkPath translationLoadingPath;
private LoadingDrawable translationLoadingDrawable;
private ArrayList<MessageObject.TextLayoutBlock> translationLoadingDrawableText;
private StaticLayout translationLoadingDrawableLayout;
private boolean drawTopic;
private MessageTopicButton topicButton;
@ -1156,6 +1164,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private int lastViewsCount;
private int lastRepliesCount;
private float selectedBackgroundProgress;
private boolean lastTranslated;
private float viewTop;
private int backgroundHeight;
@ -3043,7 +3052,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
forwardBotPressed = false;
playSoundEffect(SoundEffectConstants.CLICK);
if (delegate != null) {
if (currentViaBotUser.bot_inline_placeholder == null) {
if (currentViaBotUser != null && currentViaBotUser.bot_inline_placeholder == null) {
delegate.didPressViaBotNotInline(this, currentViaBotUser != null ? currentViaBotUser.id : 0);
} else {
delegate.didPressViaBot(this, currentViaBotUser != null ? currentViaBotUser.username : currentMessageObject.messageOwner.via_bot_name);
@ -3432,6 +3441,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
this.blurredViewTopOffset = blurredViewTopOffset;
this.blurredViewBottomOffset = blurredViewBottomOffset;
if (!botButtons.isEmpty() && viewTop != visibleTop) {
invalidate();
}
viewTop = visibleTop;
if (parent != parentHeight || parentOffset != this.parentViewTopOffset) {
@ -4081,7 +4093,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet) ||
lastPostAuthor != messageObject.messageOwner.post_author ||
wasPinned != isPinned ||
newReply != lastReplyMessage;
newReply != lastReplyMessage ||
messageObject.translated != lastTranslated;
boolean groupChanged = groupedMessages != currentMessagesGroup;
boolean pollChanged = false;
@ -4190,6 +4203,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setCrossfadeDuration(ImageReceiver.DEFAULT_CROSSFADE_DURATION);
photoImage.setCrossfadeByScale(0);
photoImage.setGradientBitmap(null);
lastTranslated = messageObject.translated;
lastSendState = messageObject.messageOwner.send_state;
lastDeleteDate = messageObject.messageOwner.destroyTime;
lastViewsCount = messageObject.messageOwner.views;
@ -4534,11 +4548,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
hasGamePreview = MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaGame && MessageObject.getMedia(messageObject.messageOwner).game instanceof TLRPC.TL_game;
hasInvoicePreview = MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaInvoice;
hasLinkPreview = !messageObject.isRestrictedMessage && MessageObject.getMedia(messageObject.messageOwner) instanceof TLRPC.TL_messageMediaWebPage && MessageObject.getMedia(messageObject.messageOwner).webpage instanceof TLRPC.TL_webPage;
TLRPC.WebPage webpage = hasLinkPreview ? MessageObject.getMedia(messageObject.messageOwner).webpage : null;
drawInstantView = hasLinkPreview && MessageObject.getMedia(messageObject.messageOwner).webpage.cached_page != null;
String siteName = hasLinkPreview ? MessageObject.getMedia(messageObject.messageOwner).webpage.site_name : null;
hasEmbed = hasLinkPreview && !TextUtils.isEmpty(MessageObject.getMedia(messageObject.messageOwner).webpage.embed_url) && !messageObject.isGif() && !"instangram".equalsIgnoreCase(siteName);
boolean slideshow = false;
String webpageType = hasLinkPreview ? MessageObject.getMedia(messageObject.messageOwner).webpage.type : null;
String webpageType = webpage != null ? webpage.type : null;
TLRPC.Document androidThemeDocument = null;
TLRPC.ThemeSettings androidThemeSettings = null;
if (!drawInstantView) {
@ -4557,7 +4572,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if ("telegram_megagroup".equals(webpageType)) {
drawInstantView = true;
drawInstantViewType = 2;
} else if ("telegram_message".equals(webpageType)) {
} else if ("telegram_message".equals(webpageType) || "photo".equals(webpageType) && webpage != null && webpage.url != null && Browser.isInternalUri(Uri.parse(webpage.url), null)) {
drawInstantView = true;
drawInstantViewType = 3;
} else if ("telegram_theme".equals(webpageType)) {
@ -4868,6 +4883,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
boolean titleIsRTL = false;
if (!titleIsRTL && author != null) {
titleIsRTL = AndroidUtilities.isRTL(author);
}
if (!titleIsRTL && messageObject.linkDescription != null) {
titleIsRTL = AndroidUtilities.isRTL(messageObject.linkDescription);
}
if (title != null) {
try {
titleX = Integer.MAX_VALUE;
@ -4915,9 +4936,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} catch (Exception e) {
FileLog.e(e);
}
if (titleIsRTL && isSmallImage) {
linkPreviewMaxWidth -= AndroidUtilities.dp(48);
}
}
if (titleIsRTL && isSmallImage) {
linkPreviewMaxWidth -= AndroidUtilities.dp(48);
}
boolean authorIsRTL = false;
@ -5649,7 +5670,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
}
if (user != null) {
if (user != null || !TextUtils.isEmpty(messageObject.vCardData)) {
drawInstantView = true;
drawInstantViewType = 5;
}
@ -7483,7 +7504,20 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int buttonWidth = (widthForButtons - AndroidUtilities.dp(5) * (buttonsCount - 1) - AndroidUtilities.dp(2)) / buttonsCount;
for (int b = 0; b < row.buttons.size(); b++) {
BotButton botButton = new BotButton();
botButton.button = row.buttons.get(b);
TLRPC.TL_keyboardButtonRequestPeer button = new TLRPC.TL_keyboardButtonRequestPeer();
button.button_id = 0;
button.text = "Request peer";
button.peer_type = new TLRPC.TL_requestPeerTypeChat();
((TLRPC.TL_requestPeerTypeChat) button.peer_type).forum = true;
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights = new TLRPC.TL_chatAdminRights();
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.change_info = true;
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.delete_messages = true;
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.pin_messages = true;
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.anonymous = true;
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).user_admin_rights.post_messages = true;
// ((TLRPC.TL_requestPeerTypeChat) button.peer_type).premium = false;
// botButton.button = button;
botButton.button = row.buttons.get(b);
String key = Utilities.bytesToHex(botButton.button.data);
String position = a + "" + b;
BotButton oldButton;
@ -7671,6 +7705,17 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
statusDrawableAnimator.removeAllListeners();
statusDrawableAnimator.cancel();
}
if (translationLoadingFloat != null) {
translationLoadingFloat.set(0, true);
}
if (translationLoadingPath != null) {
translationLoadingPath.reset();
translationLoadingPath = null;
}
if (translationLoadingDrawable != null) {
translationLoadingDrawable.reset();
translationLoadingDrawable = null;
}
transitionParams.lastStatusDrawableParams = -1;
statusDrawableAnimationInProgress = false;
@ -8149,7 +8194,20 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (seekBarWaveform != null) {
seekBarWaveform.setWaveform(waveform);
}
useTranscribeButton = currentMessageObject != null && (!currentMessageObject.isOutOwner() || currentMessageObject.isSent()) && (UserConfig.getInstance(currentAccount).isPremium() || !MessagesController.getInstance(currentAccount).didPressTranscribeButtonEnough() && (currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.voiceTranscriptionForce || currentMessageObject.getDuration() >= 60) && !MessagesController.getInstance(currentAccount).premiumLocked) && (currentMessageObject.isVoice() && useSeekBarWaveform || currentMessageObject.isRoundVideo()) && currentMessageObject.messageOwner != null && !(MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaWebPage);
useTranscribeButton = (
currentMessageObject != null &&
(!currentMessageObject.isOutOwner() || currentMessageObject.isSent()) &&
(
UserConfig.getInstance(currentAccount).isPremium() ||
!MessagesController.getInstance(currentAccount).didPressTranscribeButtonEnough() && (
currentMessageObject.messageOwner != null && currentMessageObject.messageOwner.voiceTranscriptionForce ||
currentMessageObject.getDuration() >= 60
) && !MessagesController.getInstance(currentAccount).premiumLocked
) && (
currentMessageObject.isVoice() && useSeekBarWaveform ||
currentMessageObject.isRoundVideo()
) && currentMessageObject.messageOwner != null && !(MessageObject.getMedia(currentMessageObject.messageOwner) instanceof TLRPC.TL_messageMediaWebPage)
);
updateSeekBarWaveformWidth(null);
}
@ -9346,11 +9404,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
);
}
}
drawMessageText(canvas, transitionParams.animateOutTextBlocks, false, (1.0f - transitionParams.animateChangeProgress), false);
drawMessageText(canvas, currentMessageObject.textLayoutBlocks, true, transitionParams.animateChangeProgress, false);
drawMessageText(canvas, transitionParams.animateOutTextBlocks, transitionParams.animateOutTextXOffset, false, (1.0f - transitionParams.animateChangeProgress), false);
drawMessageText(canvas, currentMessageObject.textLayoutBlocks, currentMessageObject.textXOffset, true, transitionParams.animateChangeProgress, false);
canvas.restore();
} else {
drawMessageText(canvas, currentMessageObject.textLayoutBlocks, true, 1.0f, false);
drawMessageText(canvas, currentMessageObject.textLayoutBlocks, currentMessageObject.textXOffset, true, 1.0f, false);
}
}
@ -9369,7 +9427,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.drawCircle(photoImage.getCenterX(), photoImage.getCenterY(), photoImage.getImageWidth() / 2f, drillHolePaint);
}
if (isRoundVideo && (
MediaController.getInstance().isPlayingMessage(currentMessageObject) && MediaController.getInstance().isVideoDrawingReady() && canvas.isHardwareAccelerated() && (currentMessageObject == null || !currentMessageObject.isVoiceTranscriptionOpen() || pipFloat >= 1)
MediaController.getInstance().isPlayingMessage(currentMessageObject) &&
MediaController.getInstance().isVideoDrawingReady() &&
canvas.isHardwareAccelerated() &&
(currentMessageObject == null || !currentMessageObject.isVoiceTranscriptionOpen() || pipFloat >= 1)
)) {
imageDrawn = true;
drawTime = true;
@ -9807,8 +9868,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
linkX = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() ? 11 : 17);
}
int startY = totalHeight - AndroidUtilities.dp(drawPinnedTop ? 9 : 10) - linkPreviewHeight - AndroidUtilities.dp(8);
int linkPreviewY = startY;
float startY = totalHeight - AndroidUtilities.dp(drawPinnedTop ? 9 : 10) - linkPreviewHeight - AndroidUtilities.dp(8);
float linkPreviewY = startY;
Theme.chat_replyLinePaint.setColor(getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewLine : Theme.key_chat_inPreviewLine));
AndroidUtilities.rectTmp.set(linkX, linkPreviewY - AndroidUtilities.dp(3), linkX + AndroidUtilities.dp(3), linkPreviewY + linkPreviewHeight);
@ -9850,7 +9911,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2);
}
descriptionY = linkPreviewY - AndroidUtilities.dp(3);
descriptionY = (int) linkPreviewY - AndroidUtilities.dp(3);
canvas.save();
canvas.translate(linkX + AndroidUtilities.dp(10) + descriptionX, descriptionY);
descriptionLayout.draw(canvas);
@ -10154,6 +10215,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
startY = textY + currentMessageObject.textHeight + AndroidUtilities.dp(8);
linkX = unmovedTextX + AndroidUtilities.dp(1);
}
startY += (int) transitionParams.deltaBottom;
int linkPreviewY = startY;
int smallImageStartY = 0;
@ -10502,10 +10564,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
instantButtonRect.set(linkX, instantY, linkX + instantWidth, instantY + AndroidUtilities.dp(36));
if (instantButtonLoading != null) {
instantButtonLoading.setBounds(instantButtonRect);
instantButtonLoading.setRadiiDp(6);
}
if (instantButtonPressed && instantButtonPressProgress != 1f) {
instantButtonPressProgress += (float) Math.min(40, 1000f / AndroidUtilities.screenRefreshRate) / 100f;
instantButtonPressProgress = Utilities.clamp(instantButtonPressProgress, 1f, 0);
@ -10522,6 +10580,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
selectorDrawable[0].draw(canvas);
}
if (instantButtonLoading != null && !instantButtonLoading.isDisappeared()) {
instantButtonLoading.setBounds(instantButtonRect);
instantButtonLoading.setRadiiDp(6);
instantButtonLoading.draw(canvas);
invalidate();
}
@ -10546,7 +10606,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return currentMessagesGroup == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0;
}
private void drawBotButtons(Canvas canvas, ArrayList<BotButton> botButtons, float alpha) {
private void drawBotButtons(Canvas canvas, ArrayList<BotButton> botButtons, int alpha) {
int addX;
if (currentMessageObject.isOutOwner()) {
addX = getMeasuredWidth() - widthForButtons - AndroidUtilities.dp(10);
@ -10563,8 +10623,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
rect.set(0, top, getMeasuredWidth(), top + height);
if (alpha != 1f) {
canvas.saveLayerAlpha(rect, (int) (255 * alpha), Canvas.ALL_SAVE_FLAG);
if (alpha != 0xFF) {
canvas.saveLayerAlpha(rect, alpha, Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
@ -10612,14 +10672,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.multAlpha(Theme.getColor(Theme.key_chat_serviceBackgroundSelector, resourcesProvider), 3f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_serviceBackgroundSelector, resourcesProvider), 10f)
);
button.loadingDrawable.setAlpha((int) (0xFF * alpha));
button.loadingDrawable.setAlpha(0xFF);
button.loadingDrawable.draw(canvas);
invalidateOutbounds();
}
if (button.selectorDrawable != null) {
button.selectorDrawable.setBounds(button.x + addX, (int) y, button.x + addX + button.width, (int) y + button.height);
button.selectorDrawable.setAlpha((int) (0xFF * alpha));
button.selectorDrawable.setAlpha(0xFF);
button.selectorDrawable.draw(canvas);
}
@ -10642,7 +10702,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
drawable.draw(canvas);
} else if (button.button instanceof TLRPC.TL_keyboardButtonSwitchInline) {
} else if (button.button instanceof TLRPC.TL_keyboardButtonSwitchInline || button.button instanceof TLRPC.TL_keyboardButtonRequestPeer) {
Drawable drawable = getThemedDrawable(Theme.key_drawable_botInline);
int x = button.x + button.width - AndroidUtilities.dp(3) - drawable.getIntrinsicWidth() + addX;
setDrawableBounds(drawable, x, y + AndroidUtilities.dp(3));
@ -10662,8 +10722,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return !currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0f || blurredPhotoImage.getBitmap() == null;
}
@SuppressLint("Range")
public void drawMessageText(Canvas canvas, ArrayList<MessageObject.TextLayoutBlock> textLayoutBlocks, boolean origin, float alpha, boolean drawOnlyText) {
drawMessageText(canvas, textLayoutBlocks, currentMessageObject == null ? 0 : currentMessageObject.textXOffset, origin, alpha, drawOnlyText);
}
@SuppressLint("Range")
public void drawMessageText(Canvas canvas, ArrayList<MessageObject.TextLayoutBlock> textLayoutBlocks, float rtlOffset, boolean origin, float alpha, boolean drawOnlyText) {
if (textLayoutBlocks == null || textLayoutBlocks.isEmpty() || alpha == 0) {
return;
}
@ -10685,6 +10749,62 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (transitionParams.animateText) {
textY = transitionParams.animateFromTextY * (1f - transitionParams.animateChangeProgress) + this.textY * transitionParams.animateChangeProgress;
}
boolean translating = MessagesController.getInstance(currentAccount).getTranslateController().isTranslating(getMessageObject());
if ((textLayoutBlocks == transitionParams.animateOutTextBlocks) == (currentMessageObject != null && currentMessageObject.translated)) {
if (translationLoadingFloat == null) {
translationLoadingFloat = new AnimatedFloat(this, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
}
float translationLoading = translationLoadingFloat.set(translating ? 1 : 0);
if (translationLoading > 0) {
if (translationLoadingDrawable == null) {
translationLoadingDrawable = new LoadingDrawable();
translationLoadingDrawable.setAppearByGradient(true);
if (translationLoadingPath == null) {
translationLoadingPath = new LinkPath(true);
}
translationLoadingDrawable.usePath(translationLoadingPath);
translationLoadingDrawable.setRadiiDp(5);
translationLoadingDrawable.reset();
}
if (translationLoadingDrawableText != textLayoutBlocks) {
translationLoadingDrawableText = textLayoutBlocks;
translationLoadingPath.reset();
for (int i = 0; i < textLayoutBlocks.size(); ++i) {
MessageObject.TextLayoutBlock block = textLayoutBlocks.get(i);
if (block != null && block.textLayout != null) {
translationLoadingPath.setCurrentLayout(block.textLayout, 0, block.isRtl() ? rtlOffset : 0, block.textYOffset);
block.textLayout.getSelectionPath(0, block.textLayout.getText().length(), translationLoadingPath);
}
}
translationLoadingDrawable.updateBounds();
}
if (translating && (translationLoadingDrawable.isDisappearing() || translationLoadingDrawable.isDisappeared())) {
translationLoadingDrawable.reset();
translationLoadingDrawable.resetDisappear();
} else if (!translating && !translationLoadingDrawable.isDisappearing() && !translationLoadingDrawable.isDisappeared()) {
translationLoadingDrawable.disappear();
}
int color = getThemedColor(currentMessageObject != null && currentMessageObject.isOutOwner() ? Theme.key_chat_messageLinkOut : Theme.key_chat_messageLinkIn);
translationLoadingDrawable.setColors(
Theme.multAlpha(color, .05f),
Theme.multAlpha(color, .15f),
Theme.multAlpha(color, .1f),
Theme.multAlpha(color, .3f)
);
canvas.save();
canvas.translate(textX, textY + transitionYOffsetForDrawables);
translationLoadingDrawable.setAlpha((int) (0xFF * alpha * translationLoading));
translationLoadingDrawable.draw(canvas);
canvas.restore();
invalidate();
}
}
if (firstVisibleBlockNum >= 0) {
int restore = Integer.MIN_VALUE;
int oldAlpha = 0;
@ -10725,7 +10845,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
MessageObject.TextLayoutBlock block = textLayoutBlocks.get(a);
canvas.save();
canvas.translate(textX - (block.isRtl() ? (int) Math.ceil(currentMessageObject.textXOffset) : 0), textY + block.textYOffset + transitionYOffsetForDrawables);
canvas.translate(textX - (block.isRtl() ? rtlOffset : 0), textY + block.textYOffset + transitionYOffsetForDrawables);
if (a == linkBlockNum) {
if (!drawOnlyText && links.draw(canvas)) {
invalidate();
@ -11022,10 +11142,26 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
}
canStreamVideo = (currentMessageObject.isSent() || currentMessageObject.isForwarded()) && (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && autoDownload) && currentMessageObject.canStreamVideo() && !currentMessageObject.needDrawBluredPreview();
if (SharedConfig.streamMedia && (int) currentMessageObject.getDialogId() != 0 && !currentMessageObject.isSecretMedia() &&
(documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC ||
canStreamVideo && currentPosition != null && ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0 || (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0))) {
canStreamVideo = (
(currentMessageObject.isSent() || currentMessageObject.isForwarded()) &&
(documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND ||
documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && autoDownload
) &&
currentMessageObject.canStreamVideo() &&
!currentMessageObject.needDrawBluredPreview()
);
if (
SharedConfig.streamMedia &&
(int) currentMessageObject.getDialogId() != 0 &&
!currentMessageObject.isSecretMedia() && (
documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC ||
canStreamVideo && currentPosition != null && (
(currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0 ||
(currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) == 0
)
)
) {
hasMiniProgress = fileExists ? 1 : 2;
fileExists = true;
}
@ -11146,7 +11282,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
DownloadController.getInstance(currentAccount).addLoadingFileObserver(fileName, currentMessageObject, this);
float setProgress = 0;
if (!FileLoader.getInstance(currentAccount).isLoadingFile(fileName)) {
if (!currentMessageObject.loadingCancelled && (documentAttachType == 0 && autoDownload || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && MessageObject.isGifDocument(documentAttach, currentMessageObject.hasValidGroupId()) && autoDownload)) {
if (
!currentMessageObject.loadingCancelled && autoDownload && (
documentAttachType == 0 ||
documentAttachType == DOCUMENT_ATTACH_TYPE_GIF && MessageObject.isGifDocument(documentAttach, currentMessageObject.hasValidGroupId())
)
) {
buttonState = 1;
} else {
buttonState = 0;
@ -12663,6 +12804,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
stringFinalText = TextUtils.ellipsize(sb, Theme.chat_replyTextPaint, maxWidth, TextUtils.TruncateAt.END);
replyTextOffset = 0;
replyTextLayout = new StaticLayout(stringFinalText, Theme.chat_replyTextPaint, maxWidth + AndroidUtilities.dp(10), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (replyTextLayout.getLineCount() > 0) {
replyTextWidth += (int) Math.ceil(replyTextLayout.getLineWidth(0)) + AndroidUtilities.dp(8);
@ -12738,10 +12880,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private Object getAuthorStatus() {
if (currentUser != null) {
if (currentUser.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
return ((TLRPC.TL_emojiStatusUntil) currentUser.emoji_status).document_id;
} else if (currentUser.emoji_status instanceof TLRPC.TL_emojiStatus) {
return ((TLRPC.TL_emojiStatus) currentUser.emoji_status).document_id;
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(currentUser);
if (emojiStatusId != null) {
return emojiStatusId;
} else if (currentUser.premium) {
return ContextCompat.getDrawable(ApplicationLoader.applicationContext, R.drawable.msg_premium_liststar).mutate();
}
@ -13689,10 +13830,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (!transitionParams.transitionBotButtons.isEmpty() && transitionParams.animateBotButtonsChanged) {
drawBotButtons(canvas, transitionParams.transitionBotButtons, 1f - transitionParams.animateChangeProgress);
float t = transitionParams.animateChangeProgress;
t = MathUtils.clamp(1f - (float) Math.pow(t, 2f), 0f, 1f);
drawBotButtons(canvas, transitionParams.transitionBotButtons, (int) (0xFF * t));
}
if (!botButtons.isEmpty()) {
drawBotButtons(canvas, botButtons, transitionParams.animateBotButtonsChanged ? transitionParams.animateChangeProgress : 1f);
drawBotButtons(canvas, botButtons, transitionParams.animateBotButtonsChanged ? (int) (0xFF * transitionParams.animateChangeProgress) : 0xFF);
}
drawSideButton(canvas);
}
@ -14230,13 +14373,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
ax = backgroundDrawableLeft + transitionParams.deltaLeft + backgroundDrawableRight + AndroidUtilities.dp(22) + nameWidth - adminLayout.getLineWidth(0);
}
} else if (!mediaBackground && currentMessageObject.isOutOwner()) {
ax = backgroundDrawableLeft + backgroundDrawableRight - AndroidUtilities.dp(17) - adminLayout.getLineWidth(0);
} else {
ax = backgroundDrawableLeft + backgroundDrawableRight - AndroidUtilities.dp(11) - adminLayout.getLineWidth(0);
}
}
ax += transitionParams.deltaRight;
canvas.translate(ax, nameY + AndroidUtilities.dp(0.5f));
if (transitionParams.animateSign) {
Theme.chat_adminPaint.setAlpha((int) (Color.alpha(color) * transitionParams.animateChangeProgress));
@ -14687,12 +14830,36 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyNameLayout.draw(canvas);
canvas.restore();
}
int spoilersColor;
if (currentMessageObject != null && currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount)) {
spoilersColor = getThemedColor(Theme.key_chat_outTimeText);
} else {
spoilersColor = Theme.chat_replyTextPaint.getColor();
}
if (transitionParams.animateReplyTextLayout != null && transitionParams.animateChangeProgress < 1) {
canvas.save();
canvas.clipRect(replySelectorRect);
canvas.save();
canvas.translate(forwardNameX + replyTextOffset - transitionParams.animateReplyTextOffset, replyStartY + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5));
int wasAlpha2 = Theme.chat_replyTextPaint.getAlpha();
Theme.chat_replyTextPaint.setAlpha((int) (wasAlpha2 * (1f - transitionParams.animateChangeProgress)));
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, transitionParams.animateReplyTextLayout, replySpoilers, canvas, false);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, transitionParams.animateReplyTextLayout, transitionParams.animateOutAnimateEmojiReply, 0, replySpoilers, 0, 0, 0, alpha, Theme.chat_animatedEmojiTextColorFilter);
Theme.chat_replyTextPaint.setAlpha(wasAlpha2);
canvas.restore();
}
if (replyTextLayout != null) {
canvas.save();
canvas.translate(forwardNameX, replyStartY + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5));
int spoilersColor = currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount) ? getThemedColor(Theme.key_chat_outTimeText) : replyTextLayout.getPaint().getColor();
int wasAlpha2 = Theme.chat_replyTextPaint.getAlpha();
Theme.chat_replyTextPaint.setAlpha((int) (wasAlpha2 * (transitionParams.animateReplyTextLayout != null ? transitionParams.animateChangeProgress : 1)));
SpoilerEffect.renderWithRipple(this, invalidateSpoilersParent, spoilersColor, -AndroidUtilities.dp(2), spoilersPatchedReplyTextLayout, replyTextLayout, replySpoilers, canvas, false);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, replyTextLayout, animatedEmojiReplyStack, 0, replySpoilers, 0, 0, 0, alpha, Theme.chat_animatedEmojiTextColorFilter);
Theme.chat_replyTextPaint.setAlpha(wasAlpha2);
canvas.restore();
}
if (transitionParams.animateReplyTextLayout != null && transitionParams.animateChangeProgress < 1) {
canvas.restore();
}
@ -15180,6 +15347,49 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
}
canvas.translate(captionX, captionY);
boolean translating = MessagesController.getInstance(currentAccount).getTranslateController().isTranslating(getMessageObject(), getCurrentMessagesGroup());
if (true) {
if (translationLoadingFloat == null) {
translationLoadingFloat = new AnimatedFloat(((View) getParent()), 350, CubicBezierInterpolator.EASE_OUT_QUINT);
}
float translationLoading = translationLoadingFloat.set(translating ? 1 : 0);
if (translationLoading > 0) {
if (translationLoadingDrawable == null) {
translationLoadingDrawable = new LoadingDrawable();
translationLoadingDrawable.setAppearByGradient(true);
if (translationLoadingPath == null) {
translationLoadingPath = new LinkPath(true);
}
translationLoadingDrawable.usePath(translationLoadingPath);
translationLoadingDrawable.setRadiiDp(5);
}
if (translationLoadingDrawableLayout != captionLayout) {
translationLoadingDrawableLayout = captionLayout;
translationLoadingPath.setCurrentLayout(captionLayout, 0, 0);
captionLayout.getSelectionPath(0, captionLayout.getText().length(), translationLoadingPath);
translationLoadingDrawable.updateBounds();
}
if (translating && translationLoadingDrawable.isDisappearing() || translationLoadingDrawable.isDisappeared()) {
translationLoadingDrawable.reset();
translationLoadingDrawable.resetDisappear();
} else if (!translating && !translationLoadingDrawable.isDisappearing() && !translationLoadingDrawable.isDisappeared()) {
translationLoadingDrawable.disappear();
}
int color = getThemedColor(currentMessageObject != null && currentMessageObject.isOutOwner() ? Theme.key_chat_messageLinkOut : Theme.key_chat_messageLinkIn);
translationLoadingDrawable.setColors(
Theme.multAlpha(color, .05f),
Theme.multAlpha(color, .15f),
Theme.multAlpha(color, .1f),
Theme.multAlpha(color, .3f)
);
translationLoadingDrawable.setAlpha((int) (0xFF * alpha * translationLoading));
translationLoadingDrawable.draw(canvas);
invalidate();
}
}
if (links.draw(canvas)) {
invalidate();
@ -18557,8 +18767,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private ArrayList<MessageObject.TextLayoutBlock> animateOutTextBlocks;
private ArrayList<MessageObject.TextLayoutBlock> lastDrawingTextBlocks;
private float animateOutTextXOffset;
private AnimatedEmojiSpan.EmojiGroupedSpans animateOutAnimateEmoji;
private StaticLayout animateReplyTextLayout;
private AnimatedEmojiSpan.EmojiGroupedSpans animateOutAnimateEmojiReply;
private boolean animateEditedEnter;
private StaticLayout animateEditedLayout;
private StaticLayout animateTimeLayout;
@ -18611,6 +18825,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public float lastDrawingTextX;
public float animateFromTextY;
public float lastTextXOffset;
public int lastTopOffset;
public boolean animateForwardedLayout;
@ -18624,6 +18839,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int animateForwardNameWidth;
int lastForwardNameWidth;
boolean animateBotButtonsChanged;
public StaticLayout lastDrawnReplyTextLayout;
public int lastReplyTextXOffset;
public float animateReplyTextOffset;
public void recordDrawingState() {
wasDraw = true;
@ -18697,6 +18916,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
lastForwardNameWidth = forwardedNameWidth;
lastBackgroundLeft = getCurrentBackgroundLeft();
lastBackgroundRight = currentBackgroundDrawable.getBounds().right;
lastTextXOffset = currentMessageObject.textXOffset;
lastDrawnReplyTextLayout = replyTextLayout;
lastReplyTextXOffset = replyTextOffset;
reactionsLayoutInBubble.recordDrawingState();
if (replyNameLayout != null) {
@ -18743,6 +18966,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!sameText) {
animateMessageText = true;
animateOutTextBlocks = lastDrawingTextBlocks;
animateOutTextXOffset = lastTextXOffset;
animateOutAnimateEmoji = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animateOutAnimateEmoji, lastDrawingTextBlocks, true);
animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, currentMessageObject.textLayoutBlocks);
changed = true;
@ -18750,6 +18974,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, currentMessageObject.textLayoutBlocks);
}
}
if (replyTextLayout != lastDrawnReplyTextLayout) {
animateReplyTextLayout = lastDrawnReplyTextLayout;
animateReplyTextOffset = lastReplyTextXOffset;
animateOutAnimateEmojiReply = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, false, animateOutAnimateEmojiReply, true, lastDrawnReplyTextLayout);
changed = true;
}
if (edited && !lastDrawingEdited && timeLayout != null) {
String editedStr = LocaleController.getString("EditedMessage", R.string.EditedMessage);
CharSequence text = timeLayout.getText();
@ -18831,7 +19061,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
for (int i = 0; i < botButtons.size(); i++) {
BotButton button1 = botButtons.get(i);
BotButton button2 = lastDrawBotButtons.get(i);
if (button1.x != button2.x || button1.width != button2.width) {
if (button1.x != button2.x || button1.width != button2.width || button1.title != button2.title) {
animateBotButtonsChanged = true;
break;
}

View File

@ -257,11 +257,14 @@ public class CheckBoxCell extends FrameLayout {
}
public void setText(CharSequence text, String value, boolean checked, boolean divider) {
setText(text, value, checked, divider, false);
}
public void setText(CharSequence text, String value, boolean checked, boolean divider, boolean animated) {
textView.setText(text);
if (checkBoxRound != null) {
checkBoxRound.setChecked(checked, false);
checkBoxRound.setChecked(checked, animated);
} else {
checkBoxSquare.setChecked(checked, false);
checkBoxSquare.setChecked(checked, animated);
}
valueTextView.setText(value);
needDivider = divider;
@ -359,6 +362,10 @@ public class CheckBoxCell extends FrameLayout {
}
}
public CheckBox2 getCheckBoxRound() {
return checkBoxRound;
}
public void setSquareCheckBoxColor(String uncheckedColor, String checkedColor, String checkColor) {
if (checkBoxSquare != null) {
checkBoxSquare.setColors(uncheckedColor, checkedColor, checkColor);
@ -385,4 +392,12 @@ public class CheckBoxCell extends FrameLayout {
Integer color = resourcesProvider != null ? resourcesProvider.getColor(key) : null;
return color != null ? color : Theme.getColor(key);
}
public void setIcon(int icon) {
checkBoxRound.setIcon(icon);
}
public boolean hasIcon() {
return checkBoxRound.hasIcon();
}
}

View File

@ -99,6 +99,7 @@ import org.telegram.ui.Components.TimerDrawable;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.URLSpanNoUnderlineBold;
import org.telegram.ui.Components.VectorAvatarThumbDrawable;
import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.DialogsActivity;
import org.telegram.ui.RightSlidingDialogContainer;
@ -932,6 +933,9 @@ public class DialogCell extends BaseCell {
}
}
if (message != null) {
message.updateTranslation();
}
CharSequence msgText = message != null ? message.messageText : null;
if (msgText instanceof Spannable) {
Spannable sp = new SpannableStringBuilder(msgText);
@ -1100,12 +1104,10 @@ public class DialogCell extends BaseCell {
}
drawPremium = MessagesController.getInstance(currentAccount).isPremiumUser(user) && UserConfig.getInstance(currentAccount).clientUserId != user.id && user.id != 0;
if (drawPremium) {
if (user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user);
if (emojiStatusId != null) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(((TLRPC.TL_emojiStatusUntil) user.emoji_status).document_id, false);
} else if (user.emoji_status instanceof TLRPC.TL_emojiStatus) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(((TLRPC.TL_emojiStatus) user.emoji_status).document_id, false);
emojiStatus.set(emojiStatusId, false);
} else {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(PremiumGradient.getInstance().premiumStarDrawableMini, false);
@ -1227,7 +1229,7 @@ public class DialogCell extends BaseCell {
}
}
} else {
if (dialogsType == 3 && UserObject.isUserSelf(user)) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD && UserObject.isUserSelf(user)) {
messageString = LocaleController.getString("SavedMessagesInfo", R.string.SavedMessagesInfo);
showChecks = false;
drawTime = false;
@ -1269,7 +1271,7 @@ public class DialogCell extends BaseCell {
}
if (lastMessageIsReaction) {
} else if (dialogsType == 2) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO) {
if (chat != null) {
if (ChatObject.isChannel(chat) && !chat.megagroup) {
if (chat.participants_count != 0) {
@ -1300,7 +1302,7 @@ public class DialogCell extends BaseCell {
drawCount2 = false;
showChecks = false;
drawTime = false;
} else if (dialogsType == 3 && UserObject.isUserSelf(user)) {
} else if (dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD && UserObject.isUserSelf(user)) {
messageString = LocaleController.getString("SavedMessagesInfo", R.string.SavedMessagesInfo);
showChecks = false;
drawTime = false;
@ -1599,7 +1601,7 @@ public class DialogCell extends BaseCell {
promoDialog = false;
MessagesController messagesController = MessagesController.getInstance(currentAccount);
if (dialogsType == 0 && messagesController.isPromoDialog(currentDialogId, true)) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_DEFAULT && messagesController.isPromoDialog(currentDialogId, true)) {
drawPinBackground = true;
promoDialog = true;
if (messagesController.promoDialogType == MessagesController.PROMO_TYPE_PROXY) {
@ -1645,7 +1647,7 @@ public class DialogCell extends BaseCell {
if (useMeForMyMessages) {
nameString = LocaleController.getString("FromYou", R.string.FromYou);
} else {
if (dialogsType == 3) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD) {
drawPinBackground = true;
}
nameString = LocaleController.getString("SavedMessages", R.string.SavedMessages);
@ -2587,7 +2589,7 @@ public class DialogCell extends BaseCell {
mentionCount = forumTopic.unread_mentions_count;
reactionMentionCount = forumTopic.unread_reactions_count;
}
if (dialogsType == 2) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_ADD_USERS_TO) {
drawPin = false;
}
@ -2599,12 +2601,10 @@ public class DialogCell extends BaseCell {
}
if (user != null && (mask & MessagesController.UPDATE_MASK_EMOJI_STATUS) != 0) {
user = MessagesController.getInstance(currentAccount).getUser(user.id);
if (user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user);
if (emojiStatusId != null) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(((TLRPC.TL_emojiStatusUntil) user.emoji_status).document_id, animated);
} else if (user.emoji_status instanceof TLRPC.TL_emojiStatus) {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(((TLRPC.TL_emojiStatus) user.emoji_status).document_id, animated);
emojiStatus.set(emojiStatusId, animated);
} else {
nameLayoutEllipsizeByGradient = true;
emojiStatus.set(PremiumGradient.getInstance().premiumStarDrawableMini, animated);
@ -2774,7 +2774,7 @@ public class DialogCell extends BaseCell {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else {
avatarImage.setForUserOrChat(user, avatarDrawable, null, true);
avatarImage.setForUserOrChat(user, avatarDrawable, null, true, VectorAvatarThumbDrawable.TYPE_SMALL);
}
} else if (chat != null) {
avatarDrawable.setInfo(chat);
@ -3721,6 +3721,9 @@ public class DialogCell extends BaseCell {
timerPaint.setShader(null);
if (avatarImage.getBitmap() != null && !avatarImage.getBitmap().isRecycled()) {
timerPaint.setColor(PremiumLockIconView.getDominantColor(avatarImage.getBitmap()));
} else if (avatarImage.getDrawable() instanceof VectorAvatarThumbDrawable){
VectorAvatarThumbDrawable vectorAvatarThumbDrawable = (VectorAvatarThumbDrawable) avatarImage.getDrawable();
timerPaint.setColor(vectorAvatarThumbDrawable.gradientTools.getAverageColor());
} else {
timerPaint.setColor(avatarDrawable.getColor2());
}
@ -4572,6 +4575,9 @@ public class DialogCell extends BaseCell {
applyName = false;
stringBuilder = SpannableStringBuilder.valueOf(mess);
}
if (applyThumbs) {
applyThumbs(stringBuilder);
}
} else if (captionMessage != null && captionMessage.caption != null) {
MessageObject message = captionMessage;
CharSequence mess = message.caption.toString();
@ -4784,6 +4790,10 @@ public class DialogCell extends BaseCell {
public boolean update() {
TLRPC.Dialog dialog = MessagesController.getInstance(currentAccount).dialogs_dict.get(currentDialogId);
if (dialog == null) {
if (dialogsType == DialogsActivity.DIALOGS_TYPE_FORWARD && lastDrawnDialogId != currentDialogId) {
lastDrawnDialogId = currentDialogId;
return true;
}
return false;
}
int messageHash = message == null ? 0 : message.getId();

View File

@ -0,0 +1,104 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
public class DialogsHintCell extends FrameLayout {
private LinearLayout contentView;
private TextView titleView;
private TextView messageView;
private ImageView chevronView;
public DialogsHintCell(@NonNull Context context) {
super(context);
setWillNotDraw(false);
setPadding(dp(16), dp(8), dp(16), dp(8));
contentView = new LinearLayout(context);
contentView.setOrientation(LinearLayout.VERTICAL);
contentView.setPadding(LocaleController.isRTL ? dp(24) : 0, 0, LocaleController.isRTL ? 0 : dp(24), 0);
addView(contentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
titleView = new TextView(context);
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));
messageView = new TextView(context);
messageView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
messageView.setMaxLines(2);
messageView.setEllipsize(TextUtils.TruncateAt.END);
contentView.addView(messageView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, Gravity.TOP));
chevronView = new ImageView(context);
chevronView.setImageResource(R.drawable.arrow_newchat);
chevronView.setColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText), PorterDuff.Mode.SRC_IN);
addView(chevronView, LayoutHelper.createFrame(16, 16, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL));
updateColors();
}
public void updateColors() {
titleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
messageView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
setBackground(Theme.AdaptiveRipple.filledRect());
}
public void setText(CharSequence title, CharSequence subtitle) {
titleView.setText(title);
messageView.setText(subtitle);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1, Theme.dividerPaint);
}
private int height;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
if (width <= 0) {
width = AndroidUtilities.displaySize.x;
}
contentView.measure(
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));
}
public int height() {
if (getVisibility() != View.VISIBLE) {
return 0;
}
if (height <= 0) {
height = dp(72) + 1;
}
return height;
}
}

View File

@ -0,0 +1,177 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.StickerEmptyView;
public class DialogsRequestedEmptyCell extends LinearLayout implements NotificationCenter.NotificationCenterDelegate {
int currentAccount = UserConfig.selectedAccount;
BackupImageView stickerView;
TextView titleView;
TextView subtitleView;
TextView buttonView;
public DialogsRequestedEmptyCell(Context context) {
super(context);
setOrientation(VERTICAL);
setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
LinearLayout linearLayout = new LinearLayout(context) {
Path path = new Path();
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
{
paint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite));
paint.setShadowLayer(dp(1.33f), 0, dp(.33f), 0x1e000000);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
super.onDraw(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
path.rewind();
AndroidUtilities.rectTmp.set(AndroidUtilities.dp(12), AndroidUtilities.dp(6), getMeasuredWidth() - AndroidUtilities.dp(12), getMeasuredHeight() - AndroidUtilities.dp(12));
path.addRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(10), AndroidUtilities.dp(10), Path.Direction.CW);
}
};
linearLayout.setWillNotDraw(false);
linearLayout.setOrientation(VERTICAL);
linearLayout.setPadding(AndroidUtilities.dp(12 + 20), AndroidUtilities.dp(6 + 10), AndroidUtilities.dp(12 + 20), AndroidUtilities.dp(12 +20));
stickerView = new BackupImageView(context);
stickerView.setOnClickListener(e -> {
stickerView.getImageReceiver().startAnimation();
});
updateSticker();
linearLayout.addView(stickerView, LayoutHelper.createLinear(130, 130, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
titleView = new TextView(context);
titleView.setGravity(Gravity.CENTER);
titleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
titleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
titleView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
linearLayout.addView(titleView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 6, 0, 0));
subtitleView = new TextView(context);
subtitleView.setGravity(Gravity.CENTER);
subtitleView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
subtitleView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText));
linearLayout.addView(subtitleView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 7, 0, 0));
buttonView = new TextView(context);
buttonView.setGravity(Gravity.CENTER);
buttonView.setBackground(Theme.AdaptiveRipple.filledRect(Theme.key_featuredStickers_addButton, 8));
buttonView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
buttonView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonView.setPadding(AndroidUtilities.dp(14), AndroidUtilities.dp(14), AndroidUtilities.dp(14), AndroidUtilities.dp(14));
buttonView.setOnClickListener(e -> {
onButtonClick();
});
linearLayout.addView(buttonView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 18, 0, 0));
addView(linearLayout, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
set(null);
}
protected void onButtonClick() {
}
public void set(TLRPC.RequestPeerType requestPeerType) {
if (requestPeerType instanceof TLRPC.TL_requestPeerTypeBroadcast) {
titleView.setText(LocaleController.getString("NoSuchChannels", R.string.NoSuchChannels));
subtitleView.setText(LocaleController.getString("NoSuchChannelsInfo", R.string.NoSuchChannelsInfo));
buttonView.setVisibility(View.VISIBLE);
buttonView.setText(LocaleController.getString("CreateChannelForThis", R.string.CreateChannelForThis));
} else if (requestPeerType instanceof TLRPC.TL_requestPeerTypeChat) {
titleView.setText(LocaleController.getString("NoSuchGroups", R.string.NoSuchGroups));
subtitleView.setText(LocaleController.getString("NoSuchGroupsInfo", R.string.NoSuchGroupsInfo));
buttonView.setVisibility(View.VISIBLE);
buttonView.setText(LocaleController.getString("CreateGroupForThis", R.string.CreateGroupForThis));
} else {
titleView.setText(LocaleController.getString("NoSuchUsers", R.string.NoSuchUsers));
subtitleView.setText(LocaleController.getString("NoSuchUsersInfo", R.string.NoSuchUsersInfo));
buttonView.setVisibility(View.GONE);
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.diceStickersDidLoad);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.diceStickersDidLoad);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.diceStickersDidLoad) {
String name = (String) args[0];
if (AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME.equals(name) && getVisibility() == VISIBLE) {
updateSticker();
}
}
}
private void updateSticker() {
final int stickerType = StickerEmptyView.STICKER_TYPE_SEARCH;
TLRPC.Document document = null;
TLRPC.TL_messages_stickerSet set = MediaDataController.getInstance(currentAccount).getStickerSetByName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
if (set == null) {
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME);
}
if (set != null && stickerType >= 0 && stickerType < set.documents.size() ) {
document = set.documents.get(stickerType);
}
if (document != null) {
SvgHelper.SvgDrawable svgThumb = DocumentObject.getSvgThumb(document.thumbs, Theme.key_windowBackgroundGray, 0.2f);
if (svgThumb != null) {
svgThumb.overrideWidthAndHeight(512, 512);
}
ImageLocation imageLocation = ImageLocation.getForDocument(document);
stickerView.setImage(imageLocation, "130_130", "tgs", svgThumb, set);
stickerView.getImageReceiver().setAutoRepeat(2);
} else {
MediaDataController.getInstance(currentAccount).loadStickersByEmojiOrName(AndroidUtilities.STICKERS_PLACEHOLDER_PACK_NAME, false, set == null);
stickerView.getImageReceiver().clearImage();
}
}
}

View File

@ -14,11 +14,8 @@ import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
@ -49,18 +46,22 @@ public class DrawerActionCell extends FrameLayout {
imageView = new ImageView(context);
addView(imageView, LayoutHelper.createFrame(24, 24, Gravity.LEFT | Gravity.TOP, 19, 12, 0, 0));
// addView(imageView, LayoutHelper.createFrame(24, 24, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 19, 12, LocaleController.isRTL ? 19 : 0, 0));
lottieImageView = new RLottieImageView(context);
lottieImageView.setAutoRepeat(false);
lottieImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chats_menuItemIcon), PorterDuff.Mode.SRC_IN));
addView(lottieImageView, LayoutHelper.createFrame(28, 28, Gravity.LEFT | Gravity.TOP, 17, 10, 0, 0));
// addView(lottieImageView, LayoutHelper.createFrame(28, 28, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 17, 10, LocaleController.isRTL ? 17 : 0, 0));
textView = new AnimatedTextView(context, true, true, true);
textView.setAnimationProperties(.6f, 0, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
textView.setTextColor(Theme.getColor(Theme.key_chats_menuItemText));
textView.setTextSize(AndroidUtilities.dp(15));
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setIgnoreRTL(true);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 19 + 24 + 29, 0, 16, 0));
// addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 16 : 62, 0, LocaleController.isRTL ? 62 : 16, 0));
setWillNotDraw(false);
}

View File

@ -100,7 +100,7 @@ public class DrawerProfileCell extends FrameLayout implements NotificationCenter
private float stateX, stateY;
StarParticlesView.Drawable starParticlesDrawable;
PremiumGradient.GradientTools gradientTools;
PremiumGradient.PremiumGradientTools gradientTools;
public DrawerProfileCell(Context context, DrawerLayoutContainer drawerLayoutContainer) {
super(context);
@ -587,7 +587,7 @@ public class DrawerProfileCell extends FrameLayout implements NotificationCenter
drawPremiumProgress = Utilities.clamp(drawPremiumProgress, 1f, 0);
if (drawPremiumProgress != 0) {
if (gradientTools == null) {
gradientTools = new PremiumGradient.GradientTools(Theme.key_premiumGradientBottomSheet1, Theme.key_premiumGradientBottomSheet2, Theme.key_premiumGradientBottomSheet3, null);
gradientTools = new PremiumGradient.PremiumGradientTools(Theme.key_premiumGradientBottomSheet1, Theme.key_premiumGradientBottomSheet2, Theme.key_premiumGradientBottomSheet3, null);
gradientTools.x1 = 0;
gradientTools.y1 = 1.1f;
gradientTools.x2 = 1.5f;
@ -655,14 +655,11 @@ public class DrawerProfileCell extends FrameLayout implements NotificationCenter
drawPremium = false;//user.premium;
nameTextView.setText(text);
if (user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user);
if (emojiStatusId != null) {
animatedStatus.animate().alpha(1).setDuration(200).start();
nameTextView.setDrawablePadding(AndroidUtilities.dp(4));
status.set(((TLRPC.TL_emojiStatusUntil) user.emoji_status).document_id, true);
} else if (user.emoji_status instanceof TLRPC.TL_emojiStatus) {
animatedStatus.animate().alpha(1).setDuration(200).start();
nameTextView.setDrawablePadding(AndroidUtilities.dp(4));
status.set(((TLRPC.TL_emojiStatus) user.emoji_status).document_id, true);
status.set(emojiStatusId, true);
} else if (user.premium) {
animatedStatus.animate().alpha(1).setDuration(200).start();
nameTextView.setDrawablePadding(AndroidUtilities.dp(4));

View File

@ -10,7 +10,6 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
@ -25,6 +24,7 @@ import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.NotificationsController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
@ -139,13 +139,10 @@ public class DrawerUserCell extends FrameLayout implements NotificationCenter.No
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20), false);
} catch (Exception ignore) {}
textView.setText(text);
if (user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
Long emojiStatusId = UserObject.getEmojiStatusDocumentId(user);
if (emojiStatusId != null) {
textView.setDrawablePadding(AndroidUtilities.dp(4));
status.set(((TLRPC.TL_emojiStatusUntil) user.emoji_status).document_id, true);
textView.setRightDrawableOutside(true);
} else if (user.emoji_status instanceof TLRPC.TL_emojiStatus) {
textView.setDrawablePadding(AndroidUtilities.dp(4));
status.set(((TLRPC.TL_emojiStatus) user.emoji_status).document_id, true);
status.set(emojiStatusId, true);
textView.setRightDrawableOutside(true);
} else if (MessagesController.getInstance(account).isPremiumUser(user)) {
textView.setDrawablePadding(AndroidUtilities.dp(6));

View File

@ -289,44 +289,42 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
}
nameLockTop = AndroidUtilities.dp(22.0f);
updateStatus(false, null, false);
} else {
if (chat != null) {
dialog_id = -chat.id;
drawCheck = chat.verified;
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
updateStatus(drawCheck, null, false);
} else if (user != null) {
dialog_id = user.id;
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
nameLockTop = AndroidUtilities.dp(21);
drawCheck = user.verified;
drawPremium = !user.self && MessagesController.getInstance(currentAccount).isPremiumUser(user);
updateStatus(drawCheck, user, false);
} else if (contact != null) {
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
if (actionButton == null) {
actionButton = new CanvasButton(this);
actionButton.setDelegate(() -> {
if (getParent() instanceof RecyclerListView) {
RecyclerListView parent = (RecyclerListView) getParent();
parent.getOnItemClickListener().onItemClick(this, parent.getChildAdapterPosition(this));
} else {
callOnClick();
}
});
}
} else if (chat != null) {
dialog_id = -chat.id;
drawCheck = chat.verified;
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
updateStatus(drawCheck, null, false);
} else if (user != null) {
dialog_id = user.id;
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
nameLockTop = AndroidUtilities.dp(21);
drawCheck = user.verified;
drawPremium = !savedMessages && MessagesController.getInstance(currentAccount).isPremiumUser(user);
updateStatus(drawCheck, user, false);
} else if (contact != null) {
if (!LocaleController.isRTL) {
nameLeft = AndroidUtilities.dp(AndroidUtilities.leftBaseline);
} else {
nameLeft = AndroidUtilities.dp(11);
}
if (actionButton == null) {
actionButton = new CanvasButton(this);
actionButton.setDelegate(() -> {
if (getParent() instanceof RecyclerListView) {
RecyclerListView parent = (RecyclerListView) getParent();
parent.getOnItemClickListener().onItemClick(this, parent.getChildAdapterPosition(this));
} else {
callOnClick();
}
});
}
}
@ -548,13 +546,13 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
if (verified) {
statusDrawable.set(new CombinedDrawable(Theme.dialogs_verifiedDrawable, Theme.dialogs_verifiedCheckDrawable, 0, 0), animated);
statusDrawable.setColor(null);
} else if (user != null && !user.self && user.emoji_status instanceof TLRPC.TL_emojiStatusUntil && ((TLRPC.TL_emojiStatusUntil) user.emoji_status).until > (int) (System.currentTimeMillis() / 1000)) {
} 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);
statusDrawable.setColor(Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider));
} else if (user != null && !user.self && user.emoji_status instanceof TLRPC.TL_emojiStatus) {
} else if (user != null && !savedMessages && user.emoji_status instanceof TLRPC.TL_emojiStatus) {
statusDrawable.set(((TLRPC.TL_emojiStatus) user.emoji_status).document_id, animated);
statusDrawable.setColor(Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider));
} else if (user != null && !user.self && MessagesController.getInstance(currentAccount).isPremiumUser(user)) {
} else if (user != null && !savedMessages && MessagesController.getInstance(currentAccount).isPremiumUser(user)) {
statusDrawable.set(PremiumGradient.getInstance().premiumStarDrawableMini, animated);
statusDrawable.setColor(Theme.getColor(Theme.key_chats_verifiedBackground, resourcesProvider));
} else {

View File

@ -0,0 +1,297 @@
package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
public class RequestPeerRequirementsCell extends LinearLayout {
public RequestPeerRequirementsCell(Context context) {
super(context);
setOrientation(VERTICAL);
setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
}
private TLRPC.RequestPeerType requestPeerType;
private ArrayList<Requirement> requirements = new ArrayList<>();
public void set(TLRPC.RequestPeerType requestPeerType) {
if (this.requestPeerType != requestPeerType) {
this.requestPeerType = requestPeerType;
removeAllViews();
requirements.clear();
if (requestPeerType instanceof TLRPC.TL_requestPeerTypeUser) {
TLRPC.TL_requestPeerTypeUser type = (TLRPC.TL_requestPeerTypeUser) requestPeerType;
checkRequirement(
type.premium,
R.string.PeerRequirementPremiumTrue,
R.string.PeerRequirementPremiumFalse
);
} else {
boolean isChannel = requestPeerType instanceof TLRPC.TL_requestPeerTypeBroadcast;
if (isChannel) {
checkRequirement(requestPeerType.has_username, R.string.PeerRequirementChannelPublicTrue, R.string.PeerRequirementChannelPublicFalse);
if (requestPeerType.bot_participant != null && requestPeerType.bot_participant) {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PeerRequirementChannelBotParticipant))));
}
if (requestPeerType.creator != null && requestPeerType.creator) {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PeerRequirementChannelCreatorTrue))));
}
} else {
checkRequirement(requestPeerType.has_username, R.string.PeerRequirementGroupPublicTrue, R.string.PeerRequirementGroupPublicFalse);
checkRequirement(requestPeerType.forum, R.string.PeerRequirementForumTrue, R.string.PeerRequirementForumFalse);
if (requestPeerType.bot_participant != null && requestPeerType.bot_participant) {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PeerRequirementGroupBotParticipant))));
}
if (requestPeerType.creator != null && requestPeerType.creator) {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PeerRequirementGroupCreatorTrue))));
}
}
if (!(requestPeerType.creator != null && requestPeerType.creator)) {
checkAdminRights(requestPeerType.user_admin_rights, isChannel, R.string.PeerRequirementUserRights, R.string.PeerRequirementUserRight);
}
// checkAdminRights(requestPeerType.bot_admin_rights, isChannel, R.string.PeerRequirementBotRights, R.string.PeerRequirementBotRight);
}
if (!requirements.isEmpty()) {
HeaderCell headerCell = new HeaderCell(getContext(), 20);
headerCell.setText(LocaleController.getString("PeerRequirements", R.string.PeerRequirements));
headerCell.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
addView(headerCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
addView(emptyView(9, Theme.getColor(Theme.key_windowBackgroundWhite)), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
for (Requirement requirement : requirements) {
addView(new RequirementCell(getContext(), requirement), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
addView(emptyView(12, Theme.getColor(Theme.key_windowBackgroundWhite)), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
addView(emptyView(12, Theme.getThemedDrawable(getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow)), LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
}
}
private View emptyView(int heightDp, int color) {
return emptyView(heightDp, new ColorDrawable(color));
}
private View emptyView(int heightDp, Drawable background) {
View view = new View(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(heightDp), MeasureSpec.EXACTLY));
}
};
view.setBackground(background);
return view;
}
private void checkRequirement(Boolean value, String positive, String negative) {
if (value != null) {
if (value) {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(positive)));
} else {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(negative)));
}
}
}
private void checkRequirement(Boolean value, int positiveResId, int negativeResId) {
if (value != null) {
if (value) {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(LocaleController.getString(positiveResId))));
} else {
requirements.add(Requirement.make(AndroidUtilities.replaceTags(LocaleController.getString(negativeResId))));
}
}
}
public static CharSequence rightsToString(TLRPC.TL_chatAdminRights rights, boolean isChannel) {
ArrayList<Requirement> array = new ArrayList<>();
if (rights.change_info) {
array.add(Requirement.make(
1,
isChannel ?
LocaleController.getString("EditAdminChangeChannelInfo", R.string.EditAdminChangeChannelInfo) :
LocaleController.getString("EditAdminChangeGroupInfo", R.string.EditAdminChangeGroupInfo)
));
}
if (rights.post_messages && isChannel) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminPostMessages", R.string.EditAdminPostMessages)));
}
if (rights.edit_messages && isChannel) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminEditMessages", R.string.EditAdminEditMessages)));
}
if (rights.delete_messages) {
array.add(Requirement.make(1, isChannel ? LocaleController.getString("EditAdminDeleteMessages", R.string.EditAdminDeleteMessages) : LocaleController.getString("EditAdminGroupDeleteMessages", R.string.EditAdminGroupDeleteMessages)));
}
if (rights.ban_users && !isChannel) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminBanUsers", R.string.EditAdminBanUsers)));
}
if (rights.invite_users) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminAddUsers", R.string.EditAdminAddUsers)));
}
if (rights.pin_messages && !isChannel) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminPinMessages", R.string.EditAdminPinMessages)));
}
if (rights.add_admins) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminAddAdmins", R.string.EditAdminAddAdmins)));
}
if (rights.anonymous && !isChannel) {
array.add(Requirement.make(1, LocaleController.getString("EditAdminSendAnonymously", R.string.EditAdminSendAnonymously)));
}
if (rights.manage_call) {
array.add(Requirement.make(1, LocaleController.getString("StartVoipChatPermission", R.string.StartVoipChatPermission)));
}
if (rights.manage_topics && !isChannel) {
array.add(Requirement.make(1, LocaleController.getString("ManageTopicsPermission", R.string.ManageTopicsPermission)));
}
if (array.size() == 1) {
return array.get(0).text.toString().toLowerCase();
} else if (!array.isEmpty()) {
SpannableStringBuilder string = new SpannableStringBuilder();
for (int i = 0; i < array.size(); ++i) {
if (i > 0) {
string.append(", ");
}
string.append(array.get(i).text.toString().toLowerCase());
}
return string;
}
return "";
}
private void checkAdminRights(TLRPC.TL_chatAdminRights value, boolean isChannel, CharSequence headerText, CharSequence headerSingleText) {
if (value == null) {
return;
}
ArrayList<Requirement> rights = new ArrayList<>();
if (value.change_info) {
rights.add(Requirement.make(
1,
isChannel ?
LocaleController.getString("EditAdminChangeChannelInfo", R.string.EditAdminChangeChannelInfo) :
LocaleController.getString("EditAdminChangeGroupInfo", R.string.EditAdminChangeGroupInfo)
));
}
if (value.post_messages && isChannel) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminPostMessages", R.string.EditAdminPostMessages)));
}
if (value.edit_messages && isChannel) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminEditMessages", R.string.EditAdminEditMessages)));
}
if (value.delete_messages) {
rights.add(Requirement.make(1, isChannel ? LocaleController.getString("EditAdminDeleteMessages", R.string.EditAdminDeleteMessages) : LocaleController.getString("EditAdminGroupDeleteMessages", R.string.EditAdminGroupDeleteMessages)));
}
if (value.ban_users && !isChannel) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminBanUsers", R.string.EditAdminBanUsers)));
}
if (value.invite_users) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminAddUsers", R.string.EditAdminAddUsers)));
}
if (value.pin_messages && !isChannel) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminPinMessages", R.string.EditAdminPinMessages)));
}
if (value.add_admins) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminAddAdmins", R.string.EditAdminAddAdmins)));
}
if (value.anonymous && !isChannel) {
rights.add(Requirement.make(1, LocaleController.getString("EditAdminSendAnonymously", R.string.EditAdminSendAnonymously)));
}
if (value.manage_call) {
rights.add(Requirement.make(1, LocaleController.getString("StartVoipChatPermission", R.string.StartVoipChatPermission)));
}
if (value.manage_topics && !isChannel) {
rights.add(Requirement.make(1, LocaleController.getString("ManageTopicsPermission", R.string.ManageTopicsPermission)));
}
if (rights.size() == 1) {
requirements.add(Requirement.make(TextUtils.concat(headerSingleText, " ", rights.get(0).text)));
} else if (!rights.isEmpty()) {
SpannableStringBuilder string = SpannableStringBuilder.valueOf(headerText);
string.append(" ");
for (int i = 0; i < rights.size(); ++i) {
if (i > 0) {
string.append(", ");
}
string.append(rights.get(i).text.toString().toLowerCase());
}
string.append(".");
requirements.add(Requirement.make(string));
}
}
private void checkAdminRights(TLRPC.TL_chatAdminRights value, boolean isChannel, int headerTextResId, int headerSingleTextResId) {
checkAdminRights(value, isChannel, AndroidUtilities.replaceTags(LocaleController.getString(headerTextResId)), AndroidUtilities.replaceTags(LocaleController.getString(headerSingleTextResId)));
}
class RequirementCell extends LinearLayout {
private ImageView imageView;
private TextView textView;
public RequirementCell(Context context, Requirement requirement) {
super(context);
setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
setOrientation(HORIZONTAL);
imageView = new ImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(requirement.padding <= 0 ? R.drawable.list_check : R.drawable.list_circle);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader), PorterDuff.Mode.MULTIPLY));
addView(imageView, LayoutHelper.createLinear(20, 20, 0, Gravity.TOP | Gravity.LEFT, 17 + requirement.padding * 16, -1, 0, 0));
textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2));
textView.setSingleLine(false);
textView.setText(requirement.text);
addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 1, 6, 4, 24, 4));
}
}
}
class Requirement {
public int padding;
public CharSequence text;
private Requirement(CharSequence text, int padding) {
this.text = text;
this.padding = padding;
}
public static Requirement make(CharSequence text) {
return new Requirement(text, 0);
}
public static Requirement make(int pad, CharSequence text) {
return new Requirement(text, pad);
}
}

View File

@ -255,6 +255,9 @@ public class SharedPhotoVideoCell2 extends View {
public void setVideoText(String videoText, boolean drawVideoIcon) {
this.videoText = videoText;
showVideoLayout = videoText != null;
if (showVideoLayout && videoInfoLayot != null && !videoInfoLayot.getText().toString().equals(videoText)) {
videoInfoLayot = null;
}
this.drawVideoIcon = drawVideoIcon;
}

View File

@ -75,9 +75,9 @@ public class StickerSetNameCell extends FrameLayout {
}
}
if (supportRtl) {
lp = LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, emoji ? 5 : 17, emoji ? 10 : 2, emoji ? 15 : 57, 0);
lp = LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, emoji ? 5 : 17, emoji ? 5 : 2, emoji ? 15 : 57, 0);
} else {
lp = LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, emoji ? 5 : 17, emoji ? 10 : 2, emoji ? 15 : 57, 0);
lp = LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, emoji ? 5 : 17, emoji ? 5 : 2, emoji ? 15 : 57, 0);
}
addView(textView, lp);
@ -97,10 +97,14 @@ public class StickerSetNameCell extends FrameLayout {
buttonView = new ImageView(context);
buttonView.setScaleType(ImageView.ScaleType.CENTER);
buttonView.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_emojiPanelStickerSetNameIcon), PorterDuff.Mode.MULTIPLY));
buttonView.setBackground(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), Theme.RIPPLE_MASK_CIRCLE_TO_BOUND_EDGE));
if (supportRtl) {
lp = LayoutHelper.createFrameRelatively(24, 24, Gravity.TOP | Gravity.END, 0, 0, 11, 0);
lp = LayoutHelper.createFrameRelatively(24, 24, Gravity.TOP | Gravity.END, 0, 0, isEmoji ? 0 : 11, 0);
} else {
lp = LayoutHelper.createFrame(24, 24, Gravity.TOP | Gravity.RIGHT, 0, 0, 11, 0);
lp = LayoutHelper.createFrame(24, 24, Gravity.TOP | Gravity.RIGHT, 0, 0, isEmoji ? 0 : 11, 0);
}
if (isEmoji) {
buttonView.setTranslationY(AndroidUtilities.dp(4));
}
addView(buttonView, lp);
}
@ -191,7 +195,7 @@ public class StickerSetNameCell extends FrameLayout {
if (empty) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(1, MeasureSpec.EXACTLY));
} else {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(isEmoji ? 32 : 24), MeasureSpec.EXACTLY));
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(isEmoji ? 27 : 24), MeasureSpec.EXACTLY));
}
}

View File

@ -37,6 +37,7 @@ public class TextCell extends FrameLayout {
public final SimpleTextView textView;
private final SimpleTextView subtitleView;
public final AnimatedTextView valueTextView;
public final SimpleTextView valueSpoilersTextView;
public final RLottieImageView imageView;
private Switch checkBox;
private ImageView valueImageView;
@ -88,14 +89,24 @@ public class TextCell extends FrameLayout {
subtitleView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
addView(subtitleView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
valueTextView = new AnimatedTextView(context);
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.setGravity(LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT);
valueTextView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
valueTextView.setTranslationY(AndroidUtilities.dp(-2));
addView(valueTextView);
valueSpoilersTextView = new SimpleTextView(context);
valueSpoilersTextView.setEllipsizeByGradient(18, false);
valueSpoilersTextView.setTextColor(Theme.getColor(dialog ? Theme.key_dialogTextBlue2 : Theme.key_windowBackgroundWhiteValueText, resourcesProvider));
valueSpoilersTextView.setGravity(LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT);
valueSpoilersTextView.setTextSize(16);
valueSpoilersTextView.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
valueSpoilersTextView.setVisibility(GONE);
addView(valueSpoilersTextView);
imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(dialog ? Theme.key_dialogIcon : Theme.key_windowBackgroundWhiteGrayIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
@ -143,8 +154,10 @@ public class TextCell extends FrameLayout {
}
public void setPrioritizeTitleOverValue(boolean prioritizeTitleOverValue) {
this.prioritizeTitleOverValue = prioritizeTitleOverValue;
requestLayout();
if (this.prioritizeTitleOverValue != prioritizeTitleOverValue) {
this.prioritizeTitleOverValue = prioritizeTitleOverValue;
requestLayout();
}
}
@Override
@ -152,14 +165,18 @@ public class TextCell extends FrameLayout {
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = AndroidUtilities.dp(heightDp);
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));
} else {
valueTextView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(leftPadding), LocaleController.isRTL ? MeasureSpec.AT_MOST : MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
textView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding) - valueTextView.width(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.EXACTLY));
subtitleView.measure(MeasureSpec.makeMeasureSpec(width - AndroidUtilities.dp(71 + leftPadding) - valueTextView.width(), MeasureSpec.AT_MOST), 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));
valueWidth = Math.max(valueTextView.width(), valueSpoilersTextView.getTextWidth());
textView.measure(MeasureSpec.makeMeasureSpec(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));
}
if (imageView.getVisibility() == VISIBLE) {
imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
@ -186,13 +203,14 @@ public class TextCell extends FrameLayout {
int height = bottom - top;
int width = right - left;
int viewTop = (height - valueTextView.getTextHeight()) / 2;
int viewTop = (height - Math.max(valueSpoilersTextView.getTextHeight(), valueTextView.getTextHeight())) / 2;
int viewLeft = LocaleController.isRTL ? AndroidUtilities.dp(leftPadding) : 0;
if (prioritizeTitleOverValue && !LocaleController.isRTL) {
viewLeft = width - valueTextView.getMeasuredWidth() - AndroidUtilities.dp(leftPadding);
viewLeft = width - valueTextView.getMeasuredWidth() - AndroidUtilities.dp(leftPadding);
}
valueTextView.layout(viewLeft, viewTop, viewLeft + valueTextView.getMeasuredWidth(), viewTop + valueTextView.getMeasuredHeight());
viewLeft = LocaleController.isRTL ? AndroidUtilities.dp(leftPadding) : width - valueSpoilersTextView.getMeasuredWidth() - AndroidUtilities.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);
@ -245,6 +263,7 @@ public class TextCell extends FrameLayout {
valueTextView.setText(null, false);
imageView.setVisibility(GONE);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
needDivider = divider;
setWillNotDraw(!needDivider);
@ -258,12 +277,25 @@ public class TextCell extends FrameLayout {
imageView.setImageResource(resId);
imageView.setVisibility(VISIBLE);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
needDivider = divider;
setWillNotDraw(!needDivider);
}
public void setTextAndColorfulIcon(String text, int resId, int color, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
textView.setText(text);
valueTextView.setText(null, false);
setColorfulIcon(color, resId);
valueTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
needDivider = divider;
setWillNotDraw(!needDivider);
}
public void setTextAndIcon(String text, Drawable drawable, boolean divider) {
offsetFromImage = 68;
imageLeft = 18;
@ -301,6 +333,7 @@ public class TextCell extends FrameLayout {
textView.setText(text);
valueTextView.setText(value, animated);
valueTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setVisibility(GONE);
imageView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
needDivider = divider;
@ -310,6 +343,38 @@ public class TextCell extends FrameLayout {
}
}
public void setTextAndValueAndColorfulIcon(String text, CharSequence value, boolean animated, int resId, int color, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
textView.setText(text);
valueTextView.setText(value, animated);
valueTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setVisibility(GONE);
setColorfulIcon(color, resId);
valueImageView.setVisibility(GONE);
needDivider = divider;
setWillNotDraw(!needDivider);
if (checkBox != null) {
checkBox.setVisibility(GONE);
}
}
public void setTextAndSpoilersValueAndColorfulIcon(String text, CharSequence value, int resId, int color, boolean divider) {
imageLeft = 21;
offsetFromImage = 71;
textView.setText(text);
valueSpoilersTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setText(value);
valueTextView.setVisibility(GONE);
setColorfulIcon(color, resId);
valueImageView.setVisibility(GONE);
needDivider = divider;
setWillNotDraw(!needDivider);
if (checkBox != null) {
checkBox.setVisibility(GONE);
}
}
public void setTextAndValueAndIcon(String text, String value, int resId, boolean divider) {
setTextAndValueAndIcon(text, value, false, resId, divider);
}
@ -320,6 +385,7 @@ public class TextCell extends FrameLayout {
textView.setText(text);
valueTextView.setText(value, animated);
valueTextView.setVisibility(VISIBLE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
imageView.setVisibility(VISIBLE);
imageView.setTranslationX(0);
@ -337,11 +403,11 @@ public class TextCell extends FrameLayout {
offsetFromImage = 65;
imageView.setVisibility(VISIBLE);
imageView.setPadding(AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2));
imageView.setTranslationX(AndroidUtilities.dp(-3));
imageView.setTranslationX(AndroidUtilities.dp(LocaleController.isRTL ? 0 : -3));
imageView.setTranslationY(AndroidUtilities.dp(6));
imageView.setImageResource(resId);
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
imageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(8), color));
imageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(9), color));
}
public void setTextAndCheck(String text, boolean checked, boolean divider) {
@ -364,6 +430,7 @@ public class TextCell extends FrameLayout {
offsetFromImage = 71;
textView.setText(text);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
if (checkBox != null) {
checkBox.setVisibility(VISIBLE);
@ -381,6 +448,7 @@ public class TextCell extends FrameLayout {
offsetFromImage = 71;
textView.setText(text);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
valueImageView.setVisibility(GONE);
if (checkBox != null) {
checkBox.setVisibility(VISIBLE);
@ -401,6 +469,7 @@ public class TextCell extends FrameLayout {
valueImageView.setVisibility(VISIBLE);
valueImageView.setImageDrawable(drawable);
valueTextView.setVisibility(GONE);
valueSpoilersTextView.setVisibility(GONE);
imageView.setVisibility(GONE);
imageView.setPadding(0, AndroidUtilities.dp(7), 0, 0);
needDivider = divider;
@ -456,6 +525,9 @@ public class TextCell extends FrameLayout {
if (valueTextView != null) {
valueTextView.animate().alpha(alpha).start();
}
if (valueSpoilersTextView != null) {
valueSpoilersTextView.animate().alpha(alpha).start();
}
if (valueImageView != null) {
valueImageView.animate().alpha(alpha).start();
}
@ -469,6 +541,9 @@ public class TextCell extends FrameLayout {
if (valueTextView != null) {
valueTextView.setAlpha(alpha);
}
if (valueSpoilersTextView != null) {
valueSpoilersTextView.setAlpha(alpha);
}
if (valueImageView != null) {
valueImageView.setAlpha(alpha);
}
@ -542,7 +617,12 @@ public class TextCell extends FrameLayout {
float alpha = (0.6f + 0.4f * loadingProgress) * drawLoadingProgress;
paint.setAlpha((int) (255 * alpha));
int cy = getMeasuredHeight() >> 1;
AndroidUtilities.rectTmp.set(getMeasuredWidth() - AndroidUtilities.dp(11) - AndroidUtilities.dp(loadingSize), cy - AndroidUtilities.dp(3), getMeasuredWidth() - AndroidUtilities.dp(11), cy + AndroidUtilities.dp(3));
AndroidUtilities.rectTmp.set(
getMeasuredWidth() - AndroidUtilities.dp(21) - AndroidUtilities.dp(loadingSize),
cy - AndroidUtilities.dp(3),
getMeasuredWidth() - AndroidUtilities.dp(21),
cy + AndroidUtilities.dp(3)
);
if (LocaleController.isRTL) {
AndroidUtilities.rectTmp.left = getMeasuredWidth() - AndroidUtilities.rectTmp.left;
AndroidUtilities.rectTmp.right = getMeasuredWidth() - AndroidUtilities.rectTmp.right;
@ -551,6 +631,7 @@ public class TextCell extends FrameLayout {
invalidate();
}
valueTextView.setAlpha(1f - drawLoadingProgress);
valueSpoilersTextView.setAlpha(1f - drawLoadingProgress);
super.dispatchDraw(canvas);
}

View File

@ -13,7 +13,10 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
@ -24,6 +27,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
@ -32,6 +36,7 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.Switch;
import java.util.ArrayList;
@ -53,6 +58,7 @@ public class TextCheckCell extends FrameLayout {
private boolean drawCheckRipple;
private int padding;
private Theme.ResourcesProvider resourcesProvider;
ImageView imageView;
public static final Property<TextCheckCell, Float> ANIMATION_PROGRESS = new AnimationProperties.FloatProperty<TextCheckCell>("animationProgress") {
@Override
@ -123,6 +129,10 @@ public class TextCheckCell extends FrameLayout {
checkBox.setEnabled(enabled);
}
public void setCheckBoxIcon(int icon) {
checkBox.setIcon(icon);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isMultiline) {
@ -333,7 +343,11 @@ public class TextCheckCell extends FrameLayout {
canvas.drawCircle(cx, cy, animatedRad, animationPaint);
}
if (needDivider) {
canvas.drawLine(LocaleController.isRTL ? 0 : AndroidUtilities.dp(20), getMeasuredHeight() - 1, getMeasuredWidth() - (LocaleController.isRTL ? AndroidUtilities.dp(20) : 0), getMeasuredHeight() - 1, Theme.dividerPaint);
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);
}
}
}
@ -369,4 +383,20 @@ public class TextCheckCell extends FrameLayout {
super.onDetachedFromWindow();
attached = false;
}
public void setColorfullIcon(int color, int resId) {
if (imageView == null) {
imageView = new RLottieImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER);
addView(imageView, LayoutHelper.createFrame(29, 29, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL, 19, 0, 19, 0));
padding = AndroidUtilities.dp(65);
((MarginLayoutParams)textView.getLayoutParams()).leftMargin = LocaleController.isRTL ? 70 : padding;
((MarginLayoutParams)textView.getLayoutParams()).rightMargin = LocaleController.isRTL ? padding: 70;
}
imageView.setVisibility(VISIBLE);
imageView.setPadding(AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2));
imageView.setImageResource(resId);
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
imageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(9), color));
}
}

View File

@ -10,16 +10,24 @@ package org.telegram.ui.Cells;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.Switch;
@ -31,6 +39,47 @@ public class TextCheckCell2 extends FrameLayout {
private boolean needDivider;
private boolean isMultiline;
private LinearLayout collapseViewContainer;
private AnimatedTextView animatedTextView;
private View collapsedArrow;
private View checkBoxClickArea;
public void setCollapseArrow(String text, boolean collapsed, Runnable onCheckClick) {
if (collapseViewContainer == null) {
collapseViewContainer = new LinearLayout(getContext());
collapseViewContainer.setOrientation(LinearLayout.HORIZONTAL);
animatedTextView = new AnimatedTextView(getContext(), false, true, true);
animatedTextView.setTextSize(AndroidUtilities.dp(14));
animatedTextView.getDrawable().setAllowCancel(true);
animatedTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
animatedTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
collapseViewContainer.addView(animatedTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT,20));
collapsedArrow = new View(getContext());
Drawable drawable = getContext().getResources().getDrawable(R.drawable.arrow_more).mutate();
drawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), PorterDuff.Mode.MULTIPLY));
collapsedArrow.setBackground(drawable);
collapseViewContainer.addView(collapsedArrow, LayoutHelper.createLinear(16, 16, Gravity.CENTER_VERTICAL));
collapseViewContainer.setClipChildren(false);
setClipChildren(false);
addView(collapseViewContainer, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL));
checkBoxClickArea = new View(getContext()) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawLine(0, AndroidUtilities.dp(14), 2, getMeasuredHeight()- AndroidUtilities.dp(14), Theme.dividerPaint);
}
};
checkBoxClickArea.setBackground(Theme.createSelectorDrawable(Theme.getColor(Theme.key_listSelector), 2));
addView(checkBoxClickArea, LayoutHelper.createFrame(76, LayoutHelper.MATCH_PARENT, LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT));
}
animatedTextView.setText(text);
collapsedArrow.animate().cancel();
collapsedArrow.animate().rotation(collapsed ? 0 : 180).setDuration(340).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).start();
checkBoxClickArea.setOnClickListener(v -> onCheckClick.run());
}
public TextCheckCell2(Context context) {
this(context, null);
}
@ -46,7 +95,7 @@ public class TextCheckCell2 extends FrameLayout {
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 64 : 21, 0, LocaleController.isRTL ? 21 : 64, 0));
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 64 : 21, 0, LocaleController.isRTL ? 21 : 64, 0));
valueTextView = new TextView(context);
valueTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
@ -73,10 +122,26 @@ public class TextCheckCell2 extends FrameLayout {
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (collapseViewContainer != null) {
if (LocaleController.isRTL) {
collapseViewContainer.setTranslationX(textView.getLeft() - collapseViewContainer.getMeasuredWidth() - AndroidUtilities.dp(4));
} else {
collapseViewContainer.setTranslationX(textView.getRight() + AndroidUtilities.dp(4));
}
}
}
public void setTextAndCheck(String text, boolean checked, boolean divider) {
setTextAndCheck(text, checked, divider, false);
}
public void setTextAndCheck(String text, boolean checked, boolean divider, boolean animated) {
textView.setText(text);
isMultiline = false;
checkBox.setChecked(checked, false);
checkBox.setChecked(checked, animated);
needDivider = divider;
valueTextView.setVisibility(GONE);
LayoutParams layoutParams = (LayoutParams) textView.getLayoutParams();

View File

@ -12,6 +12,7 @@ import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
@ -42,6 +43,7 @@ public class TextSettingsCell extends FrameLayout {
private TextView textView;
private AnimatedTextView valueTextView;
private ImageView imageView;
private boolean imageViewIsColorful;
private BackupImageView valueBackupImageView;
private ImageView valueImageView;
private boolean needDivider;
@ -94,14 +96,14 @@ public class TextSettingsCell extends FrameLayout {
imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY));
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
imageView.setVisibility(GONE);
addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL, 21, 0, 21, 0));
valueImageView = new ImageView(context);
valueImageView.setScaleType(ImageView.ScaleType.CENTER);
valueImageView.setVisibility(INVISIBLE);
valueImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon), PorterDuff.Mode.MULTIPLY));
valueImageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
addView(valueImageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, padding, 0, padding, 0));
}
@ -120,7 +122,11 @@ public class TextSettingsCell extends FrameLayout {
}
if (imageView.getVisibility() == VISIBLE) {
imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
if (imageViewIsColorful) {
imageView.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(28), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(28), MeasureSpec.EXACTLY));
} else {
imageView.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST));
}
}
if (valueBackupImageView != null) {
@ -213,6 +219,7 @@ public class TextSettingsCell extends FrameLayout {
public void setIcon(int resId) {
MarginLayoutParams params = (MarginLayoutParams) textView.getLayoutParams();
imageViewIsColorful = false;
if (resId == 0) {
imageView.setVisibility(GONE);
if (LocaleController.isRTL) {
@ -222,6 +229,31 @@ public class TextSettingsCell extends FrameLayout {
}
} else {
imageView.setImageResource(resId);
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_windowBackgroundWhiteGrayIcon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
imageView.setBackground(null);
imageView.setVisibility(VISIBLE);
if (LocaleController.isRTL) {
params.rightMargin = AndroidUtilities.dp(71);
} else {
params.leftMargin = AndroidUtilities.dp(71);
}
}
}
public void setColorfulIcon(int resId, int color) {
MarginLayoutParams params = (MarginLayoutParams) textView.getLayoutParams();
imageViewIsColorful = true;
if (resId == 0) {
imageView.setVisibility(GONE);
if (LocaleController.isRTL) {
params.rightMargin = AndroidUtilities.dp(this.padding);
} else {
params.leftMargin = AndroidUtilities.dp(this.padding);
}
} else {
imageView.setBackground(Theme.createRoundRectDrawable(AndroidUtilities.dp(8), color));
imageView.setImageResource(resId);
imageView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY));
imageView.setVisibility(VISIBLE);
if (LocaleController.isRTL) {
params.rightMargin = AndroidUtilities.dp(71);

View File

@ -191,6 +191,9 @@ public class ThemePreviewMessagesCell extends LinearLayout {
private GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTap(MotionEvent e) {
if (MediaDataController.getInstance(currentAccount).getDoubleTapReaction() == null) {
return false;
}
boolean added = getMessageObject().selectReaction(ReactionsLayoutInBubble.VisibleReaction.fromEmojicon(MediaDataController.getInstance(currentAccount).getDoubleTapReaction()), false, false);
setMessageObject(getMessageObject(), null, false, false);
requestLayout();

View File

@ -54,6 +54,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
@ -110,6 +111,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
private LinearLayout linearLayout2;
private HeaderCell headerCell2;
private EditTextBoldCursor editText;
private boolean isGroup;
private RLottieDrawable cameraDrawable;
@ -141,23 +143,29 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
private int currentStep;
private long chatId;
private boolean canCreatePublic = true;
private Boolean forcePublic;
private TLRPC.InputFile inputPhoto;
private TLRPC.InputFile inputVideo;
private TLRPC.VideoSize inputEmojiMarkup;
private String inputVideoPath;
private double videoTimestamp;
private boolean createAfterUpload;
private boolean donePressed;
private Integer doneRequestId;
private Utilities.Callback2<BaseFragment, Long> onFinishListener;
private final static int done_button = 1;
public ChannelCreateActivity(Bundle args) {
super(args);
currentStep = args.getInt("step", 0);
if (args.containsKey("forcePublic")) {
forcePublic = args.getBoolean("forcePublic", false);
}
if (currentStep == 0) {
avatarDrawable = new AvatarDrawable();
imageUpdater = new ImageUpdater(true);
imageUpdater = new ImageUpdater(true, ImageUpdater.FOR_TYPE_CHANNEL, true);
TLRPC.TL_channels_checkUsername req = new TLRPC.TL_channels_checkUsername();
req.username = "1";
@ -175,6 +183,10 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
}
}
public void setOnFinishListener(Utilities.Callback2<BaseFragment, Long> onFinishListener) {
this.onFinishListener = onFinishListener;
}
@Override
public boolean onFragmentCreate() {
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.chatDidCreated);
@ -343,7 +355,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
createAfterUpload = true;
return;
}
doneRequestId = MessagesController.getInstance(currentAccount).createChat(nameTextView.getText().toString(), new ArrayList<>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, false, null, null, 0, ChannelCreateActivity.this);
doneRequestId = MessagesController.getInstance(currentAccount).createChat(nameTextView.getText().toString(), new ArrayList<>(), descriptionTextView.getText().toString(), ChatObject.CHAT_TYPE_CHANNEL, false, null, null, -1, ChannelCreateActivity.this);
} else if (currentStep == 1) {
if (!isPrivate) {
if (descriptionTextView.length() == 0) {
@ -362,15 +374,30 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
AndroidUtilities.shakeView(checkTextView);
return;
} else {
MessagesController.getInstance(currentAccount).updateChannelUserName(ChannelCreateActivity.this, chatId, lastCheckName, null, null);
AndroidUtilities.runOnUIThread(enableDoneLoading, 200);
MessagesController.getInstance(currentAccount).updateChannelUserName(ChannelCreateActivity.this, chatId, lastCheckName, () -> {
updateDoneProgress(false);
if (onFinishListener != null) {
onFinishListener.run(ChannelCreateActivity.this, chatId);
}
}, () -> {
updateDoneProgress(false);
if (onFinishListener != null) {
onFinishListener.run(ChannelCreateActivity.this, chatId);
}
});
}
}
} else if (onFinishListener != null) {
onFinishListener.run(ChannelCreateActivity.this, chatId);
}
if (onFinishListener == null) {
Bundle args = new Bundle();
args.putInt("step", 2);
args.putLong("chatId", chatId);
args.putInt("chatType", ChatObject.CHAT_TYPE_CHANNEL);
presentFragment(new GroupCreateActivity(args), true);
}
Bundle args = new Bundle();
args.putInt("step", 2);
args.putLong("chatId", chatId);
args.putInt("chatType", ChatObject.CHAT_TYPE_CHANNEL);
presentFragment(new GroupCreateActivity(args), true);
}
}
}
@ -545,7 +572,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
@Override
protected void onDraw(Canvas canvas) {
if (avatarImage != null && avatarImage.getImageReceiver().hasNotThumb()) {
paint.setAlpha((int) (0x55 * avatarImage.getImageReceiver().getCurrentAlpha()));
paint.setAlpha((int) (0x55 * avatarImage.getImageReceiver().getCurrentAlpha() * avatarProgressView.getAlpha()));
canvas.drawCircle(getMeasuredWidth() / 2.0f, getMeasuredHeight() / 2.0f, getMeasuredWidth() / 2.0f, paint);
}
}
@ -559,6 +586,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
inputPhoto = null;
inputVideo = null;
inputVideoPath = null;
inputEmojiMarkup = null;
videoTimestamp = 0;
showAvatarProgress(false, true);
avatarImage.setImage(null, null, avatarDrawable, null);
@ -599,8 +627,14 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
avatarEditor.setPadding(AndroidUtilities.dp(0), 0, 0, AndroidUtilities.dp(1));
frameLayout.addView(avatarEditor, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 15, 12, LocaleController.isRTL ? 15 : 0, 12));
avatarProgressView = new RadialProgressView(context);
avatarProgressView.setSize(AndroidUtilities.dp(30));
avatarProgressView = new RadialProgressView(context) {
@Override
public void setAlpha(float alpha) {
super.setAlpha(alpha);
avatarOverlay.invalidate();
}
};
avatarProgressView.setSize(AndroidUtilities.dp(30));
avatarProgressView.setProgressColor(0xffffffff);
avatarProgressView.setNoProgress(false);
frameLayout.addView(avatarProgressView, LayoutHelper.createFrame(64, 64, Gravity.TOP | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), LocaleController.isRTL ? 0 : 16, 12, LocaleController.isRTL ? 16 : 0, 12));
@ -683,14 +717,16 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
linearLayout.setOrientation(LinearLayout.VERTICAL);
scrollView.addView(linearLayout, new ScrollView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
actionBar.setTitle(LocaleController.getString("ChannelSettingsTitle", R.string.ChannelSettingsTitle));
TLRPC.Chat chat = getMessagesController().getChat(chatId);
isGroup = chat != null && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat));
actionBar.setTitle(isGroup ? LocaleController.getString("GroupSettingsTitle", R.string.GroupSettingsTitle) : LocaleController.getString("ChannelSettingsTitle", R.string.ChannelSettingsTitle));
fragmentView.setTag(Theme.key_windowBackgroundGray);
fragmentView.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundGray));
headerCell2 = new HeaderCell(context, 23);
headerCell2.setHeight(46);
headerCell2.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
headerCell2.setText(LocaleController.getString("ChannelTypeHeader", R.string.ChannelTypeHeader));
headerCell2.setText(isGroup ? LocaleController.getString("GroupTypeHeader", R.string.GroupTypeHeader) : LocaleController.getString("ChannelTypeHeader", R.string.ChannelTypeHeader));
linearLayout.addView(headerCell2);
linearLayout2 = new LinearLayout(context);
@ -700,8 +736,14 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
radioButtonCell1 = new RadioButtonCell(context);
radioButtonCell1.setBackgroundDrawable(Theme.getSelectorDrawable(false));
radioButtonCell1.setTextAndValue(LocaleController.getString("ChannelPublic", R.string.ChannelPublic), LocaleController.getString("ChannelPublicInfo", R.string.ChannelPublicInfo), false, !isPrivate);
linearLayout2.addView(radioButtonCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (forcePublic != null && !forcePublic) {
isPrivate = true;
}
if (isGroup) {
radioButtonCell1.setTextAndValue(LocaleController.getString("MegaPublic", R.string.MegaPublic), LocaleController.getString("MegaPublicInfo", R.string.MegaPublicInfo), false, !isPrivate);
} else {
radioButtonCell1.setTextAndValue(LocaleController.getString("ChannelPublic", R.string.ChannelPublic), LocaleController.getString("ChannelPublicInfo", R.string.ChannelPublicInfo), false, !isPrivate);
}
radioButtonCell1.setOnClickListener(v -> {
if (!canCreatePublic) {
showPremiumIncreaseLimitDialog();
@ -713,11 +755,20 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
isPrivate = false;
updatePrivatePublic();
});
if (forcePublic == null || forcePublic) {
linearLayout2.addView(radioButtonCell1, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
radioButtonCell2 = new RadioButtonCell(context);
radioButtonCell2.setBackgroundDrawable(Theme.getSelectorDrawable(false));
radioButtonCell2.setTextAndValue(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate), LocaleController.getString("ChannelPrivateInfo", R.string.ChannelPrivateInfo), false, isPrivate);
linearLayout2.addView(radioButtonCell2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
if (forcePublic != null && forcePublic) {
isPrivate = false;
}
if (isGroup) {
radioButtonCell2.setTextAndValue(LocaleController.getString("MegaPrivate", R.string.MegaPrivate), LocaleController.getString("MegaPrivateInfo", R.string.MegaPrivateInfo), false, isPrivate);
} else {
radioButtonCell2.setTextAndValue(LocaleController.getString("ChannelPrivate", R.string.ChannelPrivate), LocaleController.getString("ChannelPrivateInfo", R.string.ChannelPrivateInfo), false, isPrivate);
}
radioButtonCell2.setOnClickListener(v -> {
if (isPrivate) {
return;
@ -725,6 +776,9 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
isPrivate = true;
updatePrivatePublic();
});
if (forcePublic == null || !forcePublic) {
linearLayout2.addView(radioButtonCell2, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
}
sectionCell = new ShadowSectionCell(context);
linearLayout.addView(sectionCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
@ -923,8 +977,13 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
typeInfoCell.setBackgroundDrawable(Theme.getThemedDrawable(typeInfoCell.getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
linkContainer.setVisibility(View.VISIBLE);
loadingAdminedCell.setVisibility(View.GONE);
typeInfoCell.setText(isPrivate ? LocaleController.getString("ChannelPrivateLinkHelp", R.string.ChannelPrivateLinkHelp) : LocaleController.getString("ChannelUsernameHelp", R.string.ChannelUsernameHelp));
headerCell.setText(isPrivate ? LocaleController.getString("ChannelInviteLinkTitle", R.string.ChannelInviteLinkTitle) : LocaleController.getString("ChannelLinkTitle", R.string.ChannelLinkTitle));
if (isGroup) {
typeInfoCell.setText(isPrivate ? LocaleController.getString("MegaPrivateLinkHelp", R.string.MegaPrivateLinkHelp) : LocaleController.getString("MegaUsernameHelp", R.string.MegaUsernameHelp));
headerCell.setText(isPrivate ? LocaleController.getString("ChannelInviteLinkTitle", R.string.ChannelInviteLinkTitle) : LocaleController.getString("ChannelLinkTitle", R.string.ChannelLinkTitle));
} else {
typeInfoCell.setText(isPrivate ? LocaleController.getString("ChannelPrivateLinkHelp", R.string.ChannelPrivateLinkHelp) : LocaleController.getString("ChannelUsernameHelp", R.string.ChannelUsernameHelp));
headerCell.setText(isPrivate ? LocaleController.getString("ChannelInviteLinkTitle", R.string.ChannelInviteLinkTitle) : LocaleController.getString("ChannelLinkTitle", R.string.ChannelLinkTitle));
}
publicContainer.setVisibility(isPrivate ? View.GONE : View.VISIBLE);
privateContainer.setVisibility(isPrivate ? View.VISIBLE : View.GONE);
linkContainer.setPadding(0, 0, 0, isPrivate ? 0 : AndroidUtilities.dp(7));
@ -954,11 +1013,12 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
}
@Override
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize, boolean isVideo) {
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize, boolean isVideo, TLRPC.VideoSize emojiMarkup) {
AndroidUtilities.runOnUIThread(() -> {
if (photo != null || video != null) {
inputPhoto = photo;
inputVideo = video;
inputEmojiMarkup = emojiMarkup;
inputVideoPath = videoPath;
videoTimestamp = videoStartTimestamp;
if (createAfterUpload) {
@ -975,6 +1035,7 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
doneButton.performClick();
}
showAvatarProgress(false, true);
avatarEditor.setImageDrawable(null);
} else {
avatar = smallSize.location;
avatarBig = bigSize.location;
@ -1124,10 +1185,15 @@ public class ChannelCreateActivity extends BaseFragment implements NotificationC
bundle.putInt("step", 1);
bundle.putLong("chat_id", chat_id);
bundle.putBoolean("canCreatePublic", canCreatePublic);
if (inputPhoto != null || inputVideo != null) {
MessagesController.getInstance(currentAccount).changeChatAvatar(chat_id, null, inputPhoto, inputVideo, videoTimestamp, inputVideoPath, avatar, avatarBig, null);
if (forcePublic != null) {
bundle.putBoolean("forcePublic", forcePublic);
}
presentFragment(new ChannelCreateActivity(bundle), true);
if (inputPhoto != null || inputVideo != null || inputEmojiMarkup != null) {
MessagesController.getInstance(currentAccount).changeChatAvatar(chat_id, null, inputPhoto, inputVideo, inputEmojiMarkup, videoTimestamp, inputVideoPath, avatar, avatarBig, null);
}
ChannelCreateActivity activity = new ChannelCreateActivity(bundle);
activity.setOnFinishListener(onFinishListener);
presentFragment(activity, true);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -199,8 +199,9 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
public ChatEditActivity(Bundle args) {
super(args);
avatarDrawable = new AvatarDrawable();
imageUpdater = new ImageUpdater(true);
chatId = args.getLong("chat_id", 0);
TLRPC.Chat chat = getMessagesController().getChat(chatId);
imageUpdater = new ImageUpdater(true, chat != null && ChatObject.isChannelAndNotMegaGroup(chat) ? ImageUpdater.FOR_TYPE_CHANNEL : ImageUpdater.FOR_TYPE_GROUP, true);
}
@Override
@ -605,7 +606,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
setAvatarCell.setOnClickListener(v -> {
imageUpdater.openMenu(avatar != null, () -> {
avatar = null;
MessagesController.getInstance(currentAccount).changeChatAvatar(chatId, null, null, null, 0, null, null, null, null);
MessagesController.getInstance(currentAccount).changeChatAvatar(chatId, null, null, null, null, 0, null, null, null, null);
showAvatarProgress(false, true);
avatarImage.setImage(null, null, avatarDrawable, currentChat);
cameraDrawable.setCurrentFrame(0);
@ -1110,11 +1111,11 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
}
@Override
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize, boolean isVideo) {
public void didUploadPhoto(final TLRPC.InputFile photo, final TLRPC.InputFile video, double videoStartTimestamp, String videoPath, final TLRPC.PhotoSize bigSize, final TLRPC.PhotoSize smallSize, boolean isVideo, TLRPC.VideoSize emojiMarkup) {
AndroidUtilities.runOnUIThread(() -> {
avatar = smallSize.location;
if (photo != null || video != null) {
getMessagesController().changeChatAvatar(chatId, null, photo, video, videoStartTimestamp, videoPath, smallSize.location, bigSize.location, null);
if (photo != null || video != null || emojiMarkup != null) {
getMessagesController().changeChatAvatar(chatId, null, photo, video, emojiMarkup, videoStartTimestamp, videoPath, smallSize.location, bigSize.location, null);
if (createAfterUpload) {
try {
if (progressDialog != null && progressDialog.isShowing()) {
@ -1473,24 +1474,13 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
} else {
int count = 0;
if (currentChat.default_banned_rights != null) {
if (!currentChat.default_banned_rights.send_stickers) {
count++;
}
if (!currentChat.default_banned_rights.send_media) {
count++;
}
if (!currentChat.default_banned_rights.embed_links) {
count++;
}
if (!currentChat.default_banned_rights.send_messages) {
if (!currentChat.default_banned_rights.send_plain) {
count++;
}
count += ChatUsersActivity.getSendMediaSelectedCount(currentChat.default_banned_rights);
if (!currentChat.default_banned_rights.pin_messages) {
count++;
}
if (!currentChat.default_banned_rights.send_polls) {
count++;
}
if (!currentChat.default_banned_rights.invite_users) {
count++;
}
@ -1501,9 +1491,9 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
count++;
}
} else {
count = forum ? 9 : 8;
count = forum ? 14 : 13;
}
blockCell.setTextAndValueAndIcon(LocaleController.getString("ChannelPermissions", R.string.ChannelPermissions), String.format("%d/%d", count, forum ? 9 : 8), animated, R.drawable.msg_permissions, true);
blockCell.setTextAndValueAndIcon(LocaleController.getString("ChannelPermissions", R.string.ChannelPermissions), String.format("%d/%d", count, forum ? 14 : 13), animated, R.drawable.msg_permissions, true);
}
if (memberRequestsCell != null) {
memberRequestsCell.setTextAndValueAndIcon(LocaleController.getString("MemberRequests", R.string.MemberRequests), String.format("%d", info.requests_pending), R.drawable.msg_requests, logCell != null && logCell.getVisibility() == View.VISIBLE);

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