update to 11.0.0 (5143)

This commit is contained in:
dkaraush 2024-08-14 16:33:13 +04:00
parent 5fa5549a4a
commit 3409cb1c72
362 changed files with 36051 additions and 7184 deletions

View file

@ -42,10 +42,9 @@ dependencies {
implementation 'com.googlecode.mp4parser:isoparser:1.0.6' implementation 'com.googlecode.mp4parser:isoparser:1.0.6'
implementation 'com.stripe:stripe-android:2.0.2' implementation 'com.stripe:stripe-android:2.0.2'
implementation 'com.google.mlkit:language-id:16.1.1' implementation 'com.google.mlkit:language-id:16.1.1'
implementation 'com.android.billingclient:billing:5.1.0' implementation 'com.android.billingclient:billing:6.0.1'
implementation 'com.google.code.gson:gson:2.10' implementation 'com.google.code.gson:gson:2.10'
implementation 'com.google.guava:guava:31.1-android' implementation 'com.google.guava:guava:31.1-android'
implementation 'com.airbnb.android:lottie:6.4.0'
implementation 'com.google.android.play:integrity:1.3.0' implementation 'com.google.android.play:integrity:1.3.0'
implementation 'com.google.android.gms:play-services-safetynet:18.0.1' implementation 'com.google.android.gms:play-services-safetynet:18.0.1'
@ -217,7 +216,9 @@ apply plugin: 'com.google.gms.google-services'
task checkVisibility { task checkVisibility {
doFirst { doFirst {
def isPrivateBuild = project.gradle.startParameter.taskNames.find { it.contains("HA_private") } def isPrivateBuild = project.gradle.startParameter.taskNames.find {
it.contains("HA_private") || it.contains("Debug") || it.contains("Release")
}
def isPublicAllowed = !project.hasProperty("IS_PRIVATE") || !project.property("IS_PRIVATE").toBoolean() def isPublicAllowed = !project.hasProperty("IS_PRIVATE") || !project.property("IS_PRIVATE").toBoolean()
if (!isPrivateBuild && !isPublicAllowed) { if (!isPrivateBuild && !isPublicAllowed) {
throw new GradleException("Building public version of private code!") throw new GradleException("Building public version of private code!")

View file

@ -268,6 +268,7 @@ elseif(${ANDROID_ABI} STREQUAL "arm64-v8a")
rlottie/src/vector/pixman/pixman-arma64-neon-asm.S) rlottie/src/vector/pixman/pixman-arma64-neon-asm.S)
endif() endif()
#flac #flac
add_library(flac STATIC add_library(flac STATIC
exoplayer/libFLAC/bitmath.c exoplayer/libFLAC/bitmath.c
@ -447,7 +448,8 @@ add_library(${NATIVE_LIB} SHARED
exoplayer/ffmpeg_jni.cc exoplayer/ffmpeg_jni.cc
fast-edge.cpp fast-edge.cpp
genann.c genann.c
secureid_ocr.cpp) secureid_ocr.cpp
)
target_compile_options(${NATIVE_LIB} PUBLIC target_compile_options(${NATIVE_LIB} PUBLIC
-ffast-math -Os -funroll-loops -ffast-math -fno-strict-aliasing -fno-math-errno) -ffast-math -Os -funroll-loops -ffast-math -fno-strict-aliasing -fno-math-errno)

View file

@ -528,6 +528,9 @@ void TL_user::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &er
profile_color_color = stream->readInt32(&error); profile_color_color = stream->readInt32(&error);
profile_color_background_emoji_id = stream->readInt64(&error); profile_color_background_emoji_id = stream->readInt64(&error);
} }
if ((flags2 & 4096) != 0) {
bot_active_users = stream->readInt32(&error);
}
} }
void TL_user::serializeToStream(NativeByteBuffer *stream) { void TL_user::serializeToStream(NativeByteBuffer *stream) {
@ -605,6 +608,9 @@ void TL_user::serializeToStream(NativeByteBuffer *stream) {
stream->writeInt32(profile_color_color); stream->writeInt32(profile_color_color);
stream->writeInt32(profile_color_background_emoji_id); stream->writeInt32(profile_color_background_emoji_id);
} }
if ((flags2 & 4096) != 0) {
stream->writeInt32(bot_active_users);
}
} }
InputPeer *InputPeer::TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error) { InputPeer *InputPeer::TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error) {

View file

@ -388,6 +388,7 @@ public:
int64_t color_background_emoji_id; int64_t color_background_emoji_id;
int32_t profile_color_color; int32_t profile_color_color;
int64_t profile_color_background_emoji_id; int64_t profile_color_background_emoji_id;
int32_t bot_active_users;
static User *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error); static User *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
}; };
@ -404,7 +405,7 @@ public:
class TL_user : public User { class TL_user : public User {
public: public:
static const uint32_t constructor = 0x215c4438; static const uint32_t constructor = 0x83314fca;
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error); void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
void serializeToStream(NativeByteBuffer *stream); void serializeToStream(NativeByteBuffer *stream);

View file

@ -102,7 +102,10 @@
android:requestLegacyExternalStorage="true" android:requestLegacyExternalStorage="true"
android:preserveLegacyExternalStorage="true" android:preserveLegacyExternalStorage="true"
android:allowAudioPlaybackCapture="true" android:allowAudioPlaybackCapture="true"
tools:replace="android:supportsRtl"> tools:replace="android:supportsRtl"
android:usesCleartextTraffic="true"
>
<!-- usesCleartextTraffic for browser supporting opening http:// links -->
<activity-alias <activity-alias
android:enabled="true" android:enabled="true"
@ -255,6 +258,12 @@
<data android:host="t.me" android:scheme="http" /> <data android:host="t.me" android:scheme="http" />
<data android:host="t.me" android:scheme="https" /> <data android:host="t.me" android:scheme="https" />
</intent-filter> </intent-filter>
<intent-filter android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:priority="1">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tonsite" />
</intent-filter>
<intent-filter android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:priority="1"> <intent-filter android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:priority="1">
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" /> <category android:name="android.intent.category.BROWSABLE" />

File diff suppressed because one or more lines are too long

View file

@ -441,5 +441,8 @@ code_string=-7806088
code_operator=2147483647 code_operator=2147483647
code_number=-10887465 code_number=-10887465
code_comment=2147483647 code_comment=2147483647
iv_background=-16777216
iv_backgroundGray=-14737633
iv_navigationBackground=-16777216
table_background=177390847 table_background=177390847
table_border=436207615 table_border=436207615

View file

@ -466,5 +466,8 @@ code_string=-7806088
code_operator=2147483647 code_operator=2147483647
code_number=-10887465 code_number=-10887465
code_comment=2147483647 code_comment=2147483647
iv_background=-16777216
iv_backgroundGray=-14737633
iv_navigationBackground=-16777216
table_background=177390847 table_background=177390847
table_border=436207615 table_border=436207615

View file

@ -6,6 +6,7 @@ uniform sampler2D u_BackgroundTexture;
uniform float f_xOffset; uniform float f_xOffset;
uniform float f_alpha; uniform float f_alpha;
uniform mat4 world; uniform mat4 world;
uniform float white;
varying vec3 vNormal; varying vec3 vNormal;
varying vec2 vUV; varying vec2 vUV;
@ -89,5 +90,5 @@ void main() {
clamp(flecksSpec * abs(vNormal.z) * (flecksNormal.z), 0.2, 0.3) - .2 clamp(flecksSpec * abs(vNormal.z) * (flecksNormal.z), 0.2, 0.3) - .2
); );
gl_FragColor = color * f_alpha; gl_FragColor = mix(color * f_alpha, vec4(1.0), white);
} }

View file

@ -221,6 +221,7 @@ public class AndroidUtilities {
public final static int REPLACING_TAG_TYPE_BOLD = 1; public final static int REPLACING_TAG_TYPE_BOLD = 1;
public final static int REPLACING_TAG_TYPE_LINKBOLD = 2; public final static int REPLACING_TAG_TYPE_LINKBOLD = 2;
public final static int REPLACING_TAG_TYPE_LINK_NBSP = 3; public final static int REPLACING_TAG_TYPE_LINK_NBSP = 3;
public final static int REPLACING_TAG_TYPE_UNDERLINE = 4;
public final static String TYPEFACE_ROBOTO_MEDIUM = "fonts/rmedium.ttf"; public final static String TYPEFACE_ROBOTO_MEDIUM = "fonts/rmedium.ttf";
public final static String TYPEFACE_ROBOTO_MEDIUM_ITALIC = "fonts/rmediumitalic.ttf"; public final static String TYPEFACE_ROBOTO_MEDIUM_ITALIC = "fonts/rmediumitalic.ttf";
@ -327,7 +328,7 @@ public class AndroidUtilities {
final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD; final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;
final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")"); final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");
WEB_URL = Pattern.compile( WEB_URL = Pattern.compile(
"((?:(http|https|Http|Https|ton|tg):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)" "((?:(http|https|Http|Https|ton|tg|tonsite):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_" + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?" + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
+ "(?:" + DOMAIN_NAME + ")" + "(?:" + DOMAIN_NAME + ")"
@ -530,13 +531,13 @@ public class AndroidUtilities {
if (type == REPLACING_TAG_TYPE_LINK_NBSP) { if (type == REPLACING_TAG_TYPE_LINK_NBSP) {
spannableStringBuilder.replace(index, index + len, AndroidUtilities.replaceMultipleCharSequence(" ", spannableStringBuilder.subSequence(index, index + len), " ")); spannableStringBuilder.replace(index, index + len, AndroidUtilities.replaceMultipleCharSequence(" ", spannableStringBuilder.subSequence(index, index + len), " "));
} }
if (type == REPLACING_TAG_TYPE_LINK || type == REPLACING_TAG_TYPE_LINK_NBSP || type == REPLACING_TAG_TYPE_LINKBOLD) { if (type == REPLACING_TAG_TYPE_LINK || type == REPLACING_TAG_TYPE_LINK_NBSP || type == REPLACING_TAG_TYPE_LINKBOLD || type == REPLACING_TAG_TYPE_UNDERLINE) {
spannableStringBuilder.setSpan(new ClickableSpan() { spannableStringBuilder.setSpan(new ClickableSpan() {
@Override @Override
public void updateDrawState(@NonNull TextPaint ds) { public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds); super.updateDrawState(ds);
ds.setUnderlineText(false); ds.setUnderlineText(type == REPLACING_TAG_TYPE_UNDERLINE);
if (colorKey >= 0) { if (colorKey >= 0) {
ds.setColor(Theme.getColor(colorKey, resourcesProvider)); ds.setColor(Theme.getColor(colorKey, resourcesProvider));
} }
@ -1101,7 +1102,7 @@ public class AndroidUtilities {
Linkify.addLinks(text, Linkify.PHONE_NUMBERS); Linkify.addLinks(text, Linkify.PHONE_NUMBERS);
} }
if ((mask & Linkify.WEB_URLS) != 0) { if ((mask & Linkify.WEB_URLS) != 0) {
gatherLinks(links, text, LinkifyPort.WEB_URL, new String[]{"http://", "https://", "tg://"}, sUrlMatchFilter, internalOnly); gatherLinks(links, text, LinkifyPort.WEB_URL, new String[]{"http://", "https://", "tg://", "tonsite://"}, sUrlMatchFilter, internalOnly);
} }
pruneOverlaps(links); pruneOverlaps(links);
if (links.size() == 0) { if (links.size() == 0) {
@ -1124,6 +1125,7 @@ public class AndroidUtilities {
if (url != null) { if (url != null) {
url = url.replaceAll("||%E2%81%84|%E2%88%95", "/"); url = url.replaceAll("||%E2%81%84|%E2%88%95", "/");
} }
if (Browser.isTonsitePunycode(url)) continue;
text.setSpan(new URLSpan(url), link.start, link.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); text.setSpan(new URLSpan(url), link.start, link.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
return true; return true;
@ -2105,7 +2107,7 @@ public class AndroidUtilities {
user.first_name = vcardData.name; user.first_name = vcardData.name;
user.last_name = ""; user.last_name = "";
user.id = 0; user.id = 0;
TLRPC.TL_restrictionReason reason = new TLRPC.TL_restrictionReason(); TLRPC.RestrictionReason reason = new TLRPC.RestrictionReason();
reason.text = vcardData.vcard.toString(); reason.text = vcardData.vcard.toString();
reason.platform = ""; reason.platform = "";
reason.reason = ""; reason.reason = "";
@ -4003,7 +4005,16 @@ public class AndroidUtilities {
stringBuilder.replace(a, a + 1, " "); stringBuilder.replace(a, a + 1, " ");
} }
} }
return original; return stringBuilder;
} else if (original instanceof SpannableString) {
if (TextUtils.indexOf(original, '\n') < 0) return original;
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(original);
for (int a = 0, N = original.length(); a < N; a++) {
if (original.charAt(a) == '\n') {
stringBuilder.replace(a, a + 1, " ");
}
}
return stringBuilder;
} }
return original.toString().replace('\n', ' '); return original.toString().replace('\n', ' ');
} }
@ -4734,6 +4745,21 @@ public class AndroidUtilities {
} }
} }
public static void scaleRect(RectF rect, float scale) {
scaleRect(rect, scale, rect.centerX(), rect.centerY());
}
public static void scaleRect(RectF rect, float scale, float px, float py) {
final float wl = px - rect.left, wr = rect.right - px;
final float ht = py - rect.top, hb = rect.bottom - py;
rect.set(
px - wl * scale,
py - ht * scale,
px + wr * scale,
py + hb * scale
);
}
public static float cascade(float fullAnimationT, float position, float count, float waveLength) { public static float cascade(float fullAnimationT, float position, float count, float waveLength) {
if (count <= 0) return fullAnimationT; if (count <= 0) return fullAnimationT;
final float waveDuration = 1f / count * Math.min(waveLength, count); final float waveDuration = 1f / count * Math.min(waveLength, count);
@ -4781,6 +4807,23 @@ public class AndroidUtilities {
return ""; return "";
} }
public static String getCertificateSHA1Fingerprint() {
PackageManager pm = ApplicationLoader.applicationContext.getPackageManager();
String packageName = ApplicationLoader.applicationContext.getPackageName();
try {
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
Signature[] signatures = packageInfo.signatures;
byte[] cert = signatures[0].toByteArray();
InputStream input = new ByteArrayInputStream(cert);
CertificateFactory cf = CertificateFactory.getInstance("X509");
X509Certificate c = (X509Certificate) cf.generateCertificate(input);
return Utilities.bytesToHex(Utilities.computeSHA1(c.getEncoded()));
} catch (Throwable ignore) {
}
return "";
}
private static char[] characters = new char[]{' ', ' ', '!', '"', '#', '%', '&', '\'', '(', ')', '*', ',', '-', '.', '/', ':', ';', '?', '@', '[', '\\', ']', '_', '{', '}', '¡', '§', '«', '¶', '·', '»', '¿', ';', '·', '՚', '՛', '՜', '՝', '՞', '՟', '։', '֊', '־', '׀', '׃', '׆', '׳', '״', '؉', '؊', '،', '؍', '؛', '؞', '؟', '٪', '٫', '٬', '٭', '۔', '܀', '܁', '܂', '܃', '܄', '܅', '܆', '܇', '܈', '܉', '܊', '܋', '܌', '܍', '߷', '߸', '߹', '࠰', '࠱', '࠲', '࠳', '࠴', '࠵', '࠶', '࠷', '࠸', '࠹', '࠺', '࠻', '࠼', '࠽', '࠾', '࡞', '।', '॥', '॰', '৽', '੶', '૰', '౷', '಄', '෴', '๏', '๚', '๛', '༄', '༅', '༆', '༇', '༈', '༉', '༊', '་', '༌', '།', '༎', '༏', '༐', '༑', '༒', '༔', '༺', '༻', '༼', '༽', '྅', '࿐', '࿑', '࿒', '࿓', '࿔', '࿙', '࿚', '၊', '။', '၌', '၍', '၎', '၏', '჻', '፠', '፡', '።', '፣', '፤', '፥', '፦', '፧', '፨', '', '', '᚛', '᚜', '᛫', '', '', '', '᜶', '។', '៕', '៖', '៘', '៙', '៚', '᠀', '᠁', '᠂', '', '᠄', '᠅', '᠆', '᠇', '᠈', '', '᠊', '᥄', '᥅', '᨞', '᨟', '᪠', '᪡', '᪢', '᪣', '᪤', '᪥', '᪦', '᪨', '᪩', '᪪', '᪫', '᪬', '᪭', '᭚', '᭛', '᭜', '᭝', '᭞', '᭟', '᭠', '᯼', '᯽', '᯾', '᯿', '᰻', '᰼', '᰽', '᰾', '᰿', '᱾', '᱿', '᳀', '᳁', '᳂', '᳃', '᳄', '᳅', '᳆', '᳇', '᳓', '', '', '', '', '—', '―', '‖', '‗', '', '', '', '', '“', '”', '„', '‟', '†', '‡', '•', '‣', '', '‥', '…', '‧', '‰', '‱', '', '″', '‴', '', '‶', '‷', '‸', '', '', '※', '‼', '‽', '‾', '‿', '⁀', '', '⁂', '', '⁅', '⁆', '⁇', '⁈', '⁉', '⁊', '⁋', '⁌', '⁍', '', '⁏', '⁐', '⁑', '', '⁔', '⁕', '⁖', '⁗', '⁘', '⁙', '', '⁛', '⁜', '⁝', '⁞', '⁽', '⁾', '₍', '₎', '⌈', '⌉', '⌊', '⌋', '〈', '〉', '', '', '❪', '❫', '❬', '❭', '', '', '❰', '❱', '', '', '', '', '⟅', '⟆', '⟦', '⟧', '⟨', '⟩', '⟪', '⟫', '⟬', '⟭', '⟮', '⟯', '⦃', '⦄', '⦅', '⦆', '⦇', '⦈', '⦉', '⦊', '⦋', '⦌', '⦍', '⦎', '⦏', '⦐', '⦑', '⦒', '⦓', '⦔', '⦕', '⦖', '⦗', '⦘', '⧘', '⧙', '⧚', '⧛', '⧼', '⧽', '⳹', '⳺', '⳻', '⳼', '⳾', '⳿', '⵰', '⸀', '⸁', '⸂', '⸃', '⸄', '⸅', '⸆', '⸇', '⸈', '⸉', '⸊', '⸋', '⸌', '⸍', '⸎', '⸏', '⸐', '⸑', '⸒', '⸓', '⸔', '⸕', '⸖', '⸗', '⸘', '⸙', '⸚', '⸛', '⸜', '⸝', '⸞', '⸟', '⸠', '⸡', '⸢', '⸣', '⸤', '⸥', '⸦', '⸧', '⸨', '⸩', '⸪', '⸫', '⸬', '⸭', '⸮', '⸰', '⸱', '⸲', '⸳', '⸴', '⸵', '⸶', '⸷', '⸸', '⸹', '⸺', '⸻', '⸼', '⸽', '⸾', '⸿', '', '⹁', '⹂', '⹃', '⹄', '⹅', '⹆', '⹇', '⹈', '⹉', '⹊', '⹋', '⹌', '⹍', '⹎', '⹏', '、', '。', '〃', '〈', '〉', '《', '》', '「', '」', '『', '』', '【', '】', '', '', '〖', '〗', '〘', '〙', '〚', '〛', '〜', '〝', '〞', '〟', '〰', '〽', '', '・', '꓾', '', '꘍', '', '꘏', '꙳', '꙾', '꛲', '꛳', '꛴', '꛵', '꛶', '꛷', '꡴', '꡵', '꡶', '꡷', '꣎', '꣏', '꣸', '꣹', '꣺', '꣼', '꤮', '꤯', '꥟', '꧁', '꧂', '꧃', '꧄', '꧅', '꧆', '꧇', '꧈', '꧉', '꧊', '꧋', '꧌', '꧍', '꧞', '꧟', '꩜', '꩝', '꩞', '꩟', '꫞', '꫟', '꫰', '꫱', '꯫', '', '﴿', '︐', '︑', '︒', '︓', '︔', '︕', '︖', '︗', '︘', '︙', '', '︱', '︲', '︳', '︴', '︵', '︶', '︷', '︸', '︹', '︺', '︻', '︼', '︽', '︾', '︿', '﹀', '﹁', '﹂', '﹃', '﹄', '﹅', '﹆', '﹇', '﹈', '﹉', '﹊', '﹋', '﹌', '', '', '', '﹐', '﹑', '﹒', '﹔', '﹕', '﹖', '﹗', '', '﹙', '﹚', '﹛', '﹜', '﹝', '﹞', '﹟', '﹠', '﹡', '﹣', '', '﹪', '﹫', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '_', '', '', '⦅', '⦆', '。', '「', '」', '、', '・'}; private static char[] characters = new char[]{' ', ' ', '!', '"', '#', '%', '&', '\'', '(', ')', '*', ',', '-', '.', '/', ':', ';', '?', '@', '[', '\\', ']', '_', '{', '}', '¡', '§', '«', '¶', '·', '»', '¿', ';', '·', '՚', '՛', '՜', '՝', '՞', '՟', '։', '֊', '־', '׀', '׃', '׆', '׳', '״', '؉', '؊', '،', '؍', '؛', '؞', '؟', '٪', '٫', '٬', '٭', '۔', '܀', '܁', '܂', '܃', '܄', '܅', '܆', '܇', '܈', '܉', '܊', '܋', '܌', '܍', '߷', '߸', '߹', '࠰', '࠱', '࠲', '࠳', '࠴', '࠵', '࠶', '࠷', '࠸', '࠹', '࠺', '࠻', '࠼', '࠽', '࠾', '࡞', '।', '॥', '॰', '৽', '੶', '૰', '౷', '಄', '෴', '๏', '๚', '๛', '༄', '༅', '༆', '༇', '༈', '༉', '༊', '་', '༌', '།', '༎', '༏', '༐', '༑', '༒', '༔', '༺', '༻', '༼', '༽', '྅', '࿐', '࿑', '࿒', '࿓', '࿔', '࿙', '࿚', '၊', '။', '၌', '၍', '၎', '၏', '჻', '፠', '፡', '።', '፣', '፤', '፥', '፦', '፧', '፨', '', '', '᚛', '᚜', '᛫', '', '', '', '᜶', '។', '៕', '៖', '៘', '៙', '៚', '᠀', '᠁', '᠂', '', '᠄', '᠅', '᠆', '᠇', '᠈', '', '᠊', '᥄', '᥅', '᨞', '᨟', '᪠', '᪡', '᪢', '᪣', '᪤', '᪥', '᪦', '᪨', '᪩', '᪪', '᪫', '᪬', '᪭', '᭚', '᭛', '᭜', '᭝', '᭞', '᭟', '᭠', '᯼', '᯽', '᯾', '᯿', '᰻', '᰼', '᰽', '᰾', '᰿', '᱾', '᱿', '᳀', '᳁', '᳂', '᳃', '᳄', '᳅', '᳆', '᳇', '᳓', '', '', '', '', '—', '―', '‖', '‗', '', '', '', '', '“', '”', '„', '‟', '†', '‡', '•', '‣', '', '‥', '…', '‧', '‰', '‱', '', '″', '‴', '', '‶', '‷', '‸', '', '', '※', '‼', '‽', '‾', '‿', '⁀', '', '⁂', '', '⁅', '⁆', '⁇', '⁈', '⁉', '⁊', '⁋', '⁌', '⁍', '', '⁏', '⁐', '⁑', '', '⁔', '⁕', '⁖', '⁗', '⁘', '⁙', '', '⁛', '⁜', '⁝', '⁞', '⁽', '⁾', '₍', '₎', '⌈', '⌉', '⌊', '⌋', '〈', '〉', '', '', '❪', '❫', '❬', '❭', '', '', '❰', '❱', '', '', '', '', '⟅', '⟆', '⟦', '⟧', '⟨', '⟩', '⟪', '⟫', '⟬', '⟭', '⟮', '⟯', '⦃', '⦄', '⦅', '⦆', '⦇', '⦈', '⦉', '⦊', '⦋', '⦌', '⦍', '⦎', '⦏', '⦐', '⦑', '⦒', '⦓', '⦔', '⦕', '⦖', '⦗', '⦘', '⧘', '⧙', '⧚', '⧛', '⧼', '⧽', '⳹', '⳺', '⳻', '⳼', '⳾', '⳿', '⵰', '⸀', '⸁', '⸂', '⸃', '⸄', '⸅', '⸆', '⸇', '⸈', '⸉', '⸊', '⸋', '⸌', '⸍', '⸎', '⸏', '⸐', '⸑', '⸒', '⸓', '⸔', '⸕', '⸖', '⸗', '⸘', '⸙', '⸚', '⸛', '⸜', '⸝', '⸞', '⸟', '⸠', '⸡', '⸢', '⸣', '⸤', '⸥', '⸦', '⸧', '⸨', '⸩', '⸪', '⸫', '⸬', '⸭', '⸮', '⸰', '⸱', '⸲', '⸳', '⸴', '⸵', '⸶', '⸷', '⸸', '⸹', '⸺', '⸻', '⸼', '⸽', '⸾', '⸿', '', '⹁', '⹂', '⹃', '⹄', '⹅', '⹆', '⹇', '⹈', '⹉', '⹊', '⹋', '⹌', '⹍', '⹎', '⹏', '、', '。', '〃', '〈', '〉', '《', '》', '「', '」', '『', '』', '【', '】', '', '', '〖', '〗', '〘', '〙', '〚', '〛', '〜', '〝', '〞', '〟', '〰', '〽', '', '・', '꓾', '', '꘍', '', '꘏', '꙳', '꙾', '꛲', '꛳', '꛴', '꛵', '꛶', '꛷', '꡴', '꡵', '꡶', '꡷', '꣎', '꣏', '꣸', '꣹', '꣺', '꣼', '꤮', '꤯', '꥟', '꧁', '꧂', '꧃', '꧄', '꧅', '꧆', '꧇', '꧈', '꧉', '꧊', '꧋', '꧌', '꧍', '꧞', '꧟', '꩜', '꩝', '꩞', '꩟', '꫞', '꫟', '꫰', '꫱', '꯫', '', '﴿', '︐', '︑', '︒', '︓', '︔', '︕', '︖', '︗', '︘', '︙', '', '︱', '︲', '︳', '︴', '︵', '︶', '︷', '︸', '︹', '︺', '︻', '︼', '︽', '︾', '︿', '﹀', '﹁', '﹂', '﹃', '﹄', '﹅', '﹆', '﹇', '﹈', '﹉', '﹊', '﹋', '﹌', '', '', '', '﹐', '﹑', '﹒', '﹔', '﹕', '﹖', '﹗', '', '﹙', '﹚', '﹛', '﹜', '﹝', '﹞', '﹟', '﹠', '﹡', '﹣', '', '﹪', '﹫', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '_', '', '', '⦅', '⦆', '。', '「', '」', '、', '・'};
//private static String[] longCharacters = new String[] {"𐄀", "𐄁", "𐄂", "𐎟", "𐏐", "𐕯", "𐡗", "𐤟", "𐤿", "𐩐", "𐩑", "𐩒", "𐩓", "𐩔", "𐩕", "𐩖", "𐩗", "𐩘", "𐩿", "𐫰", "𐫱", "𐫲", "𐫳", "𐫴", "𐫵", "𐫶", "𐬹", "𐬺", "𐬻", "𐬼", "𐬽", "𐬾", "𐬿", "𐮙", "𐮚", "𐮛", "𐮜", "𐽕", "𐽖", "𐽗", "𐽘", "𐽙", "𑁇", "𑁈", "𑁉", "𑁊", "𑁋", "𑁌", "𑁍", "𑂻", "𑂼", "𑂾", "𑂿", "𑃀", "𑃁", "𑅀", "𑅁", "𑅂", "𑅃", "𑅴", "𑅵", "𑇅", "𑇆", "𑇇", "𑇈", "𑇍", "𑇛", "𑇝", "𑇞", "𑇟", "𑈸", "𑈹", "𑈺", "𑈻", "𑈼", "𑈽", "𑊩", "𑑋", "𑑌", "𑑍", "𑑎", "𑑏", "𑑛", "𑑝", "𑓆", "𑗁", "𑗂", "𑗃", "𑗄", "𑗅", "𑗆", "𑗇", "𑗈", "𑗉", "𑗊", "𑗋", "𑗌", "𑗍", "𑗎", "𑗏", "𑗐", "𑗑", "𑗒", "𑗓", "𑗔", "𑗕", "𑗖", "𑗗", "𑙁", "𑙂", "𑙃", "𑙠", "𑙡", "𑙢", "𑙣", "𑙤", "𑙥", "𑙦", "𑙧", "𑙨", "𑙩", "𑙪", "𑙫", "𑙬", "𑜼", "𑜽", "𑜾", "𑠻", "𑧢", "𑨿", "𑩀", "𑩁", "𑩂", "𑩃", "𑩄", "𑩅", "𑩆", "𑪚", "𑪛", "𑪜", "𑪞", "𑪟", "𑪠", "𑪡", "𑪢", "𑱁", "𑱂", "𑱃", "𑱄", "𑱅", "𑱰", "𑱱", "𑻷", "𑻸", "𑿿", "𒑰", "𒑱", "𒑲", "𒑳", "𒑴", "𖩮", "𖩯", "𖫵", "𖬷", "𖬸", "𖬹", "𖬺", "𖬻", "𖭄", "𖺗", "𖺘", "𖺙", "𖺚", "𖿢", "𛲟", "𝪇", "𝪈", "𝪉", "𝪊", "𝪋", "𞥞", "𞥟"}; //private static String[] longCharacters = new String[] {"𐄀", "𐄁", "𐄂", "𐎟", "𐏐", "𐕯", "𐡗", "𐤟", "𐤿", "𐩐", "𐩑", "𐩒", "𐩓", "𐩔", "𐩕", "𐩖", "𐩗", "𐩘", "𐩿", "𐫰", "𐫱", "𐫲", "𐫳", "𐫴", "𐫵", "𐫶", "𐬹", "𐬺", "𐬻", "𐬼", "𐬽", "𐬾", "𐬿", "𐮙", "𐮚", "𐮛", "𐮜", "𐽕", "𐽖", "𐽗", "𐽘", "𐽙", "𑁇", "𑁈", "𑁉", "𑁊", "𑁋", "𑁌", "𑁍", "𑂻", "𑂼", "𑂾", "𑂿", "𑃀", "𑃁", "𑅀", "𑅁", "𑅂", "𑅃", "𑅴", "𑅵", "𑇅", "𑇆", "𑇇", "𑇈", "𑇍", "𑇛", "𑇝", "𑇞", "𑇟", "𑈸", "𑈹", "𑈺", "𑈻", "𑈼", "𑈽", "𑊩", "𑑋", "𑑌", "𑑍", "𑑎", "𑑏", "𑑛", "𑑝", "𑓆", "𑗁", "𑗂", "𑗃", "𑗄", "𑗅", "𑗆", "𑗇", "𑗈", "𑗉", "𑗊", "𑗋", "𑗌", "𑗍", "𑗎", "𑗏", "𑗐", "𑗑", "𑗒", "𑗓", "𑗔", "𑗕", "𑗖", "𑗗", "𑙁", "𑙂", "𑙃", "𑙠", "𑙡", "𑙢", "𑙣", "𑙤", "𑙥", "𑙦", "𑙧", "𑙨", "𑙩", "𑙪", "𑙫", "𑙬", "𑜼", "𑜽", "𑜾", "𑠻", "𑧢", "𑨿", "𑩀", "𑩁", "𑩂", "𑩃", "𑩄", "𑩅", "𑩆", "𑪚", "𑪛", "𑪜", "𑪞", "𑪟", "𑪠", "𑪡", "𑪢", "𑱁", "𑱂", "𑱃", "𑱄", "𑱅", "𑱰", "𑱱", "𑻷", "𑻸", "𑿿", "𒑰", "𒑱", "𒑲", "𒑳", "𒑴", "𖩮", "𖩯", "𖫵", "𖬷", "𖬸", "𖬹", "𖬺", "𖬻", "𖭄", "𖺗", "𖺘", "𖺙", "𖺚", "𖿢", "𛲟", "𝪇", "𝪈", "𝪉", "𝪊", "𝪋", "𞥞", "𞥟"};
private static HashSet<Character> charactersMap; private static HashSet<Character> charactersMap;
@ -5407,11 +5450,25 @@ public class AndroidUtilities {
public static boolean hasDialogOnTop(BaseFragment fragment) { public static boolean hasDialogOnTop(BaseFragment fragment) {
if (fragment == null) return false; if (fragment == null) return false;
if (fragment.visibleDialog != null) return true; if (fragment.visibleDialog != null && !(fragment.visibleDialog instanceof AlertDialog) && !(
fragment.visibleDialog instanceof BottomSheet && ((BottomSheet) fragment.visibleDialog).attachedFragment != null
)) return true;
if (fragment.getParentLayout() == null) return false; if (fragment.getParentLayout() == null) return false;
List<View> globalViews = allGlobalViews(); List<View> globalViews = allGlobalViews();
if (globalViews == null || globalViews.isEmpty()) return false; if (globalViews == null || globalViews.isEmpty()) return false;
View lastGlobalView = globalViews.get(globalViews.size() - 1); View lastGlobalView = null;
for (int i = globalViews.size() - 1; i >= 0; --i) {
lastGlobalView = globalViews.get(i);
if (fragment.visibleDialog instanceof AlertDialog) {
if (lastGlobalView == getRootView((((AlertDialog) fragment.visibleDialog).getContainerView()))) {
continue;
}
}
if (!(
lastGlobalView instanceof AlertDialog.AlertDialogView ||
lastGlobalView instanceof PipRoundVideoView.PipFrameLayout
)) break;
}
return lastGlobalView != getRootView(fragment.getParentLayout().getView()); return lastGlobalView != getRootView(fragment.getParentLayout().getView());
} }
@ -5464,7 +5521,7 @@ public class AndroidUtilities {
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite)); canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite));
for (int i = 0; i < finalViews.size(); ++i) { for (int i = 0; i < finalViews.size(); ++i) {
View view = finalViews.get(i); View view = finalViews.get(i);
if (view instanceof PipRoundVideoView.PipFrameLayout || view instanceof PipRoundVideoView.PipFrameLayout || (exclude != null && exclude.contains(view))) { if (view instanceof PipRoundVideoView.PipFrameLayout || (exclude != null && exclude.contains(view))) {
continue; continue;
} }
@ -5482,7 +5539,7 @@ public class AndroidUtilities {
try { try {
view.draw(canvas); view.draw(canvas);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e);
} }
canvas.restore(); canvas.restore();
} }
@ -5559,7 +5616,7 @@ public class AndroidUtilities {
private static Pattern uriParse; private static Pattern uriParse;
private static Pattern getURIParsePattern() { public static Pattern getURIParsePattern() {
if (uriParse == null) { if (uriParse == null) {
uriParse = Pattern.compile("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"); // RFC 3986 B uriParse = Pattern.compile("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?"); // RFC 3986 B
} }
@ -5567,6 +5624,10 @@ public class AndroidUtilities {
} }
public static String getHostAuthority(String uri) { public static String getHostAuthority(String uri) {
return getHostAuthority(uri, false);
}
public static String getHostAuthority(String uri, boolean removeWWW) {
if (uri == null) { if (uri == null) {
return null; return null;
} }
@ -5577,6 +5638,9 @@ public class AndroidUtilities {
if (authority != null) { if (authority != null) {
authority = authority.toLowerCase(); authority = authority.toLowerCase();
} }
if (removeWWW && authority != null && authority.startsWith("www.")) {
authority = authority.substring(4);
}
return authority; return authority;
} }
return null; return null;
@ -5589,6 +5653,13 @@ public class AndroidUtilities {
return getHostAuthority(uri.toString()); return getHostAuthority(uri.toString());
} }
public static String getHostAuthority(Uri uri, boolean removeWWW) {
if (uri == null) {
return null;
}
return getHostAuthority(uri.toString(), removeWWW);
}
public static boolean intersect1d(int x1, int x2, int y1, int y2) { 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); return Math.max(x1, x2) > Math.min(y1, y2) && Math.max(y1, y2) > Math.min(x1, x2);
} }
@ -5891,27 +5962,56 @@ public class AndroidUtilities {
} catch (Exception ignore) {} } catch (Exception ignore) {}
} }
public static void applySpring(Animator anim, float stiffness, float damping) { public static void applySpring(Animator anim, double stiffness, double damping) {
applySpring(anim, stiffness, damping, 1); applySpring(anim, stiffness, damping, 1, 0);
} }
public static void applySpring(Animator anim, float stiffness, float damping, float mass) { public static void applySpring(Animator anim, double stiffness, double damping, double mass) {
final double delta = damping / (2.0 * Math.sqrt(stiffness * mass)); applySpring(anim, stiffness, damping, mass, 0);
final double undampedFrequency = Math.sqrt(stiffness / mass); }
final double omega_0 = Math.sqrt(stiffness / mass);
final double zeta = damping / (2 * Math.sqrt(stiffness * mass)); public static void applySpring(Animator anim, double stiffness, double damping, double mass, double initialVelocity) {
final double w0 = Math.sqrt(stiffness / mass);
final double zeta = damping / (2.0 * Math.sqrt(stiffness * mass));
final double wd, A, B;
if (zeta < 1) {
wd = w0 * Math.sqrt(1.0 - zeta * zeta);
A = 1.0;
B = (zeta * w0 + -initialVelocity) / wd;
} else {
wd = 0.0;
A = 1.0;
B = -initialVelocity + w0;
}
final double threshold = 0.0025; final double threshold = 0.0025;
final double duration = Math.log(threshold) / (-zeta * omega_0); final double duration = Math.log(threshold) / (-zeta * w0);
anim.setDuration((long) (duration * 1000L)); anim.setDuration((long) (duration * 1000L));
anim.setInterpolator(new Interpolator() { anim.setInterpolator(new Interpolator() {
@Override @Override
public float getInterpolation(float t) { public float getInterpolation(float t) {
if (delta < 1) { if (zeta < 1) {
final double dampedFrequency = undampedFrequency * Math.sqrt(1 - delta * delta); return (float) (1.0 - Math.exp(-t * zeta * w0) * (A * Math.cos(wd * t) + B * Math.sin(wd * t)));
return (float) (1 - Math.exp(-delta * undampedFrequency * t) *
(Math.cos(dampedFrequency * t) + (delta * undampedFrequency / dampedFrequency) * Math.sin(dampedFrequency * t)));
} else { } else {
final double a = -delta * undampedFrequency * t; return (float) (1.0 - (A + B * t) * Math.exp(-t * w0));
}
}
});
}
public static void applySpring(Animator anim, float stiffness, float damping, float mass, long overrideDuration) {
final double zeta = damping / (2 * Math.sqrt(stiffness * mass));
final double omega = Math.sqrt(stiffness / mass);
final double threshold = 0.0025;
anim.setDuration(overrideDuration);
anim.setInterpolator(new Interpolator() {
@Override
public float getInterpolation(float t) {
if (zeta < 1) {
final double dampedFrequency = omega * Math.sqrt(1 - zeta * zeta);
return (float) (1 - Math.exp(-zeta * omega * t) *
(Math.cos(dampedFrequency * t) + (zeta * omega / dampedFrequency) * Math.sin(dampedFrequency * t)));
} else {
final double a = -zeta * omega * t;
return (float) (1 - (1 + a) * Math.exp(a)); return (float) (1 - (1 + a) * Math.exp(a));
} }
} }
@ -5942,9 +6042,9 @@ public class AndroidUtilities {
if (segments.size() >= 3 && "s".equals(segments.get(1))) { if (segments.size() >= 3 && "s".equals(segments.get(1))) {
return false; return false;
} else if (segments.size() > 1) { } else if (segments.size() > 1) {
final String segment = segments.get(1); final String segment0 = segments.get(0);
if (TextUtils.isEmpty(segment)) return false; if (TextUtils.isEmpty(segment0)) return false;
switch (segment) { switch (segment0) {
case "joinchat": case "joinchat":
case "login": case "login":
case "addstickers": case "addstickers":
@ -5961,6 +6061,9 @@ public class AndroidUtilities {
case "addlist": case "addlist":
return false; return false;
} }
final String segment1 = segments.get(1);
if (TextUtils.isEmpty(segment1)) return false;
if (segment1.matches("^\\d+$")) return false;
return true; return true;
} else if (segments.size() == 1) { } else if (segments.size() == 1) {
return !TextUtils.isEmpty(uri.getQueryParameter("startapp")); return !TextUtils.isEmpty(uri.getQueryParameter("startapp"));

View file

@ -638,5 +638,4 @@ public class ApplicationLoader extends Application {
public BaseFragment openSettings(int n) { public BaseFragment openSettings(int n) {
return null; return null;
} }
} }

View file

@ -192,7 +192,7 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
return; return;
} }
if ((paymentPurpose instanceof TLRPC.TL_inputStorePaymentGiftPremium || paymentPurpose instanceof TLRPC.TL_inputStorePaymentStars) && !checkedConsume) { if ((paymentPurpose instanceof TLRPC.TL_inputStorePaymentGiftPremium || paymentPurpose instanceof TLRPC.TL_inputStorePaymentStarsTopup || paymentPurpose instanceof TLRPC.TL_inputStorePaymentStarsGift) && !checkedConsume) {
queryPurchases(BillingClient.ProductType.INAPP, (billingResult, list) -> { queryPurchases(BillingClient.ProductType.INAPP, (billingResult, list) -> {
if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) { if (billingResult.getResponseCode() == BillingClient.BillingResponseCode.OK) {
Runnable callback = () -> launchBillingFlow(activity, accountInstance, paymentPurpose, productDetails, subscriptionUpdateParams, true); Runnable callback = () -> launchBillingFlow(activity, accountInstance, paymentPurpose, productDetails, subscriptionUpdateParams, true);
@ -244,7 +244,8 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
if (subscriptionUpdateParams != null) { if (subscriptionUpdateParams != null) {
flowParams.setSubscriptionUpdateParams(subscriptionUpdateParams); flowParams.setSubscriptionUpdateParams(subscriptionUpdateParams);
} }
int responseCode = billingClient.launchBillingFlow(activity, flowParams.build()).getResponseCode(); final BillingResult result = billingClient.launchBillingFlow(activity, flowParams.build());
int responseCode = result.getResponseCode();
if (responseCode != BillingClient.BillingResponseCode.OK) { if (responseCode != BillingClient.BillingResponseCode.OK) {
FileLog.d("Billing: Launch Error: " + responseCode + ", " + obfuscatedAccountId + ", " + obfuscatedData); FileLog.d("Billing: Launch Error: " + responseCode + ", " + obfuscatedAccountId + ", " + obfuscatedData);
} }
@ -281,41 +282,40 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
if (!purchase.isAcknowledged()) { if (!purchase.isAcknowledged()) {
requestingTokens.add(purchase.getPurchaseToken()); requestingTokens.add(purchase.getPurchaseToken());
retrievePurpose(purchase, opayload, payload -> { TLRPC.TL_payments_assignPlayMarketTransaction req = new TLRPC.TL_payments_assignPlayMarketTransaction();
TLRPC.TL_payments_assignPlayMarketTransaction req = new TLRPC.TL_payments_assignPlayMarketTransaction(); req.receipt = new TLRPC.TL_dataJSON();
req.receipt = new TLRPC.TL_dataJSON(); req.receipt.data = purchase.getOriginalJson();
req.receipt.data = purchase.getOriginalJson(); req.purpose = opayload.second;
req.purpose = payload.second;
final AlertDialog progressDialog = new AlertDialog(ApplicationLoader.applicationContext, AlertDialog.ALERT_TYPE_SPINNER); final AlertDialog progressDialog = new AlertDialog(ApplicationLoader.applicationContext, AlertDialog.ALERT_TYPE_SPINNER);
AndroidUtilities.runOnUIThread(() -> progressDialog.showDelayed(500)); AndroidUtilities.runOnUIThread(() -> progressDialog.showDelayed(500));
AccountInstance acc = payload.first; AccountInstance acc = opayload.first;
acc.getConnectionsManager().sendRequest(req, (response, error) -> { acc.getConnectionsManager().sendRequest(req, (response, error) -> {
AndroidUtilities.runOnUIThread(progressDialog::dismiss); AndroidUtilities.runOnUIThread(progressDialog::dismiss);
requestingTokens.remove(purchase.getPurchaseToken()); requestingTokens.remove(purchase.getPurchaseToken());
if (response instanceof TLRPC.Updates) { if (response instanceof TLRPC.Updates) {
acc.getMessagesController().processUpdates((TLRPC.Updates) response, false); acc.getMessagesController().processUpdates((TLRPC.Updates) response, false);
for (String productId : purchase.getProducts()) { for (String productId : purchase.getProducts()) {
Consumer<BillingResult> listener = resultListeners.remove(productId); Consumer<BillingResult> listener = resultListeners.remove(productId);
if (listener != null) { if (listener != null) {
listener.accept(billing); listener.accept(billing);
}
} }
consumeGiftPurchase(purchase, req.purpose);
} else if (error != null) {
if (onCanceled != null) {
onCanceled.run();
onCanceled = null;
}
NotificationCenter.getGlobalInstance().postNotificationNameOnUIThread(NotificationCenter.billingConfirmPurchaseError, req, error);
} }
}, ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagFailOnServerErrorsExceptFloodWait | ConnectionsManager.RequestFlagInvokeAfter);
}); consumeGiftPurchase(purchase, req.purpose);
BillingUtilities.cleanupPurchase(purchase);
} else if (error != null) {
if (onCanceled != null) {
onCanceled.run();
onCanceled = null;
}
NotificationCenter.getGlobalInstance().postNotificationNameOnUIThread(NotificationCenter.billingConfirmPurchaseError, req, error);
}
}, ConnectionsManager.RequestFlagFailOnServerErrors | ConnectionsManager.RequestFlagFailOnServerErrorsExceptFloodWait | ConnectionsManager.RequestFlagInvokeAfter);
} else { } else {
consumeGiftPurchase(purchase, opayload.second); consumeGiftPurchase(purchase, opayload.second);
} }
@ -323,93 +323,6 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
} }
} }
private boolean retrievePurpose(Purchase purchase, Pair<AccountInstance, TLRPC.InputStorePaymentPurpose> payload, Utilities.Callback<Pair<AccountInstance, TLRPC.InputStorePaymentPurpose>> whenPayload) {
if (payload == null || payload.first == null) {
FileLog.d("retrievePurpose: payload or account is null");
return false;
}
if (payload.second != null) {
FileLog.d("retrievePurpose: already has purpose");
whenPayload.run(payload);
return true;
}
if (purchase == null || purchase.getProducts().isEmpty()) {
FileLog.d("retrievePurpose: no products found for purpose!");
whenPayload.run(payload);
return false;
} else {
final int currentAccount = payload.first.getCurrentAccount();
final String productId = purchase.getProducts().get(0);
if (productId == null) {
FileLog.d("retrievePurpose: first product is null!");
whenPayload.run(payload);
return false;
}
ArrayList<TLRPC.TL_starsTopupOption> options = StarsController.getInstance(currentAccount).getOptionsCached();
if (options == null) {
ConnectionsManager.getInstance(currentAccount).sendRequest(new TLRPC.TL_payments_getStarsTopupOptions(), (res, err) -> AndroidUtilities.runOnUIThread(() -> {
ArrayList<TLRPC.TL_starsTopupOption> loadedOptions = new ArrayList<>();
if (res instanceof TLRPC.Vector) {
TLRPC.Vector vector = (TLRPC.Vector) res;
for (Object object : vector.objects) {
if (object instanceof TLRPC.TL_starsTopupOption) {
TLRPC.TL_starsTopupOption option = (TLRPC.TL_starsTopupOption) object;
loadedOptions.add(option);
}
}
} else if (err != null) {
FileLog.d("retrievePopup: getStarsTopupOptions gives error! " + err.code + ": " + err.text);
}
TLRPC.TL_starsTopupOption foundOption = null;
for (int i = 0; i < loadedOptions.size(); ++i) {
if (productId.equals(loadedOptions.get(i).store_product)) {
foundOption = loadedOptions.get(i);
break;
}
}
if (foundOption != null) {
TLRPC.TL_inputStorePaymentStars purpose = new TLRPC.TL_inputStorePaymentStars();
purpose.amount = foundOption.amount;
purpose.currency = foundOption.currency;
purpose.stars = foundOption.stars;
FileLog.d("retrievePurpose: found stars option of " + productId + " from stars loaded options!");
whenPayload.run(new Pair<AccountInstance, TLRPC.InputStorePaymentPurpose>(payload.first, purpose));
} else {
FileLog.d("retrievePurpose: failed to find option of " + productId + " from stars loaded options");
whenPayload.run(payload);
}
}));
return true;
} else {
TLRPC.TL_starsTopupOption foundOption = null;
for (int i = 0; i < options.size(); ++i) {
if (productId.equals(options.get(i).store_product)) {
foundOption = options.get(i);
break;
}
}
if (foundOption != null) {
TLRPC.TL_inputStorePaymentStars purpose = new TLRPC.TL_inputStorePaymentStars();
purpose.amount = foundOption.amount;
purpose.currency = foundOption.currency;
purpose.stars = foundOption.stars;
FileLog.d("retrievePurpose: found stars option of " + productId + " from stars options!");
whenPayload.run(new Pair<AccountInstance, TLRPC.InputStorePaymentPurpose>(payload.first, purpose));
return true;
} else {
FileLog.d("retrievePurpose: failed to find option of " + productId + " from stars options");
whenPayload.run(payload);
return false;
}
}
}
}
/** /**
* All consumable purchases must be consumed. For us it is a gift. * All consumable purchases must be consumed. For us it is a gift.
* Without confirmation the user will not be able to buy the product again. * Without confirmation the user will not be able to buy the product again.
@ -417,7 +330,8 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
private void consumeGiftPurchase(Purchase purchase, TLRPC.InputStorePaymentPurpose purpose) { private void consumeGiftPurchase(Purchase purchase, TLRPC.InputStorePaymentPurpose purpose) {
if (purpose instanceof TLRPC.TL_inputStorePaymentGiftPremium if (purpose instanceof TLRPC.TL_inputStorePaymentGiftPremium
|| purpose instanceof TLRPC.TL_inputStorePaymentPremiumGiftCode || purpose instanceof TLRPC.TL_inputStorePaymentPremiumGiftCode
|| purpose instanceof TLRPC.TL_inputStorePaymentStars || purpose instanceof TLRPC.TL_inputStorePaymentStarsTopup
|| purpose instanceof TLRPC.TL_inputStorePaymentStarsGift
|| purpose instanceof TLRPC.TL_inputStorePaymentPremiumGiveaway) { || purpose instanceof TLRPC.TL_inputStorePaymentPremiumGiveaway) {
billingClient.consumeAsync( billingClient.consumeAsync(
ConsumeParams.newBuilder() ConsumeParams.newBuilder()
@ -510,18 +424,19 @@ public class BillingController implements PurchasesUpdatedListener, BillingClien
public static String getResponseCodeString(int code) { public static String getResponseCodeString(int code) {
switch (code) { switch (code) {
case -3: return "SERVICE_TIMEOUT"; case BillingClient.BillingResponseCode.SERVICE_TIMEOUT: return "SERVICE_TIMEOUT";
case -2: return "FEATURE_NOT_SUPPORTED"; case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED: return "FEATURE_NOT_SUPPORTED";
case -1: return "SERVICE_DISCONNECTED"; case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED: return "SERVICE_DISCONNECTED";
case 0: return "OK"; case BillingClient.BillingResponseCode.OK: return "OK";
case 1: return "USER_CANCELED"; case BillingClient.BillingResponseCode.USER_CANCELED: return "USER_CANCELED";
case 2: return "SERVICE_UNAVAILABLE"; case BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE: return "SERVICE_UNAVAILABLE";
case 3: return "BILLING_UNAVAILABLE"; case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE: return "BILLING_UNAVAILABLE";
case 4: return "ITEM_UNAVAILABLE"; case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE: return "ITEM_UNAVAILABLE";
case 5: return "DEVELOPER_ERROR"; case BillingClient.BillingResponseCode.DEVELOPER_ERROR: return "DEVELOPER_ERROR";
case 6: return "ERROR"; case BillingClient.BillingResponseCode.ERROR: return "ERROR";
case 7: return "ITEM_ALREADY_OWNED"; case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED: return "ITEM_ALREADY_OWNED";
case 8: return "ITEM_NOT_OWNED"; case BillingClient.BillingResponseCode.ITEM_NOT_OWNED: return "ITEM_NOT_OWNED";
case BillingClient.BillingResponseCode.NETWORK_ERROR: return "NETWORK_ERROR";
} }
return null; return null;
} }

View file

@ -1782,7 +1782,7 @@ public class ChatObject {
} }
public static boolean canSendAsPeers(TLRPC.Chat chat) { public static boolean canSendAsPeers(TLRPC.Chat chat) {
return ChatObject.isChannel(chat) && chat.megagroup && (ChatObject.isPublic(chat) || chat.has_geo || chat.has_link); return ChatObject.isChannel(chat) && (!chat.megagroup && chat.signatures && ChatObject.hasAdminRights(chat) && ChatObject.canWriteToChat(chat) || chat.megagroup && (ChatObject.isPublic(chat) || chat.has_geo || chat.has_link));
} }
public static boolean isChannel(TLRPC.Chat chat) { public static boolean isChannel(TLRPC.Chat chat) {
@ -1943,6 +1943,9 @@ public class ChatObject {
if (chat != null && chat.admin_rights != null && chat.admin_rights.anonymous) { if (chat != null && chat.admin_rights != null && chat.admin_rights.anonymous) {
return invertChannel ? -chat.id : chat.id; return invertChannel ? -chat.id : chat.id;
} }
if (chat != null && ChatObject.isChannelAndNotMegaGroup(chat) && !chat.signatures) {
return invertChannel ? -chat.id : chat.id;
}
return UserConfig.getInstance(UserConfig.selectedAccount).getClientUserId(); return UserConfig.getInstance(UserConfig.selectedAccount).getClientUserId();
} }

View file

@ -309,7 +309,7 @@ public class CodeHighlighting {
for (int i = 0; i < patterns.length; ++i) { for (int i = 0; i < patterns.length; ++i) {
if (patterns[i].pattern != null && "REST".equals(patterns[i].pattern.patternSource)) { if (patterns[i].pattern != null && "REST".equals(patterns[i].pattern.patternSource)) {
if (result == null) { if (result == null) {
result = new ArrayList<>(); result = new ArrayList<TokenPattern>();
Collections.addAll(result, patterns); Collections.addAll(result, patterns);
} }
result.remove(patterns[i]); result.remove(patterns[i]);
@ -447,7 +447,7 @@ public class CodeHighlighting {
} }
private static Match matchPattern(TokenPattern pattern, int pos, String text) { private static Match matchPattern(TokenPattern pattern, int pos, String text) {
Matcher matcher = pattern.pattern.getPattern(). matcher(text); Matcher matcher = pattern.pattern.getPattern().matcher(text);
matcher.region(pos, text.length()); matcher.region(pos, text.length());
if (!matcher.find()) { if (!matcher.find()) {
return null; return null;

View file

@ -610,6 +610,11 @@ public class DownloadController extends BaseController implements NotificationCe
} }
return true; return true;
} }
if (messageObject.sponsoredMedia != null) {
return true;
}
if (messageObject.isHiddenSensitive())
return false;
return canDownloadMedia(messageObject.messageOwner) == 1; return canDownloadMedia(messageObject.messageOwner) == 1;
} }
@ -793,7 +798,7 @@ public class DownloadController extends BaseController implements NotificationCe
} else { } else {
maxSize = preset.sizes[typeToIndex(type)]; maxSize = preset.sizes[typeToIndex(type)];
} }
long size = MessageObject.getMessageSize(message); long size = MessageObject.getMediaSize(media);
if (isVideo && preset.preloadVideo && size > maxSize && maxSize > 2 * 1024 * 1024) { if (isVideo && preset.preloadVideo && size > maxSize && maxSize > 2 * 1024 * 1024) {
return (mask & type) != 0 ? 2 : 0; return (mask & type) != 0 ? 2 : 0;
} else { } else {

View file

@ -270,7 +270,7 @@ public class Emoji {
} }
public static abstract class EmojiDrawable extends Drawable { public static abstract class EmojiDrawable extends Drawable {
boolean fullSize = false; public boolean fullSize = false;
int placeholderColor = 0x10000000; int placeholderColor = 0x10000000;
public boolean isLoaded() { public boolean isLoaded() {

View file

@ -706,7 +706,7 @@ public class FileLoader extends BaseController {
for (FileLoadOperation operation : loadOperationPaths.values()) { for (FileLoadOperation operation : loadOperationPaths.values()) {
if (operation == null || operation.requestInfos == null) continue; if (operation == null || operation.requestInfos == null) continue;
for (FileLoadOperation.RequestInfo requestInfo : operation.requestInfos) { for (FileLoadOperation.RequestInfo requestInfo : operation.requestInfos) {
if (requestInfo.requestToken == requestToken) { if (requestInfo != null && requestInfo.requestToken == requestToken) {
return operation; return operation;
} }
} }

View file

@ -1,13 +1,14 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log;
import org.telegram.tgnet.RequestDelegate; import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_bots;
import org.telegram.tgnet.tl.TL_stories; import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Stories.StoriesController;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -70,7 +71,20 @@ public class FileRefController extends BaseController {
} }
public static String getKeyForParentObject(Object parentObject) { public static String getKeyForParentObject(Object parentObject) {
if (parentObject instanceof TL_stories.StoryItem) { if (parentObject instanceof StoriesController.BotPreview) {
StoriesController.BotPreview storyItem = (StoriesController.BotPreview) parentObject;
if (storyItem.list == null) {
FileLog.d("failed request reference can't find list in botpreview");
return null;
}
if (storyItem.media.document != null) {
return "botstory_doc_" + storyItem.media.document.id;
} else if (storyItem.media.photo != null) {
return "botstory_photo_" + storyItem.media.photo.id;
} else {
return "botstory_" + storyItem.id;
}
} else if (parentObject instanceof TL_stories.StoryItem) {
TL_stories.StoryItem storyItem = (TL_stories.StoryItem) parentObject; TL_stories.StoryItem storyItem = (TL_stories.StoryItem) parentObject;
if (storyItem.dialogId == 0) { if (storyItem.dialogId == 0) {
FileLog.d("failed request reference can't find dialogId"); FileLog.d("failed request reference can't find dialogId");
@ -81,8 +95,8 @@ public class FileRefController extends BaseController {
return "premium_promo"; return "premium_promo";
} else if (parentObject instanceof TLRPC.TL_availableReaction) { } else if (parentObject instanceof TLRPC.TL_availableReaction) {
return "available_reaction_" + ((TLRPC.TL_availableReaction) parentObject).reaction; return "available_reaction_" + ((TLRPC.TL_availableReaction) parentObject).reaction;
} else if (parentObject instanceof TLRPC.BotInfo) { } else if (parentObject instanceof TL_bots.BotInfo) {
TLRPC.BotInfo botInfo = (TLRPC.BotInfo) parentObject; TL_bots.BotInfo botInfo = (TL_bots.BotInfo) parentObject;
return "bot_info_" + botInfo.user_id; return "bot_info_" + botInfo.user_id;
} else if (parentObject instanceof TLRPC.TL_attachMenuBot) { } else if (parentObject instanceof TLRPC.TL_attachMenuBot) {
TLRPC.TL_attachMenuBot bot = (TLRPC.TL_attachMenuBot) parentObject; TLRPC.TL_attachMenuBot bot = (TLRPC.TL_attachMenuBot) parentObject;
@ -137,7 +151,21 @@ public class FileRefController extends BaseController {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("start loading request reference parent " + getObjectString(parentObject) + " args = " + args[0]); FileLog.d("start loading request reference parent " + getObjectString(parentObject) + " args = " + args[0]);
} }
if (args[0] instanceof TL_stories.TL_storyItem) { if (args[0] instanceof StoriesController.BotPreview) {
StoriesController.BotPreview storyItem = (StoriesController.BotPreview) args[0];
if (storyItem.media.document != null) {
location = new TLRPC.TL_inputDocumentFileLocation();
location.id = storyItem.media.document.id;
locationKey = "botstory_doc_" + storyItem.media.document.id;
} else if (storyItem.media.photo != null) {
location = new TLRPC.TL_inputPhotoFileLocation();
location.id = storyItem.media.photo.id;
locationKey = "botstory_photo_" + storyItem.media.photo.id;
} else {
locationKey = "botstory_" + storyItem.id;
location = new TLRPC.TL_inputDocumentFileLocation();
}
} else if (args[0] instanceof TL_stories.TL_storyItem) {
TL_stories.TL_storyItem storyItem = (TL_stories.TL_storyItem) args[0]; TL_stories.TL_storyItem storyItem = (TL_stories.TL_storyItem) args[0];
locationKey = "story_" + storyItem.id; locationKey = "story_" + storyItem.id;
location = new TLRPC.TL_inputDocumentFileLocation(); location = new TLRPC.TL_inputDocumentFileLocation();
@ -401,7 +429,18 @@ public class FileRefController extends BaseController {
} }
private void requestReferenceFromServer(Object parentObject, String locationKey, String parentKey, Object[] args) { private void requestReferenceFromServer(Object parentObject, String locationKey, String parentKey, Object[] args) {
if (parentObject instanceof TL_stories.StoryItem) { if (parentObject instanceof StoriesController.BotPreview) {
StoriesController.BotPreview storyItem = (StoriesController.BotPreview) parentObject;
if (storyItem.list == null) {
sendErrorToObject(args, 0);
return;
}
storyItem.list.requestReference(storyItem, newStoryItem -> {
Utilities.stageQueue.postRunnable(() -> {
onRequestComplete(locationKey, parentKey, newStoryItem, null, true, false);
});
});
} else if (parentObject instanceof TL_stories.StoryItem) {
TL_stories.StoryItem storyItem = (TL_stories.StoryItem) parentObject; TL_stories.StoryItem storyItem = (TL_stories.StoryItem) parentObject;
TL_stories.TL_stories_getStoriesByID req = new TL_stories.TL_stories_getStoriesByID(); TL_stories.TL_stories_getStoriesByID req = new TL_stories.TL_stories_getStoriesByID();
req.peer = getMessagesController().getInputPeer(storyItem.dialogId); req.peer = getMessagesController().getInputPeer(storyItem.dialogId);
@ -424,8 +463,8 @@ public class FileRefController extends BaseController {
TLRPC.TL_messages_getAvailableReactions req = new TLRPC.TL_messages_getAvailableReactions(); TLRPC.TL_messages_getAvailableReactions req = new TLRPC.TL_messages_getAvailableReactions();
req.hash = 0; req.hash = 0;
getConnectionsManager().sendRequest(req, (response, error) -> onRequestComplete(locationKey, parentKey, response, error, true, false)); getConnectionsManager().sendRequest(req, (response, error) -> onRequestComplete(locationKey, parentKey, response, error, true, false));
} else if (parentObject instanceof TLRPC.BotInfo) { } else if (parentObject instanceof TL_bots.BotInfo) {
TLRPC.BotInfo botInfo = (TLRPC.BotInfo) parentObject; TL_bots.BotInfo botInfo = (TL_bots.BotInfo) parentObject;
TLRPC.TL_users_getFullUser req = new TLRPC.TL_users_getFullUser(); TLRPC.TL_users_getFullUser req = new TLRPC.TL_users_getFullUser();
req.id = getMessagesController().getInputUser(botInfo.user_id); req.id = getMessagesController().getInputUser(botInfo.user_id);
getConnectionsManager().sendRequest(req, (response, error) -> onRequestComplete(locationKey, parentKey, response, error, true, false)); getConnectionsManager().sendRequest(req, (response, error) -> onRequestComplete(locationKey, parentKey, response, error, true, false));
@ -909,7 +948,14 @@ public class FileRefController extends BaseController {
needReplacement = new boolean[1]; needReplacement = new boolean[1];
} }
requester.completed = true; requester.completed = true;
if (response instanceof TLRPC.messages_Messages) { if (response instanceof StoriesController.BotPreview) {
StoriesController.BotPreview newStoryItem = (StoriesController.BotPreview) response;
if (newStoryItem.media.document != null) {
result = getFileReference(newStoryItem.media.document, requester.location, needReplacement, locationReplacement);
} else if (newStoryItem.media.photo != null) {
result = getFileReference(newStoryItem.media.photo, requester.location, needReplacement, locationReplacement);
}
} else if (response instanceof TLRPC.messages_Messages) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
if (!res.messages.isEmpty()) { if (!res.messages.isEmpty()) {
for (int i = 0, size3 = res.messages.size(); i < size3; i++) { for (int i = 0, size3 = res.messages.size(); i < size3; i++) {
@ -1020,7 +1066,7 @@ public class FileRefController extends BaseController {
getMessagesController().putUsers(usersFull.users, false); getMessagesController().putUsers(usersFull.users, false);
getMessagesController().putChats(usersFull.chats, false); getMessagesController().putChats(usersFull.chats, false);
TLRPC.UserFull userFull = usersFull.full_user; TLRPC.UserFull userFull = usersFull.full_user;
TLRPC.BotInfo botInfo = userFull.bot_info; TL_bots.BotInfo botInfo = userFull.bot_info;
if (botInfo != null) { if (botInfo != null) {
getMessagesStorage().updateUserInfo(userFull, true); getMessagesStorage().updateUserInfo(userFull, true);

View file

@ -32,7 +32,6 @@ import android.os.Environment;
import android.os.SystemClock; import android.os.SystemClock;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
@ -101,7 +100,6 @@ import java.util.zip.GZIPInputStream;
* firstframe - return firstframe for Lottie or Video animation * firstframe - return firstframe for Lottie or Video animation
* ignoreOrientation - do not extract EXIF orientation and do not apply it to an imagereceiver * ignoreOrientation - do not extract EXIF orientation and do not apply it to an imagereceiver
* exif check exif contents of invert/orientation * exif check exif contents of invert/orientation
* bnb airbnb canvas lottie impl
*/ */
public class ImageLoader { public class ImageLoader {
@ -1022,11 +1020,10 @@ public class ImageLoader {
cacheOptions.firstFrame = true; cacheOptions.firstFrame = true;
} }
} }
final boolean airbnb = cacheImage.filter != null && cacheImage.filter.contains("bnb");
if (compressed) { if (compressed) {
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, decompressGzip(cacheImage.finalFilePath), w, h, cacheOptions, limitFps, null, fitzModifier, airbnb); lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, decompressGzip(cacheImage.finalFilePath), w, h, cacheOptions, limitFps, null, fitzModifier);
} else { } else {
lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, w, h, cacheOptions, limitFps, null, fitzModifier, airbnb); lottieDrawable = new RLottieDrawable(cacheImage.finalFilePath, w, h, cacheOptions, limitFps, null, fitzModifier);
} }
} }
if (lastFrameBitmap || firstFrameBitmap) { if (lastFrameBitmap || firstFrameBitmap) {

View file

@ -2659,8 +2659,8 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
public void setEmojiPaused(boolean paused) { public void setEmojiPaused(boolean paused) {
if (emojiPaused == paused) return; if (emojiPaused == paused) return;
emojiPaused = paused; emojiPaused = paused;
RLottieDrawable rLottieDrawable = getLottieAnimation();
allowStartLottieAnimation = !paused; allowStartLottieAnimation = !paused;
RLottieDrawable rLottieDrawable = getLottieAnimation();
if (rLottieDrawable != null) { if (rLottieDrawable != null) {
if (paused) { if (paused) {
rLottieDrawable.stop(); rLottieDrawable.stop();

View file

@ -6,7 +6,7 @@ public class LinkifyPort {
private static String IANA_TOP_LEVEL_DOMAINS = private static String IANA_TOP_LEVEL_DOMAINS =
"(?:" "(?:"
+ "(?:aaa|aarp|abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active" + "(?:aaa|adnl|aarp|abb|abbott|abogado|academy|accenture|accountant|accountants|aco|active"
+ "|actor|ads|adult|aeg|aero|afl|agency|aig|airforce|airtel|allfinanz|alsace|amica|amsterdam" + "|actor|ads|adult|aeg|aero|afl|agency|aig|airforce|airtel|allfinanz|alsace|amica|amsterdam"
+ "|android|apartments|app|apple|aquarelle|aramco|archi|army|arpa|arte|asia|associates" + "|android|apartments|app|apple|aquarelle|aramco|archi|army|arpa|arte|asia|associates"
+ "|attorney|auction|audio|auto|autos|axa|azure|a[cdefgilmoqrstuwxz])" + "|attorney|auction|audio|auto|autos|axa|azure|a[cdefgilmoqrstuwxz])"
@ -67,7 +67,7 @@ public class LinkifyPort {
+ "|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|soy|space|spiegel|spreadbetting" + "|sky|skype|sncf|soccer|social|software|sohu|solar|solutions|sony|soy|space|spiegel|spreadbetting"
+ "|srl|stada|starhub|statoil|stc|stcgroup|stockholm|studio|study|style|sucks|supplies" + "|srl|stada|starhub|statoil|stc|stcgroup|stockholm|studio|study|style|sucks|supplies"
+ "|supply|support|surf|surgery|suzuki|swatch|swiss|sydney|systems|s[abcdeghijklmnortuvxyz])" + "|supply|support|surf|surgery|suzuki|swatch|swiss|sydney|systems|s[abcdeghijklmnortuvxyz])"
+ "|(?:tab|taipei|tatamotors|tatar|tattoo|tax|taxi|team|tech|technology|tel|telefonica" + "|(?:ton|tab|taipei|tatamotors|tatar|tattoo|tax|taxi|team|tech|technology|tel|telefonica"
+ "|temasek|tennis|thd|theater|theatre|tickets|tienda|tips|tires|tirol|today|tokyo|tools" + "|temasek|tennis|thd|theater|theatre|tickets|tienda|tips|tires|tirol|today|tokyo|tools"
+ "|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|tui|t[cdfghjklmnortvwz])" + "|top|toray|toshiba|tours|town|toyota|toys|trade|trading|training|travel|trust|tui|t[cdfghjklmnortvwz])"
+ "|(?:ubs|university|uno|uol|u[agksyz])" + "|(?:ubs|university|uno|uol|u[agksyz])"
@ -168,13 +168,13 @@ public class LinkifyPort {
private static final String LABEL_CHAR = "a-zA-Z0-9" + UCS_CHAR_FIXED; private static final String LABEL_CHAR = "a-zA-Z0-9" + UCS_CHAR_FIXED;
private static final String IRI_LABEL = "[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "_\\-]{0,61}[" + LABEL_CHAR + "]){0,1}"; private static final String IRI_LABEL = "[" + LABEL_CHAR + "](?:[" + LABEL_CHAR + "_\\-]{0,61}[" + LABEL_CHAR + "]){0,1}";
private static String STRICT_TLD = "(?:" + IANA_TOP_LEVEL_DOMAINS + "|" + PUNYCODE_TLD + ")"; private static String STRICT_TLD = "(?:" + IANA_TOP_LEVEL_DOMAINS + "|" + PUNYCODE_TLD + ")";
private static final String STRICT_HOST_NAME = "(?:(?:" + IRI_LABEL + "\\.)+" + STRICT_TLD + ")"; public static final String STRICT_HOST_NAME = "(?:(?:" + IRI_LABEL + "\\.)+" + STRICT_TLD + ")";
private static final String STRICT_DOMAIN_NAME = "(?:" + STRICT_HOST_NAME + "|" + IP_ADDRESS_STRING + ")"; private static final String STRICT_DOMAIN_NAME = "(?:" + STRICT_HOST_NAME + "|" + IP_ADDRESS_STRING + ")";
private static final String TLD = "(" + PUNYCODE_TLD + "|" + "[" + TLD_CHAR + "]{2,63}" + ")"; private static final String TLD = "(" + PUNYCODE_TLD + "|" + "[" + TLD_CHAR + "]{2,63}" + ")";
private static final String HOST_NAME = "(" + IRI_LABEL + "\\.)+" + TLD; private static final String HOST_NAME = "(" + IRI_LABEL + "\\.)+" + TLD;
private static final String DOMAIN_NAME_STR = "(" + HOST_NAME + "|" + IP_ADDRESS_STRING + ")"; private static final String DOMAIN_NAME_STR = "(" + HOST_NAME + "|" + IP_ADDRESS_STRING + ")";
private static final Pattern DOMAIN_NAME = Pattern.compile(DOMAIN_NAME_STR); private static final Pattern DOMAIN_NAME = Pattern.compile(DOMAIN_NAME_STR);
private static final String PROTOCOL = "(?i:http|https|ton|tg)://"; private static final String PROTOCOL = "(?i:http|https|ton|tg|tonsite)://";
private static final String WORD_BOUNDARY = "(?:\\b|$|^)"; private static final String WORD_BOUNDARY = "(?:\\b|$|^)";
private static final String USER_INFO = "(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)" private static final String USER_INFO = "(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_" + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"

View file

@ -1394,13 +1394,22 @@ public class LocaleController {
if (TextUtils.isEmpty(key)) { if (TextUtils.isEmpty(key)) {
return "LOC_ERR:" + key; return "LOC_ERR:" + key;
} }
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(key, "string", ApplicationLoader.applicationContext.getPackageName()); int resourceId = getStringResId(key);
if (resourceId != 0) { if (resourceId != 0) {
return getString(key, resourceId); return getString(key, resourceId);
} }
return getServerString(key); return getServerString(key);
} }
public static int getStringResId(String key) {
return ApplicationLoader.applicationContext.getResources().getIdentifier(key, "string", ApplicationLoader.applicationContext.getPackageName());
}
public static String nullable(String val) {
if (val == null || val.startsWith("LOC_ERR")) return null;
return val;
}
public static String getPluralString(String key, int plural) { public static String getPluralString(String key, int plural) {
if (key == null || key.length() == 0 || getInstance().currentPluralRules == null) { if (key == null || key.length() == 0 || getInstance().currentPluralRules == null) {
return "LOC_ERR:" + key; return "LOC_ERR:" + key;
@ -1515,7 +1524,7 @@ public class LocaleController {
if (BuildVars.USE_CLOUD_STRINGS && fallback != null) { if (BuildVars.USE_CLOUD_STRINGS && fallback != null) {
value = getInstance().localeValues.get(fallback); value = getInstance().localeValues.get(fallback);
} }
if (value == null) { if (value == null && res != 0) {
try { try {
value = ApplicationLoader.applicationContext.getString(res); value = ApplicationLoader.applicationContext.getString(res);
} catch (Exception e) { } catch (Exception e) {

View file

@ -5006,6 +5006,36 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
return ""; return "";
} }
public static File createFileInCache(String name, String ext) {
File f = null;
try {
f = AndroidUtilities.getSharingDirectory();
f.mkdirs();
if (AndroidUtilities.isInternalUri(Uri.fromFile(f))) {
return null;
}
int count = 0;
do {
f = AndroidUtilities.getSharingDirectory();
if (count == 0) {
f = new File(f, name);
} else {
int lastDotIndex = name.lastIndexOf(".");
if (lastDotIndex > 0) {
f = new File(f, name.substring(0, lastDotIndex) + " (" + count + ")" + name.substring(lastDotIndex));
} else {
f = new File(f, name + " (" + count + ")");
}
}
count++;
} while (f.exists());
return f;
} catch (Exception e) {
FileLog.e(e);
}
return null;
}
public static String copyFileToCache(Uri uri, String ext) { public static String copyFileToCache(Uri uri, String ext) {
return copyFileToCache(uri, ext, -1); return copyFileToCache(uri, ext, -1);
} }

View file

@ -58,6 +58,7 @@ import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.SerializedData; import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_bots;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.EmojiThemes; import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
@ -387,9 +388,11 @@ public class MediaDataController extends BaseController {
loaded = false; loaded = false;
hints.clear(); hints.clear();
inlineBots.clear(); inlineBots.clear();
webapps.clear();
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
getNotificationCenter().postNotificationName(NotificationCenter.reloadHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadWebappsHints);
}); });
drafts.clear(); drafts.clear();
@ -3960,7 +3963,7 @@ public class MediaDataController extends BaseController {
} }
}; };
if (isSaved) { if (isSaved) {
loadReplyMessagesForMessages(messageObjects, dialogId, 0, lastReplyMessageId, done, guid); loadReplyMessagesForMessages(messageObjects, dialogId, 0, lastReplyMessageId, done, guid, null);
} else { } else {
done.run(); done.run();
} }
@ -4322,7 +4325,7 @@ public class MediaDataController extends BaseController {
if (res != null && res.messages != null) { if (res != null && res.messages != null) {
messagesCount = res.messages.size(); messagesCount = res.messages.size();
} }
FileLog.d("process load media messagesCount " + messagesCount + " did " + dialogId + " topicId " + topicId + " count = " + count + " max_id=" + max_id + " min_id=" + min_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid); FileLog.d("process load media messagesCount " + messagesCount + " did " + dialogId + " topicId " + topicId + " count = " + count + " max_id=" + max_id + " min_id=" + min_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid + " topReached=" + topReached);
} }
if (fromCache != 0 && res != null && res.messages != null && ((res.messages.isEmpty() && min_id == 0) || (res.messages.size() <= 1 && min_id != 0)) && !DialogObject.isEncryptedDialog(dialogId)) { if (fromCache != 0 && res != null && res.messages != null && ((res.messages.isEmpty() && min_id == 0) || (res.messages.size() <= 1 && min_id != 0)) && !DialogObject.isEncryptedDialog(dialogId)) {
if (fromCache == 2) { if (fromCache == 2) {
@ -4821,6 +4824,7 @@ public class MediaDataController extends BaseController {
public ArrayList<TLRPC.TL_topPeer> hints = new ArrayList<>(); public ArrayList<TLRPC.TL_topPeer> hints = new ArrayList<>();
public ArrayList<TLRPC.TL_topPeer> inlineBots = new ArrayList<>(); public ArrayList<TLRPC.TL_topPeer> inlineBots = new ArrayList<>();
public ArrayList<TLRPC.TL_topPeer> webapps = new ArrayList<>();
boolean loaded; boolean loaded;
boolean loading; boolean loading;
@ -5030,6 +5034,7 @@ public class MediaDataController extends BaseController {
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
ArrayList<TLRPC.TL_topPeer> hintsNew = new ArrayList<>(); ArrayList<TLRPC.TL_topPeer> hintsNew = new ArrayList<>();
ArrayList<TLRPC.TL_topPeer> inlineBotsNew = new ArrayList<>(); ArrayList<TLRPC.TL_topPeer> inlineBotsNew = new ArrayList<>();
ArrayList<TLRPC.TL_topPeer> webappsNew = new ArrayList<>();
ArrayList<TLRPC.User> users = new ArrayList<>(); ArrayList<TLRPC.User> users = new ArrayList<>();
ArrayList<TLRPC.Chat> chats = new ArrayList<>(); ArrayList<TLRPC.Chat> chats = new ArrayList<>();
long selfUserId = getUserConfig().getClientUserId(); long selfUserId = getUserConfig().getClientUserId();
@ -5058,6 +5063,8 @@ public class MediaDataController extends BaseController {
hintsNew.add(peer); hintsNew.add(peer);
} else if (type == 1) { } else if (type == 1) {
inlineBotsNew.add(peer); inlineBotsNew.add(peer);
} else if (type == 2) {
webappsNew.add(peer);
} }
} }
cursor.dispose(); cursor.dispose();
@ -5075,10 +5082,12 @@ public class MediaDataController extends BaseController {
loaded = true; loaded = true;
hints = hintsNew; hints = hintsNew;
inlineBots = inlineBotsNew; inlineBots = inlineBotsNew;
webapps = webappsNew;
buildShortcuts(); buildShortcuts();
getNotificationCenter().postNotificationName(NotificationCenter.reloadHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints);
if (Math.abs(getUserConfig().lastHintsSyncTime - (int) (System.currentTimeMillis() / 1000)) >= 24 * 60 * 60) { getNotificationCenter().postNotificationName(NotificationCenter.reloadWebappsHints);
if (Math.abs(getUserConfig().lastHintsSyncTime - (int) (System.currentTimeMillis() / 1000)) >= 24 * 60 * 60 || BuildVars.DEBUG_PRIVATE_VERSION) {
loadHints(false); loadHints(false);
} }
}); });
@ -5096,6 +5105,7 @@ public class MediaDataController extends BaseController {
req.groups = false; req.groups = false;
req.channels = false; req.channels = false;
req.bots_inline = true; req.bots_inline = true;
req.bots_app = true;
req.offset = 0; req.offset = 0;
req.limit = 20; req.limit = 20;
getConnectionsManager().sendRequest(req, (response, error) -> { getConnectionsManager().sendRequest(req, (response, error) -> {
@ -5109,6 +5119,9 @@ public class MediaDataController extends BaseController {
if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) { if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) {
inlineBots = category.peers; inlineBots = category.peers;
getUserConfig().botRatingLoadTime = (int) (System.currentTimeMillis() / 1000); getUserConfig().botRatingLoadTime = (int) (System.currentTimeMillis() / 1000);
} else if (category.category instanceof TLRPC.TL_topPeerCategoryBotsApp) {
webapps = category.peers;
getUserConfig().webappRatingLoadTime = (int) (System.currentTimeMillis() / 1000);
} else { } else {
hints = category.peers; hints = category.peers;
long selfUserId = getUserConfig().getClientUserId(); long selfUserId = getUserConfig().getClientUserId();
@ -5126,6 +5139,7 @@ public class MediaDataController extends BaseController {
buildShortcuts(); buildShortcuts();
getNotificationCenter().postNotificationName(NotificationCenter.reloadHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadWebappsHints);
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
try { try {
getMessagesStorage().getDatabase().executeFast("DELETE FROM chat_hints WHERE 1").stepThis().dispose(); getMessagesStorage().getDatabase().executeFast("DELETE FROM chat_hints WHERE 1").stepThis().dispose();
@ -5138,6 +5152,8 @@ public class MediaDataController extends BaseController {
TLRPC.TL_topPeerCategoryPeers category = topPeers.categories.get(a); TLRPC.TL_topPeerCategoryPeers category = topPeers.categories.get(a);
if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) { if (category.category instanceof TLRPC.TL_topPeerCategoryBotsInline) {
type = 1; type = 1;
} else if (category.category instanceof TLRPC.TL_topPeerCategoryBotsApp) {
type = 2;
} else { } else {
type = 0; type = 0;
} }
@ -5180,8 +5196,10 @@ public class MediaDataController extends BaseController {
public void clearTopPeers() { public void clearTopPeers() {
hints.clear(); hints.clear();
inlineBots.clear(); inlineBots.clear();
webapps.clear();
getNotificationCenter().postNotificationName(NotificationCenter.reloadHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints);
getNotificationCenter().postNotificationName(NotificationCenter.reloadWebappsHints);
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
try { try {
getMessagesStorage().getDatabase().executeFast("DELETE FROM chat_hints WHERE 1").stepThis().dispose(); getMessagesStorage().getDatabase().executeFast("DELETE FROM chat_hints WHERE 1").stepThis().dispose();
@ -5192,7 +5210,7 @@ public class MediaDataController extends BaseController {
buildShortcuts(); buildShortcuts();
} }
public void increaseInlineRaiting(long uid) { public void increaseInlineRating(long uid) {
if (!getUserConfig().suggestContacts) { if (!getUserConfig().suggestContacts) {
return; return;
} }
@ -5233,8 +5251,48 @@ public class MediaDataController extends BaseController {
getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints); getNotificationCenter().postNotificationName(NotificationCenter.reloadInlineHints);
} }
public void increaseWebappRating(long uid) {
final TLRPC.User user = getMessagesController().getUser(uid);
if (user == null || !user.bot) return;
int dt;
if (getUserConfig().webappRatingLoadTime != 0) {
dt = Math.max(1, ((int) (System.currentTimeMillis() / 1000)) - getUserConfig().webappRatingLoadTime);
} else {
dt = 60;
}
TLRPC.TL_topPeer peer = null;
for (int a = 0; a < inlineBots.size(); a++) {
TLRPC.TL_topPeer p = inlineBots.get(a);
if (p.peer.user_id == uid) {
peer = p;
break;
}
}
if (peer == null) {
peer = new TLRPC.TL_topPeer();
peer.peer = new TLRPC.TL_peerUser();
peer.peer.user_id = uid;
webapps.add(peer);
}
peer.rating += Math.exp(dt / getMessagesController().ratingDecay);
Collections.sort(inlineBots, (lhs, rhs) -> {
if (lhs.rating > rhs.rating) {
return -1;
} else if (lhs.rating < rhs.rating) {
return 1;
}
return 0;
});
if (webapps.size() > 20) {
webapps.remove(webapps.size() - 1);
}
savePeer(uid, 2, peer.rating);
getNotificationCenter().postNotificationName(NotificationCenter.reloadWebappsHints);
}
public void removeInline(long dialogId) { public void removeInline(long dialogId) {
TLRPC.TL_topPeerCategoryPeers category = null;
for (int a = 0; a < inlineBots.size(); a++) { for (int a = 0; a < inlineBots.size(); a++) {
if (inlineBots.get(a).peer.user_id == dialogId) { if (inlineBots.get(a).peer.user_id == dialogId) {
inlineBots.remove(a); inlineBots.remove(a);
@ -5251,6 +5309,23 @@ public class MediaDataController extends BaseController {
} }
} }
public void removeWebapp(long dialogId) {
for (int a = 0; a < webapps.size(); a++) {
if (webapps.get(a).peer.user_id == dialogId) {
webapps.remove(a);
TLRPC.TL_contacts_resetTopPeerRating req = new TLRPC.TL_contacts_resetTopPeerRating();
req.category = new TLRPC.TL_topPeerCategoryBotsApp();
req.peer = getMessagesController().getInputPeer(dialogId);
getConnectionsManager().sendRequest(req, (response, error) -> {
});
deletePeer(dialogId, 2);
getNotificationCenter().postNotificationName(NotificationCenter.reloadWebappsHints);
return;
}
}
}
public void removePeer(long uid) { public void removePeer(long uid) {
for (int a = 0; a < hints.size(); a++) { for (int a = 0; a < hints.size(); a++) {
if (hints.get(a).peer.user_id == uid) { if (hints.get(a).peer.user_id == uid) {
@ -5942,9 +6017,10 @@ public class MediaDataController extends BaseController {
} }
} }
public void loadReplyMessagesForMessages(ArrayList<MessageObject> messages, long dialogId, int mode, long threadMessageId, Runnable callback, int classGuid) { public void loadReplyMessagesForMessages(ArrayList<MessageObject> messages, long dialogId, int mode, long threadMessageId, Runnable callback, int classGuid, Timer logLogger) {
final boolean scheduled = mode == ChatActivity.MODE_SCHEDULED; final boolean scheduled = mode == ChatActivity.MODE_SCHEDULED;
if (DialogObject.isEncryptedDialog(dialogId)) { if (DialogObject.isEncryptedDialog(dialogId)) {
Timer.Task t1 = Timer.start(logLogger, "loadReplyMessagesForMessages: (encrypted) finding messages to load");
ArrayList<Long> replyMessages = new ArrayList<>(); ArrayList<Long> replyMessages = new ArrayList<>();
LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>(); LongSparseArray<ArrayList<MessageObject>> replyMessageRandomOwners = new LongSparseArray<>();
for (int a = 0; a < messages.size(); a++) { for (int a = 0; a < messages.size(); a++) {
@ -5971,8 +6047,11 @@ public class MediaDataController extends BaseController {
} }
return; return;
} }
Timer.done(t1);
Timer.Task t2 = Timer.start(logLogger, "loadReplyMessagesForMessages (encrypted) storageQueue.postRunnable");
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
Timer.done(t2);
Timer.Task t3 = Timer.start(logLogger, "loadReplyMessagesForMessages: (encrypted) loading those messages from storage");
try { try {
ArrayList<MessageObject> loadedMessages = new ArrayList<>(); ArrayList<MessageObject> loadedMessages = new ArrayList<>();
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, m.date, r.random_id FROM randoms_v2 as r INNER JOIN messages_v2 as m ON r.mid = m.mid AND r.uid = m.uid WHERE r.random_id IN(%s)", TextUtils.join(",", replyMessages))); SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid, m.date, r.random_id FROM randoms_v2 as r INNER JOIN messages_v2 as m ON r.mid = m.mid AND r.uid = m.uid WHERE r.random_id IN(%s)", TextUtils.join(",", replyMessages)));
@ -6015,7 +6094,12 @@ public class MediaDataController extends BaseController {
} }
} }
} }
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.replyMessagesDidLoad, dialogId, loadedMessages, null)); Timer.done(t3);
Timer.Task t4 = Timer.start(logLogger, "loadReplyMessagesForMessages (encrypted) runOnUIThread: posting notification");
AndroidUtilities.runOnUIThread(() -> {
Timer.done(t4);
getNotificationCenter().postNotificationName(NotificationCenter.replyMessagesDidLoad, dialogId, loadedMessages, null);
});
if (callback != null) { if (callback != null) {
callback.run(); callback.run();
} }
@ -6027,6 +6111,7 @@ public class MediaDataController extends BaseController {
LongSparseArray<SparseArray<ArrayList<MessageObject>>> replyMessageOwners = new LongSparseArray<>(); LongSparseArray<SparseArray<ArrayList<MessageObject>>> replyMessageOwners = new LongSparseArray<>();
LongSparseArray<ArrayList<Integer>> dialogReplyMessagesIds = new LongSparseArray<>(); LongSparseArray<ArrayList<Integer>> dialogReplyMessagesIds = new LongSparseArray<>();
LongSparseArray<ArrayList<MessageObject>> messagesWithUnknownStories = null; LongSparseArray<ArrayList<MessageObject>> messagesWithUnknownStories = null;
Timer.Task t2 = Timer.start(logLogger, "loadReplyMessagesForMessages: filling replies from the same array");
for (int a = 0; a < messages.size(); a++) { for (int a = 0; a < messages.size(); a++) {
MessageObject messageObject = messages.get(a); MessageObject messageObject = messages.get(a);
if (messageObject == null) { if (messageObject == null) {
@ -6054,6 +6139,8 @@ public class MediaDataController extends BaseController {
} }
} }
} }
Timer.done(t2);
Timer.Task t3 = Timer.start(logLogger, "loadReplyMessagesForMessages: gathering ids of missing reply data");
for (int a = 0; a < messages.size(); a++) { for (int a = 0; a < messages.size(); a++) {
MessageObject messageObject = messages.get(a); MessageObject messageObject = messages.get(a);
if (messageObject == null) { if (messageObject == null) {
@ -6070,6 +6157,7 @@ public class MediaDataController extends BaseController {
array = new ArrayList<>(); array = new ArrayList<>();
messagesWithUnknownStories.put(storyDialogId, array); messagesWithUnknownStories.put(storyDialogId, array);
} }
Timer.log(logLogger, "+story did=" + storyDialogId + " at "+(messageObject.type == MessageObject.TYPE_STORY ? "forwarded" : "mentioned")+" #" + messageObject.getId());
array.add(messageObject); array.add(messageObject);
} else { } else {
long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.media.peer); long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.media.peer);
@ -6086,6 +6174,7 @@ public class MediaDataController extends BaseController {
array = new ArrayList<>(); array = new ArrayList<>();
messagesWithUnknownStories.put(storyDialogId, array); messagesWithUnknownStories.put(storyDialogId, array);
} }
Timer.log(logLogger, "+story did=" + storyDialogId + " at replied #" + messageObject.getId());
array.add(messageObject); array.add(messageObject);
} else { } else {
long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.reply_to.peer); long storyDialogId = DialogObject.getPeerDialogId(messageObject.messageOwner.reply_to.peer);
@ -6140,6 +6229,7 @@ public class MediaDataController extends BaseController {
} }
} }
arrayList.add(messageObject); arrayList.add(messageObject);
Timer.log(logLogger, "+message did=" + -channelId + " mid="+messageId+" at replied #" + messageObject.getId());
} }
if ( if (
messageObject.type == MessageObject.TYPE_TEXT && messageObject.type == MessageObject.TYPE_TEXT &&
@ -6162,6 +6252,7 @@ public class MediaDataController extends BaseController {
array = new ArrayList<>(); array = new ArrayList<>();
messagesWithUnknownStories.put(storyDialogId, array); messagesWithUnknownStories.put(storyDialogId, array);
} }
Timer.log(logLogger, "+story did=" + storyDialogId + " at webpage of #" + messageObject.getId());
array.add(messageObject); array.add(messageObject);
} else { } else {
long storyDialogId = DialogObject.getPeerDialogId(attrStory.peer); long storyDialogId = DialogObject.getPeerDialogId(attrStory.peer);
@ -6171,6 +6262,7 @@ public class MediaDataController extends BaseController {
} }
} }
} }
Timer.done(t3);
if (replyMessageOwners.isEmpty() && messagesWithUnknownStories == null) { if (replyMessageOwners.isEmpty() && messagesWithUnknownStories == null) {
if (callback != null) { if (callback != null) {
callback.run(); callback.run();
@ -6180,8 +6272,10 @@ public class MediaDataController extends BaseController {
LongSparseArray<ArrayList<MessageObject>> finalMessagesWithUnknownStories = messagesWithUnknownStories; LongSparseArray<ArrayList<MessageObject>> finalMessagesWithUnknownStories = messagesWithUnknownStories;
Timer.Task t4 = Timer.start(logLogger, "loadReplyMessagesForMessages: storageQueue.postRunnable");
AtomicInteger requestsCount = new AtomicInteger(2); AtomicInteger requestsCount = new AtomicInteger(2);
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
Timer.done(t4);
try { try {
getMessagesController().getStoriesController().fillMessagesWithStories(finalMessagesWithUnknownStories, () -> { getMessagesController().getStoriesController().fillMessagesWithStories(finalMessagesWithUnknownStories, () -> {
if (requestsCount.decrementAndGet() == 0) { if (requestsCount.decrementAndGet() == 0) {
@ -6189,8 +6283,9 @@ public class MediaDataController extends BaseController {
AndroidUtilities.runOnUIThread(callback); AndroidUtilities.runOnUIThread(callback);
} }
} }
}, classGuid); }, classGuid, logLogger);
if (replyMessageOwners.isEmpty()) { if (replyMessageOwners.isEmpty()) {
Timer.log(logLogger, "loadReplyMessagesForMessages: empty replyMessageOwners");
if (requestsCount.decrementAndGet() == 0) { if (requestsCount.decrementAndGet() == 0) {
if (callback != null) { if (callback != null) {
AndroidUtilities.runOnUIThread(callback); AndroidUtilities.runOnUIThread(callback);
@ -6198,6 +6293,9 @@ public class MediaDataController extends BaseController {
} }
return; return;
} }
Timer.Task t5 = Timer.start(logLogger, "loadReplyMessagesForMessages: getting reply messages");
ArrayList<TLRPC.Message> result = new ArrayList<>(); ArrayList<TLRPC.Message> result = new ArrayList<>();
ArrayList<TLRPC.User> users = new ArrayList<>(); ArrayList<TLRPC.User> users = new ArrayList<>();
ArrayList<TLRPC.Chat> chats = new ArrayList<>(); ArrayList<TLRPC.Chat> chats = new ArrayList<>();
@ -6257,13 +6355,16 @@ public class MediaDataController extends BaseController {
broadcastReplyMessages(result, replyMessageOwners, users, chats, dialogId, true); broadcastReplyMessages(result, replyMessageOwners, users, chats, dialogId, true);
if (!dialogReplyMessagesIds.isEmpty()) { if (!dialogReplyMessagesIds.isEmpty()) {
Timer.done(t5);
for (int a = 0, N = dialogReplyMessagesIds.size(); a < N; a++) { for (int a = 0, N = dialogReplyMessagesIds.size(); a < N; a++) {
long channelId = dialogReplyMessagesIds.keyAt(a); long channelId = dialogReplyMessagesIds.keyAt(a);
if (scheduled) { if (scheduled) {
Timer.Task t6 = Timer.start(logLogger, "loadReplyMessagesForMessages: load scheduled");
TLRPC.TL_messages_getScheduledMessages req = new TLRPC.TL_messages_getScheduledMessages(); TLRPC.TL_messages_getScheduledMessages req = new TLRPC.TL_messages_getScheduledMessages();
req.peer = getMessagesController().getInputPeer(dialogId); req.peer = getMessagesController().getInputPeer(dialogId);
req.id = dialogReplyMessagesIds.valueAt(a); req.id = dialogReplyMessagesIds.valueAt(a);
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
Timer.done(t6);
if (error == null) { if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
for (int i = 0; i < messagesRes.messages.size(); i++) { for (int i = 0; i < messagesRes.messages.size(); i++) {
@ -6317,6 +6418,8 @@ public class MediaDataController extends BaseController {
getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true); getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
saveReplyMessages(replyMessageOwners, messagesRes.messages, scheduled); saveReplyMessages(replyMessageOwners, messagesRes.messages, scheduled);
} }
} else {
Timer.log(logLogger, "getScheduledMessages error: " + error.code + " " + error.text);
} }
if (requestsCount.decrementAndGet() == 0) { if (requestsCount.decrementAndGet() == 0) {
if (callback != null) { if (callback != null) {
@ -6328,10 +6431,12 @@ public class MediaDataController extends BaseController {
getConnectionsManager().bindRequestToGuid(reqId, classGuid); getConnectionsManager().bindRequestToGuid(reqId, classGuid);
} }
} else if (channelId != 0) { } else if (channelId != 0) {
Timer.Task t6 = Timer.start(logLogger, "loadReplyMessagesForMessages: load channel messages");
TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages(); TLRPC.TL_channels_getMessages req = new TLRPC.TL_channels_getMessages();
req.channel = getMessagesController().getInputChannel(channelId); req.channel = getMessagesController().getInputChannel(channelId);
req.id = dialogReplyMessagesIds.valueAt(a); req.id = dialogReplyMessagesIds.valueAt(a);
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
Timer.done(t6);
if (error == null) { if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
for (int i = 0; i < messagesRes.messages.size(); i++) { for (int i = 0; i < messagesRes.messages.size(); i++) {
@ -6345,6 +6450,8 @@ public class MediaDataController extends BaseController {
broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, messagesRes.chats, dialogId, false); broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, messagesRes.chats, dialogId, false);
getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true); getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
saveReplyMessages(replyMessageOwners, messagesRes.messages, scheduled); saveReplyMessages(replyMessageOwners, messagesRes.messages, scheduled);
} else {
Timer.log(logLogger, "channels.getMessages error: " + error.code + " " + error.text);
} }
if (requestsCount.decrementAndGet() == 0) { if (requestsCount.decrementAndGet() == 0) {
if (callback != null) { if (callback != null) {
@ -6356,9 +6463,11 @@ public class MediaDataController extends BaseController {
getConnectionsManager().bindRequestToGuid(reqId, classGuid); getConnectionsManager().bindRequestToGuid(reqId, classGuid);
} }
} else { } else {
Timer.Task t6 = Timer.start(logLogger, "loadReplyMessagesForMessages: load messages");
TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages(); TLRPC.TL_messages_getMessages req = new TLRPC.TL_messages_getMessages();
req.id = dialogReplyMessagesIds.valueAt(a); req.id = dialogReplyMessagesIds.valueAt(a);
int reqId = getConnectionsManager().sendRequest(req, (response, error) -> { int reqId = getConnectionsManager().sendRequest(req, (response, error) -> {
Timer.done(t6);
if (error == null) { if (error == null) {
TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response; TLRPC.messages_Messages messagesRes = (TLRPC.messages_Messages) response;
for (int i = 0; i < messagesRes.messages.size(); i++) { for (int i = 0; i < messagesRes.messages.size(); i++) {
@ -6371,6 +6480,8 @@ public class MediaDataController extends BaseController {
broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, messagesRes.chats, dialogId, false); broadcastReplyMessages(messagesRes.messages, replyMessageOwners, messagesRes.users, messagesRes.chats, dialogId, false);
getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true); getMessagesStorage().putUsersAndChats(messagesRes.users, messagesRes.chats, true, true);
saveReplyMessages(replyMessageOwners, messagesRes.messages, scheduled); saveReplyMessages(replyMessageOwners, messagesRes.messages, scheduled);
} else {
Timer.log(logLogger, "messages.getMessages error: " + error.code + " " + error.text);
} }
if (requestsCount.decrementAndGet() == 0) { if (requestsCount.decrementAndGet() == 0) {
if (callback != null) { if (callback != null) {
@ -6384,6 +6495,7 @@ public class MediaDataController extends BaseController {
} }
} }
} else { } else {
Timer.done(t5);
if (requestsCount.decrementAndGet() == 0) { if (requestsCount.decrementAndGet() == 0) {
if (callback != null) { if (callback != null) {
AndroidUtilities.runOnUIThread(callback); AndroidUtilities.runOnUIThread(callback);
@ -7721,7 +7833,7 @@ public class MediaDataController extends BaseController {
//---------------- DRAFT END ---------------- //---------------- DRAFT END ----------------
private HashMap<String, TLRPC.BotInfo> botInfos = new HashMap<>(); private HashMap<String, TL_bots.BotInfo> botInfos = new HashMap<>();
private LongSparseArray<ArrayList<TLRPC.Message>> botDialogKeyboards = new LongSparseArray<>(); private LongSparseArray<ArrayList<TLRPC.Message>> botDialogKeyboards = new LongSparseArray<>();
private HashMap<MessagesStorage.TopicKey, TLRPC.Message> botKeyboards = new HashMap<>(); private HashMap<MessagesStorage.TopicKey, TLRPC.Message> botKeyboards = new HashMap<>();
private LongSparseArray<MessagesStorage.TopicKey> botKeyboardsByMids = new LongSparseArray(); private LongSparseArray<MessagesStorage.TopicKey> botKeyboardsByMids = new LongSparseArray();
@ -7813,8 +7925,8 @@ public class MediaDataController extends BaseController {
}); });
} }
private TLRPC.BotInfo loadBotInfoInternal(long uid, long dialogId) throws SQLiteException { private TL_bots.BotInfo loadBotInfoInternal(long uid, long dialogId) throws SQLiteException {
TLRPC.BotInfo botInfo = null; TL_bots.BotInfo botInfo = null;
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT info FROM bot_info_v2 WHERE uid = %d AND dialogId = %d", uid, dialogId)); SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT info FROM bot_info_v2 WHERE uid = %d AND dialogId = %d", uid, dialogId));
if (cursor.next()) { if (cursor.next()) {
NativeByteBuffer data; NativeByteBuffer data;
@ -7822,7 +7934,7 @@ public class MediaDataController extends BaseController {
if (!cursor.isNull(0)) { if (!cursor.isNull(0)) {
data = cursor.byteBufferValue(0); data = cursor.byteBufferValue(0);
if (data != null) { if (data != null) {
botInfo = TLRPC.BotInfo.TLdeserialize(data, data.readInt32(false), false); botInfo = TL_bots.BotInfo.TLdeserialize(data, data.readInt32(false), false);
data.reuse(); data.reuse();
} }
} }
@ -7831,9 +7943,16 @@ public class MediaDataController extends BaseController {
return botInfo; return botInfo;
} }
public TL_bots.BotInfo getBotInfoCached(long uid, long dialogId) {
return botInfos.get(uid + "_" + dialogId);
}
public void loadBotInfo(long uid, long dialogId, boolean cache, int classGuid) { public void loadBotInfo(long uid, long dialogId, boolean cache, int classGuid) {
loadBotInfo(uid, dialogId, cache, classGuid, null);
}
public void loadBotInfo(long uid, long dialogId, boolean cache, int classGuid, Utilities.Callback<TL_bots.BotInfo> whenReceived) {
if (cache) { if (cache) {
TLRPC.BotInfo botInfo = botInfos.get(uid + "_" + dialogId); TL_bots.BotInfo botInfo = botInfos.get(uid + "_" + dialogId);
if (botInfo != null) { if (botInfo != null) {
getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, botInfo, classGuid); getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, botInfo, classGuid);
return; return;
@ -7841,9 +7960,20 @@ public class MediaDataController extends BaseController {
} }
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
try { try {
TLRPC.BotInfo botInfo = loadBotInfoInternal(uid, dialogId); TL_bots.BotInfo botInfo = loadBotInfoInternal(uid, dialogId);
if (botInfo != null) { if (botInfo != null) {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, botInfo, classGuid)); AndroidUtilities.runOnUIThread(() -> {
if (whenReceived != null) {
whenReceived.run(botInfo);
}
getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, botInfo, classGuid);
});
} else if (whenReceived != null) {
AndroidUtilities.runOnUIThread(() -> {
if (whenReceived != null) {
whenReceived.run(null);
}
});
} }
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -7918,7 +8048,7 @@ public class MediaDataController extends BaseController {
} }
} }
public void putBotInfo(long dialogId, TLRPC.BotInfo botInfo) { public void putBotInfo(long dialogId, TL_bots.BotInfo botInfo) {
if (botInfo == null) { if (botInfo == null) {
return; return;
} }
@ -7942,14 +8072,14 @@ public class MediaDataController extends BaseController {
} }
public void updateBotInfo(long dialogId, TLRPC.TL_updateBotCommands update) { public void updateBotInfo(long dialogId, TLRPC.TL_updateBotCommands update) {
TLRPC.BotInfo botInfo = botInfos.get(update.bot_id + "_" + dialogId); TL_bots.BotInfo botInfo = botInfos.get(update.bot_id + "_" + dialogId);
if (botInfo != null) { if (botInfo != null) {
botInfo.commands = update.commands; botInfo.commands = update.commands;
getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, botInfo, 0); getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, botInfo, 0);
} }
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
try { try {
TLRPC.BotInfo info = loadBotInfoInternal(update.bot_id, dialogId); TL_bots.BotInfo info = loadBotInfoInternal(update.bot_id, dialogId);
if (info != null) { if (info != null) {
info.commands = update.commands; info.commands = update.commands;
} }

View file

@ -1,54 +0,0 @@
package org.telegram.messenger;
public class MessageLoaderLogger {
final long dialogId;
final int count;
final int loadIndex;
final long startTime;
long moveToStorageQueueTime;
long getFromDatabaseTime;
long moveToStageQueueTime;
long stageQueueProccessing;
boolean reload;
public MessageLoaderLogger(long dialogId, int loadIndex, int count) {
this.dialogId = dialogId;
this.count = count;
this.loadIndex = loadIndex;
startTime = System.currentTimeMillis();
}
public void logStorageQueuePost() {
moveToStorageQueueTime = System.currentTimeMillis() - startTime;
}
public void logStorageProccessing() {
getFromDatabaseTime = System.currentTimeMillis() - startTime;
}
public void logStageQueuePost() {
moveToStageQueueTime = System.currentTimeMillis() - startTime;
}
public void reload() {
reload = true;
}
public void logStageQueueProcessing() {
stageQueueProccessing = System.currentTimeMillis() - startTime;
}
public void finish() {
long totalTime = System.currentTimeMillis() - startTime;
FileLog.d("MessageLoaderLogger dialogId=" + dialogId + " index=" + loadIndex + " count=" + count + " " +
" moveToStorageQueueTime=" + moveToStorageQueueTime +
" getFromDatabaseTime=" + getFromDatabaseTime +
" moveToStageQueueTime=" + moveToStageQueueTime +
" stageQueueProccessing=" + stageQueueProccessing +
" wasReload=" + reload + " totalTime=" + totalTime
);
}
}

View file

@ -33,6 +33,7 @@ import android.text.style.ClickableSpan;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.util.Base64; import android.util.Base64;
import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
@ -75,6 +76,8 @@ import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.PeerColorActivity; import org.telegram.ui.PeerColorActivity;
import org.telegram.ui.Stars.StarsController; import org.telegram.ui.Stars.StarsController;
import org.telegram.ui.Stars.StarsIntroActivity; import org.telegram.ui.Stars.StarsIntroActivity;
import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.web.BotWebViewContainer;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
@ -131,6 +134,7 @@ public class MessageObject {
public static final int TYPE_JOINED_CHANNEL = 27; // recommendations list public static final int TYPE_JOINED_CHANNEL = 27; // recommendations list
public static final int TYPE_GIVEAWAY_RESULTS = 28; public static final int TYPE_GIVEAWAY_RESULTS = 28;
public static final int TYPE_PAID_MEDIA = 29; // messageMediaPaidMedia with stars public static final int TYPE_PAID_MEDIA = 29; // messageMediaPaidMedia with stars
public static final int TYPE_GIFT_STARS = 30;
public int localType; public int localType;
public String localName; public String localName;
@ -141,8 +145,10 @@ public class MessageObject {
public boolean localSupergroup; public boolean localSupergroup;
public Boolean cachedIsSupergroup; public Boolean cachedIsSupergroup;
public boolean localEdit; public boolean localEdit;
public StoriesController.StoriesList parentStoriesList;
public TLRPC.Message messageOwner; public TLRPC.Message messageOwner;
public TL_stories.StoryItem storyItem; public TL_stories.StoryItem storyItem;
public StoriesController.UploadingStory uploadingStory;
public TLRPC.Document emojiAnimatedSticker; public TLRPC.Document emojiAnimatedSticker;
public Long emojiAnimatedStickerId; public Long emojiAnimatedStickerId;
public boolean isTopicMainMessage; public boolean isTopicMainMessage;
@ -222,6 +228,7 @@ public class MessageObject {
public String sponsoredInfo, sponsoredAdditionalInfo; public String sponsoredInfo, sponsoredAdditionalInfo;
public String sponsoredButtonText; public String sponsoredButtonText;
public TLRPC.TL_peerColor sponsoredColor; public TLRPC.TL_peerColor sponsoredColor;
public TLRPC.MessageMedia sponsoredMedia;
public boolean sponsoredCanReport; public boolean sponsoredCanReport;
public boolean replyTextEllipsized; public boolean replyTextEllipsized;
@ -287,7 +294,7 @@ public class MessageObject {
private boolean hasUnwrappedEmoji; private boolean hasUnwrappedEmoji;
public int emojiOnlyCount, animatedEmojiCount; public int emojiOnlyCount, animatedEmojiCount;
private int totalAnimatedEmojiCount; public int totalAnimatedEmojiCount;
private boolean layoutCreated; private boolean layoutCreated;
private int generatedWithMinSize; private int generatedWithMinSize;
private float generatedWithDensity; private float generatedWithDensity;
@ -488,7 +495,54 @@ public class MessageObject {
} }
public boolean hasMediaSpoilers() { public boolean hasMediaSpoilers() {
return !isRepostPreview && (messageOwner.media != null && messageOwner.media.spoiler || needDrawBluredPreview()); return !isRepostPreview && (messageOwner.media != null && messageOwner.media.spoiler || needDrawBluredPreview()) || isHiddenSensitive();
}
public Boolean isSensitiveCached;
public boolean isSensitive() {
if (isSensitiveCached != null) return isSensitiveCached;
if (messageOwner == null) return false;
if (!canBeSensitive()) return false;
if (!messageOwner.restriction_reason.isEmpty()) {
for (int i = 0; i < messageOwner.restriction_reason.size(); ++i) {
TLRPC.RestrictionReason reason = messageOwner.restriction_reason.get(i);
if (
"sensitive".equals(reason.reason) &&
("all".equals(reason.platform) || !ApplicationLoader.isStandaloneBuild() && !BuildVars.isBetaApp() && "android".equals(reason.platform))
) {
return isSensitiveCached = true;
}
}
}
if (getDialogId() < 0) {
final TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-getDialogId());
if (chat != null && chat.restriction_reason != null) {
for (int i = 0; i < chat.restriction_reason.size(); ++i) {
TLRPC.RestrictionReason reason = chat.restriction_reason.get(i);
if (
"sensitive".equals(reason.reason) &&
("all".equals(reason.platform) || !ApplicationLoader.isStandaloneBuild() && !BuildVars.isBetaApp() && "android".equals(reason.platform))
) {
return isSensitiveCached = true;
}
}
}
}
return isSensitiveCached = false;
}
public boolean isHiddenSensitive() {
return isSensitive() && !MessagesController.getInstance(currentAccount).showSensitiveContent();
}
public boolean canBeSensitive() {
return messageOwner != null && (
type == TYPE_PHOTO ||
type == TYPE_VIDEO ||
type == TYPE_FILE ||
type == TYPE_GIF ||
type == TYPE_ROUND_VIDEO
) && !sendPreview && !isRepostPreview && !isOutOwner() && messageOwner.send_state == MessageObject.MESSAGE_SEND_STATE_SENT;
} }
public boolean shouldDrawReactions() { public boolean shouldDrawReactions() {
@ -760,6 +814,7 @@ public class MessageObject {
public int padTop, padBottom; public int padTop, padBottom;
public int charactersOffset; public int charactersOffset;
public int charactersEnd; public int charactersEnd;
public int originalWidth;
public int height; public int height;
public int heightByOffset; public int heightByOffset;
public byte directionFlags; public byte directionFlags;
@ -2414,6 +2469,12 @@ public class MessageObject {
} else { } else {
messageText = replaceWithLink(LocaleController.getString("EventLogToggledSignaturesOff", R.string.EventLogToggledSignaturesOff), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString("EventLogToggledSignaturesOff", R.string.EventLogToggledSignaturesOff), "un1", fromUser);
} }
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionToggleSignatureProfiles) {
if (((TLRPC.TL_channelAdminLogEventActionToggleSignatureProfiles) event.action).value) {
messageText = replaceWithLink(LocaleController.getString(R.string.EventLogToggledSignaturesProfilesOn), "un1", fromUser);
} else {
messageText = replaceWithLink(LocaleController.getString(R.string.EventLogToggledSignaturesProfilesOff), "un1", fromUser);
}
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionToggleInvites) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionToggleInvites) {
if (((TLRPC.TL_channelAdminLogEventActionToggleInvites) event.action).new_value) { if (((TLRPC.TL_channelAdminLogEventActionToggleInvites) event.action).new_value) {
messageText = replaceWithLink(LocaleController.getString("EventLogToggledInvitesOn", R.string.EventLogToggledInvitesOn), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString("EventLogToggledInvitesOn", R.string.EventLogToggledInvitesOn), "un1", fromUser);
@ -2695,9 +2756,12 @@ public class MessageObject {
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite) {
TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite action = (TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite) event.action; TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite action = (TLRPC.TL_channelAdminLogEventActionParticipantJoinByInvite) event.action;
if (action.via_chatlist) { if (action.via_chatlist) {
messageText = replaceWithLink(LocaleController.getString("ActionInviteUserFolder", R.string.ActionInviteUserFolder), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString(ChatObject.isChannelAndNotMegaGroup(chat) ? R.string.ActionInviteChannelUserFolder : R.string.ActionInviteUserFolder), "un1", fromUser);
} else { } else {
messageText = replaceWithLink(LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString(ChatObject.isChannelAndNotMegaGroup(chat) ? R.string.ActionInviteChannelUser : R.string.ActionInviteUser), "un1", fromUser);
}
if (action.invite != null && !TextUtils.isEmpty(action.invite.link)) {
messageText = TextUtils.concat(messageText, " ", action.invite.link);
} }
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionToggleNoForwards) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionToggleNoForwards) {
TLRPC.TL_channelAdminLogEventActionToggleNoForwards action = (TLRPC.TL_channelAdminLogEventActionToggleNoForwards) event.action; TLRPC.TL_channelAdminLogEventActionToggleNoForwards action = (TLRPC.TL_channelAdminLogEventActionToggleNoForwards) event.action;
@ -3538,6 +3602,7 @@ public class MessageObject {
} }
message.reactions = reactions; message.reactions = reactions;
message.flags |= 1048576; message.flags |= 1048576;
FileLog.d("msg#"+message.id+" updateReactions out=" + message.out);
} }
public boolean hasReactions() { public boolean hasReactions() {
@ -4144,6 +4209,16 @@ public class MessageObject {
messageText = replaceWithLink(messageText, "un1", fromObject); messageText = replaceWithLink(messageText, "un1", fromObject);
} }
} }
} else if (messageOwner.action instanceof TLRPC.TL_messageActionPaymentRefunded) {
TLRPC.TL_messageActionPaymentRefunded action = (TLRPC.TL_messageActionPaymentRefunded) messageOwner.action;
long did = DialogObject.getPeerDialogId(action.peer);
TLObject who;
if (did >= 0) {
who = getUser(users, sUsers, did);
} else {
who = getChat(chats, sChats, -did);
}
messageText = StarsIntroActivity.replaceStars(replaceWithLink(LocaleController.formatString(R.string.ActionRefunded, action.currency + " " + LocaleController.formatNumber(action.total_amount, ',')), "un1", who));
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionChatAddUser) {
long singleUserId = messageOwner.action.user_id; long singleUserId = messageOwner.action.user_id;
if (singleUserId == 0 && messageOwner.action.users.size() == 1) { if (singleUserId == 0 && messageOwner.action.users.size() == 1) {
@ -4200,9 +4275,9 @@ public class MessageObject {
} }
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByLink) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionChatJoinedByLink) {
if (isOut()) { if (isOut()) {
messageText = LocaleController.getString("ActionInviteYou", R.string.ActionInviteYou); messageText = LocaleController.getString(R.string.ActionInviteYou);
} else { } else {
messageText = replaceWithLink(LocaleController.getString("ActionInviteUser", R.string.ActionInviteUser), "un1", fromObject); messageText = replaceWithLink(LocaleController.getString(R.string.ActionInviteUser), "un1", fromObject);
} }
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiveawayLaunch) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiveawayLaunch) {
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null; TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null;
@ -4245,6 +4320,24 @@ public class MessageObject {
stringBuilder.append(LocaleController.formatPluralString(isChannel ? "BoostingGiveawayServiceUndistributed" : "BoostingGiveawayServiceUndistributedGroup", giveawayResults.unclaimed_count)); stringBuilder.append(LocaleController.formatPluralString(isChannel ? "BoostingGiveawayServiceUndistributed" : "BoostingGiveawayServiceUndistributedGroup", giveawayResults.unclaimed_count));
} }
messageText = stringBuilder; messageText = stringBuilder;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftStars) {
if (fromObject instanceof TLRPC.User && ((TLRPC.User) fromObject).self) {
TLRPC.User user = getUser(users, sUsers, messageOwner.peer_id.user_id);
messageText = replaceWithLink(AndroidUtilities.replaceTags(LocaleController.getString(R.string.ActionGiftOutbound)), "un1", user);
} else if (fromObject instanceof TLRPC.User && UserObject.isService(((TLRPC.User) fromObject).id)) {
messageText = TextUtils.replace(AndroidUtilities.replaceTags(LocaleController.getString(R.string.ActionGiftInbound)), new String[] {"un1"}, new CharSequence[]{ LocaleController.getString(R.string.StarsTransactionUnknown) });
} else {
messageText = replaceWithLink(AndroidUtilities.replaceTags(LocaleController.getString(R.string.ActionGiftInbound)), "un1", fromObject);
}
int i = messageText.toString().indexOf("un2");
if (i != -1) {
SpannableStringBuilder sb = SpannableStringBuilder.valueOf(messageText);
CharSequence price = BillingController.getInstance().formatCurrency(messageOwner.action.amount, messageOwner.action.currency);
if ((messageOwner.action.flags & 1) != 0) {
price = String.format("%.2f", (messageOwner.action.cryptoAmount * Math.pow(10, -9))) + " " + messageOwner.action.cryptoCurrency + " (~ " + price + ")";
}
messageText = sb.replace(i, i + 3, price);
}
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode && ((TLRPC.TL_messageActionGiftCode) messageOwner.action).boost_peer != null) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode && ((TLRPC.TL_messageActionGiftCode) messageOwner.action).boost_peer != null) {
messageText = LocaleController.getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName); messageText = LocaleController.getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName);
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium || messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium || messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
@ -4748,11 +4841,11 @@ public class MessageObject {
} }
} else { } else {
isRestrictedMessage = false; isRestrictedMessage = false;
String restrictionReason = MessagesController.getRestrictionReason(messageOwner.restriction_reason); String restrictionReason = MessagesController.getInstance(currentAccount).getRestrictionReason(messageOwner.restriction_reason);
if (!TextUtils.isEmpty(restrictionReason)) { if (!TextUtils.isEmpty(restrictionReason)) {
messageText = restrictionReason; messageText = restrictionReason;
isRestrictedMessage = true; isRestrictedMessage = true;
} else if (!isMediaEmpty()) { } else if (!isMediaEmpty() && !isSponsored()) {
// messageText = getMediaTitle(getMedia(messageOwner)); // I'm afraid doing this // messageText = getMediaTitle(getMedia(messageOwner)); // I'm afraid doing this
if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGiveaway) { if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGiveaway) {
boolean isChannel; boolean isChannel;
@ -5004,6 +5097,9 @@ public class MessageObject {
if (messageObject == null || messageObject.messageOwner == null) { if (messageObject == null || messageObject.messageOwner == null) {
return null; return null;
} }
if (messageObject.sponsoredMedia != null) {
return messageObject.sponsoredMedia;
}
return getMedia(messageObject.messageOwner); return getMedia(messageObject.messageOwner);
} }
@ -5063,7 +5159,9 @@ public class MessageObject {
int oldType = type; int oldType = type;
type = 1000; type = 1000;
isRoundVideoCached = 0; isRoundVideoCached = 0;
if (channelJoined) { if (isSponsored()) {
type = TYPE_TEXT;
} else if (channelJoined) {
type = TYPE_JOINED_CHANNEL; type = TYPE_JOINED_CHANNEL;
channelJoinedExpanded = MessagesController.getInstance(currentAccount).getMainSettings().getBoolean("c" + getDialogId() + "_rec", true); channelJoinedExpanded = MessagesController.getInstance(currentAccount).getMainSettings().getBoolean("c" + getDialogId() + "_rec", true);
} else if (messageOwner instanceof TLRPC.TL_message || messageOwner instanceof TLRPC.TL_messageForwarded_old2) { } else if (messageOwner instanceof TLRPC.TL_message || messageOwner instanceof TLRPC.TL_messageForwarded_old2) {
@ -5190,6 +5288,9 @@ public class MessageObject {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium || messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium || messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
contentType = 1; contentType = 1;
type = TYPE_GIFT_PREMIUM; type = TYPE_GIFT_PREMIUM;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftStars) {
contentType = 1;
type = TYPE_GIFT_STARS;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionChatEditPhoto || messageOwner.action instanceof TLRPC.TL_messageActionUserUpdatedPhoto) {
contentType = 1; contentType = 1;
type = TYPE_ACTION_PHOTO; type = TYPE_ACTION_PHOTO;
@ -5545,6 +5646,27 @@ public class MessageObject {
} }
} }
} }
} else if (sponsoredMedia != null) {
TLRPC.Photo photo = sponsoredMedia.photo;
TLRPC.Document document = sponsoredMedia.document;
if (photo != null) {
if (!update || photoThumbs == null) {
photoThumbs = new ArrayList<>(photo.sizes);
} else if (!photoThumbs.isEmpty()) {
updatePhotoSizeLocations(photoThumbs, photo.sizes);
}
photoThumbsObject = photo;
} else if (document != null) {
if (isDocumentHasThumb(document)) {
if (!update) {
photoThumbs = new ArrayList<>();
photoThumbs.addAll(document.thumbs);
} else if (photoThumbs != null && !photoThumbs.isEmpty()) {
updatePhotoSizeLocations(photoThumbs, document.thumbs);
}
photoThumbsObject = document;
}
}
} else if (sponsoredPhoto != null) { } else if (sponsoredPhoto != null) {
if (!update || photoThumbs == null) { if (!update || photoThumbs == null) {
photoThumbs = new ArrayList<>(sponsoredPhoto.sizes); photoThumbs = new ArrayList<>(sponsoredPhoto.sizes);
@ -6515,10 +6637,11 @@ public class MessageObject {
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityUrl) { } else if (run.urlEntity instanceof TLRPC.TL_messageEntityUrl) {
hasUrls = true; hasUrls = true;
String lowerCase = url.toLowerCase(); String lowerCase = url.toLowerCase();
url = !lowerCase.contains("://") ? "http://" + url : url; url = !lowerCase.contains("://") ? (BotWebViewContainer.isTonsite(url) ? "tonsite://" : "http://") + url : url;
if (url != null) { if (url != null) {
url = url.replaceAll("||%E2%81%84|%E2%88%95", "/"); url = url.replaceAll("||%E2%81%84|%E2%88%95", "/");
} }
if (Browser.isTonsitePunycode(url)) continue;
spannable.setSpan(new URLSpanBrowser(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); spannable.setSpan(new URLSpanBrowser(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityBankCard) { } else if (run.urlEntity instanceof TLRPC.TL_messageEntityBankCard) {
hasUrls = true; hasUrls = true;
@ -6535,6 +6658,7 @@ public class MessageObject {
if (url != null) { if (url != null) {
url = url.replaceAll("||%E2%81%84|%E2%88%95", "/"); url = url.replaceAll("||%E2%81%84|%E2%88%95", "/");
} }
if (Browser.isTonsitePunycode(url)) continue;
spannable.setSpan(new URLSpanReplacement(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); spannable.setSpan(new URLSpanReplacement(url, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (run.urlEntity instanceof TLRPC.TL_messageEntityMentionName) { } else if (run.urlEntity instanceof TLRPC.TL_messageEntityMentionName) {
spannable.setSpan(new URLSpanUserMention("" + ((TLRPC.TL_messageEntityMentionName) run.urlEntity).user_id, t, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); spannable.setSpan(new URLSpanUserMention("" + ((TLRPC.TL_messageEntityMentionName) run.urlEntity).user_id, t, run), run.start, run.end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -6841,6 +6965,7 @@ public class MessageObject {
maxWidth -= AndroidUtilities.dp(15); maxWidth -= AndroidUtilities.dp(15);
} }
int textLayoutOriginalWidth;
StaticLayout textLayout; StaticLayout textLayout;
TextPaint paint; TextPaint paint;
@ -6852,6 +6977,7 @@ public class MessageObject {
CharSequence text = messageText; CharSequence text = messageText;
try { try {
textLayoutOriginalWidth = maxWidth;
textLayout = makeStaticLayout(text, paint, maxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0); textLayout = makeStaticLayout(text, paint, maxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -6897,6 +7023,7 @@ public class MessageObject {
}, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try { try {
textLayoutOriginalWidth = maxWidth;
textLayout = makeStaticLayout(text, paint, maxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0); textLayout = makeStaticLayout(text, paint, maxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -7024,7 +7151,10 @@ public class MessageObject {
} else { } else {
sb = new SpannableString(blockText.toString()); sb = new SpannableString(blockText.toString());
} }
block.originalWidth = textLayoutOriginalWidth = blockMaxWidth;
textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0); textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, emojiOnlyCount > 0);
} else {
block.originalWidth = textLayoutOriginalWidth;
} }
block.textLayout = textLayout; block.textLayout = textLayout;
@ -7061,6 +7191,7 @@ public class MessageObject {
} else { } else {
sb = SpannableString.valueOf(blockText); sb = SpannableString.valueOf(blockText);
} }
block.originalWidth = blockMaxWidth;
block.textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, false); block.textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, totalAnimatedEmojiCount >= 4 ? -1 : 0, false);
block.height = block.textLayout.getHeight();//Math.max(block.height, block.textLayout.getLineBottom(block.textLayout.getLineCount() - 1)); block.height = block.textLayout.getHeight();//Math.max(block.height, block.textLayout.getLineBottom(block.textLayout.getLineCount() - 1));
@ -7305,11 +7436,9 @@ public class MessageObject {
width -= AndroidUtilities.dp(15); width -= AndroidUtilities.dp(15);
} }
final float lineSpacing = 1f; int textLayoutOriginalWidth;
final float lineAdd = 0;
Layout.Alignment align = Layout.Alignment.ALIGN_NORMAL; //type == TYPE_EMOJIS && isOut() ? Layout.Alignment.ALIGN_OPPOSITE : Layout.Alignment.ALIGN_NORMAL;
try { try {
textLayout = makeStaticLayout(text, textPaint, width, 1f, 0f, false); textLayout = makeStaticLayout(text, textPaint, textLayoutOriginalWidth = width, 1f, 0f, false);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
return; return;
@ -7353,6 +7482,7 @@ public class MessageObject {
}, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); }, text.length() - readMore.length(), text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
try { try {
textLayoutOriginalWidth = width;
textLayout = makeStaticLayout(text, textPaint, width, 1f, 0f, false); textLayout = makeStaticLayout(text, textPaint, width, 1f, 0f, false);
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -7471,7 +7601,10 @@ public class MessageObject {
} else { } else {
sb = new SpannableString(text.subSequence(range.start, range.end)); sb = new SpannableString(text.subSequence(range.start, range.end));
} }
block.originalWidth = textLayoutOriginalWidth = blockMaxWidth;
textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, 0f, false); textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, 0f, false);
} else {
block.originalWidth = textLayoutOriginalWidth;
} }
block.textLayout = textLayout; block.textLayout = textLayout;
@ -7495,6 +7628,7 @@ public class MessageObject {
} else { } else {
sb = SpannableString.valueOf(text.subSequence(startCharacter, endCharacter)); sb = SpannableString.valueOf(text.subSequence(startCharacter, endCharacter));
} }
block.originalWidth = blockMaxWidth;
block.textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, 0f, false); block.textLayout = makeStaticLayout(sb, layoutPaint, blockMaxWidth, 1f, 0f, false);
block.height = block.textLayout.getHeight(); block.height = block.textLayout.getHeight();
@ -7672,7 +7806,7 @@ public class MessageObject {
} }
} }
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(null, null, messageOwner.peer_id.channel_id) : null; TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(null, null, messageOwner.peer_id.channel_id) : null;
if (!messageOwner.out || !(messageOwner.from_id instanceof TLRPC.TL_peerUser) && (!(messageOwner.from_id instanceof TLRPC.TL_peerChannel) || ChatObject.isChannel(chat) && !chat.megagroup) || messageOwner.post) { if (!messageOwner.out || !(messageOwner.from_id instanceof TLRPC.TL_peerUser) && (!(messageOwner.from_id instanceof TLRPC.TL_peerChannel) || ChatObject.isChannelAndNotMegaGroup(chat)) || messageOwner.post) {
return isOutOwnerCached = false; return isOutOwnerCached = false;
} }
if (messageOwner.fwd_from == null) { if (messageOwner.fwd_from == null) {
@ -7686,6 +7820,9 @@ public class MessageObject {
} }
public boolean needDrawAvatar() { public boolean needDrawAvatar() {
if (type == TYPE_JOINED_CHANNEL) {
return false;
}
if (isRepostPreview) { if (isRepostPreview) {
return true; return true;
} }
@ -7698,7 +7835,12 @@ public class MessageObject {
if (searchType != 0) { if (searchType != 0) {
return true; return true;
} }
return !isSponsored() && (isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null); boolean channelSignatureProfiles = false;
if (getDialogId() < 0) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-getDialogId());
channelSignatureProfiles = (chat != null && chat.signature_profiles);
}
return !isSponsored() && (isFromUser() || isFromGroup() || channelSignatureProfiles || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
} }
private boolean needDrawAvatarInternal() { private boolean needDrawAvatarInternal() {
@ -8814,7 +8956,7 @@ public class MessageObject {
return dp(82); return dp(82);
} else if (type == 10) { } else if (type == 10) {
return dp(30); return dp(30);
} else if (type == TYPE_ACTION_PHOTO || type == TYPE_GIFT_PREMIUM || type == TYPE_GIFT_PREMIUM_CHANNEL || type == TYPE_SUGGEST_PHOTO) { } else if (type == TYPE_ACTION_PHOTO || type == TYPE_GIFT_PREMIUM || type == TYPE_GIFT_STARS || type == TYPE_GIFT_PREMIUM_CHANNEL || type == TYPE_SUGGEST_PHOTO) {
return dp(50); return dp(50);
} else if (type == TYPE_ROUND_VIDEO) { } else if (type == TYPE_ROUND_VIDEO) {
return AndroidUtilities.roundMessageSize; return AndroidUtilities.roundMessageSize;
@ -9948,6 +10090,141 @@ public class MessageObject {
return !isEditing() && !isSponsored() && isSent() && messageOwner.action == null && !isExpiredStory(); return !isEditing() && !isSponsored() && isSent() && messageOwner.action == null && !isExpiredStory();
} }
public boolean isPaidReactionChosen() {
if (messageOwner.reactions == null) return false;
for (int i = 0; i < messageOwner.reactions.results.size(); i++) {
if (messageOwner.reactions.results.get(i).reaction instanceof TLRPC.TL_reactionPaid) {
return messageOwner.reactions.results.get(i).chosen;
}
}
return false;
}
public void addPaidReactions(int amount, boolean chosen, boolean anonymous) {
if (messageOwner.reactions == null) {
messageOwner.reactions = new TLRPC.TL_messageReactions();
messageOwner.reactions.reactions_as_tags = MessageObject.getDialogId(messageOwner) == UserConfig.getInstance(currentAccount).getClientUserId();
messageOwner.reactions.can_see_list = isFromGroup() || isFromUser();
}
addPaidReactions(currentAccount, messageOwner.reactions, amount, anonymous, chosen);
}
public Boolean isMyPaidReactionAnonymous() {
if (messageOwner == null || messageOwner.reactions == null) return null;
if (messageOwner.reactions.top_reactors == null) return null;
for (TLRPC.MessageReactor reactor : messageOwner.reactions.top_reactors) {
if (reactor != null && reactor.my) {
return reactor.anonymous;
}
}
return null;
}
public static Boolean isMyPaidReactionAnonymous(TLRPC.MessageReactions reactions) {
if (reactions == null) return null;
if (reactions.top_reactors == null) return null;
for (TLRPC.MessageReactor reactor : reactions.top_reactors) {
if (reactor != null && reactor.my) {
return reactor.anonymous;
}
}
return null;
}
public void setMyPaidReactionAnonymous(boolean value) {
if (messageOwner == null || messageOwner.reactions == null) return;
if (messageOwner.reactions.top_reactors == null) return;
for (TLRPC.MessageReactor reactor : messageOwner.reactions.top_reactors) {
if (reactor != null && reactor.my) {
reactor.anonymous = value;
}
}
}
public boolean doesPaidReactionExist() {
if (messageOwner.reactions == null) {
messageOwner.reactions = new TLRPC.TL_messageReactions();
messageOwner.reactions.reactions_as_tags = MessageObject.getDialogId(messageOwner) == UserConfig.getInstance(currentAccount).getClientUserId();
messageOwner.reactions.can_see_list = isFromGroup() || isFromUser();
}
for (int i = 0; i < messageOwner.reactions.results.size(); i++) {
if (messageOwner.reactions.results.get(i).reaction instanceof TLRPC.TL_reactionPaid) {
return true;
}
}
return false;
}
public boolean ensurePaidReactionsExist(boolean chosen) {
if (messageOwner.reactions == null) {
messageOwner.reactions = new TLRPC.TL_messageReactions();
messageOwner.reactions.reactions_as_tags = MessageObject.getDialogId(messageOwner) == UserConfig.getInstance(currentAccount).getClientUserId();
messageOwner.reactions.can_see_list = isFromGroup() || isFromUser();
}
TLRPC.ReactionCount reactionCount = null;
for (int i = 0; i < messageOwner.reactions.results.size(); i++) {
if (messageOwner.reactions.results.get(i).reaction instanceof TLRPC.TL_reactionPaid) {
reactionCount = messageOwner.reactions.results.get(i);
}
}
if (reactionCount == null) {
reactionCount = new TLRPC.TL_reactionCount();
reactionCount.reaction = new TLRPC.TL_reactionPaid();
reactionCount.count = 1;
reactionCount.chosen = chosen;
messageOwner.reactions.results.add(0, reactionCount);
return true;
}
return false;
}
public static void addPaidReactions(
int currentAccount,
TLRPC.MessageReactions reactions,
int amount,
boolean anonymous,
boolean chosen
) {
TLRPC.ReactionCount reactionCount = null;
for (int i = 0; i < reactions.results.size(); i++) {
if (reactions.results.get(i).reaction instanceof TLRPC.TL_reactionPaid) {
reactionCount = reactions.results.get(i);
}
}
TLRPC.MessageReactor reactor = null;
for (int i = 0; i < reactions.top_reactors.size(); i++) {
if (reactions.top_reactors.get(i).my) {
reactor = reactions.top_reactors.get(i);
break;
}
}
if (reactionCount == null && amount > 0) {
reactionCount = new TLRPC.TL_reactionCount();
reactionCount.reaction = new TLRPC.TL_reactionPaid();
reactions.results.add(0, reactionCount);
}
if (reactionCount != null) {
reactionCount.chosen = chosen;
reactionCount.count = Math.max(0, reactionCount.count + amount);
if (reactionCount.count <= 0) {
reactions.results.remove(reactionCount);
}
}
if (reactor == null && amount > 0) {
reactor = new TLRPC.TL_messageReactor();
reactor.my = true;
reactor.peer_id = MessagesController.getInstance(currentAccount).getPeer(UserConfig.getInstance(currentAccount).getClientUserId());
reactions.top_reactors.add(reactor);
}
if (reactor != null) {
reactor.count = Math.max(0, reactor.count + amount);
reactor.anonymous = anonymous;
if (reactor.count <= 0) {
reactions.top_reactors.remove(reactor);
}
}
}
public boolean selectReaction(ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean big, boolean fromDoubleTap) { public boolean selectReaction(ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean big, boolean fromDoubleTap) {
if (messageOwner.reactions == null) { if (messageOwner.reactions == null) {
messageOwner.reactions = new TLRPC.TL_messageReactions(); messageOwner.reactions = new TLRPC.TL_messageReactions();
@ -9959,8 +10236,8 @@ public class MessageObject {
TLRPC.ReactionCount newReaction = null; TLRPC.ReactionCount newReaction = null;
int maxChoosenOrder = 0; int maxChoosenOrder = 0;
for (int i = 0; i < messageOwner.reactions.results.size(); i++) { for (int i = 0; i < messageOwner.reactions.results.size(); i++) {
if (messageOwner.reactions.results.get(i).chosen) { final TLRPC.ReactionCount reactionCount = messageOwner.reactions.results.get(i);
TLRPC.ReactionCount reactionCount = messageOwner.reactions.results.get(i); if (reactionCount.chosen && !(reactionCount.reaction instanceof TLRPC.TL_reactionPaid)) {
choosenReactions.add(reactionCount); choosenReactions.add(reactionCount);
if (reactionCount.chosen_order > maxChoosenOrder) { if (reactionCount.chosen_order > maxChoosenOrder) {
maxChoosenOrder = reactionCount.chosen_order; maxChoosenOrder = reactionCount.chosen_order;
@ -10013,7 +10290,10 @@ public class MessageObject {
while (!choosenReactions.isEmpty() && choosenReactions.size() >= maxReactionsCount) { while (!choosenReactions.isEmpty() && choosenReactions.size() >= maxReactionsCount) {
int minIndex = 0; int minIndex = 0;
for (int i = 1; i < choosenReactions.size(); i++) { for (int i = 1; i < choosenReactions.size(); i++) {
if (choosenReactions.get(i).chosen_order < choosenReactions.get(minIndex).chosen_order) { if (
!(choosenReactions.get(i).reaction instanceof TLRPC.TL_reactionPaid) &&
choosenReactions.get(i).chosen_order < choosenReactions.get(minIndex).chosen_order
) {
minIndex = i; minIndex = i;
} }
} }
@ -10037,7 +10317,15 @@ public class MessageObject {
if (newReaction == null) { if (newReaction == null) {
int maxChatReactions = MessagesController.getInstance(currentAccount).getChatMaxUniqReactions(getDialogId()); int maxChatReactions = MessagesController.getInstance(currentAccount).getChatMaxUniqReactions(getDialogId());
if (messageOwner.reactions.results.size() + 1 > maxChatReactions) { int chosenCount = 0;
if (messageOwner != null && messageOwner.reactions != null) {
for (TLRPC.ReactionCount reactionCount : messageOwner.reactions.results) {
if (!(reactionCount.reaction instanceof TLRPC.TL_reactionPaid)) {
chosenCount++;
}
}
}
if (chosenCount + 1 > maxChatReactions) {
return false; return false;
} }
newReaction = new TLRPC.TL_reactionCount(); newReaction = new TLRPC.TL_reactionCount();
@ -10115,6 +10403,10 @@ public class MessageObject {
return storyItem != null; return storyItem != null;
} }
public boolean isBotPreview() {
return storyItem instanceof StoriesController.BotPreview;
}
private TLRPC.WebPage storyMentionWebpage; private TLRPC.WebPage storyMentionWebpage;
public TLRPC.WebPage getStoryMentionWebpage() { public TLRPC.WebPage getStoryMentionWebpage() {
if (!isStoryMention()) { if (!isStoryMention()) {
@ -10153,7 +10445,7 @@ public class MessageObject {
} }
public boolean isAnyGift() { public boolean isAnyGift() {
return type == MessageObject.TYPE_GIFT_PREMIUM || type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL; return type == MessageObject.TYPE_GIFT_STARS || type == MessageObject.TYPE_GIFT_PREMIUM || type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL;
} }
private static CharSequence[] userSpan; private static CharSequence[] userSpan;
@ -10641,4 +10933,8 @@ public class MessageObject {
return getMedia(this) instanceof TLRPC.TL_messageMediaPaidMedia; return getMedia(this) instanceof TLRPC.TL_messageMediaPaidMedia;
} }
public float getProgress() {
return 0f;
}
} }

View file

@ -213,7 +213,7 @@ public class MessagePreviewParams {
replyMessageObject = null; replyMessageObject = null;
replyQuote = null; replyQuote = null;
} }
hasSecretMessages = replyMessageObject != null && (replyMessageObject.isVoiceOnce() || replyMessageObject.isRoundOnce()); hasSecretMessages = replyMessageObject != null && (replyMessageObject.isVoiceOnce() || replyMessageObject.isRoundOnce() || replyMessageObject.type == MessageObject.TYPE_GIFT_STARS);
if (replyMessageObject != null || replyQuote != null) { if (replyMessageObject != null || replyQuote != null) {
if (group != null) { if (group != null) {
replyMessage = new Messages(null, 1, group.messages, dialogId, null); replyMessage = new Messages(null, 1, group.messages, dialogId, null);

View file

@ -8,6 +8,8 @@
package org.telegram.messenger; package org.telegram.messenger;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.LocaleController.getString;
import static org.telegram.messenger.NotificationsController.TYPE_CHANNEL; import static org.telegram.messenger.NotificationsController.TYPE_CHANNEL;
import static org.telegram.messenger.NotificationsController.TYPE_PRIVATE; import static org.telegram.messenger.NotificationsController.TYPE_PRIVATE;
import static org.telegram.messenger.NotificationsController.TYPE_REACTIONS_MESSAGES; import static org.telegram.messenger.NotificationsController.TYPE_REACTIONS_MESSAGES;
@ -32,6 +34,9 @@ import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.SparseBooleanArray; import android.util.SparseBooleanArray;
import android.util.SparseIntArray; import android.util.SparseIntArray;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
@ -55,12 +60,17 @@ import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.SerializedData; import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_account;
import org.telegram.tgnet.tl.TL_bots;
import org.telegram.tgnet.tl.TL_stories; import org.telegram.tgnet.tl.TL_stories;
import org.telegram.tgnet.tl.TL_chatlists; import org.telegram.tgnet.tl.TL_chatlists;
import org.telegram.ui.ActionBar.ActionBarLayout;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Business.QuickRepliesController; import org.telegram.ui.Business.QuickRepliesController;
import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.ChannelMonetizationLayout; import org.telegram.ui.ChannelMonetizationLayout;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.ChatReactionsEditActivity; import org.telegram.ui.ChatReactionsEditActivity;
@ -70,6 +80,7 @@ import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
import org.telegram.ui.Components.ImageUpdater; import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.JoinCallAlert; import org.telegram.ui.Components.JoinCallAlert;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MotionBackgroundDrawable; import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.Premium.LimitReachedBottomSheet; import org.telegram.ui.Components.Premium.LimitReachedBottomSheet;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
@ -84,7 +95,11 @@ import org.telegram.ui.SecretMediaViewer;
import org.telegram.ui.Stars.BotStarsController; import org.telegram.ui.Stars.BotStarsController;
import org.telegram.ui.Stars.StarsController; import org.telegram.ui.Stars.StarsController;
import org.telegram.ui.Stories.StoriesController; import org.telegram.ui.Stories.StoriesController;
import org.telegram.ui.ThemeActivity;
import org.telegram.ui.TopicsFragment; import org.telegram.ui.TopicsFragment;
import org.telegram.ui.bots.BotWebViewAttachedSheet;
import org.telegram.ui.bots.BotWebViewSheet;
import org.telegram.ui.bots.WebViewRequestProps;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
@ -104,17 +119,17 @@ import java.util.concurrent.CountDownLatch;
public class MessagesController extends BaseController implements NotificationCenter.NotificationCenterDelegate { public class MessagesController extends BaseController implements NotificationCenter.NotificationCenterDelegate {
public int lastKnownSessionsCount; public int lastKnownSessionsCount;
private ConcurrentHashMap<Long, TLRPC.Chat> chats = new ConcurrentHashMap<>(100, 1.0f, 2); private final ConcurrentHashMap<Long, TLRPC.Chat> chats = new ConcurrentHashMap<>(100, 1.0f, 2);
private ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<>(10, 1.0f, 2); private final ConcurrentHashMap<Integer, TLRPC.EncryptedChat> encryptedChats = new ConcurrentHashMap<>(10, 1.0f, 2);
private ConcurrentHashMap<Long, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 3); private final ConcurrentHashMap<Long, TLRPC.User> users = new ConcurrentHashMap<>(100, 1.0f, 3);
private ConcurrentHashMap<String, TLObject> objectsByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2); private final ConcurrentHashMap<String, TLObject> objectsByUsernames = new ConcurrentHashMap<>(100, 1.0f, 2);
public static int stableIdPointer = 100; public static int stableIdPointer = 100;
private HashMap<Long, TLRPC.Chat> activeVoiceChatsMap = new HashMap<>(); private final HashMap<Long, TLRPC.Chat> activeVoiceChatsMap = new HashMap<>();
private ArrayList<Long> joiningToChannels = new ArrayList<>(); private final ArrayList<Long> joiningToChannels = new ArrayList<>();
private LongSparseArray<TLRPC.TL_chatInviteExported> exportedChats = new LongSparseArray<>(); private final LongSparseArray<TLRPC.TL_chatInviteExported> exportedChats = new LongSparseArray<>();
public ArrayList<TLRPC.RecentMeUrl> hintDialogs = new ArrayList<>(); public ArrayList<TLRPC.RecentMeUrl> hintDialogs = new ArrayList<>();
public SparseArray<ArrayList<TLRPC.Dialog>> dialogsByFolder = new SparseArray<>(); public SparseArray<ArrayList<TLRPC.Dialog>> dialogsByFolder = new SparseArray<>();
@ -543,6 +558,7 @@ public class MessagesController extends BaseController implements NotificationCe
public int boostsChannelLevelMax; public int boostsChannelLevelMax;
public int channelRestrictSponsoredLevelMin; public int channelRestrictSponsoredLevelMin;
public Set<String> webAppAllowedProtocols; public Set<String> webAppAllowedProtocols;
public Set<String> ignoreRestrictionReasons;
public int channelsLimitDefault; public int channelsLimitDefault;
public int channelsLimitPremium; public int channelsLimitPremium;
@ -613,6 +629,15 @@ public class MessagesController extends BaseController implements NotificationCe
public int factcheckLengthLimit; public int factcheckLengthLimit;
public long starsRevenueWithdrawalMin; public long starsRevenueWithdrawalMin;
public long starsPaidPostAmountMax; public long starsPaidPostAmountMax;
public int botPreviewMediasMax;
public String tonProxyAddress;
public String weatherSearchUsername;
public boolean storyWeatherPreload;
public boolean starsGiftsEnabled;
public long starsPaidReactionAmountMax;
public long starsSubscriptionAmountMax;
public float starsUsdSellRate1000;
public float starsUsdWithdrawRate1000;
public int savedDialogsPinnedLimitDefault; public int savedDialogsPinnedLimitDefault;
public int savedDialogsPinnedLimitPremium; public int savedDialogsPinnedLimitPremium;
@ -626,9 +651,9 @@ public class MessagesController extends BaseController implements NotificationCe
public String premiumBotUsername; public String premiumBotUsername;
public String premiumInvoiceSlug; public String premiumInvoiceSlug;
private SharedPreferences notificationsPreferences; private final SharedPreferences notificationsPreferences;
private SharedPreferences mainPreferences; private final SharedPreferences mainPreferences;
private SharedPreferences emojiPreferences; private final SharedPreferences emojiPreferences;
public volatile boolean ignoreSetOnline; public volatile boolean ignoreSetOnline;
public boolean premiumLocked; public boolean premiumLocked;
@ -1555,7 +1580,17 @@ public class MessagesController extends BaseController implements NotificationCe
factcheckLengthLimit = mainPreferences.getInt("factcheckLengthLimit", 1024); factcheckLengthLimit = mainPreferences.getInt("factcheckLengthLimit", 1024);
starsRevenueWithdrawalMin = mainPreferences.getLong("starsRevenueWithdrawalMin", 1000); starsRevenueWithdrawalMin = mainPreferences.getLong("starsRevenueWithdrawalMin", 1000);
starsPaidPostAmountMax = mainPreferences.getLong("starsPaidPostAmountMax", 10_000); starsPaidPostAmountMax = mainPreferences.getLong("starsPaidPostAmountMax", 10_000);
botPreviewMediasMax = mainPreferences.getInt("botPreviewMediasMax", 10);
webAppAllowedProtocols = mainPreferences.getStringSet("webAppAllowedProtocols", new HashSet<>(Arrays.asList("http", "https"))); webAppAllowedProtocols = mainPreferences.getStringSet("webAppAllowedProtocols", new HashSet<>(Arrays.asList("http", "https")));
ignoreRestrictionReasons = mainPreferences.getStringSet("ignoreRestrictionReasons", new HashSet<>(Arrays.asList()));
tonProxyAddress = mainPreferences.getString("tonProxyAddress", "magic.org");
weatherSearchUsername = mainPreferences.getString("weatherSearchUsername", "izweatherbot");
storyWeatherPreload = mainPreferences.getBoolean("storyWeatherPreload", true);
starsGiftsEnabled = mainPreferences.getBoolean("starsGiftsEnabled", true);
starsPaidReactionAmountMax = mainPreferences.getLong("starsPaidReactionAmountMax", 10_000L);
starsSubscriptionAmountMax = mainPreferences.getLong("starsSubscriptionAmountMax", 2500L);
starsUsdSellRate1000 = mainPreferences.getFloat("starsUsdSellRate1000", 2000);
starsUsdWithdrawRate1000 = mainPreferences.getFloat("starsUsdWithdrawRate1000", 1200);
scheduleTranscriptionUpdate(); scheduleTranscriptionUpdate();
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID); BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
if (mainPreferences.contains("dcDomainName2")) { if (mainPreferences.contains("dcDomainName2")) {
@ -1597,6 +1632,7 @@ public class MessagesController extends BaseController implements NotificationCe
exportUri.add("content://(\\d+@)?com\\.whatsapp\\.w4b\\.provider\\.media/export_chat/"); exportUri.add("content://(\\d+@)?com\\.whatsapp\\.w4b\\.provider\\.media/export_chat/");
exportUri.add("content://jp\\.naver\\.line\\.android\\.line\\.common\\.FileProvider/export-chat/"); exportUri.add("content://jp\\.naver\\.line\\.android\\.line\\.common\\.FileProvider/export-chat/");
exportUri.add(".*WhatsApp.*\\.txt$"); exportUri.add(".*WhatsApp.*\\.txt$");
exportUri.add(".*WhatsApp.*\\.zip$");
} }
exportGroupUri = mainPreferences.getStringSet("exportGroupUri", null); exportGroupUri = mainPreferences.getStringSet("exportGroupUri", null);
@ -4151,6 +4187,28 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "bot_preview_medias_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if ((int) num.value != botPreviewMediasMax) {
botPreviewMediasMax = (int) num.value;
editor.putInt("botPreviewMediasMax", botPreviewMediasMax);
changed = true;
}
}
break;
}
case "ton_proxy_address": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(str.value, tonProxyAddress)) {
tonProxyAddress = str.value;
editor.putString("tonProxyAddress", tonProxyAddress);
changed = true;
}
}
break;
}
case "web_app_allowed_protocols": { case "web_app_allowed_protocols": {
HashSet<String> newProtocols = new HashSet<>(); HashSet<String> newProtocols = new HashSet<>();
if (value.value instanceof TLRPC.TL_jsonArray) { if (value.value instanceof TLRPC.TL_jsonArray) {
@ -4170,6 +4228,102 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "weather_search_username": {
if (value.value instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString str = (TLRPC.TL_jsonString) value.value;
if (!TextUtils.equals(str.value, weatherSearchUsername)) {
weatherSearchUsername = str.value;
editor.putString("weatherSearchUsername", weatherSearchUsername);
changed = true;
}
}
break;
}
case "story_weather_preload": {
if (value.value instanceof TLRPC.TL_jsonBool) {
TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value;
if (bool.value != storyWeatherPreload) {
storyWeatherPreload = bool.value;
editor.putBoolean("storyWeatherPreload", storyWeatherPreload);
changed = true;
}
}
break;
}
case "stars_gifts_enabled": {
if (value.value instanceof TLRPC.TL_jsonBool) {
TLRPC.TL_jsonBool bool = (TLRPC.TL_jsonBool) value.value;
if (bool.value != starsGiftsEnabled) {
starsGiftsEnabled = bool.value;
editor.putBoolean("starsGiftsEnabled", starsGiftsEnabled);
changed = true;
}
}
break;
}
case "stars_paid_reaction_amount_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if ((long) num.value != starsPaidReactionAmountMax) {
starsPaidReactionAmountMax = (long) num.value;
editor.putLong("starsPaidReactionAmountMax", starsPaidReactionAmountMax);
changed = true;
}
}
break;
}
case "stars_subscription_amount_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if ((long) num.value != starsSubscriptionAmountMax) {
starsSubscriptionAmountMax = (long) num.value;
editor.putLong("starsSubscriptionAmountMax", starsSubscriptionAmountMax);
changed = true;
}
}
break;
}
case "stars_usd_sell_rate_x1000": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (Math.abs(num.value - starsUsdSellRate1000) > 0.001f) {
starsUsdSellRate1000 = (float) num.value;
editor.putFloat("starsUsdSellRate1000", starsUsdSellRate1000);
changed = true;
}
}
break;
}
case "stars_usd_withdraw_rate_x1000": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (Math.abs(num.value - starsUsdWithdrawRate1000) > 0.001f) {
starsUsdWithdrawRate1000 = (float) num.value;
editor.putFloat("starsUsdWithdrawRate1000", starsUsdWithdrawRate1000);
changed = true;
}
}
break;
}
case "ignore_restriction_reasons": {
HashSet<String> newReasons = new HashSet<>();
if (value.value instanceof TLRPC.TL_jsonArray) {
TLRPC.TL_jsonArray array = (TLRPC.TL_jsonArray) value.value;
for (int b = 0, N2 = array.value.size(); b < N2; b++) {
TLRPC.JSONValue val = array.value.get(b);
if (val instanceof TLRPC.TL_jsonString) {
TLRPC.TL_jsonString string = (TLRPC.TL_jsonString) val;
newReasons.add(string.value.toLowerCase());
}
}
}
if (!ignoreRestrictionReasons.equals(newReasons)) {
ignoreRestrictionReasons = newReasons;
editor.putStringSet("ignoreRestrictionReasons", ignoreRestrictionReasons);
changed = true;
}
break;
}
} }
} }
@ -5755,6 +5909,13 @@ public class MessagesController extends BaseController implements NotificationCe
return objectsByUsernames.get(username.toLowerCase()); return objectsByUsernames.get(username.toLowerCase());
} }
public TLRPC.User getUser(String username) {
TLObject obj = getUserOrChat(username);
if (obj instanceof TLRPC.User)
return (TLRPC.User) obj;
return null;
}
public ConcurrentHashMap<Long, TLRPC.User> getUsers() { public ConcurrentHashMap<Long, TLRPC.User> getUsers() {
return users; return users;
} }
@ -6523,7 +6684,7 @@ public class MessagesController extends BaseController implements NotificationCe
applyDialogNotificationsSettings(-chatId, 0, res.full_chat.notify_settings); applyDialogNotificationsSettings(-chatId, 0, res.full_chat.notify_settings);
for (int a = 0; a < res.full_chat.bot_info.size(); a++) { for (int a = 0; a < res.full_chat.bot_info.size(); a++) {
TLRPC.BotInfo botInfo = res.full_chat.bot_info.get(a); TL_bots.BotInfo botInfo = res.full_chat.bot_info.get(a);
getMediaDataController().putBotInfo(-chatId, botInfo); getMediaDataController().putBotInfo(-chatId, botInfo);
} }
int index = blockePeers.indexOfKey(-chatId); int index = blockePeers.indexOfKey(-chatId);
@ -6584,7 +6745,10 @@ public class MessagesController extends BaseController implements NotificationCe
} }
public void loadFullUser(final TLRPC.User user, int classGuid, boolean force) { public void loadFullUser(final TLRPC.User user, int classGuid, boolean force) {
if (user == null || loadingFullUsers.contains(user.id) || !force && loadedFullUsers.get(user.id) > 0) { loadFullUser(user, classGuid, force, null);
}
public void loadFullUser(final TLRPC.User user, int classGuid, boolean force, Utilities.Callback<TLRPC.UserFull> whenReceivedFullUser) {
if (user == null || whenReceivedFullUser == null && (loadingFullUsers.contains(user.id) || !force && loadedFullUsers.get(user.id) > 0)) {
return; return;
} }
loadingFullUsers.add(user.id); loadingFullUsers.add(user.id);
@ -6605,11 +6769,15 @@ public class MessagesController extends BaseController implements NotificationCe
getStoriesController().updateStoriesFromFullPeer(dialogId, userFull.stories); getStoriesController().updateStoriesFromFullPeer(dialogId, userFull.stories);
ChatThemeController.getInstance(currentAccount).saveChatWallpaper(res.full_user.id, res.full_user.wallpaper); ChatThemeController.getInstance(currentAccount).saveChatWallpaper(res.full_user.id, res.full_user.wallpaper);
if (whenReceivedFullUser != null) {
whenReceivedFullUser.run(userFull);
}
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
savePeerSettings(userFull.user.id, userFull.settings, false); savePeerSettings(userFull.user.id, userFull.settings, false);
applyDialogNotificationsSettings(user.id, 0, userFull.notify_settings); applyDialogNotificationsSettings(user.id, 0, userFull.notify_settings);
if (userFull.bot_info instanceof TLRPC.TL_botInfo) { if (userFull.bot_info instanceof TL_bots.TL_botInfo) {
userFull.bot_info.user_id = user.id; userFull.bot_info.user_id = user.id;
getMediaDataController().putBotInfo(user.id, userFull.bot_info); getMediaDataController().putBotInfo(user.id, userFull.bot_info);
} }
@ -6640,7 +6808,7 @@ public class MessagesController extends BaseController implements NotificationCe
if (userFull.user.photo != null && userFull.user.photo.has_video) { if (userFull.user.photo != null && userFull.user.photo.has_video) {
getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_AVATAR); getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_AVATAR);
} }
if (userFull.bot_info instanceof TLRPC.TL_botInfo) { if (userFull.bot_info instanceof TL_bots.TL_botInfo) {
userFull.bot_info.user_id = userFull.id; userFull.bot_info.user_id = userFull.id;
getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, userFull.bot_info, classGuid); getNotificationCenter().postNotificationName(NotificationCenter.botInfoDidLoad, userFull.bot_info, classGuid);
} }
@ -9965,12 +10133,12 @@ public class MessagesController extends BaseController implements NotificationCe
loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, fromCache, midDate, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, true, isTopic, null, 0L); loadMessagesInternal(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, fromCache, midDate, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, true, isTopic, null, 0L);
} }
private void loadMessagesInternal(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, boolean fromCache, int minDate, int classGuid, int load_type, int last_message_id, int mode, long threadMessageId, int loadIndex, int first_unread, int unread_count, int last_date, boolean queryFromServer, int mentionsCount, boolean loadDialog, boolean processMessages, boolean isTopic, MessageLoaderLogger loaderLogger, long hash) { private void loadMessagesInternal(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, boolean fromCache, int minDate, int classGuid, int load_type, int last_message_id, int mode, long threadMessageId, int loadIndex, int first_unread, int unread_count, int last_date, boolean queryFromServer, int mentionsCount, boolean loadDialog, boolean processMessages, boolean isTopic, Timer loaderLogger, long hash) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("load messages in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + fromCache + " mindate = " + minDate + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " mode " + mode + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic " + isTopic); FileLog.d("load messages in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + fromCache + " mindate = " + minDate + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " mode " + mode + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic " + isTopic);
} }
if (BuildVars.LOGS_ENABLED && loaderLogger == null && mode == 0) { if (BuildVars.LOGS_ENABLED && loaderLogger == null && mode == 0) {
loaderLogger = new MessageLoaderLogger(dialogId, loadIndex, count); loaderLogger = new Timer("MessageLoaderLogger dialogId=" + dialogId + " index=" + loadIndex + " count=" + count);
} }
if ((threadMessageId == 0 || isTopic || mode == ChatActivity.MODE_SAVED || mode == ChatActivity.MODE_QUICK_REPLIES) && mode != ChatActivity.MODE_PINNED && (fromCache || DialogObject.isEncryptedDialog(dialogId))) { if ((threadMessageId == 0 || isTopic || mode == ChatActivity.MODE_SAVED || mode == ChatActivity.MODE_QUICK_REPLIES) && mode != ChatActivity.MODE_PINNED && (fromCache || DialogObject.isEncryptedDialog(dialogId))) {
getMessagesStorage().getMessages(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, minDate, classGuid, load_type, mode, threadMessageId, loadIndex, processMessages, isTopic, loaderLogger); getMessagesStorage().getMessages(dialogId, mergeDialogId, loadInfo, count, max_id, offset_date, minDate, classGuid, load_type, mode, threadMessageId, loadIndex, processMessages, isTopic, loaderLogger);
@ -10281,10 +10449,11 @@ public class MessagesController extends BaseController implements NotificationCe
} }
public void processLoadedMessages(TLRPC.messages_Messages messagesRes, int resCount, long dialogId, long mergeDialogId, int count, int max_id, int offset_date, boolean isCache, int classGuid, public void processLoadedMessages(TLRPC.messages_Messages messagesRes, int resCount, long dialogId, long mergeDialogId, int count, int max_id, int offset_date, boolean isCache, int classGuid,
int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isEnd, int mode, long threadMessageId, int loadIndex, boolean queryFromServer, int mentionsCount, boolean needProcess, boolean isTopic, MessageLoaderLogger loaderLogger) { int first_unread, int last_message_id, int unread_count, int last_date, int load_type, boolean isEnd, int mode, long threadMessageId, int loadIndex, boolean queryFromServer, int mentionsCount, boolean needProcess, boolean isTopic, Timer loaderLogger) {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic " + isTopic); FileLog.d("processLoadedMessages size " + messagesRes.messages.size() + " in chat " + dialogId + " topic_id " + threadMessageId + " count " + count + " max_id " + max_id + " cache " + isCache + " guid " + classGuid + " load_type " + load_type + " last_message_id " + last_message_id + " index " + loadIndex + " firstUnread " + first_unread + " unread_count " + unread_count + " last_date " + last_date + " queryFromServer " + queryFromServer + " isTopic " + isTopic + " mode " + mode);
} }
Timer.Task t1 = Timer.start(loaderLogger, "processLoadedMessages");
long startProcessTime = SystemClock.elapsedRealtime(); long startProcessTime = SystemClock.elapsedRealtime();
boolean createDialog = false; boolean createDialog = false;
@ -10385,9 +10554,6 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
if (loaderLogger != null) {
loaderLogger.reload();
}
final long finalHash = hash; final long finalHash = hash;
AndroidUtilities.runOnUIThread(() -> loadMessagesInternal(dialogId, mergeDialogId, false, count, load_type == LOAD_FROM_UNREAD && queryFromServer ? first_unread : max_id, offset_date, false, 0, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, needProcess, isTopic, loaderLogger, finalHash)); AndroidUtilities.runOnUIThread(() -> loadMessagesInternal(dialogId, mergeDialogId, false, count, load_type == LOAD_FROM_UNREAD && queryFromServer ? first_unread : max_id, offset_date, false, 0, classGuid, load_type, last_message_id, mode, threadMessageId, loadIndex, first_unread, unread_count, last_date, queryFromServer, mentionsCount, true, needProcess, isTopic, loaderLogger, finalHash));
if (messagesRes.messages.isEmpty()) { if (messagesRes.messages.isEmpty()) {
@ -10485,9 +10651,6 @@ public class MessagesController extends BaseController implements NotificationCe
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("process time=" + (SystemClock.elapsedRealtime() - startProcessTime) + " count=" + objects.size() + " for dialog " + dialogId); FileLog.d("process time=" + (SystemClock.elapsedRealtime() - startProcessTime) + " count=" + objects.size() + " for dialog " + dialogId);
} }
if (loaderLogger != null) {
loaderLogger.logStageQueueProcessing();
}
if (mode == ChatActivity.MODE_SCHEDULED) { if (mode == ChatActivity.MODE_SCHEDULED) {
Collections.sort(objects, (o1, o2) -> { Collections.sort(objects, (o1, o2) -> {
if (o1.messageOwner.date == o2.messageOwner.date && o1.getId() >= 0 && o2.getId() >= 0) { if (o1.messageOwner.date == o2.messageOwner.date && o1.getId() >= 0 && o2.getId() >= 0) {
@ -10519,13 +10682,15 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
Timer.done(t1);
Timer.Task t2 = Timer.start(loaderLogger, "processLoadedMessages: runOnUIThread");
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
Timer.done(t2);
Timer.Task t3 = Timer.start(loaderLogger, "processLoadedMessages: post runOnUIThread");
putUsers(messagesRes.users, isCache); putUsers(messagesRes.users, isCache);
putChats(messagesRes.chats, isCache); putChats(messagesRes.chats, isCache);
if (loaderLogger != null) {
loaderLogger.finish();
}
if (messagesRes.animatedEmoji != null && needProcess) { if (messagesRes.animatedEmoji != null && needProcess) {
AnimatedEmojiDrawable.getDocumentFetcher(currentAccount).processDocuments(messagesRes.animatedEmoji); AnimatedEmojiDrawable.getDocumentFetcher(currentAccount).processDocuments(messagesRes.animatedEmoji);
} }
@ -10552,13 +10717,15 @@ public class MessagesController extends BaseController implements NotificationCe
if (!DialogObject.isEncryptedDialog(dialogId) && mode != ChatActivity.MODE_QUICK_REPLIES) { if (!DialogObject.isEncryptedDialog(dialogId) && mode != ChatActivity.MODE_QUICK_REPLIES) {
int finalFirst_unread_final = first_unread_final; int finalFirst_unread_final = first_unread_final;
Timer.Task t5 = Timer.start(loaderLogger, "loadReplyMessagesForMessages");
getMediaDataController().loadReplyMessagesForMessages(objects, dialogId, mode, threadMessageId, () -> { getMediaDataController().loadReplyMessagesForMessages(objects, dialogId, mode, threadMessageId, () -> {
Timer.done(t5);
if (!needProcess) { if (!needProcess) {
getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoadWithoutProcess, classGuid, resCount, isCache, isEnd, last_message_id); getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoadWithoutProcess, classGuid, resCount, isCache, isEnd, last_message_id);
} else { } else {
getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, finalFirst_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode); getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, finalFirst_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode);
} }
}, classGuid); }, classGuid, loaderLogger);
} else { } else {
getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, first_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode); getNotificationCenter().postNotificationName(NotificationCenter.messagesDidLoad, dialogId, count, objects, isCache, first_unread_final, last_message_id, unread_count, last_date, load_type, isEnd, classGuid, loadIndex, max_id, mentionsCount, mode);
} }
@ -10569,6 +10736,11 @@ public class MessagesController extends BaseController implements NotificationCe
if (!webpagesToReload.isEmpty()) { if (!webpagesToReload.isEmpty()) {
reloadWebPages(dialogId, webpagesToReload, mode); reloadWebPages(dialogId, webpagesToReload, mode);
} }
Timer.done(t3);
if (loaderLogger != null) {
loaderLogger.finish();
}
}); });
} }
@ -13453,16 +13625,26 @@ public class MessagesController extends BaseController implements NotificationCe
}, ConnectionsManager.RequestFlagInvokeAfter); }, ConnectionsManager.RequestFlagInvokeAfter);
} }
public void toggleChannelSignatures(long chatId, boolean enabled) { public void toggleChannelSignatures(long chatId, boolean signaturesEnabled, boolean profilesEnabled) {
TLRPC.Chat chat = getChat(chatId);
if (chat != null) {
chat.signatures = signaturesEnabled;
chat.signature_profiles = profilesEnabled;
putChat(chat, true);
}
TLRPC.TL_channels_toggleSignatures req = new TLRPC.TL_channels_toggleSignatures(); TLRPC.TL_channels_toggleSignatures req = new TLRPC.TL_channels_toggleSignatures();
req.channel = getInputChannel(chatId); req.channel = getInputChannel(chatId);
req.enabled = enabled; req.signatures_enabled = signaturesEnabled;
req.profiles_enabled = profilesEnabled;
getConnectionsManager().sendRequest(req, (response, error) -> { getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) { if (response != null) {
processUpdates((TLRPC.Updates) response, false); processUpdates((TLRPC.Updates) response, false);
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT)); AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, UPDATE_MASK_CHAT));
} }
}, ConnectionsManager.RequestFlagInvokeAfter); }, ConnectionsManager.RequestFlagInvokeAfter);
getNotificationCenter().postNotificationName(NotificationCenter.updateAllMessages, -chatId);
} }
public void toggleChannelForum(long chatId, boolean enabled) { public void toggleChannelForum(long chatId, boolean enabled) {
@ -15046,7 +15228,7 @@ public class MessagesController extends BaseController implements NotificationCe
updateInterfaceWithMessages(dialogId, arr, 0); updateInterfaceWithMessages(dialogId, arr, 0);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload); getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}); });
}, 0); }, 0, null);
} }
}); });
@ -17297,8 +17479,21 @@ public class MessagesController extends BaseController implements NotificationCe
message.out = true; message.out = true;
} }
} }
if (!message.out && message.from_id instanceof TLRPC.TL_peerUser && message.from_id.user_id == clientUserId) { if (!message.out) {
message.out = true; long from_id = DialogObject.getPeerDialogId(message.from_id);
if (from_id == clientUserId) {
message.out = true;
} else {
TLRPC.TL_channels_sendAsPeers peers = getSendAsPeers(MessageObject.getDialogId(message));
if (peers != null) {
for (TLRPC.TL_sendAsPeer peer : peers.peers) {
if (peer != null && from_id == DialogObject.getPeerDialogId(peer.peer)) {
message.out = true;
break;
}
}
}
}
} }
if (!fromGetDifference) { if (!fromGetDifference) {
for (int a = 0, count = message.entities.size(); a < count; a++) { for (int a = 0, count = message.entities.size(); a < count; a++) {
@ -18275,6 +18470,11 @@ public class MessagesController extends BaseController implements NotificationCe
} else if (baseUpdate instanceof TLRPC.TL_updateMessageReactions) { } else if (baseUpdate instanceof TLRPC.TL_updateMessageReactions) {
TLRPC.TL_updateMessageReactions update = (TLRPC.TL_updateMessageReactions) baseUpdate; TLRPC.TL_updateMessageReactions update = (TLRPC.TL_updateMessageReactions) baseUpdate;
long dialogId = MessageObject.getPeerId(update.peer); long dialogId = MessageObject.getPeerId(update.peer);
long pendingPaid = StarsController.getInstance(currentAccount).getPendingPaidReactions(dialogId, update.msg_id);
if (pendingPaid != 0) {
final StarsController starsController = StarsController.getInstance(currentAccount);
MessageObject.addPaidReactions(currentAccount, update.reactions, (int) pendingPaid, starsController.arePaidReactionsAnonymous(StarsController.MessageId.from(dialogId, update.msg_id), update.reactions), true);
}
getNotificationCenter().postNotificationName(NotificationCenter.didUpdateReactions, dialogId, update.msg_id, update.reactions); getNotificationCenter().postNotificationName(NotificationCenter.didUpdateReactions, dialogId, update.msg_id, update.reactions);
} else if (baseUpdate instanceof TLRPC.TL_updateMessageExtendedMedia) { } else if (baseUpdate instanceof TLRPC.TL_updateMessageExtendedMedia) {
TLRPC.TL_updateMessageExtendedMedia extendedMedia = (TLRPC.TL_updateMessageExtendedMedia) baseUpdate; TLRPC.TL_updateMessageExtendedMedia extendedMedia = (TLRPC.TL_updateMessageExtendedMedia) baseUpdate;
@ -18296,8 +18496,8 @@ public class MessagesController extends BaseController implements NotificationCe
getNotificationCenter().postNotificationName(NotificationCenter.webViewResultSent, resultSent.query_id); getNotificationCenter().postNotificationName(NotificationCenter.webViewResultSent, resultSent.query_id);
} else if (baseUpdate instanceof TLRPC.TL_updateAttachMenuBots) { } else if (baseUpdate instanceof TLRPC.TL_updateAttachMenuBots) {
getMediaDataController().loadAttachMenuBots(false, true); getMediaDataController().loadAttachMenuBots(false, true);
} else if (baseUpdate instanceof TLRPC.TL_updateBotMenuButton) { } else if (baseUpdate instanceof TL_bots.TL_updateBotMenuButton) {
TLRPC.TL_updateBotMenuButton updateBotMenuButton = (TLRPC.TL_updateBotMenuButton) baseUpdate; TL_bots.TL_updateBotMenuButton updateBotMenuButton = (TL_bots.TL_updateBotMenuButton) baseUpdate;
getNotificationCenter().postNotificationName(NotificationCenter.updateBotMenuButton, updateBotMenuButton.bot_id, updateBotMenuButton.button); getNotificationCenter().postNotificationName(NotificationCenter.updateBotMenuButton, updateBotMenuButton.bot_id, updateBotMenuButton.button);
} else if (baseUpdate instanceof TLRPC.TL_updateReadChannelDiscussionInbox) { } else if (baseUpdate instanceof TLRPC.TL_updateReadChannelDiscussionInbox) {
TLRPC.TL_updateReadChannelDiscussionInbox update = (TLRPC.TL_updateReadChannelDiscussionInbox) baseUpdate; TLRPC.TL_updateReadChannelDiscussionInbox update = (TLRPC.TL_updateReadChannelDiscussionInbox) baseUpdate;
@ -18563,7 +18763,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
getMediaDataController().loadReplyMessagesForMessages(arrayList, dialogId, 0, 0,null, 0); getMediaDataController().loadReplyMessagesForMessages(arrayList, dialogId, 0, 0,null, 0, null);
getNotificationCenter().postNotificationName(NotificationCenter.replaceMessagesObjects, dialogId, arrayList, false); getNotificationCenter().postNotificationName(NotificationCenter.replaceMessagesObjects, dialogId, arrayList, false);
} }
} }
@ -19082,7 +19282,6 @@ public class MessagesController extends BaseController implements NotificationCe
for (int a = 0, N = res.messages.size(); a < N; a++) { for (int a = 0, N = res.messages.size(); a < N; a++) {
TLRPC.TL_sponsoredMessage sponsoredMessage = res.messages.get(a); TLRPC.TL_sponsoredMessage sponsoredMessage = res.messages.get(a);
TLRPC.TL_message message = new TLRPC.TL_message(); TLRPC.TL_message message = new TLRPC.TL_message();
message.message = sponsoredMessage.message;
if (!sponsoredMessage.entities.isEmpty()) { if (!sponsoredMessage.entities.isEmpty()) {
message.entities = sponsoredMessage.entities; message.entities = sponsoredMessage.entities;
message.flags |= 128; message.flags |= 128;
@ -19091,6 +19290,11 @@ public class MessagesController extends BaseController implements NotificationCe
message.flags |= 256; message.flags |= 256;
message.date = getConnectionsManager().getCurrentTime(); message.date = getConnectionsManager().getCurrentTime();
message.id = messageId--; message.id = messageId--;
message.message = sponsoredMessage.message;
if (sponsoredMessage.media != null) {
message.flags |= 512;
}
message.media = sponsoredMessage.media;
MessageObject messageObject = new MessageObject(currentAccount, message, usersDict, chatsDict, true, true); MessageObject messageObject = new MessageObject(currentAccount, message, usersDict, chatsDict, true, true);
messageObject.sponsoredId = sponsoredMessage.random_id; messageObject.sponsoredId = sponsoredMessage.random_id;
messageObject.sponsoredTitle = sponsoredMessage.title; messageObject.sponsoredTitle = sponsoredMessage.title;
@ -19102,6 +19306,10 @@ public class MessagesController extends BaseController implements NotificationCe
messageObject.sponsoredButtonText = sponsoredMessage.button_text; messageObject.sponsoredButtonText = sponsoredMessage.button_text;
messageObject.sponsoredCanReport = sponsoredMessage.can_report; messageObject.sponsoredCanReport = sponsoredMessage.can_report;
messageObject.sponsoredColor = sponsoredMessage.color; messageObject.sponsoredColor = sponsoredMessage.color;
messageObject.sponsoredMedia = sponsoredMessage.media;
messageObject.setType();
messageObject.textLayoutBlocks = new ArrayList<>();
messageObject.generateThumbs(true);
result.add(messageObject); result.add(messageObject);
} }
} }
@ -19154,17 +19362,6 @@ public class MessagesController extends BaseController implements NotificationCe
putUsers(res.users, false); putUsers(res.users, false);
putChats(res.chats, false); putChats(res.chats, false);
}); });
final LongSparseArray<TLRPC.User> usersDict = new LongSparseArray<>();
final LongSparseArray<TLRPC.Chat> chatsDict = new LongSparseArray<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User u = res.users.get(a);
usersDict.put(u.id, u);
}
for (int a = 0; a < res.chats.size(); a++) {
TLRPC.Chat c = res.chats.get(a);
chatsDict.put(c.id, c);
}
} }
} else { } else {
result = null; result = null;
@ -19317,7 +19514,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
} }
getMediaDataController().loadReplyMessagesForMessages(messages, dialogId, mode, 0, null, 0); getMediaDataController().loadReplyMessagesForMessages(messages, dialogId, mode, 0, null, 0, null);
if (mode == ChatActivity.MODE_QUICK_REPLIES) { if (mode == ChatActivity.MODE_QUICK_REPLIES) {
QuickRepliesController.getInstance(currentAccount).checkLocalMessages(messages); QuickRepliesController.getInstance(currentAccount).checkLocalMessages(messages);
} }
@ -19790,12 +19987,14 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
public static String getRestrictionReason(ArrayList<TLRPC.TL_restrictionReason> reasons) { public String getRestrictionReason(ArrayList<TLRPC.RestrictionReason> reasons) {
if (reasons.isEmpty()) { if (reasons.isEmpty()) {
return null; return null;
} }
for (int a = 0, N = reasons.size(); a < N; a++) { for (int a = 0, N = reasons.size(); a < N; a++) {
TLRPC.TL_restrictionReason reason = reasons.get(a); TLRPC.RestrictionReason reason = reasons.get(a);
if (ignoreRestrictionReasons != null && ignoreRestrictionReasons.contains(reason.reason)) continue;
if ("sensitive".equals(reason.reason)) continue;
if ("all".equals(reason.platform) || !ApplicationLoader.isStandaloneBuild() && !BuildVars.isBetaApp() && "android".equals(reason.platform)) { if ("all".equals(reason.platform) || !ApplicationLoader.isStandaloneBuild() && !BuildVars.isBetaApp() && "android".equals(reason.platform)) {
return reason.text; return reason.text;
} }
@ -19803,6 +20002,83 @@ public class MessagesController extends BaseController implements NotificationCe
return null; return null;
} }
public boolean isSensitive(ArrayList<TLRPC.RestrictionReason> reasons) {
if (reasons == null || reasons.isEmpty()) {
return false;
}
for (int a = 0, N = reasons.size(); a < N; a++) {
TLRPC.RestrictionReason reason = reasons.get(a);
if (ignoreRestrictionReasons != null && ignoreRestrictionReasons.contains(reason.reason)) continue;
if ("all".equals(reason.platform) || !ApplicationLoader.isStandaloneBuild() && !BuildVars.isBetaApp() && "android".equals(reason.platform)) {
if ("sensitive".equals(reason.reason)) return true;
}
}
return false;
}
public void checkSensitive(BaseFragment fragment, long did, Runnable done, Runnable canceled) {
ArrayList<TLRPC.RestrictionReason> reasons = null;
if (did < 0) {
TLRPC.Chat chat = getChat(-did);
reasons = chat != null ? chat.restriction_reason : null;
} else if (did >= 0) {
TLRPC.User user = getUser(did);
reasons = user != null ? user.restriction_reason : null;
}
if (!isSensitive(reasons) || sensitiveAgreed.contains(did)) {
if (done != null) {
done.run();
}
return;
}
final AlertDialog progressDialog = new AlertDialog(fragment.getContext(), AlertDialog.ALERT_TYPE_SPINNER);
progressDialog.showDelayed(200);
getContentSettings(settings -> {
progressDialog.dismissUnless(200);
boolean[] always = new boolean[1];
FrameLayout frameLayout = new FrameLayout(fragment.getContext());
if (settings != null && settings.sensitive_can_change) {
CheckBoxCell checkbox = new CheckBoxCell(fragment.getContext(), 1, fragment.getResourceProvider());
checkbox.setBackground(Theme.getSelectorDrawable(false));
checkbox.setText(getString(R.string.MessageShowSensitiveContentAlways), "", always[0], false);
checkbox.setPadding(LocaleController.isRTL ? dp(16) : dp(8), 0, LocaleController.isRTL ? dp(8) : dp(16), 0);
frameLayout.addView(checkbox, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 0));
checkbox.setOnClickListener(v -> {
CheckBoxCell cell1 = (CheckBoxCell) v;
always[0] = !always[0];
cell1.setChecked(always[0], true);
});
}
final boolean[] doneSet = new boolean[1];
new AlertDialog.Builder(fragment.getContext(), fragment.getResourceProvider())
.setTitle(getString(R.string.MessageShowSensitiveContentChannelTitle))
.setMessage(getString(R.string.MessageShowSensitiveContentChannelText))
.setView(frameLayout).setCustomViewOffset(9)
.setNegativeButton(getString(R.string.Cancel), null)
.setPositiveButton(getString(R.string.MessageShowSensitiveContentButton), (di, w) -> {
doneSet[0] = true;
sensitiveAgreed.add(did);
if (always[0] && settings != null && settings.sensitive_can_change) {
getMessagesController().setContentSettings(true);
BulletinFactory.of(fragment)
.createSimpleBulletinDetail(R.raw.chats_infotip, AndroidUtilities.replaceArrows(AndroidUtilities.premiumText(getString(R.string.SensitiveContentSettingsToast), () -> {
fragment.presentFragment(new ThemeActivity(ThemeActivity.THEME_TYPE_BASIC).highlightSensitiveRow());
}), true))
.show(true);
}
if (done != null) {
done.run();
}
})
.setOnDismissListener(di -> {
if (!doneSet[0] && canceled != null) {
canceled.run();
}
})
.show();
});
}
public static void showCantOpenAlert(BaseFragment fragment, String reason) { public static void showCantOpenAlert(BaseFragment fragment, String reason) {
if (fragment == null || fragment.getParentActivity() == null) { if (fragment == null || fragment.getParentActivity() == null) {
return; return;
@ -19827,6 +20103,8 @@ public class MessagesController extends BaseController implements NotificationCe
return checkCanOpenChat(bundle, fragment, originalMessage, null); return checkCanOpenChat(bundle, fragment, originalMessage, null);
} }
private final HashSet<Long> sensitiveAgreed = new HashSet<>();
public boolean checkCanOpenChat(Bundle bundle, BaseFragment fragment, MessageObject originalMessage, Browser.Progress progress) { public boolean checkCanOpenChat(Bundle bundle, BaseFragment fragment, MessageObject originalMessage, Browser.Progress progress) {
if (bundle == null || fragment == null) { if (bundle == null || fragment == null) {
return true; return true;
@ -19836,9 +20114,12 @@ public class MessagesController extends BaseController implements NotificationCe
long userId = bundle.getLong("user_id", 0); long userId = bundle.getLong("user_id", 0);
long chatId = bundle.getLong("chat_id", 0); long chatId = bundle.getLong("chat_id", 0);
int messageId = bundle.getInt("message_id", 0); int messageId = bundle.getInt("message_id", 0);
long dialogId = 0;
if (userId != 0) { if (userId != 0) {
dialogId = userId;
user = getUser(userId); user = getUser(userId);
} else if (chatId != 0) { } else if (chatId != 0) {
dialogId = -chatId;
chat = getChat(chatId); chat = getChat(chatId);
} }
if (user == null && chat == null) { if (user == null && chat == null) {
@ -19936,7 +20217,7 @@ public class MessagesController extends BaseController implements NotificationCe
return true; return true;
} }
public static void openChatOrProfileWith(TLRPC.User user, TLRPC.Chat chat, BaseFragment fragment, int type, boolean closeLast) { public void openChatOrProfileWith(TLRPC.User user, TLRPC.Chat chat, BaseFragment fragment, int type, boolean closeLast) {
if (user == null && chat == null || fragment == null) { if (user == null && chat == null || fragment == null) {
return; return;
} }
@ -20201,7 +20482,7 @@ public class MessagesController extends BaseController implements NotificationCe
}); });
} }
public void setCustomChatReactions(long chatId, int type, List<TLRPC.Reaction> reactions, int reactionsCount, Utilities.Callback<TLRPC.TL_error> onError, Runnable onSuccess) { public void setCustomChatReactions(long chatId, int type, List<TLRPC.Reaction> reactions, int reactionsCount, Boolean allow_paid, Utilities.Callback<TLRPC.TL_error> onError, Runnable onSuccess) {
TLRPC.TL_messages_setChatAvailableReactions req = new TLRPC.TL_messages_setChatAvailableReactions(); TLRPC.TL_messages_setChatAvailableReactions req = new TLRPC.TL_messages_setChatAvailableReactions();
req.peer = getInputPeer(-chatId); req.peer = getInputPeer(-chatId);
if (type == ChatReactionsEditActivity.SELECT_TYPE_NONE || reactions.isEmpty()) { if (type == ChatReactionsEditActivity.SELECT_TYPE_NONE || reactions.isEmpty()) {
@ -20213,6 +20494,10 @@ public class MessagesController extends BaseController implements NotificationCe
req.available_reactions = someReactions; req.available_reactions = someReactions;
someReactions.reactions.addAll(reactions); someReactions.reactions.addAll(reactions);
} }
if (allow_paid != null) {
req.flags |= 2;
req.paid_enabled = allow_paid;
}
req.flags |= 1; req.flags |= 1;
req.reactions_limit = reactionsCount; req.reactions_limit = reactionsCount;
getConnectionsManager().sendRequest(req, (response, error) -> { getConnectionsManager().sendRequest(req, (response, error) -> {
@ -20252,6 +20537,9 @@ public class MessagesController extends BaseController implements NotificationCe
chatFull.flags |= 1048576; chatFull.flags |= 1048576;
} }
chatFull.reactions_limit = reactionsCount; chatFull.reactions_limit = reactionsCount;
if (allow_paid != null) {
chatFull.paid_reactions_available = allow_paid;
}
getMessagesStorage().updateChatInfo(chatFull, false); getMessagesStorage().updateChatInfo(chatFull, false);
} }
} }
@ -21485,4 +21773,219 @@ public class MessagesController extends BaseController implements NotificationCe
return true; return true;
} }
}; };
public static boolean equals(TLRPC.MessageMedia a, TLRPC.MessageMedia b) {
if (a instanceof TLRPC.TL_messageMediaDocument) {
if (!(b instanceof TLRPC.TL_messageMediaDocument)) return false;
return a.document.id == b.document.id;
} else if (b instanceof TLRPC.TL_messageMediaPhoto) {
if (!(b instanceof TLRPC.TL_messageMediaPhoto)) return false;
return a.photo.id == b.photo.id;
}
return false;
}
public static TLRPC.InputDocument toInputDocument(TLRPC.Document document) {
TLRPC.TL_inputDocument id = new TLRPC.TL_inputDocument();
id.id = document.id;
id.access_hash = document.access_hash;
id.file_reference = document.file_reference;
return id;
}
public static TLRPC.InputMedia toInputMedia(TLRPC.MessageMedia media) {
if (media instanceof TLRPC.TL_messageMediaDocument) {
TLRPC.TL_inputMediaDocument input = new TLRPC.TL_inputMediaDocument();
input.id = new TLRPC.TL_inputDocument();
input.id.id = media.document.id;
input.id.access_hash = media.document.access_hash;
input.id.file_reference = media.document.file_reference;
return input;
} else if (media instanceof TLRPC.TL_messageMediaPhoto) {
TLRPC.TL_inputMediaPhoto input = new TLRPC.TL_inputMediaPhoto();
input.id = new TLRPC.TL_inputPhoto();
input.id.id = media.photo.id;
input.id.access_hash = media.photo.access_hash;
input.id.file_reference = media.photo.file_reference;
return input;
}
return null;
}
public void openApp(TLRPC.User bot, int classGuid) {
openApp(null, bot, classGuid, null);
}
public void openApp(BaseFragment _fragment, TLRPC.User bot, int classGuid, Browser.Progress progress) {
if (bot == null) return;
boolean[] cancelled = new boolean[] { false };
if (progress != null) {
progress.onCancel(() -> cancelled[0] = true);
progress.init();
}
final TL_bots.BotInfo[] botInfo = new TL_bots.BotInfo[1];
Runnable open = () -> {
BaseFragment fragment = _fragment != null ? _fragment : LaunchActivity.getSafeLastFragment();
if (fragment == null) return;
if (progress != null) {
progress.end();
}
if (cancelled[0]) return;
if (bot.bot_has_main_app) {
if (fragment.getParentLayout() instanceof ActionBarLayout) {
fragment = ((ActionBarLayout) fragment.getParentLayout()).getSheetFragment();
}
AndroidUtilities.hideKeyboard(fragment.getFragmentView());
WebViewRequestProps props = WebViewRequestProps.of(currentAccount, bot.id, bot.id, null, null, BotWebViewAttachedSheet.TYPE_WEB_VIEW_BOT_MAIN, 0, false, null, false, null, bot, 0, false);
if (LaunchActivity.instance != null && LaunchActivity.instance.getBottomSheetTabs() != null && LaunchActivity.instance.getBottomSheetTabs().tryReopenTab(props) != null) {
return;
}
if (AndroidUtilities.isTablet()) {
BotWebViewSheet webViewSheet = new BotWebViewSheet(fragment.getContext(), fragment.getResourceProvider());
webViewSheet.setDefaultFullsize(true);
webViewSheet.setNeedsContext(true);
webViewSheet.setParentActivity(fragment.getParentActivity());
webViewSheet.requestWebView(null, props);
webViewSheet.show();
} else {
BotWebViewAttachedSheet sheet = fragment.createBotViewer();
sheet.setDefaultFullsize(true);
sheet.setNeedsContext(false);
sheet.setParentActivity(fragment.getParentActivity());
sheet.requestWebView(null, props);
sheet.show();
}
} else if (botInfo[0] != null && botInfo[0].menu_button instanceof TL_bots.TL_botMenuButton) {
if (fragment.getParentLayout() instanceof ActionBarLayout) {
fragment = ((ActionBarLayout) fragment.getParentLayout()).getSheetFragment();
}
TL_bots.TL_botMenuButton btn = (TL_bots.TL_botMenuButton) botInfo[0].menu_button;
AndroidUtilities.hideKeyboard(fragment.getFragmentView());
WebViewRequestProps props = WebViewRequestProps.of(currentAccount, bot.id, bot.id, btn.text, btn.url, BotWebViewAttachedSheet.TYPE_BOT_MENU_BUTTON, 0, false, null, false, null, bot, 0, false);
if (LaunchActivity.instance != null && LaunchActivity.instance.getBottomSheetTabs() != null && LaunchActivity.instance.getBottomSheetTabs().tryReopenTab(props) != null) {
return;
}
if (AndroidUtilities.isTablet()) {
BotWebViewSheet webViewSheet = new BotWebViewSheet(fragment.getContext(), fragment.getResourceProvider());
webViewSheet.setDefaultFullsize(false);
webViewSheet.setNeedsContext(true);
webViewSheet.setParentActivity(fragment.getParentActivity());
webViewSheet.requestWebView(null, props);
webViewSheet.show();
} else {
BotWebViewAttachedSheet sheet = fragment.createBotViewer();
sheet.setDefaultFullsize(false);
sheet.setNeedsContext(false);
sheet.setParentActivity(fragment.getParentActivity());
sheet.requestWebView(null, props);
sheet.show();
}
} else {
fragment.presentFragment(ChatActivity.of(bot.id));
}
};
botInfo[0] = getMediaDataController().getBotInfoCached(bot.id, bot.id);
if (bot.bot_has_main_app) {
open.run();
} else if (botInfo[0] == null) {
getMediaDataController().loadBotInfo(bot.id, bot.id, false, classGuid, _botInfo -> {
if (cancelled[0]) return;
botInfo[0] = _botInfo;
if (botInfo[0] == null) {
TLRPC.UserFull userFull = getUserFull(bot.id);
if (userFull == null) {
if (cancelled[0]) return;
loadFullUser(bot, classGuid, true, userFull1 -> {
if (cancelled[0]) return;
if (userFull1 != null) {
botInfo[0] = userFull1.bot_info;
}
AndroidUtilities.runOnUIThread(open);
});
} else {
botInfo[0] = userFull.bot_info;
open.run();
}
} else {
open.run();
}
});
} else {
open.run();
}
}
private boolean contentSettingsLoading;
private ArrayList<Utilities.Callback<TL_account.contentSettings>> contentSettingsCallbacks;
private long contentSettingsLoadedTime;
private TL_account.contentSettings contentSettings;
public TL_account.contentSettings getContentSettings() {
return contentSettings;
}
public void getContentSettings(Utilities.Callback<TL_account.contentSettings> whenReceived) {
if (contentSettings != null && System.currentTimeMillis() - contentSettingsLoadedTime < 1000 * 60 * 60) {
if (whenReceived != null) whenReceived.run(contentSettings);
return;
}
if (contentSettingsCallbacks == null) contentSettingsCallbacks = new ArrayList<>();
if (whenReceived != null) contentSettingsCallbacks.add(whenReceived);
if (contentSettingsLoading) return;
contentSettingsLoading = true;
TL_account.getContentSettings req = new TL_account.getContentSettings();
getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TL_account.contentSettings) {
contentSettings = (TL_account.contentSettings) res;
contentSettingsLoadedTime = System.currentTimeMillis();
}
contentSettingsLoading = false;
if (contentSettingsCallbacks != null) {
for (Utilities.Callback<TL_account.contentSettings> callback : contentSettingsCallbacks) {
callback.run(contentSettings);
}
contentSettingsCallbacks.clear();
contentSettingsCallbacks = null;
}
}));
}
public void invalidateContentSettings() {
contentSettings = null;
contentSettingsLoadedTime = 0;
}
public void setContentSettings(boolean showSensitiveContent) {
if (contentSettings != null) {
if (!contentSettings.sensitive_can_change) {
return;
}
contentSettings.sensitive_enabled = showSensitiveContent;
}
if (ignoreRestrictionReasons == null) ignoreRestrictionReasons = new HashSet<>();
if (showSensitiveContent) ignoreRestrictionReasons.add("sensitive");
else ignoreRestrictionReasons.remove("sensitive");
TL_account.setContentSettings req = new TL_account.setContentSettings();
req.sensitive_enabled = showSensitiveContent;
getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (err != null) {
BulletinFactory.showError(err);
}
}));
}
public boolean showSensitiveContent() {
if (contentSettings != null && System.currentTimeMillis() - contentSettingsLoadedTime < 1000 * 60 * 60) {
return contentSettings.sensitive_enabled;
}
return ignoreRestrictionReasons == null || ignoreRestrictionReasons.contains("sensitive");
}
} }

View file

@ -38,6 +38,7 @@ import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.RequestDelegate; import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_bots;
import org.telegram.tgnet.tl.TL_stories; import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.DialogsSearchAdapter; import org.telegram.ui.Adapters.DialogsSearchAdapter;
@ -1404,6 +1405,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM business_replies").stepThis().dispose(); database.executeFast("DELETE FROM business_replies").stepThis().dispose();
database.executeFast("DELETE FROM quick_replies_messages").stepThis().dispose(); database.executeFast("DELETE FROM quick_replies_messages").stepThis().dispose();
database.executeFast("DELETE FROM effects").stepThis().dispose(); database.executeFast("DELETE FROM effects").stepThis().dispose();
database.executeFast("DELETE FROM app_config").stepThis().dispose();
cursor = database.queryFinalized("SELECT did FROM dialogs WHERE 1"); cursor = database.queryFinalized("SELECT did FROM dialogs WHERE 1");
@ -2183,6 +2185,9 @@ public class MessagesStorage extends BaseController {
for (int a = 0; a < dialogs.size(); a++) { for (int a = 0; a < dialogs.size(); a++) {
long did = dialogs.keyAt(a); long did = dialogs.keyAt(a);
ReadDialog dialog = dialogs.valueAt(a); ReadDialog dialog = dialogs.valueAt(a);
if (getMessagesController().isForum(did)) {
getMessagesController().markAllTopicsAsRead(did);
}
getMessagesController().markDialogAsRead(did, dialog.lastMid, dialog.lastMid, dialog.date, false, 0, dialog.unreadCount, true, 0); getMessagesController().markDialogAsRead(did, dialog.lastMid, dialog.lastMid, dialog.date, false, 0, dialog.unreadCount, true, 0);
} }
}); });
@ -7453,7 +7458,7 @@ public class MessagesStorage extends BaseController {
cursor.dispose(); cursor.dispose();
cursor = null; cursor = null;
for (int a = 0; a < info.bot_info.size(); a++) { for (int a = 0; a < info.bot_info.size(); a++) {
TLRPC.BotInfo botInfo = info.bot_info.get(a); TL_bots.BotInfo botInfo = info.bot_info.get(a);
usersToLoad.add(botInfo.user_id); usersToLoad.add(botInfo.user_id);
} }
} }
@ -8282,7 +8287,7 @@ public class MessagesStorage extends BaseController {
}); });
} }
public Runnable getMessagesInternal(long dialogId, long mergeDialogId, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, int mode, long threadMessageId, int loadIndex, boolean processMessages, boolean isTopic, MessageLoaderLogger loaderLogger) { public Runnable getMessagesInternal(long dialogId, long mergeDialogId, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, int mode, long threadMessageId, int loadIndex, boolean processMessages, boolean isTopic, Timer loaderLogger) {
TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages(); TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages();
long currentUserId = getUserConfig().clientUserId; long currentUserId = getUserConfig().clientUserId;
int count_unread = 0; int count_unread = 0;
@ -9267,19 +9272,16 @@ public class MessagesStorage extends BaseController {
} }
} }
public void getMessages(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, int mode, long replyMessageId, int loadIndex, boolean processMessages, boolean isTopic, MessageLoaderLogger loaderLogger) { public void getMessages(long dialogId, long mergeDialogId, boolean loadInfo, int count, int max_id, int offset_date, int minDate, int classGuid, int load_type, int mode, long replyMessageId, int loadIndex, boolean processMessages, boolean isTopic, Timer loaderLogger) {
Timer.Task t1 = Timer.start(loaderLogger, "MessagesStorage.getMessages: storageQueue.postRunnable");
storageQueue.postRunnable(() -> { storageQueue.postRunnable(() -> {
if (loaderLogger != null) { Timer.done(t1);
loaderLogger.logStorageQueuePost(); Timer.Task t2 = Timer.start(loaderLogger, "MessagesStorage.getMessages");
}
Runnable processMessagesRunnable = getMessagesInternal(dialogId, mergeDialogId, count, max_id, offset_date, minDate, classGuid, load_type, mode, replyMessageId, loadIndex, processMessages, isTopic, loaderLogger); Runnable processMessagesRunnable = getMessagesInternal(dialogId, mergeDialogId, count, max_id, offset_date, minDate, classGuid, load_type, mode, replyMessageId, loadIndex, processMessages, isTopic, loaderLogger);
if (loaderLogger != null) { Timer.done(t2);
loaderLogger.logStorageProccessing(); Timer.Task t3 = Timer.start(loaderLogger, "MessagesStorage.getMessages: stageQueue.postRunnable");
}
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {
if (loaderLogger != null) { Timer.done(t3);
loaderLogger.logStageQueuePost();
}
processMessagesRunnable.run(); processMessagesRunnable.run();
}); });
}); });
@ -14819,6 +14821,9 @@ public class MessagesStorage extends BaseController {
} else if (oldMessage.media instanceof TLRPC.TL_messageMediaDocument && message.media instanceof TLRPC.TL_messageMediaDocument && oldMessage.media.document != null && message.media.document != null) { } else if (oldMessage.media instanceof TLRPC.TL_messageMediaDocument && message.media instanceof TLRPC.TL_messageMediaDocument && oldMessage.media.document != null && message.media.document != null) {
sameMedia = oldMessage.media.document.id == message.media.document.id; sameMedia = oldMessage.media.document.id == message.media.document.id;
} }
if (oldMessage.out && !message.out) {
message.out = oldMessage.out;
}
if (!sameMedia) { if (!sameMedia) {
addFilesToDelete(oldMessage, filesToDelete, idsToDelete, namesToDelete, false); addFilesToDelete(oldMessage, filesToDelete, idsToDelete, namesToDelete, false);
} }
@ -15362,6 +15367,14 @@ public class MessagesStorage extends BaseController {
} }
} }
} }
if (message.reactions != null && message.reactions.top_reactors != null) {
for (int i = 0; i < message.reactions.top_reactors.size(); ++i) {
final TLRPC.MessageReactor reactor = message.reactions.top_reactors.get(i);
if (reactor != null && reactor.peer_id != null) {
addLoadPeerInfo(reactor.peer_id, usersToLoad, chatsToLoad);
}
}
}
} }
public static void addLoadPeerInfo(TLRPC.Peer peer, ArrayList<Long> usersToLoad, ArrayList<Long> chatsToLoad) { public static void addLoadPeerInfo(TLRPC.Peer peer, ArrayList<Long> usersToLoad, ArrayList<Long> chatsToLoad) {

View file

@ -105,6 +105,7 @@ public class NotificationCenter {
public static final int wasUnableToFindCurrentLocation = totalEvents++; public static final int wasUnableToFindCurrentLocation = totalEvents++;
public static final int reloadHints = totalEvents++; public static final int reloadHints = totalEvents++;
public static final int reloadInlineHints = totalEvents++; public static final int reloadInlineHints = totalEvents++;
public static final int reloadWebappsHints = totalEvents++;
public static final int newDraftReceived = totalEvents++; public static final int newDraftReceived = totalEvents++;
public static final int recentDocumentsDidLoad = totalEvents++; public static final int recentDocumentsDidLoad = totalEvents++;
public static final int needAddArchivedStickers = totalEvents++; public static final int needAddArchivedStickers = totalEvents++;
@ -143,6 +144,8 @@ public class NotificationCenter {
public static final int businessMessagesUpdated = totalEvents++; public static final int businessMessagesUpdated = totalEvents++;
public static final int quickRepliesUpdated = totalEvents++; public static final int quickRepliesUpdated = totalEvents++;
public static final int quickRepliesDeleted = totalEvents++; public static final int quickRepliesDeleted = totalEvents++;
public static final int bookmarkAdded = totalEvents++;
public static final int starReactionAnonymousUpdate = totalEvents++;
public static final int businessLinksUpdated = totalEvents++; public static final int businessLinksUpdated = totalEvents++;
public static final int businessLinkCreated = totalEvents++; public static final int businessLinkCreated = totalEvents++;
@ -250,12 +253,16 @@ public class NotificationCenter {
public static final int premiumFloodWaitReceived = totalEvents++; public static final int premiumFloodWaitReceived = totalEvents++;
public static final int availableEffectsUpdate = totalEvents++; public static final int availableEffectsUpdate = totalEvents++;
public static final int starOptionsLoaded = totalEvents++; public static final int starOptionsLoaded = totalEvents++;
public static final int starGiftOptionsLoaded = totalEvents++;
public static final int starBalanceUpdated = totalEvents++; public static final int starBalanceUpdated = totalEvents++;
public static final int starTransactionsLoaded = totalEvents++; public static final int starTransactionsLoaded = totalEvents++;
public static final int starSubscriptionsLoaded = totalEvents++;
public static final int factCheckLoaded = totalEvents++; public static final int factCheckLoaded = totalEvents++;
public static final int botStarsUpdated = totalEvents++; public static final int botStarsUpdated = totalEvents++;
public static final int botStarsTransactionsLoaded = totalEvents++; public static final int botStarsTransactionsLoaded = totalEvents++;
public static final int channelStarsUpdated = totalEvents++; public static final int channelStarsUpdated = totalEvents++;
public static final int webViewResolved = totalEvents++;
public static final int updateAllMessages = totalEvents++;
//global //global
public static final int pushMessagesUpdated = totalEvents++; public static final int pushMessagesUpdated = totalEvents++;

View file

@ -34,7 +34,6 @@ import android.provider.OpenableColumns;
import android.text.Spannable; import android.text.Spannable;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Base64; import android.util.Base64;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
@ -85,12 +84,12 @@ import org.telegram.ui.TwoStepVerificationSetupActivity;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.RandomAccessFile; import java.io.RandomAccessFile;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -100,6 +99,8 @@ import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class SendMessagesHelper extends BaseController implements NotificationCenter.NotificationCenterDelegate { public class SendMessagesHelper extends BaseController implements NotificationCenter.NotificationCenterDelegate {
@ -3098,7 +3099,15 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return voteSendTime.get(pollId, 0L); return voteSendTime.get(pollId, 0L);
} }
public void sendReaction(MessageObject messageObject, ArrayList<ReactionsLayoutInBubble.VisibleReaction> visibleReactions, ReactionsLayoutInBubble.VisibleReaction addedReaction, boolean big, boolean addToRecent, BaseFragment parentFragment, Runnable callback) { public void sendReaction(
MessageObject messageObject,
ArrayList<ReactionsLayoutInBubble.VisibleReaction> visibleReactions,
ReactionsLayoutInBubble.VisibleReaction addedReaction,
boolean big,
boolean addToRecent,
BaseFragment parentFragment,
Runnable callback
) {
if (messageObject == null || parentFragment == null) { if (messageObject == null || parentFragment == null) {
return; return;
} }
@ -3148,7 +3157,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
TLRPC.TL_messages_requestUrlAuth req = new TLRPC.TL_messages_requestUrlAuth(); TLRPC.TL_messages_requestUrlAuth req = new TLRPC.TL_messages_requestUrlAuth();
req.url = url; req.url = url;
req.flags |= 4; req.flags |= 4;
getConnectionsManager().sendRequest(req, (response, error) -> { getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response != null) { if (response != null) {
if (response instanceof TLRPC.TL_urlAuthResultRequest) { if (response instanceof TLRPC.TL_urlAuthResultRequest) {
TLRPC.TL_urlAuthResultRequest res = (TLRPC.TL_urlAuthResultRequest) response; TLRPC.TL_urlAuthResultRequest res = (TLRPC.TL_urlAuthResultRequest) response;
@ -3162,7 +3171,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} else { } else {
AlertsCreator.showOpenUrlAlert(parentFragment, url, false, ask); AlertsCreator.showOpenUrlAlert(parentFragment, url, false, ask);
} }
}, ConnectionsManager.RequestFlagFailOnServerErrors); }), ConnectionsManager.RequestFlagFailOnServerErrors);
} }
public void sendCallback(final boolean cache, final MessageObject messageObject, final TLRPC.KeyboardButton button, final ChatActivity parentFragment) { public void sendCallback(final boolean cache, final MessageObject messageObject, final TLRPC.KeyboardButton button, final ChatActivity parentFragment) {
@ -3654,7 +3663,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
user.phone = newMsg.media.phone_number; user.phone = newMsg.media.phone_number;
user.first_name = newMsg.media.first_name; user.first_name = newMsg.media.first_name;
user.last_name = newMsg.media.last_name; user.last_name = newMsg.media.last_name;
TLRPC.TL_restrictionReason reason = new TLRPC.TL_restrictionReason(); TLRPC.RestrictionReason reason = new TLRPC.RestrictionReason();
reason.platform = ""; reason.platform = "";
reason.reason = ""; reason.reason = "";
reason.text = newMsg.media.vcard; reason.text = newMsg.media.vcard;
@ -3936,7 +3945,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} }
newMsg.local_id = newMsg.id = getUserConfig().getNewMessageId(); newMsg.local_id = newMsg.id = getUserConfig().getNewMessageId();
newMsg.out = true; newMsg.out = true;
if (isChannel && sendToPeer != null) { TLRPC.Chat chat = sendToPeer != null ? getMessagesController().getChat(sendToPeer.channel_id) : null;
if (isChannel && sendToPeer != null && (chat == null || !chat.signatures)) {
newMsg.from_id = new TLRPC.TL_peerChannel(); newMsg.from_id = new TLRPC.TL_peerChannel();
newMsg.from_id.channel_id = sendToPeer.channel_id; newMsg.from_id.channel_id = sendToPeer.channel_id;
} else if (fromPeer != null) { } else if (fromPeer != null) {
@ -4006,10 +4016,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
newMsg.unread = true; newMsg.unread = true;
} else { } else {
newMsg.post = true; newMsg.post = true;
if (chat.signatures) { // if (chat.signatures && !chat.signature_profiles) {
newMsg.from_id = new TLRPC.TL_peerUser(); // newMsg.from_id = new TLRPC.TL_peerUser();
newMsg.from_id.user_id = myId; // newMsg.from_id.user_id = myId;
} // }
} }
} }
} else { } else {
@ -7029,7 +7039,46 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
continue; continue;
} }
String path = MediaController.copyFileToCache(mediaUri, "txt"); String ext = "txt";
String filename = FileLoader.fixFileName(MediaController.getFileName(uri));
if (filename != null && filename.endsWith(".zip")) {
ext = "zip";
}
String path = MediaController.copyFileToCache(mediaUri, ext);
if ("zip".equals(ext)) {
File zipfile = new File(path);
try {
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(zipfile))) {
ZipEntry zipEntry = zis.getNextEntry();
while (zipEntry != null) {
if (zipEntry.getName().endsWith(".txt")) {
File newFile = MediaController.createFileInCache(zipEntry.getName(), "txt");
path = newFile.getAbsolutePath();
FileOutputStream fos = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];
int len;
while ((len = zis.read(buffer)) > 0) {
fos.write(buffer, 0, len);
}
fos.close();
break;
}
zipEntry = zis.getNextEntry();
}
zis.closeEntry();
} catch (IOException e) {
FileLog.e(e);
}
} catch (Exception e2) {
FileLog.e(e2);
}
try {
zipfile.delete();
} catch (Exception e) {
FileLog.e(e);
}
}
if (path == null) { if (path == null) {
continue; continue;
} }
@ -8064,7 +8113,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
user.phone = result.send_message.phone_number; user.phone = result.send_message.phone_number;
user.first_name = result.send_message.first_name; user.first_name = result.send_message.first_name;
user.last_name = result.send_message.last_name; user.last_name = result.send_message.last_name;
TLRPC.TL_restrictionReason reason = new TLRPC.TL_restrictionReason(); TLRPC.RestrictionReason reason = new TLRPC.RestrictionReason();
reason.text = result.send_message.vcard; reason.text = result.send_message.vcard;
reason.platform = ""; reason.platform = "";
reason.reason = ""; reason.reason = "";

View file

@ -275,12 +275,16 @@ public class SharedConfig {
// public static int saveToGalleryFlags; // public static int saveToGalleryFlags;
public static int mapPreviewType = 2; public static int mapPreviewType = 2;
public static int searchEngineType = 0;
public static String searchEngineCustomURLQuery, searchEngineCustomURLAutocomplete;
public static boolean chatBubbles = Build.VERSION.SDK_INT >= 30; public static boolean chatBubbles = Build.VERSION.SDK_INT >= 30;
public static boolean raiseToSpeak = false; public static boolean raiseToSpeak = false;
public static boolean raiseToListen = true; public static boolean raiseToListen = true;
public static boolean nextMediaTap = true; public static boolean nextMediaTap = true;
public static boolean recordViaSco = false; public static boolean recordViaSco = false;
public static boolean customTabs = true; public static boolean customTabs = true;
public static boolean inappBrowser = true;
public static boolean adaptableColorInBrowser = true;
public static boolean directShare = true; public static boolean directShare = true;
public static boolean inappCamera = true; public static boolean inappCamera = true;
public static boolean roundCamera16to9 = true; public static boolean roundCamera16to9 = true;
@ -578,11 +582,14 @@ public class SharedConfig {
preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);
SaveToGallerySettingsHelper.load(preferences); SaveToGallerySettingsHelper.load(preferences);
mapPreviewType = preferences.getInt("mapPreviewType", 2); mapPreviewType = preferences.getInt("mapPreviewType", 2);
searchEngineType = preferences.getInt("searchEngineType", 0);
raiseToListen = preferences.getBoolean("raise_to_listen", true); raiseToListen = preferences.getBoolean("raise_to_listen", true);
raiseToSpeak = preferences.getBoolean("raise_to_speak", false); raiseToSpeak = preferences.getBoolean("raise_to_speak", false);
nextMediaTap = preferences.getBoolean("next_media_on_tap", true); nextMediaTap = preferences.getBoolean("next_media_on_tap", true);
recordViaSco = preferences.getBoolean("record_via_sco", false); recordViaSco = preferences.getBoolean("record_via_sco", false);
customTabs = preferences.getBoolean("custom_tabs", true); customTabs = preferences.getBoolean("custom_tabs", true);
inappBrowser = preferences.getBoolean("inapp_browser", true);
adaptableColorInBrowser = preferences.getBoolean("adaptableBrowser", false);
directShare = preferences.getBoolean("direct_share", true); directShare = preferences.getBoolean("direct_share", true);
shuffleMusic = preferences.getBoolean("shuffleMusic", false); shuffleMusic = preferences.getBoolean("shuffleMusic", false);
playOrderReversed = !shuffleMusic && preferences.getBoolean("playOrderReversed", false); playOrderReversed = !shuffleMusic && preferences.getBoolean("playOrderReversed", false);
@ -1185,6 +1192,14 @@ public class SharedConfig {
editor.apply(); editor.apply();
} }
public static void setSearchEngineType(int value) {
searchEngineType = value;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("searchEngineType", searchEngineType);
editor.apply();
}
public static void setNoSoundHintShowed(boolean value) { public static void setNoSoundHintShowed(boolean value) {
if (noSoundHintShowed == value) { if (noSoundHintShowed == value) {
return; return;
@ -1224,14 +1239,30 @@ public class SharedConfig {
return raiseToListen && (!speak || raiseToSpeak); return raiseToListen && (!speak || raiseToSpeak);
} }
public static void toggleCustomTabs() { public static void toggleCustomTabs(boolean newValue) {
customTabs = !customTabs; customTabs = newValue;
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("custom_tabs", customTabs); editor.putBoolean("custom_tabs", customTabs);
editor.apply(); editor.apply();
} }
public static void toggleInappBrowser() {
inappBrowser = !inappBrowser;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("inapp_browser", inappBrowser);
editor.apply();
}
public static void toggleBrowserAdaptableColors() {
adaptableColorInBrowser = !adaptableColorInBrowser;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("adaptableBrowser", adaptableColorInBrowser);
editor.apply();
}
public static void toggleDirectShare() { public static void toggleDirectShare() {
directShare = !directShare; directShare = !directShare;
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();

View file

@ -0,0 +1,104 @@
package org.telegram.messenger;
import java.util.ArrayList;
public class Timer {
public static Timer create(String name) {
if (!BuildVars.LOGS_ENABLED)
return null;
return new Timer(name);
}
public static Task start(Timer logger, String task) {
if (logger != null) {
return logger.start(task);
}
return null;
}
public static void log(Timer logger, String log) {
if (logger != null) {
logger.log(log);
}
}
public static void done(Task task) {
if (task != null) {
task.done();
}
}
int pad = 0;
final String name;
final long startTime;
public Timer(String name) {
this.name = name;
this.startTime = System.currentTimeMillis();
}
public ArrayList<Task> tasks = new ArrayList<>();
public Task start(String task) {
Task timer = new Task(task);
tasks.add(timer);
return timer;
}
public void log(String log) {
tasks.add(new Log(log));
}
public void finish() {
final long totalTime = System.currentTimeMillis() - startTime;
StringBuilder s = new StringBuilder();
s.append(name).append(" total=").append(totalTime).append("ms\n");
for (int i = 0; i < tasks.size(); i++) {
if (tasks.get(i) == null) continue;
s.append("#").append(i);
final int pad = tasks.get(i).pad;
for (int j = 0; j < pad; ++j) s.append(" ");
s.append(" ").append(tasks.get(i)).append("\n");
}
FileLog.d(s.toString());
}
public class Task {
final long startTime;
long endTime = -1;
final String task;
int pad;
public Task(String task) {
startTime = System.currentTimeMillis();
this.task = task;
Timer.this.pad++;
}
public void done() {
if (this.endTime < 0)
this.pad = Timer.this.pad--;
this.endTime = System.currentTimeMillis();
}
@Override
public String toString() {
return task + ": " + (endTime < 0 ? "not done" : (endTime - startTime) + "ms");
}
}
public class Log extends Task {
public Log(String task) {
super(task);
}
@Override
public String toString() {
return task;
}
}
}

View file

@ -46,6 +46,7 @@ public class UserConfig extends BaseController {
public TLRPC.TL_account_tmpPassword tmpPassword; public TLRPC.TL_account_tmpPassword tmpPassword;
public int ratingLoadTime; public int ratingLoadTime;
public int botRatingLoadTime; public int botRatingLoadTime;
public int webappRatingLoadTime;
public boolean contactsReimported; public boolean contactsReimported;
public boolean hasValidDialogLoadIds; public boolean hasValidDialogLoadIds;
public int migrateOffsetId = -1; public int migrateOffsetId = -1;
@ -154,6 +155,7 @@ public class UserConfig extends BaseController {
editor.putBoolean("unreadDialogsLoaded", unreadDialogsLoaded); editor.putBoolean("unreadDialogsLoaded", unreadDialogsLoaded);
editor.putInt("ratingLoadTime", ratingLoadTime); editor.putInt("ratingLoadTime", ratingLoadTime);
editor.putInt("botRatingLoadTime", botRatingLoadTime); editor.putInt("botRatingLoadTime", botRatingLoadTime);
editor.putInt("webappRatingLoadTime", webappRatingLoadTime);
editor.putBoolean("contactsReimported", contactsReimported); editor.putBoolean("contactsReimported", contactsReimported);
editor.putInt("loginTime", loginTime); editor.putInt("loginTime", loginTime);
editor.putBoolean("syncContacts", syncContacts); editor.putBoolean("syncContacts", syncContacts);
@ -298,6 +300,7 @@ public class UserConfig extends BaseController {
contactsReimported = preferences.getBoolean("contactsReimported", false); contactsReimported = preferences.getBoolean("contactsReimported", false);
ratingLoadTime = preferences.getInt("ratingLoadTime", 0); ratingLoadTime = preferences.getInt("ratingLoadTime", 0);
botRatingLoadTime = preferences.getInt("botRatingLoadTime", 0); botRatingLoadTime = preferences.getInt("botRatingLoadTime", 0);
webappRatingLoadTime = preferences.getInt("webappRatingLoadTime", 0);
loginTime = preferences.getInt("loginTime", currentAccount); loginTime = preferences.getInt("loginTime", currentAccount);
syncContacts = preferences.getBoolean("syncContacts", true); syncContacts = preferences.getBoolean("syncContacts", true);
suggestContacts = preferences.getBoolean("suggestContacts", true); suggestContacts = preferences.getBoolean("suggestContacts", true);
@ -466,6 +469,7 @@ public class UserConfig extends BaseController {
migrateOffsetAccess = -1; migrateOffsetAccess = -1;
ratingLoadTime = 0; ratingLoadTime = 0;
botRatingLoadTime = 0; botRatingLoadTime = 0;
webappRatingLoadTime = 0;
draftsLoaded = false; draftsLoaded = false;
contactsReimported = true; contactsReimported = true;
syncContacts = true; syncContacts = true;

View file

@ -121,7 +121,7 @@ public class UserObject {
if (name == null) { if (name == null) {
return LocaleController.getString(R.string.HiddenName); return LocaleController.getString(R.string.HiddenName);
} }
int index = name.indexOf(" "); int index = name.indexOf(" ", 2);
if (index >= 0) { if (index >= 0) {
name = name.substring(0, index); name = name.substring(0, index);
} }

View file

@ -14,6 +14,7 @@ import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Rect; import android.graphics.Rect;
import android.net.Uri;
import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom; import com.carrotsearch.randomizedtesting.Xoroshiro128PlusRandom;
@ -612,4 +613,12 @@ public class Utilities {
return list == null || list.isEmpty(); return list == null || list.isEmpty();
} }
public static Uri uriParseSafe(String link) {
try {
return Uri.parse(link);
} catch (Exception ignore) {
return null;
}
}
} }

View file

@ -26,6 +26,7 @@ import org.telegram.ui.Components.PhotoFilterView;
import org.telegram.ui.Components.Point; import org.telegram.ui.Components.Point;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Stories.recorder.StoryEntry; import org.telegram.ui.Stories.recorder.StoryEntry;
import org.telegram.ui.Stories.recorder.Weather;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
@ -127,6 +128,7 @@ public class VideoEditedInfo {
public static final byte TYPE_ROUND = 5; public static final byte TYPE_ROUND = 5;
public static final byte TYPE_MESSAGE = 6; public static final byte TYPE_MESSAGE = 6;
public static final byte TYPE_LINK = 7; public static final byte TYPE_LINK = 7;
public static final byte TYPE_WEATHER = 8;
public byte type; public byte type;
public byte subType; public byte subType;
@ -175,6 +177,7 @@ public class VideoEditedInfo {
public TL_stories.MediaArea mediaArea; public TL_stories.MediaArea mediaArea;
public TLRPC.MessageMedia media; public TLRPC.MessageMedia media;
public Weather.State weather;
public float density; public float density;
public long roundOffset; public long roundOffset;
@ -255,6 +258,11 @@ public class VideoEditedInfo {
roundDuration = data.readInt64(exception); roundDuration = data.readInt64(exception);
} else if (type == TYPE_PHOTO) { } else if (type == TYPE_PHOTO) {
segmentedPath = data.readString(exception); segmentedPath = data.readString(exception);
} else if (type == TYPE_WEATHER) {
int magic = data.readInt32(exception);
if (magic == 0x7EA7539) {
weather = Weather.State.TLdeserialize(data);
}
} }
} }
@ -321,6 +329,13 @@ public class VideoEditedInfo {
data.writeInt64(roundDuration); data.writeInt64(roundDuration);
} else if (type == TYPE_PHOTO) { } else if (type == TYPE_PHOTO) {
data.writeString(segmentedPath); data.writeString(segmentedPath);
} else if (type == TYPE_WEATHER) {
if (weather == null) {
data.writeInt32(0xdeadbeef);
} else {
data.writeInt32(0x7EA7539);
weather.serializeToStream(data);
}
} }
} }
@ -374,6 +389,7 @@ public class VideoEditedInfo {
entity.roundLeft = roundLeft; entity.roundLeft = roundLeft;
entity.roundRight = roundRight; entity.roundRight = roundRight;
entity.linkSettings = linkSettings; entity.linkSettings = linkSettings;
entity.weather = weather;
return entity; return entity;
} }
} }

View file

@ -13,10 +13,10 @@ import android.app.PendingIntent;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
@ -43,15 +43,20 @@ import org.telegram.messenger.support.customtabsclient.shared.ServiceConnection;
import org.telegram.messenger.support.customtabsclient.shared.ServiceConnectionCallback; import org.telegram.messenger.support.customtabsclient.shared.ServiceConnectionCallback;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBarLayout;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheetTabs;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.web.RestrictedDomainsList;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.net.IDN;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Browser { public class Browser {
@ -221,9 +226,12 @@ public class Browser {
public void end() { public void end() {
end(false); end(false);
} }
public void end(boolean replaced) {} public void end(boolean replaced) {
if (onEndListener != null) {
onEndListener.run();
}
}
private Runnable onCancelListener;
public void cancel() { public void cancel() {
cancel(false); cancel(false);
} }
@ -233,20 +241,27 @@ public class Browser {
} }
end(replaced); end(replaced);
} }
private Runnable onCancelListener;
public void onCancel(Runnable onCancelListener) { public void onCancel(Runnable onCancelListener) {
this.onCancelListener = onCancelListener; this.onCancelListener = onCancelListener;
} }
private Runnable onEndListener;
public void onEnd(Runnable onEndListener) {
this.onEndListener = onEndListener;
}
} }
public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph) { public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph) {
openUrl(context, uri, allowCustom, tryTelegraph, false, null, null); openUrl(context, uri, allowCustom, tryTelegraph, false, null, null, false);
} }
public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph, Progress inCaseLoading) { public static void openUrl(final Context context, Uri uri, final boolean allowCustom, boolean tryTelegraph, Progress inCaseLoading) {
openUrl(context, uri, allowCustom, tryTelegraph, false, inCaseLoading, null); openUrl(context, uri, allowCustom, tryTelegraph, false, inCaseLoading, null, false);
} }
public static void openUrl(final Context context, Uri uri, boolean _allowCustom, boolean tryTelegraph, boolean forceNotInternalForApps, Progress inCaseLoading, String browser) { public static void openUrl(final Context context, Uri uri, boolean _allowCustom, boolean tryTelegraph, boolean forceNotInternalForApps, Progress inCaseLoading, String browser, boolean allowIntent) {
if (context == null || uri == null) { if (context == null || uri == null) {
return; return;
} }
@ -338,56 +353,8 @@ public class Browser {
} }
uri = Uri.parse("https://" + finalPath); uri = Uri.parse("https://" + finalPath);
} }
if (allowCustom && SharedConfig.customTabs && !internalUri && !scheme.equals("tel")) { if (allowCustom && !SharedConfig.inappBrowser && SharedConfig.customTabs && !internalUri && !scheme.equals("tel") && !isTonsite(uri.toString())) {
String[] browserPackageNames = null; if (forceBrowser[0] || !openInExternalApp(context, uri.toString(), false) || !hasAppToOpen(context, uri.toString())) {
try {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(browserIntent, 0);
if (list != null && !list.isEmpty()) {
browserPackageNames = new String[list.size()];
for (int a = 0; a < list.size(); a++) {
browserPackageNames[a] = list.get(a).activityInfo.packageName;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("default browser name = " + browserPackageNames[a]);
}
}
}
} catch (Exception ignore) {
}
List<ResolveInfo> allActivities = null;
try {
Intent viewIntent = new Intent(Intent.ACTION_VIEW, uri);
allActivities = context.getPackageManager().queryIntentActivities(viewIntent, 0);
if (browserPackageNames != null) {
for (int a = 0; a < allActivities.size(); a++) {
for (int b = 0; b < browserPackageNames.length; b++) {
if (browserPackageNames[b].equals(allActivities.get(a).activityInfo.packageName)) {
allActivities.remove(a);
a--;
break;
}
}
}
} else {
for (int a = 0; a < allActivities.size(); a++) {
if (allActivities.get(a).activityInfo.packageName.toLowerCase().contains("browser") || allActivities.get(a).activityInfo.packageName.toLowerCase().contains("chrome")) {
allActivities.remove(a);
a--;
}
}
}
if (BuildVars.LOGS_ENABLED) {
for (int a = 0; a < allActivities.size(); a++) {
FileLog.d("device has " + allActivities.get(a).activityInfo.packageName + " to open " + uri.toString());
}
}
} catch (Exception ignore) {
}
if (forceBrowser[0] || allActivities == null || allActivities.isEmpty()) {
if (MessagesController.getInstance(currentAccount).authDomains.contains(host)) { if (MessagesController.getInstance(currentAccount).authDomains.contains(host)) {
Intent intent = new Intent(Intent.ACTION_VIEW, uri); Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -401,11 +368,13 @@ public class Browser {
PendingIntent copy = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 0, new Intent(ApplicationLoader.applicationContext, CustomTabsCopyReceiver.class), PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT); PendingIntent copy = PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 0, new Intent(ApplicationLoader.applicationContext, CustomTabsCopyReceiver.class), PendingIntent.FLAG_MUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(getSession()); CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(getSession());
builder.addMenuItem(LocaleController.getString("CopyLink", R.string.CopyLink), copy);
builder.addMenuItem(LocaleController.getString(R.string.CopyLink), copy);
builder.setToolbarColor(Theme.getColor(Theme.key_actionBarBrowser)); builder.setToolbarColor(Theme.getColor(Theme.key_actionBarBrowser));
builder.setShowTitle(true); builder.setShowTitle(true);
builder.setActionButton(BitmapFactory.decodeResource(context.getResources(), R.drawable.msg_filled_shareout), LocaleController.getString("ShareFile", R.string.ShareFile), PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 0, share, PendingIntent.FLAG_MUTABLE ), true); builder.setActionButton(BitmapFactory.decodeResource(context.getResources(), R.drawable.msg_filled_shareout), LocaleController.getString("ShareFile", R.string.ShareFile), PendingIntent.getBroadcast(ApplicationLoader.applicationContext, 0, share, PendingIntent.FLAG_MUTABLE ), true);
CustomTabsIntent intent = builder.build(); CustomTabsIntent intent = builder.build();
intent.setUseNewTask(); intent.setUseNewTask();
intent.launchUrl(context, uri); intent.launchUrl(context, uri);
@ -416,29 +385,24 @@ public class Browser {
FileLog.e(e); FileLog.e(e);
} }
try { try {
Intent intent = new Intent(Intent.ACTION_VIEW, uri); final boolean inappBrowser = (
if (internalUri) { SharedConfig.inappBrowser &&
ComponentName componentName = new ComponentName(context.getPackageName(), LaunchActivity.class.getName()); TextUtils.isEmpty(browserPackage) &&
intent.setComponent(componentName); !RestrictedDomainsList.getInstance().isRestricted(AndroidUtilities.getHostAuthority(uri, true)) &&
} (uri.getScheme() == null || "https".equals(uri.getScheme()) || "http".equals(uri.getScheme()) || "tonsite".equals(uri.getScheme()))
if (!TextUtils.isEmpty(browserPackage)) { ||
intent.setPackage(browserPackage); isTonsite(uri.toString())
} );
intent.putExtra(android.provider.Browser.EXTRA_CREATE_NEW_TAB, true); if (internalUri && LaunchActivity.instance != null) {
intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, context.getPackageName()); LaunchActivity.dismissAllWeb();
if (internalUri && context instanceof LaunchActivity) { openAsInternalIntent(LaunchActivity.instance, uri.toString(), forceNotInternalForApps, inCaseLoading);
intent.putExtra(LaunchActivity.EXTRA_FORCE_NOT_INTERNAL_APPS, forceNotInternalForApps);
((LaunchActivity) context).onNewIntent(intent, inCaseLoading);
} else { } else {
try { if (inappBrowser) {
context.startActivity(intent); if (!openInExternalApp(context, uri.toString(), allowIntent)) {
} catch (Exception e2) { openInTelegramBrowser(context, uri.toString(), inCaseLoading);
if (browserPackage != null) {
intent.setPackage(browserPackage = null);
context.startActivity(intent);
} else {
FileLog.e(e2);
} }
} else {
openInExternalBrowser(context, uri.toString(), allowIntent, browserPackage);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -446,6 +410,189 @@ public class Browser {
} }
} }
public static boolean openAsInternalIntent(Context context, String url) {
return openAsInternalIntent(context, url, false, null);
}
public static boolean openAsInternalIntent(Context context, String url, Browser.Progress progress) {
return openAsInternalIntent(context, url, false, progress);
}
public static boolean openAsInternalIntent(Context context, String url, boolean forceNotInternalForApps) {
return openAsInternalIntent(context, url, forceNotInternalForApps, null);
}
public static boolean openAsInternalIntent(Context context, String url, boolean forceNotInternalForApps, Browser.Progress progress) {
if (url == null) return false;
LaunchActivity activity = null;
if (AndroidUtilities.findActivity(context) instanceof LaunchActivity) {
activity = (LaunchActivity) AndroidUtilities.findActivity(context);
} else if (LaunchActivity.instance != null) {
activity = LaunchActivity.instance;
} else {
return false;
}
if (activity == null) return false;
final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
ComponentName componentName = new ComponentName(context.getPackageName(), LaunchActivity.class.getName());
intent.setComponent(componentName);
intent.putExtra(android.provider.Browser.EXTRA_CREATE_NEW_TAB, true);
intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, context.getPackageName());
intent.putExtra(LaunchActivity.EXTRA_FORCE_NOT_INTERNAL_APPS, forceNotInternalForApps);
activity.onNewIntent(intent, progress);
return true;
}
public static boolean openInTelegramBrowser(Context context, String url, Browser.Progress progress) {
if (LaunchActivity.instance != null) {
BottomSheetTabs tabs = LaunchActivity.instance.getBottomSheetTabs();
if (tabs != null && tabs.tryReopenTab(url) != null) {
return true;
}
}
BaseFragment fragment = LaunchActivity.getSafeLastFragment();
if (fragment != null && fragment.getParentLayout() instanceof ActionBarLayout) {
fragment = ((ActionBarLayout) fragment.getParentLayout()).getSheetFragment();
}
if (fragment == null) {
return false;
}
fragment.createArticleViewer(false).open(url, progress);
return true;
}
public static boolean openInExternalBrowser(Context context, String url, boolean allowIntent) {
return openInExternalBrowser(context, url, allowIntent, null);
}
public static boolean openInExternalBrowser(Context context, String url, boolean allowIntent, String browser) {
if (url == null) return false;
try {
Uri uri = Uri.parse(url);
final boolean isIntentScheme = uri.getScheme() != null && uri.getScheme().equalsIgnoreCase("intent");
if (isIntentScheme && !allowIntent) return false;
final Intent intent = isIntentScheme ?
Intent.parseUri(uri.toString(), Intent.URI_INTENT_SCHEME) :
new Intent(Intent.ACTION_VIEW, uri);
if (!TextUtils.isEmpty(browser)) {
intent.setPackage(browser);
}
intent.putExtra(android.provider.Browser.EXTRA_CREATE_NEW_TAB, true);
intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, context.getPackageName());
context.startActivity(intent);
return true;
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
public static boolean isTonsite(String url) {
String domain = AndroidUtilities.getHostAuthority(url, true);
if (domain != null && (domain.endsWith(".ton") || domain.endsWith(".adnl"))) {
return true;
}
Uri uri = Uri.parse(url);
if (uri.getScheme() != null && uri.getScheme().equalsIgnoreCase("tonsite")) {
return true;
}
return false;
}
private static Pattern domainPattern;
public static boolean isTonsitePunycode(String url) {
if (domainPattern == null) domainPattern = Pattern.compile("^[a-zA-Z0-9\\-\\_\\.]+\\.[a-zA-Z0-9\\-\\_]+$");
String domain = AndroidUtilities.getHostAuthority(url, true);
if (domain != null && (domain.endsWith(".ton") || domain.endsWith(".adnl"))) {
return !domainPattern.matcher(domain).matches();
}
Uri uri = Uri.parse(url);
if (uri.getScheme() != null && uri.getScheme().equalsIgnoreCase("tonsite")) {
return !domainPattern.matcher(uri.getScheme()).matches();
}
return false;
}
public static boolean openInExternalApp(Context context, String url, boolean allowIntent) {
if (url == null) return false;
try {
if (isTonsite(url) || isInternalUrl(url, null)) return false;
Uri uri = Uri.parse(url);
url = Browser.replace(
uri,
uri.getScheme() == null ? "https" : uri.getScheme(),
uri.getHost() != null ? uri.getHost().toLowerCase() : uri.getHost(),
TextUtils.isEmpty(uri.getPath()) ? "/" : uri.getPath()
);
uri = Uri.parse(url);
final boolean isIntentScheme = uri.getScheme() != null && uri.getScheme().equalsIgnoreCase("intent");
if (isIntentScheme && !allowIntent) return false;
final Intent intent = isIntentScheme ?
Intent.parseUri(uri.toString(), Intent.URI_INTENT_SCHEME) :
new Intent(Intent.ACTION_VIEW, uri);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
} else if (!hasAppToOpen(context, url)) {
return false;
}
context.startActivity(intent);
return true;
} catch (Exception e) {
FileLog.e(e);
}
return false;
}
public static boolean hasAppToOpen(Context context, String url) {
if (url == null) return false;
String[] browserPackageNames = null;
try {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
List<ResolveInfo> list = context.getPackageManager().queryIntentActivities(browserIntent, 0);
if (list != null && !list.isEmpty()) {
browserPackageNames = new String[list.size()];
for (int a = 0; a < list.size(); a++) {
browserPackageNames[a] = list.get(a).activityInfo.packageName;
if (BuildVars.LOGS_ENABLED) {
FileLog.d("default browser name = " + browserPackageNames[a]);
}
}
}
} catch (Exception ignore) {}
List<ResolveInfo> allActivities = null;
try {
Intent viewIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
allActivities = context.getPackageManager().queryIntentActivities(viewIntent, 0);
if (browserPackageNames != null) {
for (int a = 0; a < allActivities.size(); a++) {
for (int b = 0; b < browserPackageNames.length; b++) {
if (browserPackageNames[b].equals(allActivities.get(a).activityInfo.packageName)) {
allActivities.remove(a);
a--;
break;
}
}
}
} else {
for (int a = 0; a < allActivities.size(); a++) {
final String packageName = allActivities.get(a).activityInfo.packageName.toLowerCase();
if (isBrowserPackageName(packageName)) {
allActivities.remove(a);
a--;
}
}
}
if (BuildVars.LOGS_ENABLED) {
for (int a = 0; a < allActivities.size(); a++) {
FileLog.d("device has " + allActivities.get(a).activityInfo.packageName + " to open " + url);
}
}
} catch (Exception ignore) {}
return allActivities != null && !allActivities.isEmpty();
}
public static boolean isInternalUrl(String url, boolean[] forceBrowser) { public static boolean isInternalUrl(String url, boolean[] forceBrowser) {
return isInternalUri(Uri.parse(url), false, forceBrowser); return isInternalUri(Uri.parse(url), false, forceBrowser);
} }
@ -596,30 +743,76 @@ public class Browser {
return null; return null;
} }
public static String replaceHostname(Uri originalUri, String newHostname) { public static boolean isBrowserPackageName(String name) {
String scheme = originalUri.getScheme(); return name != null && (
String userInfo = originalUri.getUserInfo(); name.contains("browser") ||
int port = originalUri.getPort(); name.contains("chrome") ||
String path = originalUri.getPath(); name.contains("firefox") ||
String query = originalUri.getQuery(); "com.microsoft.emmx".equals(name) ||
String fragment = originalUri.getFragment(); "com.opera.mini.native".equals(name) ||
"com.duckduckgo.mobile.android".equals(name) ||
"com.UCMobile.intl".equals(name)
);
}
StringBuilder modifiedUriBuilder = new StringBuilder(); public static boolean isPunycodeAllowed(String host) {
modifiedUriBuilder.append(scheme).append("://"); if (host == null) return true;
if (userInfo != null) { String[] levels = host.split("\\.");
modifiedUriBuilder.append(userInfo).append("@"); if (levels.length <= 0) return true;
String topLevel = levels[levels.length - 1];
return topLevel.startsWith("xn--");
}
public static String IDN_toUnicode(String host) {
try {
host = IDN.toASCII(host, IDN.ALLOW_UNASSIGNED);
} catch (Exception e) {
FileLog.e(e);
} }
modifiedUriBuilder.append(newHostname); if (!isPunycodeAllowed(host)) return host;
if (port != -1) { try {
modifiedUriBuilder.append(":").append(port); host = IDN.toUnicode(host, IDN.ALLOW_UNASSIGNED);
} catch (Exception e) {
FileLog.e(e);
} }
modifiedUriBuilder.append(path); return host;
if (query != null) { }
modifiedUriBuilder.append("?").append(query);
public static String replaceHostname(Uri originalUri, String newHostname, String newScheme) {
return replace(originalUri, newScheme, newHostname, null);
}
public static String replace(Uri originalUri, String newScheme, String newHostname, String newPath) {
final StringBuilder modifiedUriBuilder = new StringBuilder();
final String scheme = newScheme == null ? originalUri.getScheme() : newScheme;
if (scheme != null) {
modifiedUriBuilder.append(scheme).append("://");
} }
if (fragment != null) { if (originalUri.getUserInfo() != null) {
modifiedUriBuilder.append("#").append(fragment); modifiedUriBuilder.append(originalUri.getUserInfo()).append("@");
}
if (newHostname == null) {
if (originalUri.getHost() != null) {
modifiedUriBuilder.append(originalUri.getHost());
}
} else {
modifiedUriBuilder.append(newHostname);
}
if (originalUri.getPort() != -1) {
modifiedUriBuilder.append(":").append(originalUri.getPort());
}
if (newPath != null) {
modifiedUriBuilder.append(newPath);
} else {
modifiedUriBuilder.append(originalUri.getPath());
}
if (originalUri.getQuery() != null) {
modifiedUriBuilder.append("?").append(originalUri.getQuery());
}
if (originalUri.getFragment() != null) {
modifiedUriBuilder.append("#").append(originalUri.getFragment());
} }
return modifiedUriBuilder.toString(); return modifiedUriBuilder.toString();
} }
} }

View file

@ -355,6 +355,17 @@ public class Camera2Session {
} }
} }
private boolean flashing;
public void setFlash(boolean flash) {
if (flashing != flash) {
flashing = flash;
updateCaptureRequest();
}
}
public boolean getFlash() {
return flashing;
}
public float getZoom() { public float getZoom() {
return currentZoom; return currentZoom;
} }
@ -476,6 +487,8 @@ public class Camera2Session {
captureRequestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, isFront ? CameraMetadata.CONTROL_SCENE_MODE_NIGHT_PORTRAIT : CameraMetadata.CONTROL_SCENE_MODE_NIGHT); captureRequestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, isFront ? CameraMetadata.CONTROL_SCENE_MODE_NIGHT_PORTRAIT : CameraMetadata.CONTROL_SCENE_MODE_NIGHT);
} }
captureRequestBuilder.set(CaptureRequest.FLASH_MODE, flashing ? (recordingVideo ? CaptureRequest.FLASH_MODE_TORCH : CaptureRequest.FLASH_MODE_SINGLE) : CaptureRequest.FLASH_MODE_OFF);
if (recordingVideo) { if (recordingVideo) {
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, new Range<Integer>(30, 60)); captureRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, new Range<Integer>(30, 60));
captureRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD); captureRequestBuilder.set(CaptureRequest.CONTROL_CAPTURE_INTENT, CaptureRequest.CONTROL_CAPTURE_INTENT_VIDEO_RECORD);

View file

@ -554,6 +554,22 @@ public class CameraController implements MediaRecorder.OnInfoListener {
} }
Camera.Parameters params = camera.getParameters(); Camera.Parameters params = camera.getParameters();
List<String> rawFlashModes = params.getSupportedFlashModes();
session.availableFlashModes.clear();
if (rawFlashModes != null) {
for (int a = 0; a < rawFlashModes.size(); a++) {
String rawFlashMode = rawFlashModes.get(a);
if (rawFlashMode.equals(Camera.Parameters.FLASH_MODE_OFF) || rawFlashMode.equals(Camera.Parameters.FLASH_MODE_ON) || rawFlashMode.equals(Camera.Parameters.FLASH_MODE_AUTO)) {
session.availableFlashModes.add(rawFlashMode);
}
}
if (!TextUtils.equals(session.getCurrentFlashMode(), params.getFlashMode()) || !session.availableFlashModes.contains(session.getCurrentFlashMode())) {
session.checkFlashMode(session.availableFlashModes.get(0));
} else {
session.checkFlashMode(session.getCurrentFlashMode());
}
}
session.configureRoundCamera(true); session.configureRoundCamera(true);
if (configureCallback != null) { if (configureCallback != null) {
configureCallback.run(); configureCallback.run();

View file

@ -138,22 +138,34 @@ public class CameraSession {
return; return;
} }
currentFlashMode = mode; currentFlashMode = mode;
configurePhotoCamera(); if (isRound) {
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("camera", Activity.MODE_PRIVATE); configureRoundCamera(false);
sharedPreferences.edit().putString(cameraInfo.frontCamera != 0 ? "flashMode_front" : "flashMode", mode).commit(); } else {
configurePhotoCamera();
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("camera", Activity.MODE_PRIVATE);
sharedPreferences.edit().putString(cameraInfo.frontCamera != 0 ? "flashMode_front" : "flashMode", mode).commit();
}
} }
public void setCurrentFlashMode(String mode) { public void setCurrentFlashMode(String mode) {
currentFlashMode = mode; currentFlashMode = mode;
configurePhotoCamera(); if (isRound) {
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("camera", Activity.MODE_PRIVATE); configureRoundCamera(false);
sharedPreferences.edit().putString(cameraInfo.frontCamera != 0 ? "flashMode_front" : "flashMode", mode).commit(); } else {
configurePhotoCamera();
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("camera", Activity.MODE_PRIVATE);
sharedPreferences.edit().putString(cameraInfo.frontCamera != 0 ? "flashMode_front" : "flashMode", mode).commit();
}
} }
public void setTorchEnabled(boolean enabled) { public void setTorchEnabled(boolean enabled) {
try { try {
currentFlashMode = enabled ? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF; currentFlashMode = enabled ? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF;
configurePhotoCamera(); if (isRound) {
configureRoundCamera(false);
} else {
configurePhotoCamera();
}
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
} }
@ -262,7 +274,7 @@ public class CameraSession {
} catch (Exception e) { } catch (Exception e) {
// //
} }
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); params.setFlashMode(currentFlashMode);
params.setZoom((int) (currentZoom * maxZoom)); params.setZoom((int) (currentZoom * maxZoom));
try { try {
camera.setParameters(params); camera.setParameters(params);

View file

@ -89,7 +89,7 @@ public class RingtoneUploader implements NotificationCenter.NotificationCenterDe
} else if (error.text.equals("RINGTONE_SIZE_TOO_BIG")) { } else if (error.text.equals("RINGTONE_SIZE_TOO_BIG")) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_ERROR_SUBTITLE, LocaleController.formatString("TooLargeError", R.string.TooLargeError), LocaleController.formatString("ErrorRingtoneSizeTooBig", R.string.ErrorRingtoneSizeTooBig, (MessagesController.getInstance(currentAccount).ringtoneSizeMax / 1024))); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_ERROR_SUBTITLE, LocaleController.formatString("TooLargeError", R.string.TooLargeError), LocaleController.formatString("ErrorRingtoneSizeTooBig", R.string.ErrorRingtoneSizeTooBig, (MessagesController.getInstance(currentAccount).ringtoneSizeMax / 1024)));
} else { } else {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_ERROR_SUBTITLE, LocaleController.formatString("InvalidFormatError", R.string.InvalidFormatError), LocaleController.formatString("ErrorRingtoneInvalidFormat", R.string.ErrorRingtoneInvalidFormat)); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.showBulletin, Bulletin.TYPE_ERROR_SUBTITLE, LocaleController.formatString("InvalidFormatError", R.string.InvalidFormatError), LocaleController.getString(R.string.ErrorRingtoneInvalidFormat));
} }
}); });
} }

View file

@ -1,6 +1,8 @@
package org.telegram.messenger.utils; package org.telegram.messenger.utils;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64; import android.util.Base64;
import androidx.core.util.Pair; import androidx.core.util.Pair;
@ -15,7 +17,10 @@ import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.AbstractSerializedData;
import org.telegram.tgnet.SerializedData; import org.telegram.tgnet.SerializedData;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import java.io.InputStream; import java.io.InputStream;
@ -28,8 +33,6 @@ public class BillingUtilities {
private static final String CURRENCY_FILE = "currencies.json"; private static final String CURRENCY_FILE = "currencies.json";
private static final String CURRENCY_EXP = "exp"; private static final String CURRENCY_EXP = "exp";
private static TLRPC.InputStorePaymentPurpose remPaymentPurpose;
@SuppressWarnings("ConstantConditions") @SuppressWarnings("ConstantConditions")
public static void extractCurrencyExp(Map<String, Integer> currencyExpMap) { public static void extractCurrencyExp(Map<String, Integer> currencyExpMap) {
if (!currencyExpMap.isEmpty()) { if (!currencyExpMap.isEmpty()) {
@ -55,21 +58,146 @@ public class BillingUtilities {
long currentAccountId = accountInstance.getUserConfig().getClientUserId(); long currentAccountId = accountInstance.getUserConfig().getClientUserId();
byte[] currentAccountIdBytes = String.valueOf(currentAccountId).getBytes(Charsets.UTF_8); byte[] currentAccountIdBytes = String.valueOf(currentAccountId).getBytes(Charsets.UTF_8);
String obfuscatedAccountId = Base64.encodeToString(currentAccountIdBytes, Base64.DEFAULT); String obfuscatedAccountId = Base64.encodeToString(currentAccountIdBytes, Base64.DEFAULT);
return Pair.create(obfuscatedAccountId, savePurpose(paymentPurpose));
}
SerializedData serializedData = new SerializedData(paymentPurpose.getObjectSize()); public static String savePurpose(TLRPC.InputStorePaymentPurpose paymentPurpose) {
paymentPurpose.serializeToStream(serializedData); final long id = Utilities.random.nextLong();
String obfuscatedData = Base64.encodeToString(serializedData.toByteArray(), Base64.DEFAULT); FileLog.d("BillingUtilities.savePurpose id=" + id + " paymentPurpose=" + paymentPurpose);
serializedData.cleanup();
if ( SerializedData id_data = new SerializedData(8);
paymentPurpose instanceof TLRPC.TL_inputStorePaymentPremiumGiftCode || id_data.writeInt64(id);
paymentPurpose instanceof TLRPC.TL_inputStorePaymentPremiumGiveaway String id_hex = Utilities.bytesToHex(id_data.toByteArray());
) { id_data.cleanup();
remPaymentPurpose = paymentPurpose;
return Pair.create(obfuscatedAccountId, obfuscatedAccountId); FileLog.d("BillingUtilities.savePurpose id_hex=" + id_hex + " paymentPurpose=" + paymentPurpose);
} else {
remPaymentPurpose = null; TL_savedPurpose savedPurpose = new TL_savedPurpose();
savedPurpose.id = id;
savedPurpose.flags = 1;
savedPurpose.purpose = paymentPurpose;
SerializedData data = new SerializedData(savedPurpose.getObjectSize());
savedPurpose.serializeToStream(data);
String full_data_hex = Utilities.bytesToHex(data.toByteArray());
data.cleanup();
if (savedPurpose.getObjectSize() > 28) {
FileLog.d("BillingUtilities.savePurpose: sending short version, original size is " + savedPurpose.getObjectSize() + " bytes");
savedPurpose.flags = 0;
savedPurpose.purpose = null;
}
data = new SerializedData(savedPurpose.getObjectSize());
savedPurpose.serializeToStream(data);
String data_hex = Utilities.bytesToHex(data.toByteArray());
data.cleanup();
SharedPreferences prefs = ApplicationLoader.applicationContext.getSharedPreferences("purchases", Activity.MODE_PRIVATE);
prefs.edit().putString(id_hex, full_data_hex).apply();
FileLog.d("BillingUtilities.savePurpose: saved {" + full_data_hex + "} under " + id_hex);
FileLog.d("BillingUtilities.savePurpose: but sending {" + data_hex + "}");
return data_hex;
}
public static TLRPC.InputStorePaymentPurpose getPurpose(String data_hex) throws RuntimeException {
FileLog.d("BillingUtilities.getPurpose " + data_hex);
SerializedData data = new SerializedData(Utilities.hexToBytes(data_hex));
TL_savedPurpose savedPurpose = TL_savedPurpose.TLdeserialize(data, data.readInt32(true), true);
data.cleanup();
if (savedPurpose.purpose != null) {
FileLog.d("BillingUtilities.getPurpose: got purpose from received obfuscated profile id");
return savedPurpose.purpose;
}
SerializedData id_data = new SerializedData(8);
id_data.writeInt64(savedPurpose.id);
String id_hex = Utilities.bytesToHex(id_data.toByteArray());
id_data.cleanup();
FileLog.d("BillingUtilities.getPurpose: searching purpose under " + id_hex);
SharedPreferences prefs = ApplicationLoader.applicationContext.getSharedPreferences("purchases", Activity.MODE_PRIVATE);
String full_data_hex = prefs.getString(id_hex, null);
if (full_data_hex == null) {
FileLog.d("BillingUtilities.getPurpose: purpose under " + id_hex + " not found");
throw new RuntimeException("no purpose under " + id_hex + " found :(");
}
FileLog.d("BillingUtilities.getPurpose: got {" + full_data_hex + "} under " + id_hex);
SerializedData full_data = new SerializedData(Utilities.hexToBytes(full_data_hex));
savedPurpose = TL_savedPurpose.TLdeserialize(full_data, full_data.readInt32(true), true);
full_data.cleanup();
return savedPurpose.purpose;
}
public static void clearPurpose(String data_hex) {
try {
FileLog.d("BillingUtilities.clearPurpose: got {" + data_hex + "}");
SerializedData data = new SerializedData(Utilities.hexToBytes(data_hex));
TL_savedPurpose savedPurpose = TL_savedPurpose.TLdeserialize(data, data.readInt32(true), true);
SerializedData id_data = new SerializedData(8);
id_data.writeInt64(savedPurpose.id);
String id_hex = Utilities.bytesToHex(id_data.toByteArray());
id_data.cleanup();
FileLog.d("BillingUtilities.clearPurpose: id_hex = " + id_hex);
SharedPreferences prefs = ApplicationLoader.applicationContext.getSharedPreferences("purchases", Activity.MODE_PRIVATE);
prefs.edit().remove(id_hex).apply();
} catch (Exception e) {
FileLog.e(e);
}
}
public static class TL_savedPurpose extends TLObject {
public static final int constructor = 0x1d8ad892;
public int flags;
public long id;
public TLRPC.InputStorePaymentPurpose purpose;
public static TL_savedPurpose TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
TL_savedPurpose result = null;
switch (constructor) {
case TL_savedPurpose.constructor:
result = new TL_savedPurpose();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_savedPurpose", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
id = stream.readInt64(exception);
if ((flags & 1) != 0) {
purpose = TLRPC.InputStorePaymentPurpose.TLdeserialize(stream, stream.readInt32(exception), exception);
}
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
stream.writeInt64(id);
if ((flags & 1) != 0) {
purpose.serializeToStream(stream);
}
} }
return Pair.create(obfuscatedAccountId, obfuscatedData);
} }
private static AccountInstance findAccountById(long accountId) { private static AccountInstance findAccountById(long accountId) {
@ -99,19 +227,11 @@ public class BillingUtilities {
try { try {
TLRPC.InputStorePaymentPurpose purpose; TLRPC.InputStorePaymentPurpose purpose;
if (remPaymentPurpose == null) { try {
try { purpose = getPurpose(obfuscatedData);
byte[] obfuscatedDataBytes = Base64.decode(obfuscatedData, Base64.DEFAULT); } catch (Exception e) {
SerializedData data = new SerializedData(obfuscatedDataBytes); FileLog.e("Billing: Extract payload, failed to get purpose", e);
purpose = TLRPC.InputStorePaymentPurpose.TLdeserialize(data, data.readInt32(true), true); purpose = null;
data.cleanup();
} catch (Exception e) {
FileLog.e("Billing: Extract payload, no remPaymentPurpose; failed to get purpose", e);
purpose = null;
}
} else {
purpose = remPaymentPurpose;
remPaymentPurpose = null;
} }
byte[] obfuscatedAccountIdBytes = Base64.decode(obfuscatedAccountId, Base64.DEFAULT); byte[] obfuscatedAccountIdBytes = Base64.decode(obfuscatedAccountId, Base64.DEFAULT);
@ -128,4 +248,9 @@ public class BillingUtilities {
return null; return null;
} }
} }
public static void cleanupPurchase(Purchase purchase) {
AccountIdentifiers identifiers = purchase.getAccountIdentifiers();
clearPurpose(identifiers.getObfuscatedProfileId());
}
} }

View file

@ -41,11 +41,7 @@ import android.view.View;
import android.view.inputmethod.EditorInfo; import android.view.inputmethod.EditorInfo;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.exifinterface.media.ExifInterface;
import com.google.zxing.common.detector.MathUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
@ -1342,9 +1338,14 @@ public class TextureRenderer {
} }
private void initLocationEntity(VideoEditedInfo.MediaEntity entity) { private void initLocationEntity(VideoEditedInfo.MediaEntity entity) {
LocationMarker marker = new LocationMarker(ApplicationLoader.applicationContext, entity.density, 0); final int variant = entity.type == VideoEditedInfo.MediaEntity.TYPE_LOCATION ? LocationMarker.VARIANT_LOCATION : LocationMarker.VARIANT_WEATHER;
LocationMarker marker = new LocationMarker(ApplicationLoader.applicationContext, variant, entity.density, 0);
marker.setIsVideo(true);
marker.setText(entity.text); marker.setText(entity.text);
marker.setType(entity.subType, entity.color); marker.setType(entity.subType, entity.color);
if (entity.weather != null && entity.entities.isEmpty()) {
marker.setCodeEmoji(UserConfig.selectedAccount, entity.weather.getEmoji());
}
marker.setMaxWidth(entity.viewWidth); marker.setMaxWidth(entity.viewWidth);
if (entity.entities.size() == 1) { if (entity.entities.size() == 1) {
marker.forceEmoji(); marker.forceEmoji();

View file

@ -372,8 +372,9 @@ public class ConnectionsManager extends BaseController {
if (response != 0) { if (response != 0) {
NativeByteBuffer buff = NativeByteBuffer.wrap(response); NativeByteBuffer buff = NativeByteBuffer.wrap(response);
buff.reused = true; buff.reused = true;
int magic = buff.readInt32(true);
try { try {
resp = object.deserializeResponse(buff, buff.readInt32(true), true); resp = object.deserializeResponse(buff, magic, true);
} catch (Exception e2) { } catch (Exception e2) {
if (BuildVars.DEBUG_PRIVATE_VERSION) { if (BuildVars.DEBUG_PRIVATE_VERSION) {
throw e2; throw e2;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
package org.telegram.tgnet.tl;
import org.telegram.tgnet.AbstractSerializedData;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
public class TL_account {
public static class contentSettings extends TLObject {
public static final int constructor = 0x57e28221;
public int flags;
public boolean sensitive_enabled;
public boolean sensitive_can_change;
public static contentSettings TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (contentSettings.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_account.contentSettings", constructor));
} else {
return null;
}
}
contentSettings result = new contentSettings();
result.readParams(stream, exception);
return result;
}
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
sensitive_enabled = (flags & 1) != 0;
sensitive_can_change = (flags & 2) != 0;
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = sensitive_enabled ? (flags | 1) : (flags &~ 1);
flags = sensitive_can_change ? (flags | 2) : (flags &~ 2);
stream.writeInt32(flags);
}
}
public static class setContentSettings extends TLObject {
public static final int constructor = 0xb574b16b;
public int flags;
public boolean sensitive_enabled;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = sensitive_enabled ? (flags | 1) : (flags &~ 1);
stream.writeInt32(flags);
}
}
public static class getContentSettings extends TLObject {
public static final int constructor = 0x8b9b4dae;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return contentSettings.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
}

View file

@ -0,0 +1,937 @@
package org.telegram.tgnet.tl;
import org.telegram.tgnet.AbstractSerializedData;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import java.util.ArrayList;
public class TL_bots {
public static class botPreviewMedia extends TLObject {
public static final int constructor = 0x23e91ba3;
public int date;
public TLRPC.MessageMedia media;
public static botPreviewMedia TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (botPreviewMedia.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in botPreviewMedia", constructor));
} else {
return null;
}
}
botPreviewMedia result = new botPreviewMedia();
result.readParams(stream, exception);
return result;
}
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
date = stream.readInt32(exception);
media = TLRPC.MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(date);
media.serializeToStream(stream);
}
}
public static class addPreviewMedia extends TLObject {
public static final int constructor = 0x17aeb75a;
public TLRPC.InputUser bot;
public String lang_code = "";
public TLRPC.InputMedia media;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return botPreviewMedia.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(lang_code);
media.serializeToStream(stream);
}
}
public static class editPreviewMedia extends TLObject {
public static final int constructor = 0x8525606f;
public TLRPC.InputUser bot;
public String lang_code = "";
public TLRPC.InputMedia media;
public TLRPC.InputMedia new_media;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return botPreviewMedia.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(lang_code);
media.serializeToStream(stream);
new_media.serializeToStream(stream);
}
}
public static class deletePreviewMedia extends TLObject {
public static final int constructor = 0x2d0135b3;
public TLRPC.InputUser bot;
public String lang_code = "";
public ArrayList<TLRPC.InputMedia> media = new ArrayList<>();
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(lang_code);
stream.writeInt32(0x1cb5c415);
int count = media.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
media.get(a).serializeToStream(stream);
}
}
}
public static class reorderPreviewMedias extends TLObject {
public static final int constructor = 0xb627f3aa;
public TLRPC.InputUser bot;
public String lang_code = "";
public ArrayList<TLRPC.InputMedia> order = new ArrayList<>();
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(lang_code);
stream.writeInt32(0x1cb5c415);
int count = order.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
order.get(a).serializeToStream(stream);
}
}
}
public static class getPreviewMedias extends TLObject {
public static final int constructor = 0xa2a5594d;
public TLRPC.InputUser bot;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
TLRPC.Vector vector = new TLRPC.Vector();
int size = stream.readInt32(exception);
for (int a = 0; a < size; a++) {
vector.objects.add(botPreviewMedia.TLdeserialize(stream, stream.readInt32(exception), exception));
}
return vector;
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
}
}
public static class getPreviewInfo extends TLObject {
public static final int constructor = 0x423ab3ad;
public TLRPC.InputUser bot;
public String lang_code = "";
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return previewInfo.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(lang_code);
}
}
public static class previewInfo extends TLObject {
public static final int constructor = 0xca71d64;
public ArrayList<TL_bots.botPreviewMedia> media = new ArrayList<>();
public ArrayList<String> lang_codes = new ArrayList<>();
public static previewInfo TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (previewInfo.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in previewInfo", constructor));
} else {
return null;
}
}
previewInfo result = new previewInfo();
result.readParams(stream, exception);
return result;
}
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
botPreviewMedia object = botPreviewMedia.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
media.add(object);
}
magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
lang_codes.add(stream.readString(exception));
}
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(0x1cb5c415);
int count = media.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
media.get(i).serializeToStream(stream);
}
stream.writeInt32(0x1cb5c415);
count = lang_codes.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
stream.writeString(lang_codes.get(i));
}
}
}
public static class setBotInfo extends TLObject {
public static final int constructor = 0x10cf3123;
public int flags;
public TLRPC.InputUser bot;
public String lang_code;
public String name;
public String about;
public String description;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
if ((flags & 4) != 0) {
bot.serializeToStream(stream);
}
stream.writeString(lang_code);
if ((flags & 8) != 0) {
stream.writeString(name);
}
if ((flags & 1) != 0) {
stream.writeString(about);
}
if ((flags & 2) != 0) {
stream.writeString(description);
}
}
}
public static class getBotInfo extends TLObject {
public static final int constructor = 0xdcd914fd;
public int flags;
public TLRPC.InputUser bot;
public String lang_code;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return BotInfo.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
bot.serializeToStream(stream);
}
stream.writeString(lang_code);
}
}
public static class reorderUsernames extends TLObject {
public static final int constructor = 0x9709b1c2;
public TLRPC.InputUser bot;
public ArrayList<String> order = new ArrayList<>();
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeInt32(0x1cb5c415);
int count = order.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
stream.writeString(order.get(a));
}
}
}
public static class toggleUsername extends TLObject {
public static final int constructor = 0x53ca973;
public TLRPC.InputUser bot;
public String username;
public boolean active;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(username);
stream.writeBool(active);
}
}
public static abstract class BotInfo extends TLObject {
public long user_id;
public String description;
public ArrayList<TLRPC.TL_botCommand> commands = new ArrayList<>();
public int version;
public BotMenuButton menu_button;
public int flags;
public TLRPC.Photo description_photo;
public TLRPC.Document description_document;
public boolean has_preview_medias;
public String privacy_policy_url;
public static BotInfo TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
BotInfo result = null;
switch (constructor) {
case TL_botInfo_layer140.constructor:
result = new TL_botInfo_layer140();
break;
case TL_botInfoEmpty_layer48.constructor:
result = new TL_botInfoEmpty_layer48();
break;
case TL_botInfo_layer131.constructor:
result = new TL_botInfo_layer131();
break;
case TL_botInfo_layer48.constructor:
result = new TL_botInfo_layer48();
break;
case TL_botInfo_layer139.constructor:
result = new TL_botInfo_layer139();
break;
case TL_botInfo_layer185.constructor:
result = new TL_botInfo_layer185();
break;
case TL_botInfo.constructor:
result = new TL_botInfo();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in BotInfo", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_botInfoEmpty_layer48 extends TL_botInfo {
public static final int constructor = 0xbb2e37ce;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_botInfo_layer131 extends TL_botInfo {
public static final int constructor = 0x98e81d3a;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt32(exception);
description = stream.readString(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.TL_botCommand object = TLRPC.TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
commands.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32((int) user_id);
stream.writeString(description);
stream.writeInt32(0x1cb5c415);
int count = commands.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
commands.get(a).serializeToStream(stream);
}
}
}
public static class TL_botInfo_layer48 extends TL_botInfo {
public static final int constructor = 0x9cf585d;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt32(exception);
version = stream.readInt32(exception);
stream.readString(exception);
description = stream.readString(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.TL_botCommand object = TLRPC.TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
commands.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32((int) user_id);
stream.writeInt32(version);
stream.writeString("");
stream.writeString(description);
stream.writeInt32(0x1cb5c415);
int count = commands.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
commands.get(a).serializeToStream(stream);
}
}
}
public static class TL_botInfo_layer139 extends BotInfo {
public static final int constructor = 0x1b74b335;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt64(exception);
description = stream.readString(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.TL_botCommand object = TLRPC.TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
commands.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(user_id);
stream.writeString(description);
stream.writeInt32(0x1cb5c415);
int count = commands.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
commands.get(a).serializeToStream(stream);
}
}
}
public static class TL_botInfo extends BotInfo {
public static final int constructor = 0x82437e74;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
has_preview_medias = (flags & 64) != 0;
if ((flags & 1) != 0) {
user_id = stream.readInt64(exception);
}
if ((flags & 2) != 0) {
description = stream.readString(exception);
}
if ((flags & 16) != 0) {
description_photo = TLRPC.Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 32) != 0) {
description_document = TLRPC.Document.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.TL_botCommand object = TLRPC.TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
commands.add(object);
}
}
if ((flags & 8) != 0) {
menu_button = BotMenuButton.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 128) != 0) {
privacy_policy_url = stream.readString(exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = has_preview_medias ? flags | 64 : flags &~ 64;
stream.writeInt32(flags);
if ((flags & 1) != 0) {
stream.writeInt64(user_id);
}
if ((flags & 2) != 0) {
stream.writeString(description);
}
if ((flags & 16) != 0) {
description_photo.serializeToStream(stream);
}
if ((flags & 32) != 0) {
description_document.serializeToStream(stream);
}
if ((flags & 4) != 0) {
stream.writeInt32(0x1cb5c415);
int count = commands.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
commands.get(a).serializeToStream(stream);
}
}
if ((flags & 8) != 0) {
menu_button.serializeToStream(stream);
}
if ((flags & 128) != 0) {
stream.writeString(privacy_policy_url);
}
}
}
public static class TL_botInfo_layer185 extends TL_botInfo {
public static final int constructor = 0x8f300b57;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
has_preview_medias = (flags & 64) != 0;
if ((flags & 1) != 0) {
user_id = stream.readInt64(exception);
}
if ((flags & 2) != 0) {
description = stream.readString(exception);
}
if ((flags & 16) != 0) {
description_photo = TLRPC.Photo.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 32) != 0) {
description_document = TLRPC.Document.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 4) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.TL_botCommand object = TLRPC.TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
commands.add(object);
}
}
if ((flags & 8) != 0) {
menu_button = BotMenuButton.TLdeserialize(stream, stream.readInt32(exception), exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = has_preview_medias ? flags | 64 : flags &~ 64;
stream.writeInt32(flags);
if ((flags & 1) != 0) {
stream.writeInt64(user_id);
}
if ((flags & 2) != 0) {
stream.writeString(description);
}
if ((flags & 16) != 0) {
description_photo.serializeToStream(stream);
}
if ((flags & 32) != 0) {
description_document.serializeToStream(stream);
}
if ((flags & 4) != 0) {
stream.writeInt32(0x1cb5c415);
int count = commands.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
commands.get(a).serializeToStream(stream);
}
}
if ((flags & 8) != 0) {
menu_button.serializeToStream(stream);
}
}
}
public static class TL_botInfo_layer140 extends TL_botInfo {
public static final int constructor = 0xe4169b5d;
public void readParams(AbstractSerializedData stream, boolean exception) {
user_id = stream.readInt64(exception);
description = stream.readString(exception);
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.TL_botCommand object = TLRPC.TL_botCommand.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
commands.add(object);
}
menu_button = BotMenuButton.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(user_id);
stream.writeString(description);
stream.writeInt32(0x1cb5c415);
int count = commands.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
commands.get(a).serializeToStream(stream);
}
menu_button.serializeToStream(stream);
}
}
public static abstract class BotMenuButton extends TLObject {
public static BotMenuButton TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
BotMenuButton result = null;
switch (constructor) {
case 0xc7b57ce6:
result = new TL_botMenuButton();
break;
case 0x7533a588:
result = new TL_botMenuButtonDefault();
break;
case 0x4258c205:
result = new TL_botMenuButtonCommands();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in BotMenuButton", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_botMenuButton extends BotMenuButton {
public static final int constructor = 0xc7b57ce6;
public String text;
public String url;
public void readParams(AbstractSerializedData stream, boolean exception) {
text = stream.readString(exception);
url = stream.readString(exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(text);
stream.writeString(url);
}
}
public static class TL_botMenuButtonDefault extends BotMenuButton {
public static final int constructor = 0x7533a588;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_botMenuButtonCommands extends BotMenuButton {
public static final int constructor = 0x4258c205;
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
}
}
public static class TL_updateBotMenuButton extends TLRPC.Update {
public static final int constructor = 0x14b85813;
public long bot_id;
public BotMenuButton button;
public void readParams(AbstractSerializedData stream, boolean exception) {
bot_id = stream.readInt64(exception);
button = BotMenuButton.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt64(bot_id);
button.serializeToStream(stream);
}
}
public static class setBotMenuButton extends TLObject {
public static final int constructor = 0x4504d54f;
public TLRPC.InputUser user_id;
public BotMenuButton button;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
user_id.serializeToStream(stream);
button.serializeToStream(stream);
}
}
public static class getBotMenuButton extends TLObject {
public static final int constructor = 0x9c60eb28;
public TLRPC.InputUser user_id;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return BotMenuButton.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
user_id.serializeToStream(stream);
}
}
public static class canSendMessage extends TLObject {
public static final int constructor = 0x1359f4e6;
public TLRPC.InputUser bot;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Bool.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
}
}
public static class allowSendMessage extends TLObject {
public static final int constructor = 0xf132e3ef;
public TLRPC.InputUser bot;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Updates.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
}
}
public static class invokeWebViewCustomMethod extends TLObject {
public static final int constructor = 0x87fc5e7;
public TLRPC.InputUser bot;
public String custom_method;
public TLRPC.TL_dataJSON params;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.TL_dataJSON.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
bot.serializeToStream(stream);
stream.writeString(custom_method);
params.serializeToStream(stream);
}
}
public static class getPopularAppBots extends TLObject {
public static final int constructor = 0xc2510192;
public String offset;
public int limit;
@Override
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return popularAppBots.TLdeserialize(stream, constructor, exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeString(offset);
stream.writeInt32(limit);
}
}
public static class popularAppBots extends TLObject {
public static final int constructor = 0x1991b13b;
public int flags;
public String next_offset;
public ArrayList<TLRPC.User> users = new ArrayList<>();
public static popularAppBots TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (popularAppBots.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_bots_popularAppBots", constructor));
} else {
return null;
}
}
popularAppBots result = new popularAppBots();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
if ((flags & 1) != 0) {
next_offset = stream.readString(exception);
}
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.User object = TLRPC.User.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
users.add(object);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
stream.writeString(next_offset);
}
stream.writeInt32(0x1cb5c415);
int count = users.size();
stream.writeInt32(count);
for (int i = 0; i < count; ++i) {
users.get(i).serializeToStream(stream);
}
}
}
}

View file

@ -3120,13 +3120,21 @@ public class TL_stories {
case TL_mediaAreaChannelPost.constructor: case TL_mediaAreaChannelPost.constructor:
result = new TL_mediaAreaChannelPost(); result = new TL_mediaAreaChannelPost();
break; break;
case TL_inputMediaAreaVenue.constructor: case TL_inputMediaAreaVenue.constructor:
result = new TL_inputMediaAreaVenue(); result = new TL_inputMediaAreaVenue();
break; break;
case TL_inputMediaAreaChannelPost.constructor: case TL_inputMediaAreaChannelPost.constructor:
result = new TL_inputMediaAreaChannelPost(); result = new TL_inputMediaAreaChannelPost();
break; break;
case TL_mediaAreaWeather.constructor:
result = new TL_mediaAreaWeather();
break;
case TL_mediaAreaWeatherOld.constructor:
result = new TL_mediaAreaWeatherOld();
break;
case TL_mediaAreaWeather2.constructor:
result = new TL_mediaAreaWeather2();
break;
} }
if (result == null && exception) { if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in MediaArea", constructor)); throw new RuntimeException(String.format("can't parse magic %x in MediaArea", constructor));
@ -3233,6 +3241,83 @@ public class TL_stories {
} }
} }
public static class TL_mediaAreaWeather2 extends MediaArea {
public static final int constructor = 0x855f223e;
public String emoji;
public int temperature_c;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
dark = (flags & 1) != 0;
coordinates = MediaAreaCoordinates.TLdeserialize(stream, stream.readInt32(exception), exception);
emoji = stream.readString(exception);
temperature_c = stream.readInt32(exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = dark ? flags | 1 : flags &~ 1;
stream.writeInt32(flags);
coordinates.serializeToStream(stream);
stream.writeString(emoji);
stream.writeInt32(temperature_c);
}
}
public static class TL_mediaAreaWeather extends MediaArea {
public static final int constructor = 0x49a6549c;
public String emoji;
public double temperature_c;
public int color;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
coordinates = MediaAreaCoordinates.TLdeserialize(stream, stream.readInt32(exception), exception);
emoji = stream.readString(exception);
temperature_c = stream.readDouble(exception);
color = stream.readInt32(exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
coordinates.serializeToStream(stream);
stream.writeString(emoji);
stream.writeDouble(temperature_c);
stream.writeInt32(color);
}
}
public static class TL_mediaAreaWeatherOld extends MediaArea {
public static final int constructor = 0x4386f849;
public String emoji;
public double temperature_c;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
dark = (flags & 1) != 0;
coordinates = MediaAreaCoordinates.TLdeserialize(stream, stream.readInt32(exception), exception);
emoji = stream.readString(exception);
temperature_c = stream.readDouble(exception);
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = dark ? flags | 1 : flags &~ 1;
stream.writeInt32(flags);
coordinates.serializeToStream(stream);
stream.writeString(emoji);
stream.writeDouble(temperature_c);
}
}
public static class TL_inputMediaAreaVenue extends MediaArea { public static class TL_inputMediaAreaVenue extends MediaArea {
public static final int constructor = 0xb282217f; public static final int constructor = 0xb282217f;

View file

@ -27,6 +27,8 @@ import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.RenderEffect;
import android.graphics.RuntimeShader;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
@ -61,6 +63,9 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.BackButtonMenu; import org.telegram.ui.Components.BackButtonMenu;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.EmptyBaseFragment;
import org.telegram.ui.Stars.SuperRipple;
import org.telegram.ui.bots.BotWebViewSheet; import org.telegram.ui.bots.BotWebViewSheet;
import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.ChatAttachAlert; import org.telegram.ui.Components.ChatAttachAlert;
@ -118,7 +123,12 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
if (!fragmentsStack.isEmpty()) { if (!fragmentsStack.isEmpty()) {
lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
} }
if (storyViewerAttached() && lastFragment != null && lastFragment.getLastSheet() != null && lastFragment.getLastSheet().isFullyVisible() && lastFragment.getLastSheet().getWindowView() != child) { if (sheetFragment != null && sheetFragment.sheetsStack != null && !sheetFragment.sheetsStack.isEmpty()) {
lastFragment = sheetFragment;
}
BaseFragment.AttachedSheet lastSheet = null;
if (lastFragment != null) lastSheet = lastFragment.getLastSheet();
if (lastSheet != null && lastSheet.isFullyVisible() && lastSheet.getWindowView() != child) {
return true; return true;
} }
if (child instanceof ActionBar) { if (child instanceof ActionBar) {
@ -367,6 +377,11 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
} }
} }
@Override
public boolean allowSwipe() {
return (sheetFragment == null || sheetFragment.getLastSheet() == null || !sheetFragment.getLastSheet().isShown());
}
private static Drawable headerShadowDrawable; private static Drawable headerShadowDrawable;
private static Drawable layerShadowDrawable; private static Drawable layerShadowDrawable;
private static Paint scrimPaint; private static Paint scrimPaint;
@ -381,11 +396,36 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
private ColorDrawable previewBackgroundDrawable; private ColorDrawable previewBackgroundDrawable;
public LayoutContainer containerView; public LayoutContainer containerView;
private LayoutContainer containerViewBack; public LayoutContainer containerViewBack;
public LayoutContainer sheetContainer;
private DrawerLayoutContainer drawerLayoutContainer; private DrawerLayoutContainer drawerLayoutContainer;
private ActionBar currentActionBar; private ActionBar currentActionBar;
private BottomSheetTabs bottomSheetTabs; private BottomSheetTabs bottomSheetTabs;
private EmptyBaseFragment sheetFragment;
public EmptyBaseFragment getSheetFragment() {
return getSheetFragment(true);
}
public EmptyBaseFragment getSheetFragment(boolean create) {
if (parentActivity == null)
return null;
if (sheetFragment == null) {
sheetFragment = new EmptyBaseFragment();
sheetFragment.setParentLayout(this);
View fragmentView = sheetFragment.fragmentView;
if (fragmentView == null) {
fragmentView = sheetFragment.createView(parentActivity);
}
if (fragmentView.getParent() != sheetContainer) {
AndroidUtilities.removeFromParent(fragmentView);
sheetContainer.addView(fragmentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
sheetFragment.onResume();
sheetFragment.onBecomeFullyVisible();
}
return sheetFragment;
}
private BaseFragment newFragment; private BaseFragment newFragment;
private BaseFragment oldFragment; private BaseFragment oldFragment;
@ -476,7 +516,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
public void setFragmentStack(List<BaseFragment> stack) { public void setFragmentStack(List<BaseFragment> stack) {
this.fragmentsStack = stack; this.fragmentsStack = stack;
FrameLayout.LayoutParams layoutParams; LayoutParams layoutParams;
if (main) { if (main) {
if (bottomSheetTabs != null) { if (bottomSheetTabs != null) {
AndroidUtilities.removeFromParent(bottomSheetTabs); AndroidUtilities.removeFromParent(bottomSheetTabs);
@ -484,7 +524,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
} }
bottomSheetTabs = new BottomSheetTabs(parentActivity, this); bottomSheetTabs = new BottomSheetTabs(parentActivity, this);
layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp(68 + 8)); layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp(68 + 8));
layoutParams.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL; layoutParams.gravity = Gravity.BOTTOM | Gravity.FILL_HORIZONTAL;
addView(bottomSheetTabs, layoutParams); addView(bottomSheetTabs, layoutParams);
@ -493,22 +533,40 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
} }
} }
if (containerViewBack != null) {
AndroidUtilities.removeFromParent(containerViewBack);
}
this.containerViewBack = new LayoutContainer(parentActivity); this.containerViewBack = new LayoutContainer(parentActivity);
addView(containerViewBack); addView(containerViewBack);
layoutParams = (FrameLayout.LayoutParams) containerViewBack.getLayoutParams(); layoutParams = (LayoutParams) containerViewBack.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT; layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT; layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT; layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
containerViewBack.setLayoutParams(layoutParams); containerViewBack.setLayoutParams(layoutParams);
if (containerView != null) {
AndroidUtilities.removeFromParent(containerView);
}
containerView = new LayoutContainer(parentActivity); containerView = new LayoutContainer(parentActivity);
addView(containerView); addView(containerView);
layoutParams = (FrameLayout.LayoutParams) containerView.getLayoutParams(); layoutParams = (LayoutParams) containerView.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT; layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT; layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT; layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
containerView.setLayoutParams(layoutParams); containerView.setLayoutParams(layoutParams);
if (sheetContainer != null) {
AndroidUtilities.removeFromParent(sheetContainer);
}
sheetContainer = new LayoutContainer(parentActivity);
addView(sheetContainer);
layoutParams = (LayoutParams) sheetContainer.getLayoutParams();
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
sheetContainer.setLayoutParams(layoutParams);
for (BaseFragment fragment : fragmentsStack) { for (BaseFragment fragment : fragmentsStack) {
fragment.setParentLayout(this); fragment.setParentLayout(this);
} }
@ -728,6 +786,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onResume(); lastFragment.onResume();
} }
if (sheetFragment != null) {
sheetFragment.onResume();
}
} }
@Override @Override
@ -736,6 +797,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onUserLeaveHint(); lastFragment.onUserLeaveHint();
} }
if (sheetFragment != null) {
sheetFragment.onUserLeaveHint();
}
} }
@Override @Override
@ -744,6 +808,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
lastFragment.onPause(); lastFragment.onPause();
} }
if (sheetFragment != null) {
sheetFragment.onPause();
}
} }
@Override @Override
@ -951,6 +1018,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
containerView = containerViewBack; containerView = containerViewBack;
containerViewBack = temp; containerViewBack = temp;
bringChildToFront(containerView); bringChildToFront(containerView);
if (sheetContainer != null) {
bringChildToFront(sheetContainer);
}
lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
currentActionBar = lastFragment.actionBar; currentActionBar = lastFragment.actionBar;
@ -1041,7 +1111,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
@Override @Override
public boolean onTouchEvent(MotionEvent ev) { public boolean onTouchEvent(MotionEvent ev) {
if (!checkTransitionAnimation() && !inActionMode && !animationInProgress) { if (!checkTransitionAnimation() && !inActionMode && !animationInProgress) {
if (fragmentsStack.size() > 1) { if (fragmentsStack.size() > 1 && allowSwipe()) {
if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) { if (ev != null && ev.getAction() == MotionEvent.ACTION_DOWN) {
BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1); BaseFragment currentFragment = fragmentsStack.get(fragmentsStack.size() - 1);
if (!currentFragment.isSwipeBackEnabled(ev)) { if (!currentFragment.isSwipeBackEnabled(ev)) {
@ -1189,6 +1259,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
currentActionBar.closeSearchField(); currentActionBar.closeSearchField();
return; return;
} }
if (sheetFragment != null && !sheetFragment.onBackPressed()) {
return;
}
BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1); BaseFragment lastFragment = fragmentsStack.get(fragmentsStack.size() - 1);
if (lastFragment.onBackPressed()) { if (lastFragment.onBackPressed()) {
if (!fragmentsStack.isEmpty()) { if (!fragmentsStack.isEmpty()) {
@ -1340,7 +1413,18 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
Integer newNavigationBarColor = newFragment != null ? newFragment.getNavigationBarColor() : null; Integer newNavigationBarColor = newFragment != null ? newFragment.getNavigationBarColor() : null;
if (newFragment != null && oldNavigationBarColor != null) { if (newFragment != null && oldNavigationBarColor != null) {
float ratio = MathUtils.clamp(4f * animationProgress, 0f, 1f); float ratio = MathUtils.clamp(4f * animationProgress, 0f, 1f);
newFragment.setNavigationBarColor(ColorUtils.blendARGB(oldNavigationBarColor, newNavigationBarColor, ratio)); int color = ColorUtils.blendARGB(oldNavigationBarColor, newNavigationBarColor, ratio);
if (sheetFragment != null) {
if (sheetFragment.sheetsStack != null) {
for (int i = 0; i < sheetFragment.sheetsStack.size(); ++i) {
BaseFragment.AttachedSheet sheet = sheetFragment.sheetsStack.get(i);
if (sheet.attachedToParent()) {
color = sheet.getNavigationBarColor(color);
}
}
}
}
newFragment.setNavigationBarColor(color);
} }
float interpolated; float interpolated;
if (preview) { if (preview) {
@ -1564,6 +1648,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
} }
bringChildToFront(containerView); bringChildToFront(containerView);
if (sheetContainer != null) {
bringChildToFront(sheetContainer);
}
if (!needAnimation) { if (!needAnimation) {
presentFragmentInternalRemoveOld(removeLast, currentFragment); presentFragmentInternalRemoveOld(removeLast, currentFragment);
if (backgroundView != null) { if (backgroundView != null) {
@ -1884,6 +1971,9 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
containerViewBack.setVisibility(View.INVISIBLE); containerViewBack.setVisibility(View.INVISIBLE);
containerViewBack.setTranslationY(0); containerViewBack.setTranslationY(0);
bringChildToFront(containerView); bringChildToFront(containerView);
if (sheetContainer != null) {
bringChildToFront(sheetContainer);
}
onFragmentStackChanged("closeLastFragmentInternalRemoveOld"); onFragmentStackChanged("closeLastFragmentInternalRemoveOld");
} }
@ -2817,11 +2907,17 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
@Override @Override
public boolean dispatchTouchEvent(MotionEvent ev) { public boolean dispatchTouchEvent(MotionEvent ev) {
final boolean tabs = ev.getY() > getHeight() - getBottomTabsHeight(true); final boolean tabs = ev.getY() > getHeight() - getBottomTabsHeight(true);
if (
getLastFragment() != null && BaseFragment.AttachedSheet lastSheet = null;
getLastFragment().getLastSheet() != null && if (lastSheet == null && sheetFragment != null && sheetFragment.getLastSheet() != null) {
getLastFragment().getLastSheet().attachedToParent() lastSheet = sheetFragment.getLastSheet();
) { if (!lastSheet.attachedToParent() || lastSheet.getWindowView() == null) lastSheet = null;
}
if (lastSheet == null && getLastFragment() != null && getLastFragment().getLastSheet() != null) {
lastSheet = getLastFragment().getLastSheet();
if (!lastSheet.attachedToParent() || lastSheet.getWindowView() == null) lastSheet = null;
}
if (lastSheet != null) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) { if (ev.getAction() == MotionEvent.ACTION_DOWN) {
tabsEvents = tabs; tabsEvents = tabs;
} }
@ -2829,7 +2925,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) { if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
tabsEvents = false; tabsEvents = false;
} }
return getLastFragment().getLastSheet().getWindowView().dispatchTouchEvent(ev); return lastSheet.getWindowView().dispatchTouchEvent(ev);
} }
} }
if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) { if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
@ -2885,6 +2981,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
requestLayout(); requestLayout();
containerView.requestLayout(); containerView.requestLayout();
containerViewBack.requestLayout(); containerViewBack.requestLayout();
sheetContainer.requestLayout();
if (animated) { if (animated) {
bottomTabsAnimator = ValueAnimator.ofFloat(bottomTabsProgress, bottomTabsHeight); bottomTabsAnimator = ValueAnimator.ofFloat(bottomTabsProgress, bottomTabsHeight);
bottomTabsAnimator.addUpdateListener(anm -> { bottomTabsAnimator.addUpdateListener(anm -> {

View file

@ -25,7 +25,7 @@ import org.telegram.ui.Components.RLottieImageView;
public class ActionBarMenuSubItem extends FrameLayout { public class ActionBarMenuSubItem extends FrameLayout {
private TextView textView; private TextView textView;
private TextView subtextView; public TextView subtextView;
public RLottieImageView imageView; public RLottieImageView imageView;
private boolean checkViewLeft; private boolean checkViewLeft;
private CheckBox2 checkView; private CheckBox2 checkView;
@ -237,7 +237,9 @@ public class ActionBarMenuSubItem extends FrameLayout {
} }
public void setSubtextColor(int color) { public void setSubtextColor(int color) {
subtextView.setTextColor(color); if (subtextView != null) {
subtextView.setTextColor(color);
}
} }
public void setSubtext(String text) { public void setSubtext(String text) {

View file

@ -298,6 +298,7 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
@Override @Override
public void show() { public void show() {
if (!AndroidUtilities.isSafeToShow(getContext())) return; if (!AndroidUtilities.isSafeToShow(getContext())) return;
dismissed = false;
super.show(); super.show();
if (progressViewContainer != null && progressViewStyle == ALERT_TYPE_SPINNER) { if (progressViewContainer != null && progressViewStyle == ALERT_TYPE_SPINNER) {
progressViewContainer.setScaleX(0); progressViewContainer.setScaleX(0);
@ -311,275 +312,285 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
shownAt = System.currentTimeMillis(); shownAt = System.currentTimeMillis();
} }
protected View inflateContent(boolean setContent) { public class AlertDialogView extends LinearLayout {
LinearLayout containerView = new LinearLayout(getContext()) { public AlertDialogView(Context context) {
super(context);
}
private boolean inLayout; private boolean inLayout;
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (progressViewStyle == ALERT_TYPE_SPINNER) { if (progressViewStyle == ALERT_TYPE_SPINNER) {
showCancelAlert(); showCancelAlert();
return false;
}
return super.onTouchEvent(event);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
showCancelAlert();
return false;
}
return super.onInterceptTouchEvent(ev);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
progressViewContainer.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY));
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
} else {
inLayout = true;
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (customWidth > 0) {
width = customWidth + backgroundPaddings.left + backgroundPaddings.right;
}
int maxContentHeight;
int availableHeight = maxContentHeight = height - getPaddingTop() - getPaddingBottom();
int availableWidth = width - getPaddingLeft() - getPaddingRight();
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(availableWidth - AndroidUtilities.dp(48), MeasureSpec.EXACTLY);
int childFullWidthMeasureSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY);
LayoutParams layoutParams;
if (buttonsLayout != null) {
int count = buttonsLayout.getChildCount();
for (int a = 0; a < count; a++) {
View child = buttonsLayout.getChildAt(a);
if (child instanceof TextView) {
TextView button = (TextView) child;
button.setMaxWidth(AndroidUtilities.dp((availableWidth - AndroidUtilities.dp(24)) / 2));
}
}
buttonsLayout.measure(childFullWidthMeasureSpec, heightMeasureSpec);
layoutParams = (LayoutParams) buttonsLayout.getLayoutParams();
availableHeight -= buttonsLayout.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (secondTitleTextView != null) {
secondTitleTextView.measure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(childWidthMeasureSpec), MeasureSpec.AT_MOST), heightMeasureSpec);
}
if (titleTextView != null) {
if (secondTitleTextView != null) {
titleTextView.measure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(childWidthMeasureSpec) - secondTitleTextView.getMeasuredWidth() - AndroidUtilities.dp(8), MeasureSpec.EXACTLY), heightMeasureSpec);
} else {
titleTextView.measure(childWidthMeasureSpec, heightMeasureSpec);
}
}
if (titleContainer != null) {
titleContainer.measure(childWidthMeasureSpec, heightMeasureSpec);
layoutParams = (LayoutParams) titleContainer.getLayoutParams();
availableHeight -= titleContainer.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (subtitleTextView != null) {
subtitleTextView.measure(childWidthMeasureSpec, heightMeasureSpec);
layoutParams = (LayoutParams) subtitleTextView.getLayoutParams();
availableHeight -= subtitleTextView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (topImageView != null) {
topImageView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(topHeight), MeasureSpec.EXACTLY));
availableHeight -= topImageView.getMeasuredHeight();
}
if (topView != null) {
int w = width;
int h;
if (aspectRatio == 0) {
float scale = w / 936.0f;
h = (int) (354 * scale);
} else {
h = (int) (w * aspectRatio);
}
topView.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
topView.getLayoutParams().height = h;
availableHeight -= topView.getMeasuredHeight();
}
if (progressViewStyle == ALERT_TYPE_MESSAGE) {
layoutParams = (LayoutParams) contentScrollView.getLayoutParams();
if (customView != null) {
layoutParams.topMargin = titleTextView == null && messageTextView.getVisibility() == GONE && items == null ? AndroidUtilities.dp(16) : 0;
layoutParams.bottomMargin = buttonsLayout == null ? AndroidUtilities.dp(8) : 0;
} else if (items != null) {
layoutParams.topMargin = titleTextView == null && messageTextView.getVisibility() == GONE ? AndroidUtilities.dp(8) : 0;
layoutParams.bottomMargin = AndroidUtilities.dp(8);
} else if (messageTextView.getVisibility() == VISIBLE) {
layoutParams.topMargin = titleTextView == null ? AndroidUtilities.dp(19) : 0;
layoutParams.bottomMargin = AndroidUtilities.dp(20);
}
availableHeight -= layoutParams.bottomMargin + layoutParams.topMargin;
contentScrollView.measure(childFullWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
availableHeight -= contentScrollView.getMeasuredHeight();
} else {
if (progressViewContainer != null) {
progressViewContainer.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
layoutParams = (LayoutParams) progressViewContainer.getLayoutParams();
availableHeight -= progressViewContainer.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
} else if (messageTextView != null) {
messageTextView.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
if (messageTextView.getVisibility() != GONE) {
layoutParams = (LayoutParams) messageTextView.getLayoutParams();
availableHeight -= messageTextView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
}
if (lineProgressView != null) {
lineProgressView.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(4), MeasureSpec.EXACTLY));
layoutParams = (LayoutParams) lineProgressView.getLayoutParams();
availableHeight -= lineProgressView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
lineProgressViewPercent.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
layoutParams = (LayoutParams) lineProgressViewPercent.getLayoutParams();
availableHeight -= lineProgressViewPercent.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
}
setMeasuredDimension(width, maxContentHeight - availableHeight + getPaddingTop() + getPaddingBottom() - (topAnimationIsNew ? AndroidUtilities.dp(8) : 0));
inLayout = false;
if (lastScreenWidth != AndroidUtilities.displaySize.x) {
AndroidUtilities.runOnUIThread(() -> {
lastScreenWidth = AndroidUtilities.displaySize.x;
final int calculatedWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(56);
int maxWidth;
if (AndroidUtilities.isTablet()) {
if (AndroidUtilities.isSmallTablet()) {
maxWidth = AndroidUtilities.dp(446);
} else {
maxWidth = AndroidUtilities.dp(496);
}
} else {
maxWidth = AndroidUtilities.dp(356);
}
Window window = getWindow();
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.copyFrom(window.getAttributes());
params.width = Math.min(maxWidth, calculatedWidth) + backgroundPaddings.left + backgroundPaddings.right;
try {
window.setAttributes(params);
} catch (Throwable e) {
FileLog.e(e);
}
});
}
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (progressViewStyle == ALERT_TYPE_SPINNER) {
int x = (r - l - progressViewContainer.getMeasuredWidth()) / 2;
int y = (b - t - progressViewContainer.getMeasuredHeight()) / 2;
progressViewContainer.layout(x, y, x + progressViewContainer.getMeasuredWidth(), y + progressViewContainer.getMeasuredHeight());
} else if (contentScrollView != null) {
if (onScrollChangedListener == null) {
onScrollChangedListener = () -> {
runShadowAnimation(0, titleTextView != null && contentScrollView.getScrollY() > scrollContainer.getTop());
runShadowAnimation(1, buttonsLayout != null && contentScrollView.getScrollY() + contentScrollView.getHeight() < scrollContainer.getBottom());
contentScrollView.invalidate();
};
contentScrollView.getViewTreeObserver().addOnScrollChangedListener(onScrollChangedListener);
}
onScrollChangedListener.onScrollChanged();
}
getLocationOnScreen(containerViewLocation);
if (blurMatrix != null && blurShader != null) {
blurMatrix.reset();
blurMatrix.postScale(8f, 8f);
blurMatrix.postTranslate(-containerViewLocation[0], -containerViewLocation[1]);
blurShader.setLocalMatrix(blurMatrix);
}
}
@Override
public void requestLayout() {
if (inLayout) {
return;
}
super.requestLayout();
}
@Override
public boolean hasOverlappingRendering() {
return false; return false;
} }
return super.onTouchEvent(event);
}
private AnimatedFloat blurPaintAlpha = new AnimatedFloat(0, this); @Override
private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public boolean onInterceptTouchEvent(MotionEvent ev) {
if (progressViewStyle == ALERT_TYPE_SPINNER) {
showCancelAlert();
return false;
}
return super.onInterceptTouchEvent(ev);
}
@Override @Override
public void draw(Canvas canvas) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (blurredBackground && !blurredNativeBackground) { if (progressViewStyle == ALERT_TYPE_SPINNER) {
float r; progressViewContainer.measure(MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(86), MeasureSpec.EXACTLY));
if (progressViewStyle == ALERT_TYPE_SPINNER && progressViewContainer != null) { setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
r = AndroidUtilities.dp(18); } else {
float w = progressViewContainer.getWidth() * progressViewContainer.getScaleX(); inLayout = true;
float h = progressViewContainer.getHeight() * progressViewContainer.getScaleY(); int width = MeasureSpec.getSize(widthMeasureSpec);
AndroidUtilities.rectTmp.set( int height = MeasureSpec.getSize(heightMeasureSpec);
if (customWidth > 0) {
width = customWidth + backgroundPaddings.left + backgroundPaddings.right;
}
int maxContentHeight;
int availableHeight = maxContentHeight = height - getPaddingTop() - getPaddingBottom();
int availableWidth = width - getPaddingLeft() - getPaddingRight();
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(availableWidth - AndroidUtilities.dp(48), MeasureSpec.EXACTLY);
int childFullWidthMeasureSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY);
LayoutParams layoutParams;
if (buttonsLayout != null) {
int count = buttonsLayout.getChildCount();
for (int a = 0; a < count; a++) {
View child = buttonsLayout.getChildAt(a);
if (child instanceof TextView) {
TextView button = (TextView) child;
button.setMaxWidth(AndroidUtilities.dp((availableWidth - AndroidUtilities.dp(24)) / 2));
}
}
buttonsLayout.measure(childFullWidthMeasureSpec, heightMeasureSpec);
layoutParams = (LayoutParams) buttonsLayout.getLayoutParams();
availableHeight -= buttonsLayout.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (secondTitleTextView != null) {
secondTitleTextView.measure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(childWidthMeasureSpec), MeasureSpec.AT_MOST), heightMeasureSpec);
}
if (titleTextView != null) {
if (secondTitleTextView != null) {
titleTextView.measure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(childWidthMeasureSpec) - secondTitleTextView.getMeasuredWidth() - AndroidUtilities.dp(8), MeasureSpec.EXACTLY), heightMeasureSpec);
} else {
titleTextView.measure(childWidthMeasureSpec, heightMeasureSpec);
}
}
if (titleContainer != null) {
titleContainer.measure(childWidthMeasureSpec, heightMeasureSpec);
layoutParams = (LayoutParams) titleContainer.getLayoutParams();
availableHeight -= titleContainer.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (subtitleTextView != null) {
subtitleTextView.measure(childWidthMeasureSpec, heightMeasureSpec);
layoutParams = (LayoutParams) subtitleTextView.getLayoutParams();
availableHeight -= subtitleTextView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
if (topImageView != null) {
topImageView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(topHeight), MeasureSpec.EXACTLY));
availableHeight -= topImageView.getMeasuredHeight();
}
if (topView != null) {
int w = width;
int h;
if (aspectRatio == 0) {
float scale = w / 936.0f;
h = (int) (354 * scale);
} else {
h = (int) (w * aspectRatio);
}
topView.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
topView.getLayoutParams().height = h;
availableHeight -= topView.getMeasuredHeight();
}
if (progressViewStyle == ALERT_TYPE_MESSAGE) {
layoutParams = (LayoutParams) contentScrollView.getLayoutParams();
if (customView != null) {
layoutParams.topMargin = titleTextView == null && messageTextView.getVisibility() == GONE && items == null ? AndroidUtilities.dp(16) : 0;
layoutParams.bottomMargin = buttonsLayout == null ? AndroidUtilities.dp(8) : 0;
} else if (items != null) {
layoutParams.topMargin = titleTextView == null && messageTextView.getVisibility() == GONE ? AndroidUtilities.dp(8) : 0;
layoutParams.bottomMargin = AndroidUtilities.dp(8);
} else if (messageTextView.getVisibility() == VISIBLE) {
layoutParams.topMargin = titleTextView == null ? AndroidUtilities.dp(19) : 0;
layoutParams.bottomMargin = AndroidUtilities.dp(20);
}
availableHeight -= layoutParams.bottomMargin + layoutParams.topMargin;
contentScrollView.measure(childFullWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
availableHeight -= contentScrollView.getMeasuredHeight();
} else {
if (progressViewContainer != null) {
progressViewContainer.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
layoutParams = (LayoutParams) progressViewContainer.getLayoutParams();
availableHeight -= progressViewContainer.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
} else if (messageTextView != null) {
messageTextView.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
if (messageTextView.getVisibility() != GONE) {
layoutParams = (LayoutParams) messageTextView.getLayoutParams();
availableHeight -= messageTextView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
}
if (lineProgressView != null) {
lineProgressView.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(4), MeasureSpec.EXACTLY));
layoutParams = (LayoutParams) lineProgressView.getLayoutParams();
availableHeight -= lineProgressView.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
lineProgressViewPercent.measure(childWidthMeasureSpec, MeasureSpec.makeMeasureSpec(availableHeight, MeasureSpec.AT_MOST));
layoutParams = (LayoutParams) lineProgressViewPercent.getLayoutParams();
availableHeight -= lineProgressViewPercent.getMeasuredHeight() + layoutParams.bottomMargin + layoutParams.topMargin;
}
}
setMeasuredDimension(width, maxContentHeight - availableHeight + getPaddingTop() + getPaddingBottom() - (topAnimationIsNew ? AndroidUtilities.dp(8) : 0));
inLayout = false;
if (lastScreenWidth != AndroidUtilities.displaySize.x) {
AndroidUtilities.runOnUIThread(() -> {
lastScreenWidth = AndroidUtilities.displaySize.x;
final int calculatedWidth = AndroidUtilities.displaySize.x - AndroidUtilities.dp(56);
int maxWidth;
if (AndroidUtilities.isTablet()) {
if (AndroidUtilities.isSmallTablet()) {
maxWidth = AndroidUtilities.dp(446);
} else {
maxWidth = AndroidUtilities.dp(496);
}
} else {
maxWidth = AndroidUtilities.dp(356);
}
Window window = getWindow();
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.copyFrom(window.getAttributes());
params.width = Math.min(maxWidth, calculatedWidth) + backgroundPaddings.left + backgroundPaddings.right;
try {
window.setAttributes(params);
} catch (Throwable e) {
FileLog.e(e);
}
});
}
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
if (progressViewStyle == ALERT_TYPE_SPINNER) {
int x = (r - l - progressViewContainer.getMeasuredWidth()) / 2;
int y = (b - t - progressViewContainer.getMeasuredHeight()) / 2;
progressViewContainer.layout(x, y, x + progressViewContainer.getMeasuredWidth(), y + progressViewContainer.getMeasuredHeight());
} else if (contentScrollView != null) {
if (onScrollChangedListener == null) {
onScrollChangedListener = () -> {
runShadowAnimation(0, titleTextView != null && contentScrollView.getScrollY() > scrollContainer.getTop());
runShadowAnimation(1, buttonsLayout != null && contentScrollView.getScrollY() + contentScrollView.getHeight() < scrollContainer.getBottom());
contentScrollView.invalidate();
};
contentScrollView.getViewTreeObserver().addOnScrollChangedListener(onScrollChangedListener);
}
onScrollChangedListener.onScrollChanged();
}
getLocationOnScreen(containerViewLocation);
if (blurMatrix != null && blurShader != null) {
blurMatrix.reset();
blurMatrix.postScale(8f, 8f);
blurMatrix.postTranslate(-containerViewLocation[0], -containerViewLocation[1]);
blurShader.setLocalMatrix(blurMatrix);
}
}
@Override
public void requestLayout() {
if (inLayout) {
return;
}
super.requestLayout();
}
@Override
public boolean hasOverlappingRendering() {
return false;
}
private AnimatedFloat blurPaintAlpha = new AnimatedFloat(0, this);
private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@Override
public void draw(Canvas canvas) {
if (blurredBackground && !blurredNativeBackground) {
float r;
if (progressViewStyle == ALERT_TYPE_SPINNER && progressViewContainer != null) {
r = AndroidUtilities.dp(18);
float w = progressViewContainer.getWidth() * progressViewContainer.getScaleX();
float h = progressViewContainer.getHeight() * progressViewContainer.getScaleY();
AndroidUtilities.rectTmp.set(
(getWidth() - w) / 2f, (getWidth() - w) / 2f,
(getHeight() - h) / 2f, (getHeight() - h) / 2f,
(getWidth() + w) / 2f, (getWidth() + w) / 2f,
(getHeight() + h) / 2f (getHeight() + h) / 2f
); );
} else { } else {
r = AndroidUtilities.dp(10); r = AndroidUtilities.dp(10);
AndroidUtilities.rectTmp.set(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getMeasuredHeight() - getPaddingBottom()); AndroidUtilities.rectTmp.set(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getMeasuredHeight() - getPaddingBottom());
}
// draw blur of background
float blurAlpha = blurPaintAlpha.set(blurPaint != null ? 1f : 0f);
if (blurPaint != null) {
blurPaint.setAlpha((int) (0xFF * blurAlpha));
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, blurPaint);
}
// draw dim above blur
if (dimBlurPaint == null) {
dimBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dimBlurPaint.setColor(ColorUtils.setAlphaComponent(0xff000000, (int) (0xFF * dimAlpha)));
}
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, dimBlurPaint);
// draw background
backgroundPaint.setColor(backgroundColor);
backgroundPaint.setAlpha((int) (backgroundPaint.getAlpha() * (blurAlpha * (blurOpacity - 1f) + 1f)));
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, backgroundPaint);
} }
super.draw(canvas);
}
@Override // draw blur of background
protected void dispatchDraw(Canvas canvas) { float blurAlpha = blurPaintAlpha.set(blurPaint != null ? 1f : 0f);
if (drawBackground && !blurredBackground) { if (blurPaint != null) {
shadowDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight()); blurPaint.setAlpha((int) (0xFF * blurAlpha));
if (topView != null && notDrawBackgroundOnTopView) { canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, blurPaint);
int clipTop = topView.getBottom();
canvas.save();
canvas.clipRect(0, clipTop, getMeasuredWidth(), getMeasuredHeight());
shadowDrawable.draw(canvas);
canvas.restore();
} else {
shadowDrawable.draw(canvas);
}
} }
super.dispatchDraw(canvas);
// draw dim above blur
if (dimBlurPaint == null) {
dimBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dimBlurPaint.setColor(ColorUtils.setAlphaComponent(0xff000000, (int) (0xFF * dimAlpha)));
}
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, dimBlurPaint);
// draw background
backgroundPaint.setColor(backgroundColor);
backgroundPaint.setAlpha((int) (backgroundPaint.getAlpha() * (blurAlpha * (blurOpacity - 1f) + 1f)));
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, backgroundPaint);
} }
}; super.draw(canvas);
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (drawBackground && !blurredBackground) {
shadowDrawable.setBounds(0, 0, getMeasuredWidth(), getMeasuredHeight());
if (topView != null && notDrawBackgroundOnTopView) {
int clipTop = topView.getBottom();
canvas.save();
canvas.clipRect(0, clipTop, getMeasuredWidth(), getMeasuredHeight());
shadowDrawable.draw(canvas);
canvas.restore();
} else {
shadowDrawable.draw(canvas);
}
}
super.dispatchDraw(canvas);
}
}
private AlertDialogView containerView;
public AlertDialogView getContainerView() {
return containerView;
}
protected View inflateContent(boolean setContent) {
containerView = new AlertDialogView(getContext());
containerView.setOrientation(LinearLayout.VERTICAL); containerView.setOrientation(LinearLayout.VERTICAL);
if ((blurredBackground || progressViewStyle == ALERT_TYPE_SPINNER) && progressViewStyle != ALERT_TYPE_LOADING) { if ((blurredBackground || progressViewStyle == ALERT_TYPE_SPINNER) && progressViewStyle != ALERT_TYPE_LOADING) {
containerView.setBackgroundDrawable(null); containerView.setBackgroundDrawable(null);
@ -1320,6 +1331,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
} }
} }
private boolean dismissed;
public boolean isDismissed() {
return dismissed;
}
@Override @Override
public void dismiss() { public void dismiss() {
if (overridenDissmissListener != null) { if (overridenDissmissListener != null) {
@ -1328,6 +1344,8 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
listener.run(this::dismiss); listener.run(this::dismiss);
return; return;
} }
if (dismissed) return;
dismissed = true;
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded); NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.emojiLoaded);
if (onDismissListener != null) { if (onDismissListener != null) {
onDismissListener.onDismiss(this); onDismissListener.onDismiss(this);
@ -1681,8 +1699,24 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
return alertDialog; return alertDialog;
} }
private final boolean[] red = new boolean[3];
public Builder makeRed(int button) {
int index = (-button) - 1;
if (index >= 0 && index < red.length) {
red[index] = true;
}
return this;
}
public AlertDialog show() { public AlertDialog show() {
alertDialog.show(); alertDialog.show();
for (int i = 0; i < red.length; i++) {
if (!red[i]) continue;
TextView button = (TextView) alertDialog.getButton(-(i + 1));
if (button != null) {
button.setTextColor(alertDialog.getThemedColor(Theme.key_text_RedBold));
}
}
return alertDialog; return alertDialog;
} }

View file

@ -39,6 +39,10 @@ public class BackDrawable extends Drawable {
private boolean rotated = true; private boolean rotated = true;
private int arrowRotation; private int arrowRotation;
public float getRotation() {
return finalRotation;
}
public BackDrawable(boolean close) { public BackDrawable(boolean close) {
super(); super();
paint.setStrokeWidth(AndroidUtilities.dp(2)); paint.setStrokeWidth(AndroidUtilities.dp(2));

View file

@ -53,6 +53,7 @@ import org.telegram.messenger.SecretChatHelper;
import org.telegram.messenger.SendMessagesHelper; import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.ui.ArticleViewer;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.Stories.StoryViewer; import org.telegram.ui.Stories.StoryViewer;
@ -83,6 +84,7 @@ public abstract class BaseFragment {
private boolean removingFromStack; private boolean removingFromStack;
private PreviewDelegate previewDelegate; private PreviewDelegate previewDelegate;
protected Theme.ResourcesProvider resourceProvider; protected Theme.ResourcesProvider resourceProvider;
private boolean isFullyVisible;
// public ArrayList<StoryViewer> storyViewerStack; // public ArrayList<StoryViewer> storyViewerStack;
// public ArrayList<BotWebViewAttachedSheet> botsStack; // public ArrayList<BotWebViewAttachedSheet> botsStack;
// //
@ -99,14 +101,17 @@ public abstract class BaseFragment {
public boolean attachedToParent(); public boolean attachedToParent();
public boolean onBackPressed(); public boolean onAttachedBackPressed();
public boolean showDialog(Dialog dialog); public boolean showDialog(Dialog dialog);
public void setKeyboardHeightFromParent(int keyboardHeight); public void setKeyboardHeightFromParent(int keyboardHeight);
public boolean isAttachedLightStatusBar();
public int getNavigationBarColor(int color); public int getNavigationBarColor(int color);
public void setOnDismissListener(Runnable onDismiss); public void setOnDismissListener(Runnable onDismiss);
default void setLastVisible(boolean lastVisible) {};
} }
public static interface AttachedSheetWindow {} public static interface AttachedSheetWindow {}
@ -142,6 +147,24 @@ public abstract class BaseFragment {
return sheetsStack != null && !sheetsStack.isEmpty(); return sheetsStack != null && !sheetsStack.isEmpty();
} }
public boolean hasShownSheet() {
if (!hasSheet()) return false;
for (int i = sheetsStack.size() - 1; i >= 0; --i) {
if (sheetsStack.get(i).isShown()) {
return true;
}
}
return false;
}
public static boolean hasSheets(BaseFragment fragment) {
if (fragment == null) return false;
if (fragment.hasShownSheet()) return true;
if (!(fragment.getParentLayout() instanceof ActionBarLayout)) return false;
final BaseFragment sheetFragment = ((ActionBarLayout) fragment.getParentLayout()).getSheetFragment(false);
return sheetFragment != null && sheetFragment.hasShownSheet();
}
public void clearSheets() { public void clearSheets() {
if (sheetsStack == null || sheetsStack.isEmpty()) if (sheetsStack == null || sheetsStack.isEmpty())
return; return;
@ -286,7 +309,9 @@ public abstract class BaseFragment {
} }
public void onRemoveFromParent() { public void onRemoveFromParent() {
clearSheets(); if (sheetsStack == null || sheetsStack.isEmpty())
return;
updateSheetsVisibility();
} }
public void setParentFragment(BaseFragment fragment) { public void setParentFragment(BaseFragment fragment) {
@ -425,6 +450,15 @@ public abstract class BaseFragment {
if (hasForceLightStatusBar() && !AndroidUtilities.isTablet() && getParentLayout().getLastFragment() == this && getParentActivity() != null && !finishing) { if (hasForceLightStatusBar() && !AndroidUtilities.isTablet() && getParentLayout().getLastFragment() == this && getParentActivity() != null && !finishing) {
AndroidUtilities.setLightStatusBar(getParentActivity().getWindow(), Theme.getColor(Theme.key_actionBarDefault) == Color.WHITE); AndroidUtilities.setLightStatusBar(getParentActivity().getWindow(), Theme.getColor(Theme.key_actionBarDefault) == Color.WHITE);
} }
if (sheetsStack != null) {
for (int i = sheetsStack.size() - 1; i >= 0; --i) {
AttachedSheet sheet = sheetsStack.get(i);
sheet.setLastVisible(false);
sheet.dismiss(true);
sheetsStack.remove(i);
}
}
} }
public boolean needDelayOpenAnimation() { public boolean needDelayOpenAnimation() {
@ -509,7 +543,7 @@ public abstract class BaseFragment {
if (sheetsStack != null) { if (sheetsStack != null) {
for (int i = sheetsStack.size() - 1; i >= 0; --i) { for (int i = sheetsStack.size() - 1; i >= 0; --i) {
if (sheetsStack.get(i).isShown()) { if (sheetsStack.get(i).isShown()) {
return sheetsStack.get(i).onBackPressed(); return sheetsStack.get(i).onAttachedBackPressed();
} }
} }
} }
@ -656,6 +690,7 @@ public abstract class BaseFragment {
} }
public void onBecomeFullyVisible() { public void onBecomeFullyVisible() {
isFullyVisible = true;
AccessibilityManager mgr = (AccessibilityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACCESSIBILITY_SERVICE); AccessibilityManager mgr = (AccessibilityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (mgr.isEnabled()) { if (mgr.isEnabled()) {
ActionBar actionBar = getActionBar(); ActionBar actionBar = getActionBar();
@ -671,6 +706,15 @@ public abstract class BaseFragment {
fullyVisibleListener = null; fullyVisibleListener = null;
c.run(); c.run();
} }
updateSheetsVisibility();
}
private void updateSheetsVisibility() {
if (sheetsStack == null) return;
for (int i = 0; i < sheetsStack.size(); ++i) {
AttachedSheet sheet = sheetsStack.get(i);
sheet.setLastVisible(i == sheetsStack.size() - 1 && isFullyVisible);
}
} }
private Runnable fullyVisibleListener; private Runnable fullyVisibleListener;
@ -683,7 +727,8 @@ public abstract class BaseFragment {
} }
public void onBecomeFullyHidden() { public void onBecomeFullyHidden() {
isFullyVisible = false;
updateSheetsVisibility();
} }
public AnimatorSet onCustomTransitionAnimation(boolean isOpen, Runnable callback) { public AnimatorSet onCustomTransitionAnimation(boolean isOpen, Runnable callback) {
@ -1191,10 +1236,29 @@ public abstract class BaseFragment {
storyViewer.fromBottomSheet = true; storyViewer.fromBottomSheet = true;
} }
sheetsStack.add(storyViewer); sheetsStack.add(storyViewer);
updateSheetsVisibility();
} }
return storyViewer; return storyViewer;
} }
public void removeSheet(BaseFragment.AttachedSheet sheet) {
if (sheetsStack == null) return;
sheetsStack.remove(sheet);
updateSheetsVisibility();
}
public void addSheet(BaseFragment.AttachedSheet sheet) {
if (sheetsStack == null) {
sheetsStack = new ArrayList<>();
}
StoryViewer storyViewer = getLastStoryViewer();
if (storyViewer != null) {
storyViewer.listenToAttachedSheet(sheet);
}
sheetsStack.add(sheet);
updateSheetsVisibility();
}
public StoryViewer createOverlayStoryViewer() { public StoryViewer createOverlayStoryViewer() {
if (sheetsStack == null) { if (sheetsStack == null) {
sheetsStack = new ArrayList<>(); sheetsStack = new ArrayList<>();
@ -1204,19 +1268,39 @@ public abstract class BaseFragment {
storyViewer.fromBottomSheet = true; storyViewer.fromBottomSheet = true;
} }
sheetsStack.add(storyViewer); sheetsStack.add(storyViewer);
updateSheetsVisibility();
return storyViewer; return storyViewer;
} }
public BotWebViewAttachedSheet createBotViewer() { public ArticleViewer createArticleViewer(boolean forceRecreate) {
if (sheetsStack == null) { if (sheetsStack == null) {
sheetsStack = new ArrayList<>(); sheetsStack = new ArrayList<>();
} }
BotWebViewAttachedSheet botViewer = new BotWebViewAttachedSheet(this); if (!forceRecreate) {
StoryViewer storyViewer = getLastStoryViewer(); if (getLastSheet() instanceof ArticleViewer.Sheet && getLastSheet().isShown()) {
if (storyViewer != null) { return ((ArticleViewer.Sheet) getLastSheet()).getArticleViewer();
storyViewer.listenToAttachedSheet(botViewer); }
if (
parentLayout instanceof ActionBarLayout &&
((ActionBarLayout) parentLayout).getSheetFragment(false) != null &&
((ActionBarLayout) parentLayout).getSheetFragment(false).getLastSheet() instanceof ArticleViewer.Sheet
) {
ArticleViewer.Sheet lastSheet = (ArticleViewer.Sheet) ((ActionBarLayout) parentLayout).getSheetFragment(false).getLastSheet();
if (lastSheet.isShown()) {
return lastSheet.getArticleViewer();
}
}
} }
sheetsStack.add(botViewer); ArticleViewer articleViewer = ArticleViewer.makeSheet(this);
addSheet(articleViewer.sheet);
BottomSheetTabDialog.checkSheet(articleViewer.sheet);
return articleViewer;
}
public BotWebViewAttachedSheet createBotViewer() {
BotWebViewAttachedSheet botViewer = new BotWebViewAttachedSheet(this);
addSheet(botViewer);
BottomSheetTabDialog.checkSheet(botViewer);
return botViewer; return botViewer;
} }

View file

@ -30,6 +30,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -43,12 +44,15 @@ import android.view.WindowInsets;
import android.view.WindowManager; import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.core.graphics.ColorUtils;
import androidx.core.view.NestedScrollingParent; import androidx.core.view.NestedScrollingParent;
import androidx.core.view.NestedScrollingParentHelper; import androidx.core.view.NestedScrollingParentHelper;
import androidx.core.view.ViewCompat; import androidx.core.view.ViewCompat;
@ -60,15 +64,17 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.camera.CameraView; import org.telegram.messenger.camera.CameraView;
import org.telegram.ui.Components.AnimationProperties; import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.Bulletin; import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.LaunchActivity;
import java.util.ArrayList; import java.util.ArrayList;
public class BottomSheet extends Dialog { public class BottomSheet extends Dialog implements BaseFragment.AttachedSheet {
private final static boolean AVOID_SYSTEM_CUTOUT_FULLSCREEN = false; private final static boolean AVOID_SYSTEM_CUTOUT_FULLSCREEN = false;
protected int currentAccount = UserConfig.selectedAccount; protected int currentAccount = UserConfig.selectedAccount;
@ -382,7 +388,7 @@ public class BottomSheet extends Dialog {
container.invalidate(); container.invalidate();
} }
} else if (ev == null || ev.getPointerId(0) == startedTrackingPointerId && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_POINTER_UP)) { } else if (ev == null || ev.getPointerId(0) == startedTrackingPointerId && (ev.getAction() == MotionEvent.ACTION_CANCEL || ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_POINTER_UP)) {
containerView.setTranslationX(0); // containerView.setTranslationX(0);
if (velocityTracker == null) { if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain(); velocityTracker = VelocityTracker.obtain();
} }
@ -394,13 +400,15 @@ public class BottomSheet extends Dialog {
ValueAnimator animator = ValueAnimator.ofFloat(swipeBackX, 0); ValueAnimator animator = ValueAnimator.ofFloat(swipeBackX, 0);
animator.addUpdateListener(animation -> { animator.addUpdateListener(animation -> {
swipeBackX = (float) animation.getAnimatedValue(); swipeBackX = (float) animation.getAnimatedValue();
setTranslationX(swipeBackX); containerView.setTranslationX(swipeBackX);
container.invalidate();
}); });
animator.addListener(new AnimatorListenerAdapter() { animator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
swipeBackX = 0; swipeBackX = 0;
setTranslationX(0); containerView.setTranslationX(0);
container.invalidate();
} }
}); });
animator.setInterpolator(CubicBezierInterpolator.DEFAULT); animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
@ -410,18 +418,30 @@ public class BottomSheet extends Dialog {
ValueAnimator animator = ValueAnimator.ofFloat(swipeBackX, getMeasuredWidth()); ValueAnimator animator = ValueAnimator.ofFloat(swipeBackX, getMeasuredWidth());
animator.addUpdateListener(animation -> { animator.addUpdateListener(animation -> {
swipeBackX = (float) animation.getAnimatedValue(); swipeBackX = (float) animation.getAnimatedValue();
setTranslationX(swipeBackX); containerView.setTranslationX(swipeBackX);
container.invalidate();
}); });
animator.addListener(new AnimatorListenerAdapter() { animator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
skipDismissAnimation = true; skipDismissAnimation = true;
containerView.setTranslationX(getMeasuredWidth());
dismiss(); dismiss();
container.invalidate();
} }
}); });
animator.setInterpolator(CubicBezierInterpolator.DEFAULT); animator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
animator.setDuration(150); animator.setDuration(320);
animator.start(); animator.start();
ValueAnimator dimAnimator = ValueAnimator.ofFloat(1f, 0f);
dimAnimator.addUpdateListener(animation -> {
final float t = (float) animation.getAnimatedValue();
backDrawable.setAlpha(dimBehind ? (int) (dimBehindAlpha * t) : 0);
});
dimAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
dimAnimator.setDuration(320);
dimAnimator.start();
} }
maybeStartTracking = false; maybeStartTracking = false;
startedTracking = false; startedTracking = false;
@ -1104,7 +1124,7 @@ public class BottomSheet extends Dialog {
Bulletin.removeDelegate(this); Bulletin.removeDelegate(this);
} }
}; };
container.setBackgroundDrawable(backDrawable); container.setBackground(backDrawable);
focusable = needFocus; focusable = needFocus;
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
container.setFitsSystemWindows(true); container.setFitsSystemWindows(true);
@ -1155,10 +1175,32 @@ public class BottomSheet extends Dialog {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
onCreateInternal();
}
Window window = getWindow(); private void onCreateInternal() {
window.setWindowAnimations(R.style.DialogNoAnimation);
setContentView(container, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); Window window = null;
if (attachedFragment != null) {
attachedFragment.addSheet(this);
if (attachedFragment.getLayoutContainer() == null) return;
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.hideSoftInputFromWindow(attachedFragment.getLayoutContainer().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS)) {
AndroidUtilities.runOnUIThread(() -> {
AndroidUtilities.removeFromParent(container);
attachedFragment.getLayoutContainer().addView(container);
}, 80);
} else {
AndroidUtilities.removeFromParent(container);
attachedFragment.getLayoutContainer().addView(container);
}
} else {
window = getWindow();
window.setWindowAnimations(R.style.DialogNoAnimation);
setContentView(container, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
if (useLightStatusBar && Build.VERSION.SDK_INT >= 23) { if (useLightStatusBar && Build.VERSION.SDK_INT >= 23) {
int color = Theme.getColor(Theme.key_actionBarDefault, null, true); int color = Theme.getColor(Theme.key_actionBarDefault, null, true);
@ -1183,7 +1225,7 @@ public class BottomSheet extends Dialog {
public void setTranslationY(float translationY) { public void setTranslationY(float translationY) {
super.setTranslationY(translationY); super.setTranslationY(translationY);
if (topBulletinContainer != null) { if (topBulletinContainer != null) {
topBulletinContainer.setTranslationY(-getHeight() + translationY - getPaddingTop() - AndroidUtilities.statusBarHeight + backgroundPaddingTop); topBulletinContainer.setTranslationY(-(container.getHeight() - containerView.getY()) + backgroundPaddingTop);
} }
onContainerTranslationYChanged(translationY); onContainerTranslationYChanged(translationY);
} }
@ -1281,30 +1323,34 @@ public class BottomSheet extends Dialog {
} }
} }
WindowManager.LayoutParams params = window.getAttributes(); if (attachedFragment != null) {
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT; } else if (window != null) {
params.dimAmount = 0; WindowManager.LayoutParams params = window.getAttributes();
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND; params.width = ViewGroup.LayoutParams.MATCH_PARENT;
if (focusable) { params.gravity = Gravity.TOP | Gravity.LEFT;
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; params.dimAmount = 0;
} else { params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; if (focusable) {
} params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
if (isFullscreen) { } else {
if (Build.VERSION.SDK_INT >= 21) { params.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
} }
params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; if (isFullscreen) {
container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN); if (Build.VERSION.SDK_INT >= 21) {
params.flags |= WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN |
WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR |
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;
}
params.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN);
}
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
if (Build.VERSION.SDK_INT >= 28) {
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
window.setAttributes(params);
} }
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
if (Build.VERSION.SDK_INT >= 28) {
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
window.setAttributes(params);
} }
@Override @Override
@ -1324,6 +1370,14 @@ public class BottomSheet extends Dialog {
} }
container.setSystemUiVisibility(flags); container.setSystemUiVisibility(flags);
} }
if (attachedFragment != null) {
LaunchActivity.instance.checkSystemBarColors(true, true, true, false);
}
}
@Override
public boolean isAttachedLightStatusBar() {
return useLightStatusBar;
} }
public boolean isFocusable() { public boolean isFocusable() {
@ -1358,7 +1412,11 @@ public class BottomSheet extends Dialog {
@Override @Override
public void show() { public void show() {
if (!AndroidUtilities.isSafeToShow(getContext())) return; if (!AndroidUtilities.isSafeToShow(getContext())) return;
super.show(); if (attachedFragment != null) {
onCreateInternal();
} else {
super.show();
}
setShowing(true); setShowing(true);
if (focusable) { if (focusable) {
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
@ -1738,6 +1796,16 @@ public class BottomSheet extends Dialog {
forceKeyboardOnDismiss = true; forceKeyboardOnDismiss = true;
} }
@Override
public View getWindowView() {
return container;
}
@Override
public boolean isShown() {
return !dismissed;
}
@Override @Override
public void dismiss() { public void dismiss() {
if (delegate != null && !delegate.canDismiss()) { if (delegate != null && !delegate.canDismiss()) {
@ -1836,16 +1904,77 @@ public class BottomSheet extends Dialog {
setShowing(false); setShowing(false);
} }
@Override
public void dismiss(boolean tabs) {
this.dismiss();
}
@Override
public void release() {
dismissInternal();
}
@Override
public boolean isFullyVisible() {
return false;
}
@Override
public boolean attachedToParent() {
return container != null && container.isAttachedToWindow();
}
@Override
public boolean showDialog(Dialog dialog) {
return false;
}
@Override
public void setKeyboardHeightFromParent(int keyboardHeight) {
}
@Override
public int getNavigationBarColor(int color) {
final float t;
if (!attachedToParent() || containerView == null) {
t = 0;
} else if (transitionFromRight) {
t = containerView.getAlpha();
} else {
final float fullHeight = getContainerViewHeight() + keyboardHeight + AndroidUtilities.dp(10) + (scrollNavBar ? getBottomInset() : 0);
t = Utilities.clamp01(1f - containerView.getTranslationY() / fullHeight);
}
return ColorUtils.blendARGB(color, navBarColor, t);
}
@Override
public void setOnDismissListener(Runnable onDismiss) {
if (onDismiss != null) {
setOnHideListener(d -> onDismiss.run());
}
}
@Override
public void setOnDismissListener(@Nullable OnDismissListener listener) {
super.setOnDismissListener(listener);
}
public int getSheetAnimationType() { public int getSheetAnimationType() {
return currentSheetAnimationType; return currentSheetAnimationType;
} }
public void dismissInternal() { public void dismissInternal() {
try { if (attachedFragment != null) {
super.dismiss(); attachedFragment.removeSheet(this);
} catch (Exception e) { AndroidUtilities.removeFromParent(container);
//ignore: not attached to window manager } else {
FileLog.e(e, false); try {
super.dismiss();
} catch (Exception e) {
//ignore: not attached to window manager
FileLog.e(e, false);
}
} }
} }
@ -2061,6 +2190,12 @@ public class BottomSheet extends Dialog {
container.invalidate(); container.invalidate();
} }
if (attachedFragment != null) {
LaunchActivity.instance.checkSystemBarColors(true, true, true, false);
AndroidUtilities.setLightNavigationBar(getWindowView(), AndroidUtilities.computePerceivedBrightness(getNavigationBarColor(getThemedColor(Theme.key_windowBackgroundGray))) >= .721f);
// AndroidUtilities.setLightStatusBar(dialog != null ? dialog.windowView : windowView, attachedToActionBar && AndroidUtilities.computePerceivedBrightness(actionBar.getBackgroundColor()) > .721f);
return;
}
// if (Color.alpha(color) > 120) { // if (Color.alpha(color) > 120) {
// AndroidUtilities.setLightStatusBar(getWindow(), false); // AndroidUtilities.setLightStatusBar(getWindow(), false);
// AndroidUtilities.setLightNavigationBar(getWindow(), false); // AndroidUtilities.setLightNavigationBar(getWindow(), false);
@ -2124,4 +2259,28 @@ public class BottomSheet extends Dialog {
protected void onSmoothContainerViewLayout(float ty) { protected void onSmoothContainerViewLayout(float ty) {
} }
public BaseFragment attachedFragment;
public void makeAttached(BaseFragment fragment) {
if (AndroidUtilities.isTablet()) return;
this.attachedFragment = fragment;
}
@Override
public boolean onAttachedBackPressed() {
onBackPressed();
return true;
}
@Override
public void onBackPressed() {
if (attachedFragment == null) {
super.onBackPressed();
} else {
dismiss();
}
}
} }

View file

@ -0,0 +1,157 @@
package org.telegram.ui.ActionBar;
import android.app.Dialog;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.RectF;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyboardShortcutGroup;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.R;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.LaunchActivity;
import java.util.List;
public class BottomSheetTabDialog extends Dialog {
public static BottomSheetTabsOverlay.Sheet checkSheet(BottomSheetTabsOverlay.Sheet sheet) {
BaseFragment fragment = LaunchActivity.getSafeLastFragment();
if (fragment == null) return sheet;
if (AndroidUtilities.isTablet() || AndroidUtilities.hasDialogOnTop(fragment)) {
final BottomSheetTabDialog dialog = new BottomSheetTabDialog(sheet);
if (sheet.setDialog(dialog)) {
dialog.windowView.putView();
return sheet;
}
}
return sheet;
}
public final BottomSheetTabsOverlay.Sheet sheet;
public final BottomSheetTabsOverlay.SheetView sheetView;
public final WindowView windowView;
public BottomSheetTabDialog(BottomSheetTabsOverlay.Sheet sheet) {
super(sheet.getWindowView().getContext(), R.style.TransparentDialog);
this.sheet = sheet;
this.sheetView = sheet.getWindowView();
setContentView(windowView = new WindowView(sheetView), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
window.setWindowAnimations(R.style.DialogNoAnimation);
WindowManager.LayoutParams params = window.getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.dimAmount = 0;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
window.setAttributes(params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
window.setStatusBarColor(Color.TRANSPARENT);
}
windowView.setFitsSystemWindows(true);
windowView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
windowView.setPadding(0, 0, 0, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
windowView.setOnApplyWindowInsetsListener((v, insets) -> {
v.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
if (Build.VERSION.SDK_INT >= 30) {
return WindowInsets.CONSUMED;
} else {
return insets.consumeSystemWindowInsets();
}
});
}
}
public void updateNavigationBarColor() {
final int color = sheet.getNavigationBarColor(0);
AndroidUtilities.setNavigationBarColor(getWindow(), color);
AndroidUtilities.setLightNavigationBar(getWindow(), AndroidUtilities.computePerceivedBrightness(color) >= .721f);
}
public static class WindowView extends FrameLayout implements BottomSheetTabsOverlay.SheetView {
public final BottomSheetTabsOverlay.SheetView sheetView;
public WindowView(BottomSheetTabsOverlay.SheetView sheetView) {
super(sheetView.getContext());
this.sheetView = sheetView;
}
public void putView() {
View view = (View) sheetView;
AndroidUtilities.removeFromParent(view);
addView(view, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL));
}
@Override
public void setDrawingFromOverlay(boolean value) {
sheetView.setDrawingFromOverlay(value);
}
@Override
public RectF getRect() {
return sheetView.getRect();
}
@Override
public float drawInto(Canvas canvas, RectF finalRect, float progress, RectF clipRect, float alpha, boolean opening) {
return sheetView.drawInto(canvas, finalRect, progress, clipRect, alpha, opening);
}
}
private boolean attached;
public void attach() {
if (attached) return;
attached = true;
super.show();
}
public void detach() {
sheet.setDialog(null);
if (!attached) return;
attached = false;
super.dismiss();
}
@Override
public void dismiss() {
sheet.dismiss(false);
}
}

View file

@ -2,15 +2,22 @@ package org.telegram.ui.ActionBar;
import static org.telegram.messenger.AndroidUtilities.dp; import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.lerp; import static org.telegram.messenger.AndroidUtilities.lerp;
import static org.telegram.messenger.LocaleController.getString;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@ -21,14 +28,17 @@ import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ArticleViewer;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AnimatedColor; import org.telegram.ui.Components.AnimatedColor;
import org.telegram.ui.Components.AnimatedFloat; import org.telegram.ui.Components.AnimatedFloat;
@ -36,8 +46,9 @@ import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.Text; import org.telegram.ui.Components.Text;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.bots.BotWebViewAttachedSheet; import org.telegram.ui.bots.BotWebViewAttachedSheet;
import org.telegram.ui.bots.BotWebViewContainer; import org.telegram.ui.web.BotWebViewContainer;
import org.telegram.ui.bots.BotWebViewSheet; import org.telegram.ui.bots.BotWebViewSheet;
import org.telegram.ui.bots.WebViewRequestProps;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -61,7 +72,10 @@ public class BottomSheetTabs extends FrameLayout {
final int count = tabs.size(); final int count = tabs.size();
if (count == 0) return; if (count == 0) return;
WebTabData lastTab = tabs.get(tabs.size() - 1); WebTabData lastTab = tabs.get(tabs.size() - 1);
BottomSheetTabsOverlay overlay = LaunchActivity.instance.getBottomSheetTabsOverlay(); BottomSheetTabsOverlay overlay = LaunchActivity.instance == null ? null : LaunchActivity.instance.getBottomSheetTabsOverlay();
if (overlay != null) {
overlay.stopAnimations();
}
if (count == 1 || overlay == null) { if (count == 1 || overlay == null) {
openTab(lastTab); openTab(lastTab);
@ -82,6 +96,18 @@ public class BottomSheetTabs extends FrameLayout {
((ChatActivity) lastFragment).getChatActivityEnterView().hidePopup(true, false); ((ChatActivity) lastFragment).getChatActivityEnterView().hidePopup(true, false);
} }
} }
if (tab.articleViewer != null) {
BaseFragment fragment = actionBarLayout.getSheetFragment();
final ArticleViewer articleViewer = tab.articleViewer;
BottomSheetTabDialog.checkSheet(articleViewer.sheet);
fragment.addSheet(articleViewer.sheet);
articleViewer.sheet.reset();
articleViewer.setParentActivity(fragment.getParentActivity(), fragment);
articleViewer.sheet.attachInternal(fragment);
articleViewer.sheet.animateOpen(true, true, null);
removeTab(tab, false);
return;
}
boolean closed = closeAttachedSheets(); boolean closed = closeAttachedSheets();
Utilities.Callback<BaseFragment> open = fragment -> { Utilities.Callback<BaseFragment> open = fragment -> {
if (fragment == null) return; if (fragment == null) return;
@ -91,10 +117,10 @@ public class BottomSheetTabs extends FrameLayout {
((ChatActivity) fragment).getChatActivityEnterView().hidePopup(true, false); ((ChatActivity) fragment).getChatActivityEnterView().hidePopup(true, false);
} }
} }
if (fragment.getContext() == null) { if (fragment.getContext() == null || fragment.getParentActivity() == null) {
return; return;
} }
if (AndroidUtilities.isTablet()) { if (AndroidUtilities.isTablet() && !tab.isWeb) {
BotWebViewSheet sheet = new BotWebViewSheet(fragment.getContext(), fragment.getResourceProvider()); BotWebViewSheet sheet = new BotWebViewSheet(fragment.getContext(), fragment.getResourceProvider());
sheet.setParentActivity(fragment.getParentActivity()); sheet.setParentActivity(fragment.getParentActivity());
if (sheet.restoreState(fragment, tab)) { if (sheet.restoreState(fragment, tab)) {
@ -102,30 +128,26 @@ public class BottomSheetTabs extends FrameLayout {
sheet.show(); sheet.show();
} }
} else { } else {
BottomSheetTabsOverlay overlay = LaunchActivity.instance.getBottomSheetTabsOverlay(); BaseFragment sheetFragment = actionBarLayout.getSheetFragment();
BotWebViewAttachedSheet webViewSheet = fragment.createBotViewer(); if (sheetFragment == null) return;
BotWebViewAttachedSheet webViewSheet = sheetFragment.createBotViewer();
webViewSheet.setParentActivity(fragment.getParentActivity()); webViewSheet.setParentActivity(fragment.getParentActivity());
if (webViewSheet.restoreState(fragment, tab)) { if (webViewSheet.restoreState(fragment, tab)) {
// if (overlay != null && overlay.isOpened() && overlay.openSheet(webViewSheet, tab, null)) { removeTab(tab, false);
// removeTab(tab, false); webViewSheet.show(closed);
// webViewSheet.show(closed, true);
// } else {
removeTab(tab, false);
webViewSheet.show(closed);
// }
} }
} }
}; };
open.run(lastFragment);
if (tab.needsContext && (!(lastFragment instanceof ChatActivity) || ((ChatActivity) lastFragment).getDialogId() != tab.props.botId)) { if (tab.needsContext && (!(lastFragment instanceof ChatActivity) || ((ChatActivity) lastFragment).getDialogId() != tab.props.botId)) {
BaseFragment chatActivity = ChatActivity.of(tab.props.botId); BaseFragment chatActivity = ChatActivity.of(tab.props.botId);
chatActivity.whenFullyVisible(() -> open.run(chatActivity)); AndroidUtilities.runOnUIThread(() -> {
lastFragment.presentFragment(chatActivity); lastFragment.presentFragment(chatActivity);
} else { }, 220);
open.run(lastFragment);
} }
} }
public WebTabData tryReopenTab(BotWebViewAttachedSheet.WebViewRequestProps props) { public WebTabData tryReopenTab(WebViewRequestProps props) {
ArrayList<WebTabData> tabs = this.tabs.get(currentAccount); ArrayList<WebTabData> tabs = this.tabs.get(currentAccount);
if (tabs == null) this.tabs.put(currentAccount, tabs = new ArrayList<>()); if (tabs == null) this.tabs.put(currentAccount, tabs = new ArrayList<>());
@ -140,6 +162,63 @@ public class BottomSheetTabs extends FrameLayout {
return null; return null;
} }
public static String urlWithoutFragment(String url) {
if (url == null) return null;
int index = url.indexOf('#');
if (index >= 0) return url.substring(0, index + 1);
return url;
}
public WebTabData tryReopenTab(String url) {
if (TextUtils.isEmpty(url)) return null;
final ArrayList<WebTabData> tabs = getTabs();
for (int i = 0; i < tabs.size(); ++i) {
WebTabData tab = tabs.get(i);
if (tab.articleViewer != null && !tab.articleViewer.pagesStack.isEmpty()) {
Object lastPage = tab.articleViewer.pagesStack.get(tab.articleViewer.pagesStack.size() - 1);
if (lastPage instanceof ArticleViewer.CachedWeb) {
ArticleViewer.CachedWeb web = (ArticleViewer.CachedWeb) lastPage;
BotWebViewContainer.MyWebView webView = web.webView;
if (webView == null && tab.articleViewer.pages != null && tab.articleViewer.pages[0] != null) {
webView = tab.articleViewer.pages[0].getWebView();
}
if (webView != null && TextUtils.equals(urlWithoutFragment(webView.canGoBack() ? webView.getUrl() : webView.getOpenURL()), urlWithoutFragment(url))) {
openTab(tab);
return tab;
}
}
}
}
return null;
}
public WebTabData tryReopenTab(TLRPC.WebPage webpage) {
if (webpage == null) return null;
final ArrayList<WebTabData> tabs = getTabs();
for (int i = 0; i < tabs.size(); ++i) {
WebTabData tab = tabs.get(i);
if (tab.articleViewer != null && !tab.articleViewer.pagesStack.isEmpty()) {
Object lastPage = tab.articleViewer.pagesStack.get(tab.articleViewer.pagesStack.size() - 1);
if (lastPage instanceof TLRPC.WebPage) {
TLRPC.WebPage pageWebPage = (TLRPC.WebPage) lastPage;
if (pageWebPage != null && pageWebPage.id == webpage.id) {
openTab(tab);
return tab;
}
}
}
}
return null;
}
public WebTabData tryReopenTab(MessageObject messageObject) {
if (messageObject == null) return null;
if (messageObject.messageOwner == null) return null;
if (messageObject.messageOwner.media == null) return null;
if (messageObject.messageOwner.media.webpage == null) return null;
return tryReopenTab(messageObject.messageOwner.media.webpage);
}
public boolean closeAttachedSheets() { public boolean closeAttachedSheets() {
boolean had = false; boolean had = false;
BottomSheetTabsOverlay overlay = LaunchActivity.instance.getBottomSheetTabsOverlay(); BottomSheetTabsOverlay overlay = LaunchActivity.instance.getBottomSheetTabsOverlay();
@ -221,12 +300,20 @@ public class BottomSheetTabs extends FrameLayout {
} }
public ArrayList<WebTabData> getTabs() { public ArrayList<WebTabData> getTabs() {
return getTabs(this.currentAccount);
}
public ArrayList<TabDrawable> getTabDrawables() {
return getTabDrawables(this.currentAccount);
}
public ArrayList<WebTabData> getTabs(int currentAccount) {
ArrayList<WebTabData> tabs = this.tabs.get(currentAccount); ArrayList<WebTabData> tabs = this.tabs.get(currentAccount);
if (tabs == null) this.tabs.put(currentAccount, tabs = new ArrayList<>()); if (tabs == null) this.tabs.put(currentAccount, tabs = new ArrayList<>());
return tabs; return tabs;
} }
public ArrayList<TabDrawable> getTabDrawables() { public ArrayList<TabDrawable> getTabDrawables(int currentAccount) {
ArrayList<TabDrawable> tabDrawables = this.tabDrawables.get(currentAccount); ArrayList<TabDrawable> tabDrawables = this.tabDrawables.get(currentAccount);
if (tabDrawables == null) this.tabDrawables.put(currentAccount, tabDrawables = new ArrayList<>()); if (tabDrawables == null) this.tabDrawables.put(currentAccount, tabDrawables = new ArrayList<>());
return tabDrawables; return tabDrawables;
@ -274,21 +361,31 @@ public class BottomSheetTabs extends FrameLayout {
return super.verifyDrawable(who) || true; return super.verifyDrawable(who) || true;
} }
private static TextPaint textPaint;
private static TextPaint getTextPaint() {
if (textPaint == null) {
textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
textPaint.setTypeface(AndroidUtilities.bold());
textPaint.setTextSize(AndroidUtilities.dp(17));
}
return textPaint;
}
private void updateMultipleTitle() { private void updateMultipleTitle() {
final ArrayList<WebTabData> tabs = getTabs(); final ArrayList<WebTabData> tabs = getTabs();
final ArrayList<TabDrawable> tabDrawables = getTabDrawables(); final ArrayList<TabDrawable> tabDrawables = getTabDrawables();
String title = null; CharSequence title = null;
for (int i = 0; i < tabDrawables.size(); ++i) { for (int i = 0; i < tabDrawables.size(); ++i) {
TabDrawable drawable = tabDrawables.get(i); TabDrawable drawable = tabDrawables.get(i);
if (tabs.size() > 1 && drawable.position == 0) { if (tabs.size() > 1 && drawable.position == 0) {
TLRPC.User user = MessagesController.getInstance(drawable.tab.props.currentAccount).getUser(drawable.tab.props.botId); title = LocaleController.formatPluralString("BotMoreTabs", tabs.size() - 1, drawable.tab.getTitle());
title = LocaleController.formatPluralString("BotMoreTabs", tabs.size() - 1, UserObject.getUserName(user)); title = Emoji.replaceEmoji(title, getTextPaint().getFontMetricsInt(), false);
drawable.setOverrideTitle(title); drawable.setOverrideTitle(title);
} else { } else {
TLRPC.User user = MessagesController.getInstance(drawable.tab.props.currentAccount).getUser(drawable.tab.props.botId); title = drawable.tab.getTitle();
title = UserObject.getUserName(user); title = Emoji.replaceEmoji(title, getTextPaint().getFontMetricsInt(), false);
drawable.setOverrideTitle(null); drawable.setOverrideTitle(null);
} }
} }
@ -320,6 +417,20 @@ public class BottomSheetTabs extends FrameLayout {
return tabs.isEmpty(); return tabs.isEmpty();
} }
public boolean tryRemoveTabWith(ArticleViewer articleViewer) {
for (int account = 0; account < this.tabs.size(); ++account) {
ArrayList<WebTabData> tabs = this.tabs.get(account);
if (tabs != null) {
for (WebTabData tab : tabs) {
if (tab.articleViewer == articleViewer) {
return removeTab(account, tab, true);
}
}
}
}
return false;
}
public void removeTab(WebTabData tab, Utilities.Callback<Boolean> callback) { public void removeTab(WebTabData tab, Utilities.Callback<Boolean> callback) {
if (tab == null) { if (tab == null) {
callback.run(true); callback.run(true);
@ -341,14 +452,14 @@ public class BottomSheetTabs extends FrameLayout {
final AlertDialog[] dialog = new AlertDialog[1]; final AlertDialog[] dialog = new AlertDialog[1];
dialog[0] = new AlertDialog.Builder(getContext()) dialog[0] = new AlertDialog.Builder(getContext())
.setTitle(botName) .setTitle(botName)
.setMessage(LocaleController.getString(R.string.BotWebViewChangesMayNotBeSaved)) .setMessage(getString(R.string.BotWebViewChangesMayNotBeSaved))
.setPositiveButton(LocaleController.getString(R.string.BotWebViewCloseAnyway), (d, w) -> { .setPositiveButton(getString(R.string.BotWebViewCloseAnyway), (d, w) -> {
clicked[0] = true; clicked[0] = true;
removeTab(tab, true); removeTab(tab, true);
callback.run(true); callback.run(true);
dialog[0].dismiss(); dialog[0].dismiss();
}) })
.setNegativeButton(LocaleController.getString(R.string.Cancel), (d, w) -> { .setNegativeButton(getString(R.string.Cancel), (d, w) -> {
clicked[0] = true; clicked[0] = true;
callback.run(false); callback.run(false);
dialog[0].dismiss(); dialog[0].dismiss();
@ -366,8 +477,12 @@ public class BottomSheetTabs extends FrameLayout {
} }
public boolean removeTab(WebTabData tab, boolean destroy) { public boolean removeTab(WebTabData tab, boolean destroy) {
final ArrayList<WebTabData> tabs = getTabs(); return removeTab(currentAccount, tab, destroy);
final ArrayList<TabDrawable> tabDrawables = getTabDrawables(); }
public boolean removeTab(int currentAccount, WebTabData tab, boolean destroy) {
final ArrayList<WebTabData> tabs = getTabs(currentAccount);
final ArrayList<TabDrawable> tabDrawables = getTabDrawables(currentAccount);
tabs.remove(tab); tabs.remove(tab);
if (destroy) { if (destroy) {
@ -495,7 +610,9 @@ public class BottomSheetTabs extends FrameLayout {
public final AnimatedFloat animatedAlpha; public final AnimatedFloat animatedAlpha;
private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint iconPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint iconPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint faviconPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
public int closeRippleColor; public int closeRippleColor;
public final Drawable closeRipple = Theme.createSelectorDrawable(0x30ffffff, Theme.RIPPLE_MASK_CIRCLE_20DP); public final Drawable closeRipple = Theme.createSelectorDrawable(0x30ffffff, Theme.RIPPLE_MASK_CIRCLE_20DP);
@ -504,7 +621,12 @@ public class BottomSheetTabs extends FrameLayout {
private int backgroundColor, tabColor; private int backgroundColor, tabColor;
private boolean backgroundIsDark, tabIsDark; private boolean backgroundIsDark, tabIsDark;
private Text title; private float progress;
private Bitmap favicon;
private Drawable iconDrawable;
private int iconDrawableColor = Color.WHITE;
private final Text title;
private Text overrideTitle; private Text overrideTitle;
public TabDrawable(View view, WebTabData tab) { public TabDrawable(View view, WebTabData tab) {
@ -519,10 +641,15 @@ public class BottomSheetTabs extends FrameLayout {
animatedPosition = new AnimatedFloat(view, 320, CubicBezierInterpolator.EASE_OUT_QUINT); animatedPosition = new AnimatedFloat(view, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
animatedAlpha = new AnimatedFloat(view, 320, CubicBezierInterpolator.EASE_OUT_QUINT); animatedAlpha = new AnimatedFloat(view, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
TLRPC.User user = MessagesController.getInstance(tab.props.currentAccount).getUser(tab.getBotId()); this.favicon = tab.favicon;
this.title = new Text(UserObject.getUserName(user), 17, AndroidUtilities.bold()); CharSequence title = Emoji.replaceEmoji(tab.getTitle(), getTextPaint().getFontMetricsInt(), false);
this.title = new Text(title, 17, AndroidUtilities.bold());
this.tabColor = tab.actionBarColor; this.tabColor = tab.actionBarColor;
this.tabIsDark = AndroidUtilities.computePerceivedBrightness(tabColor) < .721f; this.tabIsDark = AndroidUtilities.computePerceivedBrightness(tabColor) < .721f;
if (tab.isArticle()) {
iconDrawable = view.getContext().getResources().getDrawable(R.drawable.msg_instant).mutate();
}
progress = tab.articleProgress;
closePath.rewind(); closePath.rewind();
closePath.moveTo(0, 0); closePath.moveTo(0, 0);
@ -536,7 +663,7 @@ public class BottomSheetTabs extends FrameLayout {
expandPath.lineTo(dp(12.66f), dp(6.33f) / 2f); expandPath.lineTo(dp(12.66f), dp(6.33f) / 2f);
} }
public void setOverrideTitle(String title) { public void setOverrideTitle(CharSequence title) {
if (title == null) { if (title == null) {
overrideTitle = null; overrideTitle = null;
} else { } else {
@ -595,6 +722,14 @@ public class BottomSheetTabs extends FrameLayout {
rectPath.addRoundRect(bounds, radii, Path.Direction.CW); rectPath.addRoundRect(bounds, radii, Path.Direction.CW);
canvas.drawPath(rectPath, backgroundPaint); canvas.drawPath(rectPath, backgroundPaint);
if (progress > 0 && expandProgress > 0 && alpha > 0) {
canvas.save();
canvas.clipPath(rectPath);
progressPaint.setColor(Theme.multAlpha(AndroidUtilities.computePerceivedBrightness(backgroundColor) > .721f ? Color.BLACK : Color.WHITE, .07f * alpha * expandProgress));
canvas.drawRect(bounds.left, bounds.top, bounds.left + bounds.width() * progress, bounds.bottom, progressPaint);
canvas.restore();
}
final float isDark = lerp(backgroundIsDark ? 1f : 0f, tabIsDark ? 1f : 0f, expandProgress); final float isDark = lerp(backgroundIsDark ? 1f : 0f, tabIsDark ? 1f : 0f, expandProgress);
final int iconColor = ColorUtils.blendARGB(0xFF000000, 0xFFFFFFFF, isDark); final int iconColor = ColorUtils.blendARGB(0xFF000000, 0xFFFFFFFF, isDark);
@ -628,28 +763,69 @@ public class BottomSheetTabs extends FrameLayout {
canvas.drawPath(expandPath, iconPaint); canvas.drawPath(expandPath, iconPaint);
canvas.restore(); canvas.restore();
int leftPadding = 0;
if (favicon != null) {
final int sz = dp(24);
canvas.save();
AndroidUtilities.rectTmp2.set(
(int) (bounds.left + dp(56)),
(int) (bounds.centerY() - sz / 2f),
(int) (bounds.left + dp(56) + sz),
(int) (bounds.centerY() + sz / 2f)
);
faviconPaint.setAlpha((int) (0xFF * alpha * contentAlpha));
canvas.drawBitmap(favicon, null, AndroidUtilities.rectTmp2, faviconPaint);
canvas.restore();
leftPadding = sz + dp(4);
} else if (iconDrawable != null) {
final int sz = dp(24);
final int h = sz;
final int w = (int) (sz / (float) iconDrawable.getIntrinsicHeight() * iconDrawable.getIntrinsicWidth());
final float s = .7f;
AndroidUtilities.rectTmp2.set(
(int) (bounds.left + dp(56)),
(int) (bounds.centerY() - h / 2f * s),
(int) (bounds.left + dp(56) + w * s),
(int) (bounds.centerY() + h / 2f * s)
);
if (iconColor != iconDrawableColor) {
iconDrawable.setColorFilter(new PorterDuffColorFilter(iconDrawableColor = iconColor, PorterDuff.Mode.SRC_IN));
}
iconDrawable.setAlpha((int) (0xFF * alpha * contentAlpha));
iconDrawable.setBounds(AndroidUtilities.rectTmp2);
iconDrawable.draw(canvas);
leftPadding = w - dp(2);
}
if (overrideTitle != null) { if (overrideTitle != null) {
overrideTitle overrideTitle
.ellipsize((int) (bounds.width() - dp(100))) .ellipsize((int) (bounds.width() - dp(100) - leftPadding))
.draw(canvas, bounds.left + dp(60), bounds.centerY(), iconColor, (1f - expandProgress) * alpha * contentAlpha); .draw(canvas, bounds.left + dp(60) + leftPadding, bounds.centerY(), iconColor, (1f - expandProgress) * alpha * contentAlpha);
} }
title title
.ellipsize((int) (bounds.width() - dp(100))) .ellipsize((int) (bounds.width() - dp(100) - leftPadding))
.draw(canvas, bounds.left + dp(60), bounds.centerY(), iconColor, (overrideTitle == null ? 1f : expandProgress) * alpha * contentAlpha); .draw(canvas, bounds.left + dp(60) + leftPadding, bounds.centerY(), iconColor, (overrideTitle == null ? 1f : expandProgress) * alpha * contentAlpha);
} }
} }
public static class WebTabData { public static class WebTabData {
public BotWebViewAttachedSheet.WebViewRequestProps props; public WebViewRequestProps props;
public Bundle webViewState; public Bundle webViewState;
public BotWebViewContainer.MyWebView webView; public BotWebViewContainer.MyWebView webView;
public BotWebViewContainer.WebViewProxy webViewProxy; public View view2;
public int webViewWidth, webViewHeight; public Object proxy;
public int webViewScroll; public int viewWidth, viewHeight;
public int viewScroll;
public boolean expanded; public boolean expanded;
public float expandedOffset = Float.MAX_VALUE; public float expandedOffset = Float.MAX_VALUE;
public boolean allowSwipes = true;
public Bitmap previewBitmap; public Bitmap previewBitmap;
public Object previewNode; public Object previewNode;
@ -671,6 +847,19 @@ public class BottomSheetTabs extends FrameLayout {
public boolean themeIsDark; public boolean themeIsDark;
public boolean isWeb;
public String title;
public Bitmap favicon;
public String startUrl;
public String currentUrl;
public boolean error;
public int errorCode;
public String errorDescription;
public float articleProgress;
public ArticleViewer articleViewer;
public long getBotId() { public long getBotId() {
if (props == null) return 0; if (props == null) return 0;
return props.botId; return props.botId;
@ -682,11 +871,29 @@ public class BottomSheetTabs extends FrameLayout {
webView.destroy(); webView.destroy();
webView = null; webView = null;
} }
if (articleViewer != null) {
articleViewer.destroy();
}
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
} }
} }
public boolean isArticle() {
return articleViewer != null && articleViewer.isLastArticle();
}
public String getTitle() {
if (isWeb || articleViewer != null) {
if (TextUtils.isEmpty(title))
return getString(R.string.WebEmpty);
return title;
}
if (props == null) return "";
TLRPC.User user = MessagesController.getInstance(props.currentAccount).getUser(props.botId);
return UserObject.getUserName(user);
}
} }
} }

View file

@ -2,6 +2,7 @@ package org.telegram.ui.ActionBar;
import static org.telegram.messenger.AndroidUtilities.dp; import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.lerp; import static org.telegram.messenger.AndroidUtilities.lerp;
import static org.telegram.messenger.AndroidUtilities.scaleRect;
import static org.telegram.messenger.LocaleController.getString; import static org.telegram.messenger.LocaleController.getString;
import static org.telegram.messenger.Utilities.clamp01; import static org.telegram.messenger.Utilities.clamp01;
@ -50,20 +51,43 @@ import org.telegram.ui.Components.ButtonBounce;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.Text; import org.telegram.ui.Components.Text;
import org.telegram.ui.GradientClip; import org.telegram.ui.GradientClip;
import org.telegram.ui.bots.BotWebViewAttachedSheet;
import org.telegram.ui.bots.BotWebViewMenuContainer;
import org.telegram.ui.bots.BotWebViewSheet;
import java.util.ArrayList; import java.util.ArrayList;
public class BottomSheetTabsOverlay extends FrameLayout { public class BottomSheetTabsOverlay extends FrameLayout {
private BottomSheetTabs tabsView; public interface Sheet {
public SheetView getWindowView();
private BotWebViewAttachedSheet dismissingSheet; public void show();
private BotWebViewSheet dismissingSheet2; public void dismiss(boolean tabs);
private BotWebViewAttachedSheet openingSheet;
private BotWebViewMenuContainer dismissingMenuContainer; public BottomSheetTabs.WebTabData saveState();
public boolean restoreState(BaseFragment fragment, BottomSheetTabs.WebTabData tab);
public void release();
public boolean isFullSize();
public boolean setDialog(BottomSheetTabDialog dialog);
default void setLastVisible(boolean lastVisible) {};
public int getNavigationBarColor(int color);
}
public interface SheetView {
public Context getContext();
public void setDrawingFromOverlay(boolean value);
public RectF getRect();
public float drawInto(Canvas canvas, RectF finalRect, float progress, RectF clipRect, float alpha, boolean opening);
public boolean post(Runnable r);
}
private BottomSheetTabs tabsView;
private Sheet dismissingSheet;
private Sheet openingSheet;
private BottomSheetTabs.TabDrawable dismissingTab; private BottomSheetTabs.TabDrawable dismissingTab;
private BottomSheetTabs.TabDrawable openingTab; private BottomSheetTabs.TabDrawable openingTab;
private float openingTabScroll; private float openingTabScroll;
@ -361,6 +385,10 @@ public class BottomSheetTabsOverlay extends FrameLayout {
return Math.min(SharedConfig.botTabs3DEffect ? 3 : 6, getScrollRange()); return Math.min(SharedConfig.botTabs3DEffect ? 3 : 6, getScrollRange());
} }
public float getScrollWindow(boolean animated) {
return Math.min(SharedConfig.botTabs3DEffect ? 3 : 6, getScrollRange(animated));
}
public float getScrollMin() { public float getScrollMin() {
return getScrollMin(true); return getScrollMin(true);
} }
@ -374,7 +402,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
} }
public float getScrollMax(boolean animated) { public float getScrollMax(boolean animated) {
return getScrollRange(animated) - getScrollWindow() - getScrollWindow() / 3f * Utilities.clamp(4f - getScrollRange(animated), .5f, 0); return getScrollRange(animated) - getScrollWindow(animated) - getScrollWindow(animated) / 3f * Utilities.clamp(4f - getScrollRange(animated), .5f, 0);
} }
public boolean canScroll() { public boolean canScroll() {
@ -401,7 +429,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
this.slowerDismiss = slowerDismiss; this.slowerDismiss = slowerDismiss;
} }
public boolean openSheet(BotWebViewAttachedSheet sheet, BottomSheetTabs.WebTabData tab, Runnable whenOpened) { public boolean openSheet(Sheet sheet, BottomSheetTabs.WebTabData tab, Runnable whenOpened) {
if (sheet == null) return false; if (sheet == null) return false;
if (tabsView == null) return false; if (tabsView == null) return false;
@ -455,7 +483,14 @@ public class BottomSheetTabsOverlay extends FrameLayout {
return true; return true;
} }
public boolean dismissSheet(BotWebViewAttachedSheet sheet) { public void stopAnimations() {
if (animator != null) {
animator.cancel();
animator = null;
}
}
public boolean dismissSheet(Sheet sheet) {
if (sheet == null) return false; if (sheet == null) return false;
if (tabsView == null) return false; if (tabsView == null) return false;
@ -467,6 +502,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
} }
dismissingSheet = sheet; dismissingSheet = sheet;
sheet.setLastVisible(false);
sheet.getWindowView().setDrawingFromOverlay(true); sheet.getWindowView().setDrawingFromOverlay(true);
invalidate(); invalidate();
@ -477,10 +513,6 @@ public class BottomSheetTabsOverlay extends FrameLayout {
BottomSheetTabs.WebTabData tab = sheet.saveState(); BottomSheetTabs.WebTabData tab = sheet.saveState();
dismissingTab = tabsView.pushTab(tab); dismissingTab = tabsView.pushTab(tab);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
renderHardwareViewToBitmap(tab.webView, -tab.webViewScroll, b -> tab.previewBitmap = b);
}
dismissProgress = 0; dismissProgress = 0;
animator = ValueAnimator.ofFloat(0, 1); animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(anm -> { animator.addUpdateListener(anm -> {
@ -490,12 +522,16 @@ public class BottomSheetTabsOverlay extends FrameLayout {
animator.addListener(new AnimatorListenerAdapter() { animator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (tab.webView != null && tab.previewBitmap == null && tab.webViewWidth > 0 && tab.webViewHeight > 0) { sheet.getWindowView().setDrawingFromOverlay(false);
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) { View view = tab.webView != null ? tab.webView : tab.view2;
tab.previewBitmap = Bitmap.createBitmap(tab.webViewWidth, tab.webViewHeight, Bitmap.Config.RGB_565); if (view != null && tab.previewBitmap == null && tab.viewWidth > 0 && tab.viewHeight > 0) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
renderHardwareViewToBitmap(view, -tab.viewScroll, b -> tab.previewBitmap = b);
} else {
tab.previewBitmap = Bitmap.createBitmap(tab.viewWidth, tab.viewHeight, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tab.previewBitmap); Canvas canvas = new Canvas(tab.previewBitmap);
canvas.translate(0, -tab.webViewScroll); canvas.translate(0, -tab.viewScroll);
tab.webView.draw(canvas); view.draw(canvas);
} }
} }
sheet.release(); sheet.release();
@ -503,8 +539,8 @@ public class BottomSheetTabsOverlay extends FrameLayout {
invalidate(); invalidate();
} }
}); });
if (slowerDismiss || sheet.getFullSize()) { if (slowerDismiss || sheet.isFullSize()) {
AndroidUtilities.applySpring(animator, 260, 30, 1); AndroidUtilities.applySpring(animator, 220, 30, 1);
} else { } else {
AndroidUtilities.applySpring(animator, 350, 30, 1); AndroidUtilities.applySpring(animator, 350, 30, 1);
} }
@ -515,112 +551,6 @@ public class BottomSheetTabsOverlay extends FrameLayout {
return true; return true;
} }
public boolean dismissSheet(BotWebViewSheet sheet) {
if (sheet == null) return false;
if (tabsView == null) return false;
if (dismissingSheet != null || openingSheet != null) {
if (animator != null) {
animator.end();
animator = null;
}
}
dismissingSheet2 = sheet;
sheet.getWindowView().setDrawingFromOverlay(true);
invalidate();
if (animator != null) {
animator.cancel();
}
BottomSheetTabs.WebTabData tab = sheet.saveState();
dismissingTab = tabsView.pushTab(tab);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
renderHardwareViewToBitmap(tab.webView, -tab.webViewScroll, b -> tab.previewBitmap = b);
}
dismissProgress = 0;
animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(anm -> {
dismissProgress = (float) anm.getAnimatedValue();
invalidate();
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (tab.webView != null && tab.previewBitmap == null && tab.webViewWidth > 0 && tab.webViewHeight > 0) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
tab.previewBitmap = Bitmap.createBitmap(tab.webViewWidth, tab.webViewHeight, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tab.previewBitmap);
canvas.translate(0, -tab.webViewScroll);
tab.webView.draw(canvas);
}
}
sheet.release();
dismissingSheet2 = null;
invalidate();
}
});
AndroidUtilities.applySpring(animator, 350, 30, 1);
animator.setDuration(animator.getDuration() * 2);
animator.start();
slowerDismiss = false;
return true;
}
public boolean dismissSheet(BotWebViewMenuContainer menuContainer) {
if (menuContainer == null) return false;
if (tabsView == null) return false;
dismissingMenuContainer = menuContainer;
menuContainer.setDrawingFromOverlay(true);
invalidate();
if (animator != null) {
animator.cancel();
}
BottomSheetTabs.WebTabData tab = menuContainer.saveState();
dismissingTab = tabsView.pushTab(tab);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
renderHardwareViewToBitmap(tab.webView, -tab.webViewScroll, b -> tab.previewBitmap = b);
}
dismissProgress = 0;
animator = ValueAnimator.ofFloat(0, 1);
animator.addUpdateListener(anm -> {
dismissProgress = (float) anm.getAnimatedValue();
invalidate();
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (tab.webView != null && tab.previewBitmap == null && tab.webViewWidth > 0 && tab.webViewHeight > 0) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
tab.previewBitmap = Bitmap.createBitmap(tab.webViewWidth, tab.webViewHeight, Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tab.previewBitmap);
canvas.translate(0, -tab.webViewScroll);
tab.webView.draw(canvas);
}
}
menuContainer.onDismiss();
menuContainer.setDrawingFromOverlay(false);
dismissingMenuContainer = null;
invalidate();
}
});
AndroidUtilities.applySpring(animator, 350, 30, 1);
animator.setDuration(animator.getDuration());
animator.start();
return true;
}
public boolean onBackPressed() { public boolean onBackPressed() {
if (isOpen) { if (isOpen) {
closeTabsView(); closeTabsView();
@ -634,7 +564,9 @@ public class BottomSheetTabsOverlay extends FrameLayout {
private Paint blurBitmapPaint; private Paint blurBitmapPaint;
private Matrix blurMatrix; private Matrix blurMatrix;
private void prepareBlur(View view) { private void prepareBlur(View view) {
AndroidUtilities.makingGlobalBlurBitmap = true;
blurBitmap = AndroidUtilities.makeBlurBitmap(view, 14, 14); blurBitmap = AndroidUtilities.makeBlurBitmap(view, 14, 14);
AndroidUtilities.makingGlobalBlurBitmap = false;
blurBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); blurBitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
blurBitmapPaint.setShader(blurBitmapShader = new BitmapShader(blurBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)); blurBitmapPaint.setShader(blurBitmapShader = new BitmapShader(blurBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
@ -651,6 +583,8 @@ public class BottomSheetTabsOverlay extends FrameLayout {
public void openTabsView() { public void openTabsView() {
if (tabsView == null || !(tabsView.getParent() instanceof View)) return; if (tabsView == null || !(tabsView.getParent() instanceof View)) return;
stopAnimations();
actionBarLayout = (View) tabsView.getParent(); actionBarLayout = (View) tabsView.getParent();
if (actionBarLayout != null) { if (actionBarLayout != null) {
actionBarLayout.getLocationOnScreen(pos); actionBarLayout.getLocationOnScreen(pos);
@ -777,48 +711,6 @@ public class BottomSheetTabsOverlay extends FrameLayout {
canvas.restore(); canvas.restore();
} }
} }
if (dismissingSheet2 != null) {
BotWebViewSheet.WindowView windowView = dismissingSheet2.getWindowView();
getLocationOnScreen(pos2);
tabsView.getLocationOnScreen(pos);
tabsView.getTabBounds(rect, 0);
rect.offset(pos[0] - pos2[0], pos[1] - pos2[1]);
float radius = windowView.drawInto(canvas, rect, dismissProgress, clipRect);
if (dismissingTab != null) {
clipPath.rewind();
clipPath.addRoundRect(clipRect, radius, radius, Path.Direction.CW);
canvas.save();
canvas.clipPath(clipPath);
final float y = clipRect.top - dp(50) * (1f - dismissProgress);
rect.set(clipRect.left, y, clipRect.right, y + dp(50));
tabsView.setupTab(dismissingTab);
dismissingTab.draw(canvas, rect, radius, dismissProgress, 1f);
canvas.restore();
}
}
if (dismissingMenuContainer != null) {
getLocationOnScreen(pos2);
dismissingMenuContainer.getLocationOnScreen(pos3);
tabsView.getLocationOnScreen(pos);
tabsView.getTabBounds(rect, 0);
rect.offset(pos[0] - pos2[0], pos[1] - pos2[1]);
float radius = dismissingMenuContainer.drawInto(canvas, rect, dismissProgress, clipRect);
if (dismissingTab != null) {
clipPath.rewind();
clipPath.addRoundRect(clipRect, radius, radius, Path.Direction.CW);
canvas.save();
canvas.clipPath(clipPath);
final float y = clipRect.top - dp(50) * (1f - dismissProgress);
rect.set(clipRect.left, y, clipRect.right, y + dp(50));
tabsView.setupTab(dismissingTab);
dismissingTab.draw(canvas, rect, radius, dismissProgress, 1f);
canvas.restore();
}
}
} }
@Override @Override
@ -867,7 +759,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
final float paddingBottom = dp(68); final float paddingBottom = dp(68);
final int width = (int) Math.min(dp(340), thisWidth * .95f); final int width = (int) Math.min(dp(340), thisWidth * .95f);
final int height = (int) (AndroidUtilities.isTablet() ? Math.min(thisWidth, thisHeight) * .75f : thisHeight * .75f); final int height = (int) (AndroidUtilities.isTablet() ? tabsViewBounds.height() * .5f : thisHeight * .75f);
final float cx = thisWidth / 2f; final float cx = thisWidth / 2f;
float tabCount = 0; float tabCount = 0;
for (int i = 0; i < tabs.size(); ++i) { for (int i = 0; i < tabs.size(); ++i) {
@ -922,8 +814,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
boolean drawSimple = tab.tabDrawable != openingTab && (rect2.top > thisHeight || rect2.bottom < 0 || open < .1f) && position < count - 3; boolean drawSimple = tab.tabDrawable != openingTab && (rect2.top > thisHeight || rect2.bottom < 0 || open < .1f) && position < count - 3;
if (openingSheet != null && tab.tabDrawable == openingTab) { if (openingSheet != null && tab.tabDrawable == openingTab) {
BotWebViewAttachedSheet.WindowView windowView = openingSheet.getWindowView(); rect.set(openingSheet.getWindowView().getRect());
rect.set(windowView.getRect());
AndroidUtilities.lerpCentered(rect2, rect, opening, rect2); AndroidUtilities.lerpCentered(rect2, rect, opening, rect2);
} else { } else {
tabsView.getTabBounds(rect, Utilities.clamp(tab.tabDrawable.getPosition(), 1, 0)); tabsView.getTabBounds(rect, Utilities.clamp(tab.tabDrawable.getPosition(), 1, 0));
@ -979,8 +870,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
); );
if (openingSheet != null && tab.tabDrawable == openingTab) { if (openingSheet != null && tab.tabDrawable == openingTab) {
BotWebViewAttachedSheet.WindowView windowView = openingSheet.getWindowView(); openingSheet.getWindowView().drawInto(canvas, rect2, 1f, rect2, opening, true);
windowView.drawInto(canvas, rect2, 1f, rect2, opening, true);
} }
canvas.restore(); canvas.restore();
@ -995,7 +885,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
openProgress openProgress
); );
canvas.scale(s, s, rect2.centerX(), rect2.top); canvas.scale(s, s, rect2.centerX(), rect2.top);
scale(tab.clickBounds, s, rect.centerX(), rect2.top); scaleRect(tab.clickBounds, s, rect.centerX(), rect2.top);
tab.draw(canvas, rect2, drawSimple, lerp(tab.tabDrawable.getAlpha(), 1f, openProgress), open, 0f, lerp(clamp01(position - count + 2), 1f, clamp01((open - .1f) / .8f))); tab.draw(canvas, rect2, drawSimple, lerp(tab.tabDrawable.getAlpha(), 1f, openProgress), open, 0f, lerp(clamp01(position - count + 2), 1f, clamp01((open - .1f) / .8f)));
canvas.restore(); canvas.restore();
@ -1036,17 +926,6 @@ public class BottomSheetTabsOverlay extends FrameLayout {
canvas.restore(); canvas.restore();
} }
private void scale(RectF rect, float s, float px, float py) {
final float wl = px - rect.left, wr = rect.right - px;
final float ht = py - rect.top, hb = rect.bottom - py;
rect.set(
px - wl * s,
py - ht * s,
px + wr * s,
py + hb * s
);
}
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas); super.dispatchDraw(canvas);
@ -1062,9 +941,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
public final View parentView; public final View parentView;
public final BottomSheetTabs.WebTabData tabData; public final BottomSheetTabs.WebTabData tabData;
public final BottomSheetTabs.TabDrawable tabDrawable; public final BottomSheetTabs.TabDrawable tabDrawable;
public final Bitmap previewBitmap;
public WebView webView; public WebView webView;
public final Object previewNode;
private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ -1122,9 +999,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
this.parentView = parentView; this.parentView = parentView;
this.tabData = tabData; this.tabData = tabData;
this.tabDrawable = tabDrawable; this.tabDrawable = tabDrawable;
this.previewBitmap = tabData.previewBitmap;
this.webView = null;// tabData.webView; this.webView = null;// tabData.webView;
this.previewNode = tabData.previewNode;
this.bounce = new ButtonBounce(parentView); this.bounce = new ButtonBounce(parentView);
backgroundPaint.setColor(tabData.backgroundColor); backgroundPaint.setColor(tabData.backgroundColor);
@ -1155,7 +1030,7 @@ public class BottomSheetTabsOverlay extends FrameLayout {
final float s = bounce.getScale(.01f); final float s = bounce.getScale(.01f);
canvas.scale(s, s, bounds.centerX(), bounds.centerY()); canvas.scale(s, s, bounds.centerX(), bounds.centerY());
final float r = lerp(dp(10), dp(8), expandProgress); final float r = lerp(dp(10), dp(6), expandProgress);
if (simple) { if (simple) {
shadowPaint.setColor(0); shadowPaint.setColor(0);
shadowPaint.setShadowLayer(dp(30), 0, dp(10), Theme.multAlpha(0x20000000, alpha * expandProgress * (1f - openingProgress))); shadowPaint.setShadowLayer(dp(30), 0, dp(10), Theme.multAlpha(0x20000000, alpha * expandProgress * (1f - openingProgress)));
@ -1174,23 +1049,23 @@ public class BottomSheetTabsOverlay extends FrameLayout {
canvas.drawPath(clipPath, shadowPaint); canvas.drawPath(clipPath, shadowPaint);
canvas.clipPath(clipPath); canvas.clipPath(clipPath);
backgroundPaint.setAlpha((int) (0xFF * alpha)); backgroundPaint.setAlpha((int) (0xFF * alpha * expandProgress));
canvas.drawRoundRect(bounds, r, r, backgroundPaint); canvas.drawRoundRect(bounds, r, r, backgroundPaint);
canvas.save(); canvas.save();
canvas.translate(bounds.left, bounds.top + dp(50) * tabScaleY + tabTranslateY); canvas.translate(bounds.left, bounds.top + dp(50) * tabScaleY + tabTranslateY);
canvas.scale(1f, lerp(1f, 1.25f, expandProgress * (1f - openingProgress))); canvas.scale(1f, lerp(1f, 1.25f, expandProgress * (1f - openingProgress)));
if (previewNode != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && ((RenderNode) previewNode).hasDisplayList()) { if (tabData != null && tabData.previewNode != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && ((RenderNode) tabData.previewNode).hasDisplayList()) {
RenderNode node = (RenderNode) previewNode; RenderNode node = (RenderNode) tabData.previewNode;
final float s2 = bounds.width() / node.getWidth(); final float s2 = bounds.width() / node.getWidth();
canvas.scale(s2, s2); canvas.scale(s2, s2);
node.setAlpha(alpha * expandProgress); node.setAlpha(alpha * expandProgress);
canvas.drawRenderNode(node); canvas.drawRenderNode(node);
} else if (previewBitmap != null) { } else if (tabData != null && tabData.previewBitmap != null) {
final float s2 = bounds.width() / previewBitmap.getWidth(); final float s2 = bounds.width() / tabData.previewBitmap.getWidth();
canvas.scale(s2, s2); canvas.scale(s2, s2);
bitmapPaint.setAlpha((int) (0xFF * alpha * expandProgress)); bitmapPaint.setAlpha((int) (0xFF * alpha * expandProgress));
canvas.drawBitmap(previewBitmap, 0, 0, bitmapPaint); canvas.drawBitmap(tabData.previewBitmap, 0, 0, bitmapPaint);
} else if (webView != null) { } else if (webView != null) {
final float s2 = bounds.width() / webView.getWidth(); final float s2 = bounds.width() / webView.getWidth();
canvas.scale(s2, s2); canvas.scale(s2, s2);

View file

@ -47,6 +47,7 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.PasscodeView; import org.telegram.ui.Components.PasscodeView;
import org.telegram.ui.Stars.SuperRipple;
public class DrawerLayoutContainer extends FrameLayout { public class DrawerLayoutContainer extends FrameLayout {
@ -449,7 +450,7 @@ public class DrawerLayoutContainer extends FrameLayout {
return true; return true;
} }
if ((allowOpenDrawerBySwipe || drawerOpened) && allowOpenDrawer && parentActionBarLayout.getFragmentStack().size() == 1 && (parentActionBarLayout.getLastFragment().getLastSheet() == null || !parentActionBarLayout.getLastFragment().getLastSheet().attachedToParent())) { if ((allowOpenDrawerBySwipe || drawerOpened) && allowOpenDrawer && parentActionBarLayout.getFragmentStack().size() == 1 && parentActionBarLayout.allowSwipe() && (parentActionBarLayout.getLastFragment().getLastSheet() == null || !parentActionBarLayout.getLastFragment().getLastSheet().attachedToParent())) {
if (ev != null && (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_MOVE) && !startedTracking && !maybeStartTracking) { if (ev != null && (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_MOVE) && !startedTracking && !maybeStartTracking) {
View scrollingChild = findScrollingChild(this, ev.getX(),ev.getY()); View scrollingChild = findScrollingChild(this, ev.getX(),ev.getY());
if (scrollingChild != null) { if (scrollingChild != null) {

View file

@ -41,6 +41,7 @@ public interface INavigationLayout {
void setFragmentStackChangedListener(Runnable onFragmentStackChanged); void setFragmentStackChangedListener(Runnable onFragmentStackChanged);
boolean isTransitionAnimationInProgress(); boolean isTransitionAnimationInProgress();
void resumeDelayedFragmentAnimation(); void resumeDelayedFragmentAnimation();
boolean allowSwipe();
boolean isInPassivePreviewMode(); boolean isInPassivePreviewMode();
void setInBubbleMode(boolean bubbleMode); void setInBubbleMode(boolean bubbleMode);

View file

@ -282,7 +282,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
return size; return size;
} }
public Paint getPaint() { public TextPaint getPaint() {
return textPaint; return textPaint;
} }

View file

@ -4160,6 +4160,11 @@ public class Theme {
public static final int key_code_comment = colorsCount++; public static final int key_code_comment = colorsCount++;
public static final int key_code_function = colorsCount++; public static final int key_code_function = colorsCount++;
public static final int key_iv_background = colorsCount++;
public static final int key_iv_backgroundGray = colorsCount++;
public static final int key_iv_ab_progress = colorsCount++;
public static final int key_iv_navigationBackground = colorsCount++;
public static final String key_drawable_botInline = "drawableBotInline"; public static final String key_drawable_botInline = "drawableBotInline";
public static final String key_drawable_botLink = "drawableBotLink"; public static final String key_drawable_botLink = "drawableBotLink";
public static final String key_drawable_botWebView = "drawableBotWebView"; public static final String key_drawable_botWebView = "drawableBotWebView";
@ -4248,6 +4253,10 @@ public class Theme {
static { static {
defaultColors = ThemeColors.createDefaultColors(); defaultColors = ThemeColors.createDefaultColors();
fallbackKeys.put(key_iv_background, key_windowBackgroundWhite);
fallbackKeys.put(key_iv_backgroundGray, key_windowBackgroundGray);
fallbackKeys.put(key_iv_navigationBackground, key_windowBackgroundGray);
fallbackKeys.put(key_iv_ab_progress, key_featuredStickers_addButton);
fallbackKeys.put(key_chat_inQuote, key_featuredStickers_addButtonPressed); fallbackKeys.put(key_chat_inQuote, key_featuredStickers_addButtonPressed);
fallbackKeys.put(key_chat_outQuote, key_chat_outReplyLine); fallbackKeys.put(key_chat_outQuote, key_chat_outReplyLine);
fallbackKeys.put(key_chat_outReplyLine2, key_chat_outReplyLine); fallbackKeys.put(key_chat_outReplyLine2, key_chat_outReplyLine);
@ -5222,6 +5231,21 @@ public class Theme {
return defaultDrawable; return defaultDrawable;
} }
public static ShapeDrawable createCircleDrawable(int size, int colorTop, int colorBottom) {
OvalShape ovalShape = new OvalShape();
ovalShape.resize(size, size);
ShapeDrawable defaultDrawable = new ShapeDrawable(ovalShape);
defaultDrawable.setIntrinsicWidth(size);
defaultDrawable.setIntrinsicHeight(size);
LinearGradient gradient = new LinearGradient(
0, 0, 0, size,
colorTop, colorBottom,
Shader.TileMode.CLAMP
);
defaultDrawable.getPaint().setShader(gradient);
return defaultDrawable;
}
public static CombinedDrawable createCircleDrawableWithIcon(int size, int iconRes) { public static CombinedDrawable createCircleDrawableWithIcon(int size, int iconRes) {
return createCircleDrawableWithIcon(size, iconRes, 0); return createCircleDrawableWithIcon(size, iconRes, 0);
} }
@ -5314,13 +5338,13 @@ public class Theme {
} }
} }
public static Drawable createRoundRectDrawable(int rad, int defaultColor) { public static ShapeDrawable createRoundRectDrawable(int rad, int defaultColor) {
ShapeDrawable defaultDrawable = new ShapeDrawable(new RoundRectShape(new float[]{rad, rad, rad, rad, rad, rad, rad, rad}, null, null)); ShapeDrawable defaultDrawable = new ShapeDrawable(new RoundRectShape(new float[]{rad, rad, rad, rad, rad, rad, rad, rad}, null, null));
defaultDrawable.getPaint().setColor(defaultColor); defaultDrawable.getPaint().setColor(defaultColor);
return defaultDrawable; return defaultDrawable;
} }
public static Drawable createRoundRectDrawable(int topRad, int bottomRad, int defaultColor) { public static ShapeDrawable createRoundRectDrawable(int topRad, int bottomRad, int defaultColor) {
ShapeDrawable defaultDrawable = new ShapeDrawable(new RoundRectShape(new float[]{topRad, topRad, topRad, topRad, bottomRad, bottomRad, bottomRad, bottomRad}, null, null)); ShapeDrawable defaultDrawable = new ShapeDrawable(new RoundRectShape(new float[]{topRad, topRad, topRad, topRad, bottomRad, bottomRad, bottomRad, bottomRad}, null, null));
defaultDrawable.getPaint().setColor(defaultColor); defaultDrawable.getPaint().setColor(defaultColor);
return defaultDrawable; return defaultDrawable;
@ -10543,6 +10567,10 @@ public class Theme {
} }
} }
public interface Colorable {
public void updateColors();
}
public static Paint DEBUG_RED = new Paint(); static { DEBUG_RED.setColor(0xffff0000); } public static Paint DEBUG_RED = new Paint(); static { DEBUG_RED.setColor(0xffff0000); }
public static Paint DEBUG_BLUE = new Paint(); static { DEBUG_BLUE.setColor(0xff0000ff); } public static Paint DEBUG_BLUE = new Paint(); static { DEBUG_BLUE.setColor(0xff0000ff); }
} }

View file

@ -790,6 +790,11 @@ public class ThemeColors {
defaultColors[key_code_comment] = 0x80000000; defaultColors[key_code_comment] = 0x80000000;
defaultColors[key_code_function] = 0xFFF28C39; defaultColors[key_code_function] = 0xFFF28C39;
defaultColors[key_iv_background] = 0xFFFFFFFF;
defaultColors[key_iv_backgroundGray] = 0xfff0f0f0;
defaultColors[key_iv_ab_progress] = 0xff50a8eb;
defaultColors[key_iv_navigationBackground] = 0xfff0f0f0;
return defaultColors; return defaultColors;
} }
@ -1538,6 +1543,10 @@ public class ThemeColors {
colorKeysMap.put(key_code_number, "code_number"); colorKeysMap.put(key_code_number, "code_number");
colorKeysMap.put(key_code_comment, "code_comment"); colorKeysMap.put(key_code_comment, "code_comment");
colorKeysMap.put(key_code_function, "code_function"); colorKeysMap.put(key_code_function, "code_function");
colorKeysMap.put(key_iv_background, "iv_background");
colorKeysMap.put(key_iv_backgroundGray, "iv_backgroundGray");
colorKeysMap.put(key_iv_navigationBackground, "iv_navigationBackground");
colorKeysMap.put(key_iv_ab_progress, "iv_ab_progress");
return colorKeysMap; return colorKeysMap;
} }

View file

@ -46,6 +46,7 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.RequestDelegate; import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_bots;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Business.QuickRepliesActivity; import org.telegram.ui.Business.QuickRepliesActivity;
@ -103,7 +104,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
private TLRPC.TL_inlineBotSwitchPM searchResultBotContextSwitch; private TLRPC.TL_inlineBotSwitchPM searchResultBotContextSwitch;
private TLRPC.TL_inlineBotWebView searchResultBotWebViewSwitch; private TLRPC.TL_inlineBotWebView searchResultBotWebViewSwitch;
private MentionsAdapterDelegate delegate; private MentionsAdapterDelegate delegate;
private LongSparseArray<TLRPC.BotInfo> botInfo; private LongSparseArray<TL_bots.BotInfo> botInfo;
private int resultStartPosition; private int resultStartPosition;
private int resultLength; private int resultLength;
private String lastText; private String lastText;
@ -494,7 +495,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
needBotContext = value; needBotContext = value;
} }
public void setBotInfo(LongSparseArray<TLRPC.BotInfo> info) { public void setBotInfo(LongSparseArray<TL_bots.BotInfo> info) {
botInfo = info; botInfo = info;
} }
@ -1417,7 +1418,7 @@ public class MentionsAdapter extends RecyclerListView.SelectionAdapter implement
ArrayList<TLRPC.User> newResultUsers = new ArrayList<>(); ArrayList<TLRPC.User> newResultUsers = new ArrayList<>();
String command = result.toString().toLowerCase(); String command = result.toString().toLowerCase();
for (int b = 0; b < botInfo.size(); b++) { for (int b = 0; b < botInfo.size(); b++) {
TLRPC.BotInfo info = botInfo.valueAt(b); TL_bots.BotInfo info = botInfo.valueAt(b);
for (int a = 0; a < info.commands.size(); a++) { for (int a = 0; a < info.commands.size(); a++) {
TLRPC.TL_botCommand botCommand = info.commands.get(a); TLRPC.TL_botCommand botCommand = info.commands.get(a);
if (botCommand != null && botCommand.command != null && botCommand.command.startsWith(command)) { if (botCommand != null && botCommand.command != null && botCommand.command.startsWith(command)) {

View file

@ -86,8 +86,8 @@ public class MessagesSearchAdapter extends RecyclerListView.SelectionAdapter imp
}; };
public void searchStories(String hashtag, boolean instant) { public void searchStories(String hashtag, boolean instant) {
if (hashtag.startsWith("$")) hashtag = ""; // if (hashtag.startsWith("$")) hashtag = hashtag.substring(1);
if (hashtag.startsWith("#")) hashtag = hashtag.substring(1); // if (hashtag.startsWith("#")) hashtag = hashtag.substring(1);
final String currentHashtag = storiesList == null ? "" : storiesList.query; final String currentHashtag = storiesList == null ? "" : storiesList.query;
if (TextUtils.equals(currentHashtag, hashtag)) return; if (TextUtils.equals(currentHashtag, hashtag)) return;

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@ import static org.telegram.messenger.AndroidUtilities.dp;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.Spannable; import android.text.Spannable;
import android.text.style.ReplacementSpan; import android.text.style.ReplacementSpan;
import android.util.Log; import android.util.Log;
@ -36,6 +37,7 @@ public class AvatarSpan extends ReplacementSpan {
public AvatarSpan(View parent, int currentAccount, float sz) { public AvatarSpan(View parent, int currentAccount, float sz) {
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.imageReceiver = new ImageReceiver(parent); this.imageReceiver = new ImageReceiver(parent);
imageReceiver.setInvalidateAll(true);
this.avatarDrawable = new AvatarDrawable(); this.avatarDrawable = new AvatarDrawable();
setSize(sz); setSize(sz);
@ -112,6 +114,10 @@ public class AvatarSpan extends ReplacementSpan {
imageReceiver.setForUserOrChat(null, avatarDrawable); imageReceiver.setForUserOrChat(null, avatarDrawable);
} }
public void setImageDrawable(Drawable drawable) {
imageReceiver.setImageBitmap(drawable);
}
@Override @Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) { public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
return dp(sz); return dp(sz);

View file

@ -41,6 +41,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_bots;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LinkPath; import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.LinkSpanDrawable; import org.telegram.ui.Components.LinkSpanDrawable;
@ -109,7 +110,7 @@ public class BotHelpCell extends View {
setText(bot, text, null, null); setText(bot, text, null, null);
} }
public void setText(boolean bot, String text, TLObject imageOrAnimation, TLRPC.BotInfo botInfo) { public void setText(boolean bot, String text, TLObject imageOrAnimation, TL_bots.BotInfo botInfo) {
boolean photoVisible = imageOrAnimation != null; boolean photoVisible = imageOrAnimation != null;
boolean textVisible = !TextUtils.isEmpty(text); boolean textVisible = !TextUtils.isEmpty(text);
if ((text == null || text.length() == 0) && !photoVisible) { if ((text == null || text.length() == 0) && !photoVisible) {

View file

@ -9,6 +9,9 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp; import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.LocaleController.formatPluralStringComma;
import static org.telegram.messenger.LocaleController.formatString;
import static org.telegram.messenger.LocaleController.getString;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
@ -68,6 +71,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper; import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser; import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;
@ -97,6 +101,7 @@ import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PhotoViewer; import org.telegram.ui.PhotoViewer;
import org.telegram.ui.ProfileActivity; import org.telegram.ui.ProfileActivity;
import org.telegram.ui.Stars.StarsIntroActivity;
import org.telegram.ui.Stories.StoriesUtilities; import org.telegram.ui.Stories.StoriesUtilities;
import org.telegram.ui.Stories.UploadingDotsSpannable; import org.telegram.ui.Stories.UploadingDotsSpannable;
import org.telegram.ui.Stories.recorder.HintView2; import org.telegram.ui.Stories.recorder.HintView2;
@ -395,9 +400,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
CharSequence newText; CharSequence newText;
if (scheduled) { if (scheduled) {
if (date == 0x7ffffffe) { if (date == 0x7ffffffe) {
newText = LocaleController.getString("MessageScheduledUntilOnline", R.string.MessageScheduledUntilOnline); newText = getString("MessageScheduledUntilOnline", R.string.MessageScheduledUntilOnline);
} else { } else {
newText = LocaleController.formatString("MessageScheduledOn", R.string.MessageScheduledOn, LocaleController.formatDateChat(date)); newText = formatString("MessageScheduledOn", R.string.MessageScheduledOn, LocaleController.formatDateChat(date));
} }
} else { } else {
newText = LocaleController.formatDateChat(date); newText = LocaleController.formatDateChat(date);
@ -573,7 +578,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else { } else {
radialProgress.setIcon(MediaActionDrawable.ICON_CANCEL, !messageIdChanged, !messageIdChanged); radialProgress.setIcon(MediaActionDrawable.ICON_CANCEL, !messageIdChanged, !messageIdChanged);
} }
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) { } else if (messageObject.type == MessageObject.TYPE_GIFT_STARS || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
imageReceiver.setRoundRadius(0); imageReceiver.setRoundRadius(0);
if (USE_PREMIUM_GIFT_LOCAL_STICKER) { if (USE_PREMIUM_GIFT_LOCAL_STICKER) {
@ -595,37 +600,62 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(packName); set = MediaDataController.getInstance(currentAccount).getStickerSetByEmojiOrName(packName);
} }
if (set != null) { if (set != null) {
int months = messageObject.messageOwner.action.months; int months = messageObject.messageOwner.action.months;
String monthsEmoticon; String monthsEmoticon;
if (USE_PREMIUM_GIFT_MONTHS_AS_EMOJI_NUMBERS) { if (messageObject.type == MessageObject.TYPE_GIFT_STARS) {
StringBuilder monthsEmoticonBuilder = new StringBuilder(); final long stars = ((TLRPC.TL_messageActionGiftStars) messageObject.messageOwner.action).stars;
while (months > 0) { String emoji;
monthsEmoticonBuilder.insert(0, (months % 10) + "\u20E3"); if (stars <= 1000) {
months /= 10; emoji = "2⃣";
} else if (stars < 2500) {
emoji = "3⃣";
} else {
emoji = "4⃣";
} }
monthsEmoticon = monthsEmoticonBuilder.toString(); for (int i = 0; i < set.packs.size(); ++i) {
} else { TLRPC.TL_stickerPack pack = set.packs.get(i);
monthsEmoticon = monthsToEmoticon.get(months); if (TextUtils.equals(pack.emoticon, emoji) && !pack.documents.isEmpty()) {
} long documentId = pack.documents.get(0);
for (TLRPC.TL_stickerPack pack : set.packs) { for (int j = 0; j < set.documents.size(); ++j) {
if (Objects.equals(pack.emoticon, monthsEmoticon)) { TLRPC.Document d = set.documents.get(j);
for (long id : pack.documents) { if (d != null && d.id == documentId) {
for (TLRPC.Document doc : set.documents) { document = d;
if (doc.id == id) {
document = doc;
break; break;
} }
} }
if (document != null) { break;
break;
}
} }
} }
if (document != null) { } else {
break; if (USE_PREMIUM_GIFT_MONTHS_AS_EMOJI_NUMBERS) {
StringBuilder monthsEmoticonBuilder = new StringBuilder();
while (months > 0) {
monthsEmoticonBuilder.insert(0, (months % 10) + "\u20E3");
months /= 10;
}
monthsEmoticon = monthsEmoticonBuilder.toString();
} else {
monthsEmoticon = monthsToEmoticon.get(months);
}
for (TLRPC.TL_stickerPack pack : set.packs) {
if (Objects.equals(pack.emoticon, monthsEmoticon)) {
for (long id : pack.documents) {
for (TLRPC.Document doc : set.documents) {
if (doc.id == id) {
document = doc;
break;
}
}
if (document != null) {
break;
}
}
}
if (document != null) {
break;
}
} }
} }
if (document == null && !set.documents.isEmpty()) { if (document == null && !set.documents.isEmpty()) {
document = set.documents.get(0); document = set.documents.get(0);
} }
@ -841,10 +871,14 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
bounce.setPressed(false); bounce.setPressed(false);
if (delegate != null) { if (delegate != null) {
if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) { if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
playSoundEffect(SoundEffectConstants.CLICK);
openPremiumGiftChannel(); openPremiumGiftChannel();
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
playSoundEffect(SoundEffectConstants.CLICK); playSoundEffect(SoundEffectConstants.CLICK);
openPremiumGiftPreview(); openPremiumGiftPreview();
} else if (messageObject.type == MessageObject.TYPE_GIFT_STARS) {
playSoundEffect(SoundEffectConstants.CLICK);
openStarsGiftTransaction();
} else { } else {
ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id); ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id);
if (imageUpdater == null) { if (imageUpdater == null) {
@ -877,6 +911,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
openPremiumGiftChannel(); openPremiumGiftChannel();
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
openPremiumGiftPreview(); openPremiumGiftPreview();
} else if (messageObject.type == MessageObject.TYPE_GIFT_STARS) {
openStarsGiftTransaction();
} else if (delegate != null) { } else if (delegate != null) {
boolean consumed = false; boolean consumed = false;
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) { if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
@ -959,9 +995,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
private boolean isSelfGiftCode() { private boolean isSelfGiftCode() {
if (currentMessageObject != null && currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) { if (currentMessageObject != null && (currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftCode || currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftStars)) {
if (currentMessageObject.messageOwner.from_id instanceof TLRPC.TL_peerUser) { if (currentMessageObject.messageOwner.from_id instanceof TLRPC.TL_peerUser) {
return MessagesController.getInstance(currentAccount).getUser(currentMessageObject.messageOwner.from_id.user_id).self; return UserObject.isUserSelf(MessagesController.getInstance(currentAccount).getUser(currentMessageObject.messageOwner.from_id.user_id));
} }
} }
return false; return false;
@ -988,6 +1024,12 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
} }
private void openStarsGiftTransaction() {
if (currentMessageObject == null || currentMessageObject.messageOwner == null) return;
if (!(currentMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionGiftStars)) return;
StarsIntroActivity.showTransactionSheet(getContext(), currentAccount, currentMessageObject.messageOwner.date, currentMessageObject.messageOwner.from_id, currentMessageObject.messageOwner.peer_id, (TLRPC.TL_messageActionGiftStars) currentMessageObject.messageOwner.action, avatarStoryParams.resourcesProvider);
}
private void openLink(CharacterStyle link) { private void openLink(CharacterStyle link) {
if (delegate != null && link instanceof URLSpan) { if (delegate != null && link instanceof URLSpan) {
String url = ((URLSpan) link).getURL(); String url = ((URLSpan) link).getURL();
@ -1102,7 +1144,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
if (isButtonLayout(messageObject)) { if (isButtonLayout(messageObject)) {
giftRectSize = Math.min((int) (AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() * 0.6f : AndroidUtilities.displaySize.x * 0.62f - dp(34)), AndroidUtilities.displaySize.y - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - dp(64)); giftRectSize = Math.min((int) (AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() * 0.6f : AndroidUtilities.displaySize.x * 0.62f - dp(34)), AndroidUtilities.displaySize.y - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - dp(64));
if (!AndroidUtilities.isTablet() && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) { if (!AndroidUtilities.isTablet() && (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_GIFT_STARS)) {
giftRectSize = (int) (giftRectSize * 1.2f); giftRectSize = (int) (giftRectSize * 1.2f);
} }
stickerSize = giftRectSize - dp(106); stickerSize = giftRectSize - dp(106);
@ -1146,7 +1188,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
giftPremiumAdditionalHeight -= dp(30); giftPremiumAdditionalHeight -= dp(30);
} }
if (giftPremiumSubtitleLayout.getLineCount() > 2) { if (currentMessageObject.type == MessageObject.TYPE_GIFT_STARS) {
giftPremiumAdditionalHeight += giftPremiumSubtitleLayout.getHeight() - dp(20);
} else if (giftPremiumSubtitleLayout.getLineCount() > 2) {
giftPremiumAdditionalHeight += (giftPremiumSubtitleLayout.getLineBottom(0) - giftPremiumSubtitleLayout.getLineTop(0)) * giftPremiumSubtitleLayout.getLineCount() - 2; giftPremiumAdditionalHeight += (giftPremiumSubtitleLayout.getLineBottom(0) - giftPremiumSubtitleLayout.getLineTop(0)) * giftPremiumSubtitleLayout.getLineCount() - 2;
} }
@ -1225,14 +1269,14 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (text == null) { if (text == null) {
if (messageObject.messageOwner != null && messageObject.messageOwner.media != null && messageObject.messageOwner.media.ttl_seconds != 0) { if (messageObject.messageOwner != null && messageObject.messageOwner.media != null && messageObject.messageOwner.media.ttl_seconds != 0) {
if (messageObject.messageOwner.media.photo != null) { if (messageObject.messageOwner.media.photo != null) {
text = LocaleController.getString(R.string.AttachPhotoExpired); text = getString(R.string.AttachPhotoExpired);
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_documentEmpty || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && messageObject.messageOwner.media.document == null) { } else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_documentEmpty || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && messageObject.messageOwner.media.document == null) {
if (messageObject.messageOwner.media.voice) { if (messageObject.messageOwner.media.voice) {
text = LocaleController.getString(R.string.AttachVoiceExpired); text = getString(R.string.AttachVoiceExpired);
} else if (messageObject.messageOwner.media.round) { } else if (messageObject.messageOwner.media.round) {
text = LocaleController.getString(R.string.AttachRoundExpired); text = getString(R.string.AttachRoundExpired);
} else { } else {
text = LocaleController.getString(R.string.AttachVideoExpired); text = getString(R.string.AttachVideoExpired);
} }
} else { } else {
text = AnimatedEmojiSpan.cloneSpans(messageObject.messageText); text = AnimatedEmojiSpan.cloneSpans(messageObject.messageText);
@ -1250,10 +1294,19 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imageReceiver.setImageCoords((previousWidth - AndroidUtilities.roundMessageSize) / 2f, textHeight + dp(19), AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize); imageReceiver.setImageCoords((previousWidth - AndroidUtilities.roundMessageSize) / 2f, textHeight + dp(19), AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize);
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
createGiftPremiumChannelLayouts(); createGiftPremiumChannelLayouts();
} else if (messageObject.type == MessageObject.TYPE_GIFT_STARS) {
final TLRPC.TL_messageActionGiftStars action = (TLRPC.TL_messageActionGiftStars) messageObject.messageOwner.action;
final TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(currentMessageObject.getDialogId());
createGiftPremiumLayouts(
formatPluralStringComma("ActionGiftStarsTitle", (int) action.stars),
AndroidUtilities.replaceTags(currentMessageObject.isOutOwner() ? formatString(R.string.ActionGiftStarsSubtitle, UserObject.getForcedFirstName(user)) : getString(R.string.ActionGiftStarsSubtitleYou)),
getString(R.string.ActionGiftStarsView),
giftRectSize,
true
);
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
String actionName = isGiftCode() && !isSelfGiftCode() ? LocaleController.getString("GiftPremiumUseGiftBtn", R.string.GiftPremiumUseGiftBtn) : String actionName = getString(isGiftCode() && !isSelfGiftCode() ? R.string.GiftPremiumUseGiftBtn : R.string.ActionGiftPremiumView);
LocaleController.getString("ActionGiftPremiumView", R.string.ActionGiftPremiumView); createGiftPremiumLayouts(getString(R.string.ActionGiftPremiumTitle), formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), actionName, giftRectSize, true);
createGiftPremiumLayouts(LocaleController.getString(R.string.ActionGiftPremiumTitle), LocaleController.formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), actionName, giftRectSize, true);
} else if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) { } else if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
TLRPC.TL_messageActionSuggestProfilePhoto actionSuggestProfilePhoto = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action; TLRPC.TL_messageActionSuggestProfilePhoto actionSuggestProfilePhoto = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action;
String description; String description;
@ -1262,22 +1315,22 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (user.id == UserConfig.getInstance(currentAccount).clientUserId) { if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId()); TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId());
if (isVideo) { if (isVideo) {
description = LocaleController.formatString(R.string.ActionSuggestVideoFromYouDescription, user2.first_name); description = formatString(R.string.ActionSuggestVideoFromYouDescription, user2.first_name);
} else { } else {
description = LocaleController.formatString(R.string.ActionSuggestPhotoFromYouDescription, user2.first_name); description = formatString(R.string.ActionSuggestPhotoFromYouDescription, user2.first_name);
} }
} else { } else {
if (isVideo) { if (isVideo) {
description = LocaleController.formatString(R.string.ActionSuggestVideoToYouDescription, user.first_name); description = formatString(R.string.ActionSuggestVideoToYouDescription, user.first_name);
} else { } else {
description = LocaleController.formatString(R.string.ActionSuggestPhotoToYouDescription, user.first_name); description = formatString(R.string.ActionSuggestPhotoToYouDescription, user.first_name);
} }
} }
String action; String action;
if (actionSuggestProfilePhoto.video || (actionSuggestProfilePhoto.photo.video_sizes != null && !actionSuggestProfilePhoto.photo.video_sizes.isEmpty())) { if (actionSuggestProfilePhoto.video || (actionSuggestProfilePhoto.photo.video_sizes != null && !actionSuggestProfilePhoto.photo.video_sizes.isEmpty())) {
action = LocaleController.getString(R.string.ViewVideoAction); action = getString(R.string.ViewVideoAction);
} else { } else {
action = LocaleController.getString(R.string.ViewPhotoAction); action = getString(R.string.ViewPhotoAction);
} }
createGiftPremiumLayouts(null, description, action, giftRectSize, true); createGiftPremiumLayouts(null, description, action, giftRectSize, true);
textLayout = null; textLayout = null;
@ -1292,13 +1345,13 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
description = messageObject.messageText; description = messageObject.messageText;
} else if (!messageObject.isOutOwner() && messageObject.isWallpaperForBoth() && messageObject.isCurrentWallpaper()) { } else if (!messageObject.isOutOwner() && messageObject.isWallpaperForBoth() && messageObject.isCurrentWallpaper()) {
description = messageObject.messageText; description = messageObject.messageText;
action = LocaleController.getString(R.string.RemoveWallpaperAction); action = getString(R.string.RemoveWallpaperAction);
actionClickableAsImage = false; actionClickableAsImage = false;
} else if (user != null && user.id == UserConfig.getInstance(currentAccount).clientUserId) { } else if (user != null && user.id == UserConfig.getInstance(currentAccount).clientUserId) {
description = messageObject.messageText; description = messageObject.messageText;
} else { } else {
description = messageObject.messageText; description = messageObject.messageText;
action = LocaleController.getString(R.string.ViewWallpaperAction); action = getString(R.string.ViewWallpaperAction);
} }
createGiftPremiumLayouts(null, description, action, giftRectSize, actionClickableAsImage); createGiftPremiumLayouts(null, description, action, giftRectSize, actionClickableAsImage);
textLayout = null; textLayout = null;
@ -1311,11 +1364,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (user.self) { if (user.self) {
TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId()); TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId());
description = AndroidUtilities.replaceTags(LocaleController.formatString("StoryYouMentionedTitle", R.string.StoryYouMentionedTitle, user2.first_name)); description = AndroidUtilities.replaceTags(formatString("StoryYouMentionedTitle", R.string.StoryYouMentionedTitle, user2.first_name));
} else { } else {
description = AndroidUtilities.replaceTags(LocaleController.formatString("StoryMentionedTitle", R.string.StoryMentionedTitle, user.first_name)); description = AndroidUtilities.replaceTags(formatString("StoryMentionedTitle", R.string.StoryMentionedTitle, user.first_name));
} }
action = LocaleController.getString(R.string.StoryMentionedAction); action = getString(R.string.StoryMentionedAction);
createGiftPremiumLayouts(null, description, action, giftRectSize, true); createGiftPremiumLayouts(null, description, action, giftRectSize, true);
textLayout = null; textLayout = null;
@ -1336,27 +1389,27 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
String from = chat == null ? null : chat.title; String from = chat == null ? null : chat.title;
boolean isPrize = gifCodeAction.via_giveaway; boolean isPrize = gifCodeAction.via_giveaway;
CharSequence title = gifCodeAction.unclaimed ? CharSequence title = gifCodeAction.unclaimed ?
LocaleController.getString("BoostingUnclaimedPrize", R.string.BoostingUnclaimedPrize) getString("BoostingUnclaimedPrize", R.string.BoostingUnclaimedPrize)
: LocaleController.getString("BoostingCongratulations", R.string.BoostingCongratulations); : getString("BoostingCongratulations", R.string.BoostingCongratulations);
SpannableStringBuilder subtitle; SpannableStringBuilder subtitle;
CharSequence monthsStr = months == 12 ? LocaleController.formatPluralString("BoldYears", 1) : LocaleController.formatPluralString("BoldMonths", months); CharSequence monthsStr = months == 12 ? LocaleController.formatPluralString("BoldYears", 1) : LocaleController.formatPluralString("BoldMonths", months);
if (isPrize) { if (isPrize) {
if (gifCodeAction.unclaimed) { if (gifCodeAction.unclaimed) {
subtitle = new SpannableStringBuilder(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingYouHaveUnclaimedPrize", R.string.BoostingYouHaveUnclaimedPrize, from))); subtitle = new SpannableStringBuilder(AndroidUtilities.replaceTags(formatString("BoostingYouHaveUnclaimedPrize", R.string.BoostingYouHaveUnclaimedPrize, from)));
subtitle.append("\n\n"); subtitle.append("\n\n");
subtitle.append(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingUnclaimedPrizeDuration", R.string.BoostingUnclaimedPrizeDuration, monthsStr))); subtitle.append(AndroidUtilities.replaceTags(formatString("BoostingUnclaimedPrizeDuration", R.string.BoostingUnclaimedPrizeDuration, monthsStr)));
} else { } else {
subtitle = new SpannableStringBuilder(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingReceivedPrizeFrom", R.string.BoostingReceivedPrizeFrom, from))); subtitle = new SpannableStringBuilder(AndroidUtilities.replaceTags(formatString("BoostingReceivedPrizeFrom", R.string.BoostingReceivedPrizeFrom, from)));
subtitle.append("\n\n"); subtitle.append("\n\n");
subtitle.append(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingReceivedPrizeDuration", R.string.BoostingReceivedPrizeDuration, monthsStr))); subtitle.append(AndroidUtilities.replaceTags(formatString("BoostingReceivedPrizeDuration", R.string.BoostingReceivedPrizeDuration, monthsStr)));
} }
} else { } else {
subtitle = new SpannableStringBuilder(AndroidUtilities.replaceTags(from == null ? LocaleController.getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName) : LocaleController.formatString("BoostingReceivedGiftFrom", R.string.BoostingReceivedGiftFrom, from))); subtitle = new SpannableStringBuilder(AndroidUtilities.replaceTags(from == null ? getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName) : formatString("BoostingReceivedGiftFrom", R.string.BoostingReceivedGiftFrom, from)));
subtitle.append("\n\n"); subtitle.append("\n\n");
subtitle.append(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingReceivedGiftDuration", R.string.BoostingReceivedGiftDuration, monthsStr))); subtitle.append(AndroidUtilities.replaceTags(formatString("BoostingReceivedGiftDuration", R.string.BoostingReceivedGiftDuration, monthsStr)));
} }
String btnText = LocaleController.getString("BoostingReceivedGiftOpenBtn", R.string.BoostingReceivedGiftOpenBtn); String btnText = getString("BoostingReceivedGiftOpenBtn", R.string.BoostingReceivedGiftOpenBtn);
SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title); SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title);
titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -1374,15 +1427,22 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private void createGiftPremiumLayouts(CharSequence title, CharSequence subtitle, CharSequence button, int width, boolean buttonClickableAsImage) { private void createGiftPremiumLayouts(CharSequence title, CharSequence subtitle, CharSequence button, int width, boolean buttonClickableAsImage) {
width -= dp(16); width -= dp(16);
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_GIFT_STARS) {
width -= dp(16);
}
if (title != null) { if (title != null) {
giftTitlePaint.setTextSize(dp(16)); if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_GIFT_STARS) {
giftTitlePaint.setTextSize(dp(14));
} else {
giftTitlePaint.setTextSize(dp(16));
}
SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title); SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title);
titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.bold()), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
} else { } else {
giftPremiumTitleLayout = null; giftPremiumTitleLayout = null;
} }
if (currentMessageObject != null && isNewStyleButtonLayout()) { if (currentMessageObject != null && (isNewStyleButtonLayout() || currentMessageObject.type == MessageObject.TYPE_GIFT_STARS)) {
giftSubtitlePaint.setTextSize(dp(13)); giftSubtitlePaint.setTextSize(dp(13));
} else { } else {
giftSubtitlePaint.setTextSize(dp(15)); giftSubtitlePaint.setTextSize(dp(15));
@ -1451,6 +1511,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
imageSize = (int) (stickerSize * (AndroidUtilities.isTablet() ? 1.0f : 1.2f)); imageSize = (int) (stickerSize * (AndroidUtilities.isTablet() ? 1.0f : 1.2f));
imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(22), imageSize, imageSize); imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(22), imageSize, imageSize);
} else if (messageObject.type == MessageObject.TYPE_GIFT_STARS) {
imageSize = (int) (stickerSize * 1.1f);
imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(22), imageSize, imageSize);
} else { } else {
imageSize = (int) (stickerSize * 1f); imageSize = (int) (stickerSize * 1f);
imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(4), imageSize, imageSize); imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(4), imageSize, imageSize);
@ -1560,6 +1623,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) { if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
y += dp(16); y += dp(16);
} }
if (messageObject.type == MessageObject.TYPE_GIFT_STARS) {
y -= dp(3.66f);
}
if (giftPremiumButtonLayout == null) { if (giftPremiumButtonLayout == null) {
y -= dp(24); y -= dp(24);
} }
@ -1567,7 +1633,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
canvas.translate(x, y); canvas.translate(x, y);
if (giftPremiumTitleLayout != null) { if (giftPremiumTitleLayout != null) {
canvas.save();
canvas.translate((giftRectSize - dp(16) - giftPremiumTitleLayout.getWidth()) / 2f, 0);
giftPremiumTitleLayout.draw(canvas); giftPremiumTitleLayout.draw(canvas);
canvas.restore();
y += giftPremiumTitleLayout.getHeight(); y += giftPremiumTitleLayout.getHeight();
y += dp(messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL ? 6 : 0); y += dp(messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL ? 6 : 0);
} else { } else {
@ -1583,7 +1652,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (settingWallpaperLayout == null) { if (settingWallpaperLayout == null) {
settingWallpaperPaint = new TextPaint(); settingWallpaperPaint = new TextPaint();
settingWallpaperPaint.setTextSize(dp(13)); settingWallpaperPaint.setTextSize(dp(13));
SpannableStringBuilder cs = new SpannableStringBuilder(LocaleController.getString(R.string.ActionSettingWallpaper)); SpannableStringBuilder cs = new SpannableStringBuilder(getString(R.string.ActionSettingWallpaper));
int index = cs.toString().indexOf("..."), len = 3; int index = cs.toString().indexOf("..."), len = 3;
if (index < 0) { if (index < 0) {
index = cs.toString().indexOf(""); index = cs.toString().indexOf("");
@ -1616,7 +1685,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
float s = 0.8f + 0.2f * p; float s = 0.8f + 0.2f * p;
canvas.save(); canvas.save();
canvas.scale(s, s, giftPremiumSubtitleWidth / 2f, giftPremiumSubtitleLayout.getHeight() / 2f); canvas.scale(s, s, giftPremiumSubtitleWidth / 2f, giftPremiumSubtitleLayout.getHeight() / 2f);
canvas.translate((giftPremiumSubtitleWidth -giftPremiumSubtitleLayout.getWidth()) / 2f, 0); canvas.translate((giftPremiumSubtitleWidth - giftPremiumSubtitleLayout.getWidth()) / 2f, 0);
SpoilerEffect.layoutDrawMaybe(giftPremiumSubtitleLayout, canvas); SpoilerEffect.layoutDrawMaybe(giftPremiumSubtitleLayout, canvas);
canvas.restore(); canvas.restore();
@ -1652,7 +1721,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
} else if (giftPremiumSubtitleLayout != null) { } else if (giftPremiumSubtitleLayout != null) {
canvas.save(); canvas.save();
canvas.translate((giftPremiumSubtitleWidth - giftPremiumSubtitleLayout.getWidth()) / 2f, 0); canvas.translate((giftRectSize - dp(16) - giftPremiumSubtitleLayout.getWidth()) / 2f, 0);
SpoilerEffect.layoutDrawMaybe(giftPremiumSubtitleLayout, canvas); SpoilerEffect.layoutDrawMaybe(giftPremiumSubtitleLayout, canvas);
canvas.restore(); canvas.restore();
} }
@ -1726,6 +1795,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
float s = 1f - progressToProgress; float s = 1f - progressToProgress;
canvas.scale(s, s, giftButtonRect.centerX(), giftButtonRect.centerY()); canvas.scale(s, s, giftButtonRect.centerX(), giftButtonRect.centerY());
canvas.translate(x, giftButtonRect.top + dp(8)); canvas.translate(x, giftButtonRect.top + dp(8));
canvas.translate((giftRectSize - dp(16) - giftPremiumButtonLayout.getWidth()) / 2f, 0);
giftPremiumButtonLayout.draw(canvas); giftPremiumButtonLayout.draw(canvas);
canvas.restore(); canvas.restore();
} }
@ -2134,7 +2204,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
private boolean isButtonLayout(MessageObject messageObject) { private boolean isButtonLayout(MessageObject messageObject) {
return messageObject != null && (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL || isNewStyleButtonLayout()); return messageObject != null && (messageObject.type == MessageObject.TYPE_GIFT_STARS || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM || messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL || isNewStyleButtonLayout());
} }
private boolean isGiftChannel(MessageObject messageObject) { private boolean isGiftChannel(MessageObject messageObject) {

View file

@ -142,6 +142,7 @@ import org.telegram.ui.Components.BackgroundGradientDrawable;
import org.telegram.ui.Components.ButtonBounce; import org.telegram.ui.Components.ButtonBounce;
import org.telegram.ui.Components.CheckBoxBase; import org.telegram.ui.Components.CheckBoxBase;
import org.telegram.ui.Components.ClipRoundedDrawable; import org.telegram.ui.Components.ClipRoundedDrawable;
import org.telegram.ui.Components.ColoredImageSpan;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EmptyStubSpan; import org.telegram.ui.Components.EmptyStubSpan;
import org.telegram.ui.Components.FloatSeekBarAccessibilityDelegate; import org.telegram.ui.Components.FloatSeekBarAccessibilityDelegate;
@ -298,8 +299,21 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else { } else {
currentPhoto = null; currentPhoto = null;
} }
avatarDrawable.setInfo(currentAccount, currentChat); if (currentChat.signature_profiles) {
avatarImage.setForUserOrChat(currentChat, avatarDrawable); long did = DialogObject.getPeerDialogId(messageObject.messageOwner.from_id);
if (did >= 0) {
TLRPC.User user = MessagesController.getInstance(messageObject.currentAccount).getUser(did);
avatarDrawable.setInfo(currentAccount, user);
avatarImage.setForUserOrChat(user, avatarDrawable);
} else {
TLRPC.Chat chat = MessagesController.getInstance(messageObject.currentAccount).getChat(-did);
avatarDrawable.setInfo(currentAccount, chat);
avatarImage.setForUserOrChat(chat, avatarDrawable);
}
} else {
avatarDrawable.setInfo(currentAccount, currentChat);
avatarImage.setForUserOrChat(currentChat, avatarDrawable);
}
} else if (messageObject.isSponsored()) { } else if (messageObject.isSponsored()) {
if (messageObject.sponsoredPhoto != null) { if (messageObject.sponsoredPhoto != null) {
avatarImage.setImage(ImageLocation.getForPhoto(FileLoader.getClosestPhotoSizeWithSize(messageObject.sponsoredPhoto.sizes, AndroidUtilities.dp(50), false, null, true), messageObject.sponsoredPhoto), "50_50", avatarDrawable, null, null, 0); avatarImage.setImage(ImageLocation.getForPhoto(FileLoader.getClosestPhotoSizeWithSize(messageObject.sponsoredPhoto.sizes, AndroidUtilities.dp(50), false, null, true), messageObject.sponsoredPhoto), "50_50", avatarDrawable, null, null, 0);
@ -561,7 +575,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
default void didLongPressBotButton(ChatMessageCell cell, TLRPC.KeyboardButton button) { default void didLongPressBotButton(ChatMessageCell cell, TLRPC.KeyboardButton button) {
} }
default void didPressReaction(ChatMessageCell cell, TLRPC.ReactionCount reaction, boolean longpress) { default void didPressReaction(ChatMessageCell cell, TLRPC.ReactionCount reaction, boolean longpress, float x, float y) {
} }
default void didPressVoteButtons(ChatMessageCell cell, ArrayList<TLRPC.PollAnswer> buttons, int showCount, int x, int y) { default void didPressVoteButtons(ChatMessageCell cell, ArrayList<TLRPC.PollAnswer> buttons, int showCount, int x, int y) {
@ -685,6 +699,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
default void didPressRevealSensitiveContent(ChatMessageCell cell) {
}
default void didPressEffect(ChatMessageCell cell) { default void didPressEffect(ChatMessageCell cell) {
} }
@ -799,6 +817,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public static final int INSTANT_BUTTON_TYPE_CONTACT_VIEW = 5; public static final int INSTANT_BUTTON_TYPE_CONTACT_VIEW = 5;
public static final int INSTANT_BUTTON_TYPE_CONTACT_SEND_MESSAGE = 30; public static final int INSTANT_BUTTON_TYPE_CONTACT_SEND_MESSAGE = 30;
public static final int INSTANT_BUTTON_TYPE_CONTACT_ADD = 31; public static final int INSTANT_BUTTON_TYPE_CONTACT_ADD = 31;
public static final int INSTANT_BUTTON_TYPE_PROFILE = 32;
public static final int INSTANT_BUTTON_TYPE_STICKER_SET = 23; public static final int INSTANT_BUTTON_TYPE_STICKER_SET = 23;
public static final int INSTANT_BUTTON_TYPE_EMOJI_SET = 24; public static final int INSTANT_BUTTON_TYPE_EMOJI_SET = 24;
@ -1052,6 +1071,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private int infoX; private int infoX;
private int infoWidth; private int infoWidth;
private Text sensitiveText, sensitiveTextShort;
private String currentUrl; private String currentUrl;
private WebFile currentWebFile; private WebFile currentWebFile;
private WebFile lastWebFile; private WebFile lastWebFile;
@ -1349,6 +1370,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private MessageTopicButton topicButton; private MessageTopicButton topicButton;
private int drawSideButton; private int drawSideButton;
private boolean sideButtonVisible;
private int drawSideButton2; private int drawSideButton2;
private boolean sideButtonPressed; private boolean sideButtonPressed;
private int pressedSideButton; private int pressedSideButton;
@ -2511,7 +2533,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
videoButtonPressed = 1; videoButtonPressed = 1;
invalidate(); invalidate();
return true; return true;
} else if (drawPhotoImage && drawImageButton && buttonState != -1 && (!checkOnlyButtonPressed && photoImage.isInsideImage(x, y) || x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE)) { } else if (drawPhotoImage && currentMessageObject.sponsoredMedia != null && photoImage.isInsideImage(x, y) || drawPhotoImage && drawImageButton && buttonState != -1 && (!checkOnlyButtonPressed && photoImage.isInsideImage(x, y) || x >= buttonX && x <= buttonX + AndroidUtilities.dp(48) && y >= buttonY && y <= buttonY + AndroidUtilities.dp(48) && radialProgress.getIcon() != MediaActionDrawable.ICON_NONE)) {
buttonPressed = 1; buttonPressed = 1;
invalidate(); invalidate();
return true; return true;
@ -2598,7 +2620,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (buttonPressed != 0) { } else if (buttonPressed != 0) {
buttonPressed = 0; buttonPressed = 0;
playSoundEffect(SoundEffectConstants.CLICK); playSoundEffect(SoundEffectConstants.CLICK);
if (drawVideoImageButton) { if (drawVideoImageButton || currentMessageObject.sponsoredMedia != null) {
didClickedImage(); didClickedImage();
} else { } else {
didPressButton(true, false); didPressButton(true, false);
@ -4065,6 +4087,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
forwardBotPressed = true; forwardBotPressed = true;
result = true; result = true;
} else if ( } else if (
sideButtonVisible &&
drawSideButton != 0 && drawSideButton != 0 &&
x >= sideStartX - dp(24) && x <= sideStartX + dp(40) && x >= sideStartX - dp(24) && x <= sideStartX + dp(40) &&
y >= sideStartY - dp(24) && y <= sideStartY + dp(38 + (drawSideButton == 3 && commentLayout != null ? 18 : 0) + (drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE ? 38 : 0)) y >= sideStartY - dp(24) && y <= sideStartY + dp(38 + (drawSideButton == 3 && commentLayout != null ? 18 : 0) + (drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE ? 38 : 0))
@ -4316,6 +4339,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
pressedSideButton = 0; pressedSideButton = 0;
} else if (event.getAction() == MotionEvent.ACTION_MOVE) { } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (!( if (!(
sideButtonVisible &&
x >= sideStartX - dp(24) && x <= sideStartX + dp(40) && x >= sideStartX - dp(24) && x <= sideStartX + dp(40) &&
y >= sideStartY - dp(24) && y <= sideStartY + dp(38 + (drawSideButton == 3 && commentLayout != null ? 18 : 0) + (drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE ? 38 : 0)) y >= sideStartY - dp(24) && y <= sideStartY + dp(38 + (drawSideButton == 3 && commentLayout != null ? 18 : 0) + (drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE ? 38 : 0))
)) { )) {
@ -4346,10 +4370,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
(position.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (position.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 &&
(position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) { (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
if (cell == this) { if (cell == this) {
return reactionsLayoutInBubble.chekTouchEvent(event); return reactionsLayoutInBubble.checkTouchEvent(event);
} else { } else {
event.offsetLocation(this.getLeft() - cell.getLeft(), this.getTop() - cell.getTop()); event.offsetLocation(this.getLeft() - cell.getLeft(), this.getTop() - cell.getTop());
boolean result = cell.reactionsLayoutInBubble.chekTouchEvent(event); boolean result = cell.reactionsLayoutInBubble.checkTouchEvent(event);
event.offsetLocation(-(this.getLeft() - cell.getLeft()), -(this.getTop() - cell.getTop())); event.offsetLocation(-(this.getLeft() - cell.getLeft()), -(this.getTop() - cell.getTop()));
return result; return result;
} }
@ -4358,7 +4382,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
return false; return false;
} }
return reactionsLayoutInBubble.chekTouchEvent(event); return reactionsLayoutInBubble.checkTouchEvent(event);
} }
@ -4796,6 +4820,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private void didClickedImage() { private void didClickedImage() {
if (currentMessageObject.hasMediaSpoilers() && !currentMessageObject.needDrawBluredPreview() && !currentMessageObject.isMediaSpoilersRevealed) { if (currentMessageObject.hasMediaSpoilers() && !currentMessageObject.needDrawBluredPreview() && !currentMessageObject.isMediaSpoilersRevealed) {
if (delegate != null && currentMessageObject.isSensitive()) {
delegate.didPressRevealSensitiveContent(this);
return;
}
startRevealMedia(lastTouchX, lastTouchY); startRevealMedia(lastTouchX, lastTouchY);
return; return;
} }
@ -4861,6 +4889,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (buttonState == -1) { if (buttonState == -1) {
delegate.didPressImage(this, lastTouchX, lastTouchY); delegate.didPressImage(this, lastTouchX, lastTouchY);
} }
} else if (currentMessageObject.sponsoredMedia != null) {
if (delegate != null) {
delegate.didPressImage(this, lastTouchX, lastTouchY);
}
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) { } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
if (buttonState == -1) { if (buttonState == -1) {
TLRPC.WebPage webPage = MessageObject.getMedia(currentMessageObject.messageOwner).webpage; TLRPC.WebPage webPage = MessageObject.getMedia(currentMessageObject.messageOwner).webpage;
@ -6057,8 +6089,19 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawInstantView = true; drawInstantView = true;
drawInstantViewType = 1; drawInstantViewType = 1;
} else if ("telegram_user".equals(webpageType)) { } else if ("telegram_user".equals(webpageType)) {
boolean isProfile = false;
if (webpage != null && webpage.url != null) {
Uri data = Uri.parse(webpage.url);
if (data != null && data.getBooleanQueryParameter("profile", false)) {
isProfile = true;
}
}
drawInstantView = true; drawInstantView = true;
drawInstantViewType = 13; if (isProfile) {
drawInstantViewType = INSTANT_BUTTON_TYPE_PROFILE;
} else {
drawInstantViewType = 13;
}
} else if ("telegram_megagroup".equals(webpageType)) { } else if ("telegram_megagroup".equals(webpageType)) {
drawInstantView = true; drawInstantView = true;
drawInstantViewType = 2; drawInstantViewType = 2;
@ -6345,15 +6388,26 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
webDocument = null; webDocument = null;
overrideDescrption = messageObject.messageText; overrideDescrption = messageObject.messageText;
description = overrideDescrption != null ? overrideDescrption.toString() : null; description = overrideDescrption != null ? overrideDescrption.toString() : null;
photo = null;
author = null; author = null;
document = null; document = null;
photo = messageObject.sponsoredPhoto; photo = messageObject.sponsoredPhoto;
isSmallImage = photo != null || peerPhoto != null;
smallImage = true;
duration = 0; duration = 0;
type = null; type = null;
isSmallImage = photo != null || peerPhoto != null; if (messageObject.sponsoredMedia != null) {
if (messageObject.sponsoredMedia instanceof TLRPC.TL_messageMediaDocument) {
TLRPC.TL_messageMediaDocument media = (TLRPC.TL_messageMediaDocument) messageObject.sponsoredMedia;
document = media.document;
duration = (int) MessageObject.getDocumentDuration(media.document);
} else if (messageObject.sponsoredMedia instanceof TLRPC.TL_messageMediaPhoto) {
TLRPC.TL_messageMediaPhoto media = (TLRPC.TL_messageMediaPhoto) messageObject.sponsoredMedia;
photo = media.photo;
}
smallImage = false;
isSmallImage = false;
}
linkPreviewAbove = false; linkPreviewAbove = false;
smallImage = true;
} else if (drawInstantViewType == 19) { } else if (drawInstantViewType == 19) {
site_name = null; site_name = null;
title = null; title = null;
@ -6416,7 +6470,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
"telegram_user".equals(type) || "telegram_channel".equals(type) || "telegram_user".equals(type) || "telegram_channel".equals(type) ||
"telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) || "telegram_videochat".equals(type) || "telegram_megagroup".equals(type) || "telegram_voicechat".equals(type) || "telegram_videochat".equals(type) ||
"telegram_livestream".equals(type) || "telegram_channel_boost".equals(type) || "telegram_group_boost".equals(type); "telegram_livestream".equals(type) || "telegram_channel_boost".equals(type) || "telegram_group_boost".equals(type);
smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 2 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 25 || drawInstantViewType == 13 || drawInstantViewType == 18 || drawInstantViewType == 20 || drawInstantViewType == 22) && document == null && isSmallImageType || (drawInstantViewType == 23 || drawInstantViewType == 24) && stickers != null && !stickers.isEmpty(); smallImage = !slideshow && (!drawInstantView || drawInstantViewType == 1 || drawInstantViewType == 2 || drawInstantViewType == 9 || drawInstantViewType == 11 || drawInstantViewType == 25 || drawInstantViewType == 13 || drawInstantViewType == 18 || drawInstantViewType == 20 || drawInstantViewType == 22 || drawInstantViewType == INSTANT_BUTTON_TYPE_PROFILE) && document == null && isSmallImageType || (drawInstantViewType == 23 || drawInstantViewType == 24) && stickers != null && !stickers.isEmpty();
TLRPC.MessageMedia media = MessageObject.getMedia(messageObject.messageOwner); TLRPC.MessageMedia media = MessageObject.getMedia(messageObject.messageOwner);
if (media != null && !(drawInstantViewType == 23 || drawInstantViewType == 24 || drawInstantViewType == 25)) { if (media != null && !(drawInstantViewType == 23 || drawInstantViewType == 24 || drawInstantViewType == 25)) {
if (media.force_large_media) { if (media.force_large_media) {
@ -6757,7 +6811,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 90); currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(photo.sizes, 90);
photoParentObject = photo; photoParentObject = photo;
} }
if (currentPhotoObject != null && (currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) { if (currentPhotoObject != null && (currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject.w == 0 || currentPhotoObject.h == 0)) {
for (int a = 0; a < document.attributes.size(); a++) { for (int a = 0; a < document.attributes.size(); a++) {
TLRPC.DocumentAttribute attribute = document.attributes.get(a); TLRPC.DocumentAttribute attribute = document.attributes.get(a);
if (attribute instanceof TLRPC.TL_documentAttributeImageSize || attribute instanceof TLRPC.TL_documentAttributeVideo) { if (attribute instanceof TLRPC.TL_documentAttributeImageSize || attribute instanceof TLRPC.TL_documentAttributeVideo) {
@ -7149,7 +7203,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) { } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
photoImage.setNeedsQualityThumb(true); photoImage.setNeedsQualityThumb(true);
photoImage.setShouldGenerateQualityThumb(true); photoImage.setShouldGenerateQualityThumb(true);
if (!isSmallImage && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && (!currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || currentMessageObject.revealingMediaSpoilers) && ( if (!isSmallImage && !currentMessageObject.isHiddenSensitive() && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && (!currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || currentMessageObject.revealingMediaSpoilers) && (
(currentMessageObject.mediaExists || currentMessageObject.attachPathExists) || (currentMessageObject.mediaExists || currentMessageObject.attachPathExists) ||
messageObject.canStreamVideo() && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject) messageObject.canStreamVideo() && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject)
)) { )) {
@ -7175,6 +7229,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId())) { } else if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId())) {
autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject); autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
} }
if (currentMessageObject.isHiddenSensitive()) {
autoDownload = false;
}
String filter = currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter; String filter = currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter;
if ((messageObject.mediaExists || autoDownload) && !currentMessageObject.isRepostPreview) { if ((messageObject.mediaExists || autoDownload) && !currentMessageObject.isRepostPreview) {
autoPlayingMedia = true; autoPlayingMedia = true;
@ -7916,7 +7973,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (captionWidth > widthForCaption) { if (captionWidth > widthForCaption) {
groupMedia.setOverrideWidth(captionWidth + getExtraTextX() * 2 + dp(20) - dp(8 + 9) + dp(14)); groupMedia.setOverrideWidth(captionWidth + getExtraTextX() * 2 + dp(20) - dp(8 + 9) + dp(14));
} }
if (captionLayout.hasCodeAtBottom || captionLayout.hasQuoteAtBottom) { if (!captionAbove && (captionLayout.hasCodeAtBottom || captionLayout.hasQuoteAtBottom)) {
captionHeight += AndroidUtilities.dp(14); captionHeight += AndroidUtilities.dp(14);
addedCaptionHeight += AndroidUtilities.dp(14); addedCaptionHeight += AndroidUtilities.dp(14);
} }
@ -8887,7 +8944,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
captionHeight = captionLayout.textHeight(); captionHeight = captionLayout.textHeight();
addedCaptionHeight = captionHeight + AndroidUtilities.dp(9); addedCaptionHeight = captionHeight + AndroidUtilities.dp(9);
if (captionLayout.hasCodeAtBottom || captionLayout.hasQuoteAtBottom) { if (!captionAbove && (captionLayout.hasCodeAtBottom || captionLayout.hasQuoteAtBottom)) {
captionHeight += AndroidUtilities.dp(14); captionHeight += AndroidUtilities.dp(14);
addedCaptionHeight += AndroidUtilities.dp(14); addedCaptionHeight += AndroidUtilities.dp(14);
} }
@ -9029,7 +9086,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObjectThumb.size = -1; currentPhotoObjectThumb.size = -1;
} }
if (SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && (!currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || currentMessageObject.revealingMediaSpoilers) && (messageObject.type == MessageObject.TYPE_VIDEO /*|| messageObject.type == MessageObject.TYPE_STORY && messageObject.getDocument() != null*/) && !messageObject.needDrawBluredPreview() && if (!currentMessageObject.isHiddenSensitive() && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && (!currentMessageObject.hasMediaSpoilers() || currentMessageObject.isMediaSpoilersRevealed || currentMessageObject.revealingMediaSpoilers) && (messageObject.type == MessageObject.TYPE_VIDEO /*|| messageObject.type == MessageObject.TYPE_STORY && messageObject.getDocument() != null*/) && !messageObject.needDrawBluredPreview() &&
((currentMessageObject.mediaExists || currentMessageObject.attachPathExists) || messageObject.canStreamVideo() && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject)) ((currentMessageObject.mediaExists || currentMessageObject.attachPathExists) || messageObject.canStreamVideo() && DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject))
) { ) {
if (currentPosition != null) { if (currentPosition != null) {
@ -9127,6 +9184,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId()) || messageObject.type == MessageObject.TYPE_ROUND_VIDEO) { if (MessageObject.isGifDocument(document, messageObject.hasValidGroupId()) || messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject); autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
} }
if (messageObject.isHiddenSensitive()) {
autoDownload = false;
}
TLRPC.VideoSize videoSize = MessageObject.getDocumentVideoThumb(document); TLRPC.VideoSize videoSize = MessageObject.getDocumentVideoThumb(document);
if (((MessageObject.isGifDocument(document, messageObject.hasValidGroupId()) && messageObject.videoEditedInfo == null) || (!messageObject.isSending() && !messageObject.isEditing())) && (localFile != 0 || FileLoader.getInstance(currentAccount).isLoadingFile(fileName) || autoDownload)) { if (((MessageObject.isGifDocument(document, messageObject.hasValidGroupId()) && messageObject.videoEditedInfo == null) || (!messageObject.isSending() && !messageObject.isEditing())) && (localFile != 0 || FileLoader.getInstance(currentAccount).isLoadingFile(fileName) || autoDownload)) {
if (localFile != 1 && !messageObject.needDrawBluredPreview() && (localFile != 0 || messageObject.canStreamVideo() && autoDownload)) { if (localFile != 1 && !messageObject.needDrawBluredPreview() && (localFile != 0 || messageObject.canStreamVideo() && autoDownload)) {
@ -9276,7 +9336,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
invalidate(); invalidate();
} }
if ((currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.type == MessageObject.TYPE_PAID_MEDIA || currentMessageObject.isDocument()) && !messageObject.isAnyKindOfSticker() && addedCaptionHeight == 0 && !messageObject.isExpiredStory() && !messageObject.isUnsupported()) { if ((currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.type == MessageObject.TYPE_PAID_MEDIA || currentMessageObject.isDocument()) && !messageObject.isSponsored() && !messageObject.isAnyKindOfSticker() && addedCaptionHeight == 0 && !messageObject.isExpiredStory() && !messageObject.isUnsupported()) {
int addCaptionLayoutWidth = 0; int addCaptionLayoutWidth = 0;
int width = backgroundWidth; int width = backgroundWidth;
if ((currentMessageObject.type == MessageObject.TYPE_VOICE || isRoundVideo) && messageObject.isVoiceTranscriptionOpen() && messageObject.getFactCheck() == null) { if ((currentMessageObject.type == MessageObject.TYPE_VOICE || isRoundVideo) && messageObject.isVoiceTranscriptionOpen() && messageObject.getFactCheck() == null) {
@ -10097,10 +10157,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (super.invalidateCallback != null) { if (super.invalidateCallback != null) {
super.invalidateCallback.run(); super.invalidateCallback.run();
} }
if (invalidateCallback != null) { if (overrideInvalidate != null) {
invalidateCallback.run(); overrideInvalidate.run();
return; return;
} }
if (invalidateListener != null) {
invalidateListener.run();
}
super.invalidate(); super.invalidate();
if ((invalidatesParent || currentMessagesGroup != null && invalidateParentForce()) && getParent() != null) { if ((invalidatesParent || currentMessagesGroup != null && invalidateParentForce()) && getParent() != null) {
View parent = (View) getParent(); View parent = (View) getParent();
@ -10120,10 +10183,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject == null) { if (currentMessageObject == null) {
return; return;
} }
if (invalidateCallback != null) { if (overrideInvalidate != null) {
invalidateCallback.run(); overrideInvalidate.run();
return; return;
} }
if (invalidateListener != null) {
invalidateListener.run();
}
super.invalidate(); super.invalidate();
if ((invalidatesParent || currentMessagesGroup != null && invalidateParentForce()) && getParent() != null) { if ((invalidatesParent || currentMessagesGroup != null && invalidateParentForce()) && getParent() != null) {
View parent = (View) getParent(); View parent = (View) getParent();
@ -10138,9 +10204,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
private Runnable invalidateCallback; private Runnable overrideInvalidate;
public void setInvalidateCallback(Runnable callback) { public void setOverrideInvalidate(Runnable callback) {
invalidateCallback = callback; overrideInvalidate = callback;
}
private Runnable invalidateListener;
public void setInvalidateListener(Runnable listener) {
invalidateListener = listener;
} }
@ -10149,10 +10220,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject == null) { if (currentMessageObject == null) {
return; return;
} }
if (invalidateCallback != null) { if (overrideInvalidate != null) {
invalidateCallback.run(); overrideInvalidate.run();
return; return;
} }
if (invalidateListener != null) {
invalidateListener.run();
}
super.invalidate(l, t, r, b); super.invalidate(l, t, r, b);
if (invalidatesParent) { if (invalidatesParent) {
if (getParent() != null) { if (getParent() != null) {
@ -10382,7 +10456,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
private int createDocumentLayout(int maxWidth, MessageObject messageObject) { private int createDocumentLayout(int maxWidth, MessageObject messageObject) {
if (messageObject.type == MessageObject.TYPE_TEXT) { if (messageObject.sponsoredMedia != null) {
documentAttach = messageObject.sponsoredMedia.document;
} else if (messageObject.type == MessageObject.TYPE_TEXT) {
documentAttach = MessageObject.getMedia(messageObject.messageOwner).webpage.document; documentAttach = MessageObject.getMedia(messageObject.messageOwner).webpage.document;
} else { } else {
documentAttach = messageObject.getDocument(); documentAttach = messageObject.getDocument();
@ -10507,6 +10583,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 320); currentPhotoObject = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 320);
currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40); currentPhotoObjectThumb = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 40);
if (currentMessageObject.isHiddenSensitive() || (DownloadController.getInstance(currentAccount).getAutodownloadMask() & DownloadController.AUTODOWNLOAD_TYPE_PHOTO) == 0) {
currentPhotoObject = null;
}
if (currentPhotoObject == null || currentPhotoObject == currentPhotoObjectThumb) { if (currentPhotoObject == null || currentPhotoObject == currentPhotoObjectThumb) {
currentPhotoObject = null; currentPhotoObject = null;
photoImage.setNeedsQualityThumb(true); photoImage.setNeedsQualityThumb(true);
@ -11050,6 +11129,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
str = getString(R.string.OpenChannel); str = getString(R.string.OpenChannel);
} else if (drawInstantViewType == 13) { } else if (drawInstantViewType == 13) {
str = getString(R.string.SendMessage).toUpperCase(); str = getString(R.string.SendMessage).toUpperCase();
} else if (drawInstantViewType == INSTANT_BUTTON_TYPE_PROFILE) {
str = getString(R.string.OpenProfile).toUpperCase();
} else if (drawInstantViewType == 10) { } else if (drawInstantViewType == 10) {
str = getString(R.string.OpenBot); str = getString(R.string.OpenBot);
} else if (drawInstantViewType == 2) { } else if (drawInstantViewType == 2) {
@ -12029,7 +12110,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) { if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
if (drawPhotoImage && !currentMessageObject.isRepostPreview && photoImage.getVisible() && !hasGamePreview && !currentMessageObject.needDrawBluredPreview() && !currentMessageObject.preview && !isSmallImage) { if (drawPhotoImage && !currentMessageObject.isRepostPreview && !currentMessageObject.isSponsored() && photoImage.getVisible() && !hasGamePreview && !currentMessageObject.needDrawBluredPreview() && !currentMessageObject.preview && !isSmallImage && !currentMessageObject.isSponsored()) {
int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha(); int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha();
Theme.chat_msgMediaMenuDrawable.setAlpha((int) (oldAlpha * controlsAlpha)); Theme.chat_msgMediaMenuDrawable.setAlpha((int) (oldAlpha * controlsAlpha));
setDrawableBounds(Theme.chat_msgMediaMenuDrawable, otherX = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(14)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8.1f))); setDrawableBounds(Theme.chat_msgMediaMenuDrawable, otherX = (int) (photoImage.getImageX() + photoImage.getImageWidth() - AndroidUtilities.dp(14)), otherY = (int) (photoImage.getImageY() + AndroidUtilities.dp(8.1f)));
@ -12058,6 +12139,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable); radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable);
radialProgress.iconScale = 1f; radialProgress.iconScale = 1f;
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
radialProgress.iconScale *= mediaSpoilerRevealProgress;
}
radialProgress.draw(canvas); radialProgress.draw(canvas);
canvas.save(); canvas.save();
@ -12161,6 +12245,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!enterTransitionInProgress && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO) { if (!enterTransitionInProgress && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO) {
radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable); radialProgress.setBackgroundDrawable(isDrawSelectionBackground() ? currentBackgroundSelectedDrawable : currentBackgroundDrawable);
radialProgress.iconScale = 1f; radialProgress.iconScale = 1f;
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
radialProgress.iconScale *= mediaSpoilerRevealProgress;
}
drawVoiceOnce(canvas, seekBarWaveform == null ? 1f : 1f - seekBarWaveform.explosionRate, () -> radialProgress.draw(canvas)); drawVoiceOnce(canvas, seekBarWaveform == null ? 1f : 1f - seekBarWaveform.explosionRate, () -> radialProgress.draw(canvas));
} }
@ -12334,7 +12421,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
updateReactionLayoutPosition(); updateReactionLayoutPosition();
if (shouldDrawCaptionLayout() && !currentMessageObject.preview) { if (shouldDrawCaptionLayout() && !currentMessageObject.preview) {
drawCaptionLayout(canvas, false, 1f); drawCaptionLayout(canvas, false, 1f);
drawReactionsLayout(canvas, 1f); drawReactionsLayout(canvas, 1f, null);
} }
if (currentMessagesGroup == null) { if (currentMessagesGroup == null) {
@ -12681,7 +12768,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (hasNewLineForTime && !(drawForwardedName && hasLinkPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO)) { if (hasNewLineForTime && !(drawForwardedName && hasLinkPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO)) {
reactionsLayoutInBubble.y -= AndroidUtilities.dp(16); reactionsLayoutInBubble.y -= AndroidUtilities.dp(16);
} }
if (currentMessageObject.type != MessageObject.TYPE_FILE && (captionLayout != null && ((currentMessageObject.type != MessageObject.TYPE_VOICE && !(currentMessageObject.isOut() && drawForwardedName && !drawPhotoImage)) || (currentPosition != null && currentMessagesGroup != null)))) { if (currentMessageObject.type != MessageObject.TYPE_FILE && (captionLayout != null && ((currentMessageObject.type != MessageObject.TYPE_VOICE && !(currentMessageObject.isOut() && drawForwardedName && !drawPhotoImage)) || (currentPosition != null && currentMessagesGroup != null) || currentMessageObject.type == MessageObject.TYPE_PAID_MEDIA))) {
reactionsLayoutInBubble.y -= AndroidUtilities.dp(14); reactionsLayoutInBubble.y -= AndroidUtilities.dp(14);
} }
reactionsLayoutInBubble.y += reactionsLayoutInBubble.positionOffsetY; reactionsLayoutInBubble.y += reactionsLayoutInBubble.positionOffsetY;
@ -12875,8 +12962,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_replyNamePaint.setColor(linkLine.check(currentMessageObject, currentUser, currentChat, resourcesProvider, ReplyMessageLine.TYPE_LINK)); Theme.chat_replyNamePaint.setColor(linkLine.check(currentMessageObject, currentUser, currentChat, resourcesProvider, ReplyMessageLine.TYPE_LINK));
linkLine.setEmojiAlpha(drawInstantViewType == 23 || drawInstantViewType == 24 ? 0.5f : 1f); linkLine.setEmojiAlpha(drawInstantViewType == 23 || drawInstantViewType == 24 ? 0.5f : 1f);
final boolean drawPhotoImageBefore = drawInstantView && (drawInstantViewType != 9 && drawInstantViewType != 2 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 25 && drawInstantViewType != 1 && drawInstantViewType != 18 && drawInstantViewType != 22) || drawInstantViewType == 6 && imageBackgroundColor != 0; final boolean drawPhotoImageBeforeBefore = currentMessageObject.isSponsored() && !isSmallImage;
final boolean drawPhotoImageAfter = !drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 2 || drawInstantViewType == 11 || drawInstantViewType == 25 || drawInstantViewType == 13 || drawInstantViewType == 1 || drawInstantViewType == 18 || drawInstantViewType == 22 || isSmallImage; final boolean drawPhotoImageBefore = !drawPhotoImageBeforeBefore && drawInstantView && (drawInstantViewType != 9 && drawInstantViewType != 2 && drawInstantViewType != 13 && drawInstantViewType != 11 && drawInstantViewType != 25 && drawInstantViewType != 1 && drawInstantViewType != 18 && drawInstantViewType != 22) || drawInstantViewType == 6 && imageBackgroundColor != 0;
final boolean drawPhotoImageAfter = !drawPhotoImageBeforeBefore && (!drawInstantView || drawInstantViewType == 9 || drawInstantViewType == 2 || drawInstantViewType == 11 || drawInstantViewType == 25 || drawInstantViewType == 13 || drawInstantViewType == 1 || drawInstantViewType == 18 || drawInstantViewType == 22 || drawInstantViewType == INSTANT_BUTTON_TYPE_PROFILE || isSmallImage);
boolean restore = false; boolean restore = false;
boolean drawInstantButtonInside = false; boolean drawInstantButtonInside = false;
@ -12915,6 +13003,67 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkLine.drawLoadingBackground(canvas, AndroidUtilities.rectTmp, rad, rad, rad, alpha); linkLine.drawLoadingBackground(canvas, AndroidUtilities.rectTmp, rad, rad, rad, alpha);
} }
if (drawPhotoImage && drawPhotoImageBeforeBefore) {
if (linkPreviewY != startY) {
linkPreviewY += AndroidUtilities.dp(2);
}
final int photoWidth = width - AndroidUtilities.dp(17);
if (isSmallImage) {
photoImage.setImageX(linkX + width - photoImage.getImageWidth() - AndroidUtilities.dp(6));
photoImage.setImageY(smallImageStartY);
} else {
photoImage.setImageX(linkX + (hasInvoicePreview ? -AndroidUtilities.dp(6.3f) : AndroidUtilities.dp(10)));
photoImage.setImageY(linkPreviewY);
}
if (transitionParams != null && transitionParams.animateSmallImage) {
if (!isSmallImage && documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT) {
photoImage.setImageWidth((int) AndroidUtilities.lerp(transitionParams.photoImageFromWidth, photoWidth, transitionParams.animateChangeProgress));
}
photoImage.setImageX(AndroidUtilities.lerp(transitionParams.photoImageFromCenterX, photoImage.getCenterX(), transitionParams.animateChangeProgress) - photoImage.getImageWidth() / 2f);
photoImage.setImageY(AndroidUtilities.lerp(transitionParams.photoImageFromCenterY, photoImage.getCenterY(), transitionParams.animateChangeProgress) - photoImage.getImageHeight() / 2f);
} else if (!isSmallImage && documentAttachType != DOCUMENT_ATTACH_TYPE_ROUND && documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT) {
photoImage.setImageWidth(photoWidth);
}
if (!isSmallImage && drawImageButton) {
int size = AndroidUtilities.dp(48);
buttonX = this.buttonX = (int) (photoImage.getImageX() + (photoImage.getImageWidth() - size) / 2.0f);
buttonY = this.buttonY = (int) (photoImage.getImageY() + (photoImage.getImageHeight() - size) / 2.0f);
radialProgress.setProgressRect((int) buttonX, (int) buttonY, (int) buttonX + size, (int) buttonY + size);
}
if (isRoundVideo && MediaController.getInstance().isPlayingMessage(currentMessageObject) && MediaController.getInstance().isVideoDrawingReady() && canvas.isHardwareAccelerated()) {
imageDrawn = true;
drawTime = true;
} else {
if (delegate == null || delegate.getPinchToZoomHelper() == null || !delegate.getPinchToZoomHelper().isInOverlayModeFor(this)) {
if (alpha != 1f) {
photoImage.setAlpha(alpha);
if (allowDrawPhotoImage()) {
imageDrawn = photoImage.draw(canvas);
} else {
imageDrawn = true;
}
if (currentMessageObject.hasMediaSpoilers()) {
blurredPhotoImage.setAlpha(alpha);
drawBlurredPhoto(canvas);
blurredPhotoImage.setAlpha(1f);
}
photoImage.setAlpha(1f);
} else {
if (allowDrawPhotoImage()) {
imageDrawn = photoImage.draw(canvas);
} else {
imageDrawn = true;
}
if (currentMessageObject.hasMediaSpoilers()) {
drawBlurredPhoto(canvas);
}
}
}
}
linkPreviewY += photoImage.getImageHeight() + dp(6);
}
if (siteNameLayout != null) { if (siteNameLayout != null) {
if (titleLabelLayout != null) { if (titleLabelLayout != null) {
linkPreviewY += AndroidUtilities.dp(1); linkPreviewY += AndroidUtilities.dp(1);
@ -13682,7 +13831,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
private boolean shouldDrawMenuDrawable() { private boolean shouldDrawMenuDrawable() {
return (currentMessagesGroup == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0) && !hasLinkPreview && (currentMessageObject == null || !currentMessageObject.isRepostPreview); return (currentMessagesGroup == null || (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) != 0) && !hasLinkPreview && (currentMessageObject == null || !currentMessageObject.isRepostPreview && !currentMessageObject.isSponsored());
} }
private void drawContact(Canvas canvas) { private void drawContact(Canvas canvas) {
@ -14092,6 +14241,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
translationLoadingDrawable.setAppearByGradient(true); translationLoadingDrawable.setAppearByGradient(true);
if (translationLoadingPath == null) { if (translationLoadingPath == null) {
translationLoadingPath = new LinkPath(true); translationLoadingPath = new LinkPath(true);
translationLoadingPath.setUseCornerPathImplementation(true);
} }
translationLoadingDrawable.usePath(translationLoadingPath); translationLoadingDrawable.usePath(translationLoadingPath);
translationLoadingDrawable.setRadiiDp(5); translationLoadingDrawable.setRadiiDp(5);
@ -14109,6 +14259,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
block.textLayout.getSelectionPath(0, block.textLayout.getText().length(), translationLoadingPath); block.textLayout.getSelectionPath(0, block.textLayout.getText().length(), translationLoadingPath);
} }
} }
translationLoadingPath.closeRects();
translationLoadingDrawable.updateBounds(); translationLoadingDrawable.updateBounds();
} }
@ -14677,6 +14828,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else { } else {
autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject); autoDownload = DownloadController.getInstance(currentAccount).canDownloadMedia(currentMessageObject);
} }
if (currentMessageObject.isHiddenSensitive()) {
autoDownload = false;
}
canStreamVideo = ( canStreamVideo = (
(currentMessageObject.isSent() || currentMessageObject.isForwarded()) && (currentMessageObject.isSent() || currentMessageObject.isForwarded()) &&
(documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO ||
@ -15095,6 +15249,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
private void didPressButton(boolean animated, boolean video) { private void didPressButton(boolean animated, boolean video) {
if (delegate != null && currentMessageObject.isSensitive() && currentMessageObject.hasMediaSpoilers() && !currentMessageObject.needDrawBluredPreview() && !currentMessageObject.isMediaSpoilersRevealed) {
delegate.didPressRevealSensitiveContent(this);
return;
}
if (currentMessageObject != null && !currentMessageObject.isAnyKindOfSticker()) { if (currentMessageObject != null && !currentMessageObject.isAnyKindOfSticker()) {
currentMessageObject.putInDownloadsStore = true; currentMessageObject.putInDownloadsStore = true;
} }
@ -15326,7 +15484,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
photoImage.setAllowStartAnimation(true); photoImage.setAllowStartAnimation(true);
photoImage.startAnimation(); photoImage.startAnimation();
autoPlayingMedia = true; autoPlayingMedia = true;
} else if (!isSmallImage && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0)) { } else if (!isSmallImage && !currentMessageObject.isHiddenSensitive() && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0)) {
animatingNoSound = 2; animatingNoSound = 2;
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0); photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
if (!PhotoViewer.isPlayingMessage(currentMessageObject)) { if (!PhotoViewer.isPlayingMessage(currentMessageObject)) {
@ -15338,7 +15496,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
autoPlayingMedia = true; autoPlayingMedia = true;
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) { } else if (documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0); photoImage.setImage(ImageLocation.getForDocument(documentAttach), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoObject instanceof TLRPC.TL_photoStrippedSize || currentPhotoObject != null && "s".equals(currentPhotoObject.type) ? currentPhotoFilterThumb : currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, currentPhotoObjectThumbStripped, documentAttach.size, null, currentMessageObject, 0);
if (SharedConfig.isAutoplayGifs() && !currentMessageObject.isRepostPreview) { if (!currentMessageObject.isHiddenSensitive() && SharedConfig.isAutoplayGifs() && !currentMessageObject.isRepostPreview) {
photoImage.setAllowStartAnimation(true); photoImage.setAllowStartAnimation(true);
photoImage.startAnimation(); photoImage.startAnimation();
} else { } else {
@ -15657,6 +15815,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else { } else {
signString = null; signString = null;
} }
if (messageObject.getDialogId() < 0) {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-messageObject.getDialogId());
if (chat != null && chat.signature_profiles) {
signString = null;
}
}
String timeString; String timeString;
TLRPC.User author = null; TLRPC.User author = null;
if (currentMessageObject.isFromUser()) { if (currentMessageObject.isFromUser()) {
@ -15891,7 +16055,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentUser = new TLRPC.TL_user(); currentUser = new TLRPC.TL_user();
currentUser.first_name = fwd_from.from_name; currentUser.first_name = fwd_from.from_name;
} else { } else {
long did = currentMessageObject.getDialogId();
long fromId = currentMessageObject.getFromChatId(); long fromId = currentMessageObject.getFromChatId();
TLRPC.Chat fromChat = null;
if (DialogObject.isChatDialog(fromId)) {
fromChat = messagesController.getChat(-fromId);
}
TLRPC.Chat chat = null;
if (DialogObject.isChatDialog(did)) {
chat = messagesController.getChat(-did);
}
if (DialogObject.isEncryptedDialog(currentMessageObject.getDialogId())) { if (DialogObject.isEncryptedDialog(currentMessageObject.getDialogId())) {
if (currentMessageObject.isOutOwner()) { if (currentMessageObject.isOutOwner()) {
currentUser = UserConfig.getInstance(currentAccount).getCurrentUser(); currentUser = UserConfig.getInstance(currentAccount).getCurrentUser();
@ -15901,10 +16074,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
currentUser = messagesController.getUser(echat.user_id); currentUser = messagesController.getUser(echat.user_id);
} }
} }
} else if (DialogObject.isUserDialog(fromId) && !currentMessageObject.messageOwner.post) { } else if (DialogObject.isUserDialog(fromId) && (!currentMessageObject.messageOwner.post || fromChat != null && fromChat.signature_profiles)) {
currentUser = messagesController.getUser(fromId); currentUser = messagesController.getUser(fromId);
} else if (currentMessageObject.messageOwner.post && chat != null && !chat.signature_profiles) {
currentChat = chat;
} else if (DialogObject.isChatDialog(fromId)) { } else if (DialogObject.isChatDialog(fromId)) {
currentChat = messagesController.getChat(-fromId); currentChat = fromChat;
} else if (currentMessageObject.messageOwner.post) { } else if (currentMessageObject.messageOwner.post) {
currentChat = messagesController.getChat(currentMessageObject.messageOwner.peer_id.channel_id); currentChat = messagesController.getChat(currentMessageObject.messageOwner.peer_id.channel_id);
} }
@ -16482,6 +16657,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (mess.length() > 150) { if (mess.length() > 150) {
mess = mess.subSequence(0, 150); mess = mess.subSequence(0, 150);
} }
if (!(mess instanceof SpannableStringBuilder)) {
mess = new SpannableStringBuilder(mess);
}
mess = AndroidUtilities.replaceNewLines(mess); mess = AndroidUtilities.replaceNewLines(mess);
stringFinalText = Emoji.replaceEmoji(mess, textPaint.getFontMetricsInt(), AndroidUtilities.dp(14), true); stringFinalText = Emoji.replaceEmoji(mess, textPaint.getFontMetricsInt(), AndroidUtilities.dp(14), true);
if (messageObject.replyMessageObject.messageOwner != null) { if (messageObject.replyMessageObject.messageOwner != null) {
@ -16711,6 +16889,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentUser != null) { if (currentUser != null) {
return UserObject.getUserName(currentUser); return UserObject.getUserName(currentUser);
} else if (currentChat != null) { } else if (currentChat != null) {
if (currentMessageObject != null && currentChat.signature_profiles) {
long did = DialogObject.getPeerDialogId(currentMessageObject.messageOwner.from_id);
if (did >= 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(did);
if (user != null) return UserObject.getUserName(user);
} else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-did);
if (chat != null) return chat.title;
}
}
return currentChat.title; return currentChat.title;
} else if (currentMessageObject != null && currentMessageObject.isSponsored()) { } else if (currentMessageObject != null && currentMessageObject.isSponsored()) {
return currentMessageObject.sponsoredTitle; return currentMessageObject.sponsoredTitle;
@ -16860,7 +17048,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawable.setBotButtonsBottom(currentMessageObject != null && currentMessageObject.hasInlineBotButtons()); drawable.setBotButtonsBottom(currentMessageObject != null && currentMessageObject.hasInlineBotButtons());
} }
float transitionYOffsetForDrawables; public float transitionYOffsetForDrawables;
public void setDrawableBoundsInner(Drawable drawable, int x, int y, int w, int h) { public void setDrawableBoundsInner(Drawable drawable, int x, int y, int w, int h) {
if (drawable != null) { if (drawable != null) {
@ -18118,6 +18306,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
sideStartX -= offsetX; sideStartX -= offsetX;
sideStartY -= offsetY; sideStartY -= offsetY;
} }
sideButtonVisible = true;
if (drawSideButton == 3) { if (drawSideButton == 3) {
if (!(enterTransitionInProgress && !currentMessageObject.isVoice())) { if (!(enterTransitionInProgress && !currentMessageObject.isVoice())) {
drawCommentButton(canvas, 1f); drawCommentButton(canvas, 1f);
@ -18127,6 +18316,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return; return;
} }
rect.set(sideStartX, sideStartY, sideStartX + AndroidUtilities.dp(32), sideStartY + AndroidUtilities.dp(drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE ? 64 : 32)); rect.set(sideStartX, sideStartY, sideStartX + AndroidUtilities.dp(32), sideStartY + AndroidUtilities.dp(drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE ? 64 : 32));
if (rect.right >= getMeasuredWidth()) {
sideButtonVisible = false;
return;
}
applyServiceShaderMatrix(); applyServiceShaderMatrix();
if (drawSideButton == SIDE_BUTTON_SPONSORED_CLOSE && drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE && sideButtonPressed) { if (drawSideButton == SIDE_BUTTON_SPONSORED_CLOSE && drawSideButton2 == SIDE_BUTTON_SPONSORED_MORE && sideButtonPressed) {
if (sideButtonPath1 == null) { if (sideButtonPath1 == null) {
@ -19360,7 +19553,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
private boolean shouldDrawCaptionLayout() { private boolean shouldDrawCaptionLayout() {
return currentMessageObject != null && !currentMessageObject.preview && (currentPosition == null || (currentMessagesGroup != null && currentMessagesGroup.isDocuments && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0)) && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && currentMessageObject.isVoice()); return currentMessageObject != null && !currentMessageObject.preview && !currentMessageObject.isSponsored() && (currentPosition == null || (currentMessagesGroup != null && currentMessagesGroup.isDocuments && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) == 0)) && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInProgress && currentMessageObject.isVoice());
} }
public void drawCaptionLayout(Canvas canvas, boolean selectionOnly, float alpha) { public void drawCaptionLayout(Canvas canvas, boolean selectionOnly, float alpha) {
@ -19383,7 +19576,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
public void drawReactionsLayout(Canvas canvas, float alpha) { public void drawReactionsLayout(Canvas canvas, float alpha, Integer only) {
if (isRoundVideo) { if (isRoundVideo) {
reactionsLayoutInBubble.drawServiceShaderBackground = 1f - getVideoTranscriptionProgress(); reactionsLayoutInBubble.drawServiceShaderBackground = 1f - getVideoTranscriptionProgress();
} }
@ -19396,11 +19589,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha()), Canvas.ALL_SAVE_FLAG); canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (0xFF * getAlpha()), Canvas.ALL_SAVE_FLAG);
} }
if (reactionsLayoutInBubble.drawServiceShaderBackground > 0 || !transitionParams.animateBackgroundBoundsInner || currentPosition != null || isRoundVideo) { if (reactionsLayoutInBubble.drawServiceShaderBackground > 0 || !transitionParams.animateBackgroundBoundsInner || currentPosition != null || isRoundVideo) {
reactionsLayoutInBubble.draw(canvas, transitionParams.animateChange ? transitionParams.animateChangeProgress : 1f, null); reactionsLayoutInBubble.draw(canvas, transitionParams.animateChange ? transitionParams.animateChangeProgress : 1f, only);
} else { } else {
canvas.save(); canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getBackgroundDrawableBottom() + transitionParams.deltaBottom); canvas.clipRect(0, 0, getMeasuredWidth(), getBackgroundDrawableBottom() + transitionParams.deltaBottom);
reactionsLayoutInBubble.draw(canvas, transitionParams.animateChange ? transitionParams.animateChangeProgress : 1f, null); reactionsLayoutInBubble.draw(canvas, transitionParams.animateChange ? transitionParams.animateChangeProgress : 1f, only);
canvas.restore(); canvas.restore();
} }
if (getAlpha() != 1f) { if (getAlpha() != 1f) {
@ -19922,8 +20115,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
path.rewind(); path.rewind();
int start = spanned.getSpanStart(progressLoadingLink); int start = spanned.getSpanStart(progressLoadingLink);
int end = spanned.getSpanEnd(progressLoadingLink); int end = spanned.getSpanEnd(progressLoadingLink);
path.setUseCornerPathImplementation(true);
path.setCurrentLayout(layout, start, yOffset); path.setCurrentLayout(layout, start, yOffset);
layout.getSelectionPath(start, end, path); layout.getSelectionPath(start, end, path);
path.closeRects();
progressLoadingLinkCurrentDrawable.updateBounds(); progressLoadingLinkCurrentDrawable.updateBounds();
return true; return true;
} }
@ -21010,7 +21205,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_PHOTO || currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) { } else if (currentMessageObject.type == MessageObject.TYPE_VIDEO || currentMessageObject.type == MessageObject.TYPE_PHOTO || currentMessageObject.type == MessageObject.TYPE_EXTENDED_MEDIA_PREVIEW || documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO || documentAttachType == DOCUMENT_ATTACH_TYPE_GIF) {
if (photoImage.getVisible() && !currentMessageObject.isRepostPreview) { if (photoImage.getVisible() && !currentMessageObject.isRepostPreview) {
if (!currentMessageObject.needDrawBluredPreview() && !currentMessageObject.isRepostPreview && !currentMessageObject.preview && !isSmallImage) { if (!currentMessageObject.needDrawBluredPreview() && !currentMessageObject.isSponsored() && !currentMessageObject.isRepostPreview && !currentMessageObject.preview && !isSmallImage) {
if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) { if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha(); int oldAlpha = ((BitmapDrawable) Theme.chat_msgMediaMenuDrawable).getPaint().getAlpha();
if (drawMediaCheckBox) { if (drawMediaCheckBox) {
@ -21063,6 +21258,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
loadingProgressAlpha *= (1f - isSmallImage()); loadingProgressAlpha *= (1f - isSmallImage());
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
loadingProgressAlpha *= mediaSpoilerRevealProgress;
}
if (loadingProgressAlpha > 0) { if (loadingProgressAlpha > 0) {
boolean bigRadius = false; boolean bigRadius = false;
@ -21760,7 +21958,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if ( if (
(!isRoundVideo || !hasLinkPreview) && (!isRoundVideo || !hasLinkPreview) &&
(!currentMessageObject.needDrawBluredPreview() || !MediaController.getInstance().isPlayingMessage(currentMessageObject)) && (!currentMessageObject.needDrawBluredPreview() || !MediaController.getInstance().isPlayingMessage(currentMessageObject)) &&
!(currentMessageObject.hasMediaSpoilers() && (!currentMessageObject.isMediaSpoilersRevealed || !currentMessageObject.revealingMediaSpoilers) && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && currentMessagesGroup == null && (radialProgress.getIcon() == MediaActionDrawable.ICON_PLAY || radialProgress.getIcon() == MediaActionDrawable.ICON_NONE)) !(currentMessageObject.hasMediaSpoilers() && (!currentMessageObject.isMediaSpoilersRevealed || !currentMessageObject.revealingMediaSpoilers) && SharedConfig.isAutoplayVideo() && !currentMessageObject.isRepostPreview && currentMessagesGroup == null && (radialProgress.getIcon() == MediaActionDrawable.ICON_PLAY || radialProgress.getIcon() == MediaActionDrawable.ICON_NONE)) &&
!currentMessageObject.isHiddenSensitive()
) { ) {
if (currentMessageObject.needDrawBluredPreview()) { if (currentMessageObject.needDrawBluredPreview()) {
radialProgress.overrideCircleAlpha = 0f; radialProgress.overrideCircleAlpha = 0f;
@ -21803,6 +22002,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
if ((drawVideoImageButton || animatingDrawVideoImageButton != 0) && !currentMessageObject.isRepostPreview && !currentMessageObject.sendPreview && photoImage.getVisible() && !isSmallImage) { if ((drawVideoImageButton || animatingDrawVideoImageButton != 0) && !currentMessageObject.isRepostPreview && !currentMessageObject.sendPreview && photoImage.getVisible() && !isSmallImage) {
float alpha = controlsAlpha; float alpha = controlsAlpha;
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
alpha *= mediaSpoilerRevealProgress;
}
videoRadialProgress.setOverrideAlpha(alpha); videoRadialProgress.setOverrideAlpha(alpha);
videoRadialProgress.draw(canvas); videoRadialProgress.draw(canvas);
} }
@ -21940,6 +22142,52 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_timePaint.setAlpha(255); Theme.chat_timePaint.setAlpha(255);
} }
} }
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
if (sensitiveText == null) {
SpannableStringBuilder sensitiveTextString = new SpannableStringBuilder("x " + getString(R.string.MessageSensitiveContent));
ColoredImageSpan span = new ColoredImageSpan(R.drawable.filled_sensitive);
sensitiveTextString.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sensitiveText = new Text(sensitiveTextString, 14, AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
}
Text text = sensitiveText;
if (photoImage.getImageWidth() < dp(13 + 13) + sensitiveText.getCurrentWidth()) {
if (sensitiveTextShort == null) {
SpannableStringBuilder sensitiveTextString = new SpannableStringBuilder("x " + getString(R.string.MessageSensitiveContentShort));
ColoredImageSpan span = new ColoredImageSpan(R.drawable.filled_sensitive);
sensitiveTextString.setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sensitiveTextShort = new Text(sensitiveTextString, 14, AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
}
text = sensitiveTextShort;
}
final float cx = photoImage.getImageX() + photoImage.getImageWidth() / 2f;
final float cy = photoImage.getImageY() + photoImage.getImageHeight() / 2f;
final float w = text.getCurrentWidth() + dp(13 + 13);
final float h = dp(32), r = h / 2f;
float s = AndroidUtilities.lerp(.8f, 1f, 1f - mediaSpoilerRevealProgress);
AndroidUtilities.rectTmp.set(cx - w / 2f * s, cy - h / 2f * s, cx + w / 2f * s, cy + h / 2f * s);
rectPath.reset();
rectPath.addRoundRect(AndroidUtilities.rectTmp, r, r, Path.Direction.CW);
canvas.save();
canvas.clipPath(rectPath);
float wasAlpha = blurredPhotoImage.getAlpha();
blurredPhotoImage.setAlpha((1f - mediaSpoilerRevealProgress) * wasAlpha);
blurredPhotoImage.draw(canvas);
blurredPhotoImage.setAlpha(wasAlpha);
canvas.restore();
int oldAlpha = getThemedPaint(Theme.key_paint_chatTimeBackground).getAlpha();
getThemedPaint(Theme.key_paint_chatTimeBackground).setAlpha((int) (oldAlpha * controlsAlpha * (1f - mediaSpoilerRevealProgress) * .35f));
canvas.drawRoundRect(AndroidUtilities.rectTmp, r, r, getThemedPaint(Theme.key_paint_chatTimeBackground));
getThemedPaint(Theme.key_paint_chatTimeBackground).setAlpha(oldAlpha);
canvas.save();
canvas.scale(s, s, cx, cy);
text.draw(canvas, cx - w / 2f + dp(13), cy, 0xFFFFFFFF, 1f - mediaSpoilerRevealProgress);
canvas.restore();
}
} }
private Paint clipPaint; private Paint clipPaint;
@ -21962,6 +22210,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawPhotoBlurRect(canvas, radialProgress.getProgressRect()); drawPhotoBlurRect(canvas, radialProgress.getProgressRect());
} }
radialProgress.iconScale = 1f; radialProgress.iconScale = 1f;
if (drawPhotoImage && currentMessageObject != null && currentMessageObject.hasMediaSpoilers() && currentMessageObject.isSensitive() && (!currentMessageObject.isMediaSpoilersRevealed || mediaSpoilerRevealProgress != 0 && mediaSpoilerRevealProgress < 1)) {
radialProgress.iconScale *= mediaSpoilerRevealProgress;
}
radialProgress.draw(canvas); radialProgress.draw(canvas);
if (withPeriod) { if (withPeriod) {
@ -24257,7 +24508,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
public boolean needDrawAvatar() { public boolean needDrawAvatar() {
return isChat && !isSavedPreviewChat && (!isThreadPost || isForum) && currentMessageObject != null && !currentMessageObject.isOutOwner() && currentMessageObject.needDrawAvatar() || currentMessageObject != null && currentMessageObject.forceAvatar; return (
isChat && !isSavedPreviewChat && (!isThreadPost || isForum) && (
currentMessageObject != null && !currentMessageObject.isOutOwner() && currentMessageObject.needDrawAvatar()
) ||
currentMessageObject != null && currentMessageObject.forceAvatar
);
} }
protected boolean drawPhotoImage(Canvas canvas) { protected boolean drawPhotoImage(Canvas canvas) {

View file

@ -460,10 +460,10 @@ public class CheckBoxCell extends FrameLayout {
linksTextView.setSingleLine(false); linksTextView.setSingleLine(false);
linksTextView.setEllipsize(null); linksTextView.setEllipsize(null);
if (currentType != TYPE_CHECK_BOX_URL) { if (currentType != TYPE_CHECK_BOX_URL) {
layoutParams.height = LayoutParams.WRAP_CONTENT; // layoutParams.height = LayoutParams.WRAP_CONTENT;
layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP; // layoutParams.gravity = (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP;
layoutParams.topMargin = dp(14); // layoutParams.topMargin = dp(14);
layoutParams.bottomMargin = dp(10); // layoutParams.bottomMargin = dp(10);
} }
} else { } else {
linksTextView.setLines(1); linksTextView.setLines(1);

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