update to 10.2.6 (4082)

This commit is contained in:
dkaraush 2023-11-07 23:22:00 +04:00
parent c319639e9a
commit 017f019314
67 changed files with 1833 additions and 485 deletions

View file

@ -430,3 +430,10 @@ chat_inContactIcon=-1
code_comment=-2130706433
chat_outCodeBackground=857487708
chat_inCodeBackground=856033549
code_keyword=-27776
code_constant=-27776
code_function=-27776
code_string=-7806088
code_operator=2147483647
code_number=-10887465
code_comment=2147483647

BIN
TMessagesProj/src/main/assets/fonts/rmono.ttf Executable file → Normal file

Binary file not shown.

View file

@ -455,3 +455,10 @@ chat_inContactIcon=-1
code_comment=-2130706433
chat_outCodeBackground=859062986
chat_inCodeBackground=855638016
code_keyword=-27776
code_constant=-27776
code_function=-27776
code_string=-7806088
code_operator=2147483647
code_number=-10887465
code_comment=2147483647

View file

@ -515,6 +515,35 @@ public class AndroidUtilities {
return spannableStringBuilder;
}
public static SpannableStringBuilder replaceSingleLink(String str, int color) {
int startIndex = str.indexOf("**");
int endIndex = str.indexOf("**", startIndex + 1);
str = str.replace("**", "");
int index = -1;
int len = 0;
if (startIndex >= 0 && endIndex >= 0 && endIndex - startIndex > 2) {
len = endIndex - startIndex - 2;
index = startIndex;
}
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
if (index >= 0) {
spannableStringBuilder.setSpan(new ClickableSpan() {
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(color);
}
@Override
public void onClick(@NonNull View view) {
}
}, index, index + len, 0);
}
return spannableStringBuilder;
}
public static void recycleBitmaps(List<Bitmap> bitmapToRecycle) {
if (Build.VERSION.SDK_INT <= 23) {
// cause to crash:
@ -2941,6 +2970,9 @@ public class AndroidUtilities {
}
public static void shakeViewSpring(View view, float shiftDp, Runnable endCallback) {
if (view == null) {
return;
}
int shift = dp(shiftDp);
if (view.getTag(R.id.spring_tag) != null) {
((SpringAnimation) view.getTag(R.id.spring_tag)).cancel();

View file

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

View file

@ -1,9 +1,13 @@
package org.telegram.messenger;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.Editable;
import android.text.Layout;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
@ -12,6 +16,7 @@ import android.text.SpannedString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.LeadingMarginSpan;
import android.text.style.LineHeightSpan;
import android.text.style.MetricAffectingSpan;
import android.util.Log;
@ -52,7 +57,13 @@ public class CodeHighlighting {
public static final int MATCH_COMMENT = 6;
public static final int MATCH_FUNCTION = 7;
public static class Span extends MetricAffectingSpan {
public static int getTextSizeDecrement(int codeLength) {
if (codeLength > 120) return 5;
if (codeLength > 50) return 3;
return 2;
}
public static class Span extends CharacterStyle {
public final String lng;
public final String code;
@ -67,36 +78,15 @@ public class CodeHighlighting {
this.lng = lng;
this.code = code;
if (code == null) {
this.decrementSize = 2;
} else if (code.length() > 120) {
this.decrementSize = 5;
} else if (code.length() > 50) {
this.decrementSize = 3;
} else {
this.decrementSize = 2;
}
this.decrementSize = getTextSizeDecrement(code == null ? 0 : code.length());
this.currentType = type;
this.style = style;
}
@Override
public void updateMeasureState(TextPaint p) {
if (smallerSize) {
p.setTextSize(AndroidUtilities.dp(SharedConfig.fontSize - decrementSize));
}
p.setFlags(p.getFlags() | Paint.SUBPIXEL_TEXT_FLAG);
if (style != null) {
style.applyStyle(p);
} else {
p.setTypeface(Typeface.MONOSPACE);
}
}
@Override
public void updateDrawState(TextPaint p) {
if (smallerSize) {
p.setTextSize(AndroidUtilities.dp(SharedConfig.fontSize - decrementSize));
p.setTextSize(dp(SharedConfig.fontSize - decrementSize));
}
if (currentType == 2) {
p.setColor(0xffffffff);

View file

@ -1384,6 +1384,14 @@ public class DatabaseMigrationHelper {
version = 135;
}
if (version == 135) {
// database.executeFast("DROP TABLE stickersets").stepThis().dispose();
database.executeFast("CREATE TABLE stickersets2(id INTEGER PRIMATE KEY, data BLOB, hash INTEGER, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS stickersets2_id_index ON stickersets2(id);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 136").stepThis().dispose();
version = 136;
}
return version;
}

View file

@ -170,7 +170,7 @@ public class FileLog {
//exclude file loading
excludeRequests = new HashSet<>();
excludeRequests.add("TL_upload_getFile");
excludeRequests.add("TL_upload_a");
excludeRequests.add("TL_upload_getWebFile");
ExclusionStrategy strategy = new ExclusionStrategy() {

View file

@ -1244,19 +1244,36 @@ public class MediaDataController extends BaseController {
return null;
}
private boolean cleanedupStickerSetCache;
private void cleanupStickerSetCache() {
if (cleanedupStickerSetCache) {
return;
}
cleanedupStickerSetCache = true;
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
final long minDate = (System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7);
getMessagesStorage().getDatabase().executeFast("DELETE FROM stickersets2 WHERE date < " + minDate).stepThis().dispose();
} catch (Exception e) {
FileLog.e(e);
}
});
}
private void saveStickerSetIntoCache(TLRPC.TL_messages_stickerSet set) {
if (set == null || set.set == null) {
return;
}
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO stickersets VALUES(?, ?, ?)");
SQLitePreparedStatement state = getMessagesStorage().getDatabase().executeFast("REPLACE INTO stickersets2 VALUES(?, ?, ?, ?)");
state.requery();
NativeByteBuffer data = new NativeByteBuffer(set.getObjectSize());
set.serializeToStream(data);
state.bindLong(1, set.set.id);
state.bindByteBuffer(2, data);
state.bindInteger(3, set.set.hash);
state.bindLong(4, System.currentTimeMillis());
state.step();
data.reuse();
state.dispose();
@ -1264,6 +1281,7 @@ public class MediaDataController extends BaseController {
FileLog.e(e);
}
});
cleanupStickerSetCache();
}
private TLRPC.TL_messages_stickerSet getCachedStickerSetInternal(long id, Integer hash) {
@ -1271,7 +1289,7 @@ public class MediaDataController extends BaseController {
SQLiteCursor cursor = null;
NativeByteBuffer data = null;
try {
cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT data, hash FROM stickersets WHERE id = " + id + " LIMIT 1");
cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT data, hash FROM stickersets2 WHERE id = " + id + " LIMIT 1");
if (cursor.next() && !cursor.isNull(0)) {
data = cursor.byteBufferValue(0);
if (data != null) {
@ -6283,11 +6301,15 @@ public class MediaDataController extends BaseController {
content = substring(content, 0, content.length() - 1);
}
if (!TextUtils.isEmpty(content)) {
if (content.length() > 1 && content.charAt(0) == '\n') {
content = content.subSequence(1, content.length());
index--;
}
message[0] = AndroidUtilities.concat(startMessage, content, endMessage);
TLRPC.TL_messageEntityPre entity = new TLRPC.TL_messageEntityPre();
entity.offset = start + (replacedFirst ? 0 : 1);
entity.length = index - start - 3 - (language.length() + (!language.isEmpty() ? 1 : 0)) + (replacedFirst ? 0 : 1);
entity.language = language;
entity.language = TextUtils.isEmpty(language) || language.trim().length() == 0 ? "" : language;
entities.add(entity);
lastIndex -= 6;
}
@ -6630,10 +6652,13 @@ public class MediaDataController extends BaseController {
TLRPC.Peer peer2 = getMessagesController().getPeer(dialogId);
TLRPC.Peer thisPeer = quote.message.messageOwner.peer_id;
if (peer2 != null && !MessageObject.peersEqual(peer2, thisPeer)) {
draftMessage.reply_to.flags |= 1;
draftMessage.reply_to.reply_to_peer_id = getMessagesController().getInputPeer(peer2);
draftMessage.reply_to.flags |= 2;
draftMessage.reply_to.reply_to_peer_id = getMessagesController().getInputPeer(thisPeer);
}
}
} else if (dialogId != MessageObject.getDialogId(replyToMessage)) {
draftMessage.reply_to.flags |= 2;
draftMessage.reply_to.reply_to_peer_id = getMessagesController().getInputPeer(getMessagesController().getPeer(MessageObject.getDialogId(replyToMessage)));
}
}
if (entities != null && !entities.isEmpty()) {
@ -6644,10 +6669,20 @@ public class MediaDataController extends BaseController {
SparseArray<TLRPC.DraftMessage> threads = drafts.get(dialogId);
TLRPC.DraftMessage currentDraft = threads == null ? null : threads.get(threadId);
if (!clean) {
if (
currentDraft != null && currentDraft.message.equals(draftMessage.message) && replyToEquals(currentDraft.reply_to, draftMessage.reply_to) && currentDraft.no_webpage == draftMessage.no_webpage ||
currentDraft == null && TextUtils.isEmpty(draftMessage.message) && (draftMessage.reply_to == null || draftMessage.reply_to.reply_to_msg_id == 0)
) {
boolean sameDraft;
if (currentDraft != null) {
sameDraft = (
currentDraft.message.equals(draftMessage.message) &&
replyToEquals(currentDraft.reply_to, draftMessage.reply_to) &&
currentDraft.no_webpage == draftMessage.no_webpage
);
} else {
sameDraft = (
TextUtils.isEmpty(draftMessage.message) &&
(draftMessage.reply_to == null || draftMessage.reply_to.reply_to_msg_id == 0)
);
}
if (sameDraft) {
return;
}
}
@ -6791,7 +6826,7 @@ public class MediaDataController extends BaseController {
if (threads != null) {
replyToMessage = threads.get(threadId);
}
if (replyToMessage == null || replyToMessage.id != draft.reply_to.reply_to_msg_id || !MessageObject.peersEqual(replyToMessage.peer_id, getMessagesController().getPeer(draft.reply_to.reply_to_msg_id))) {
if (replyToMessage == null || replyToMessage.id != draft.reply_to.reply_to_msg_id || !MessageObject.peersEqual(draft.reply_to.reply_to_peer_id, replyToMessage.peer_id)) {
replyToMessage = null;
}
} else if (draft != null && draft.reply_to == null) {
@ -6823,13 +6858,14 @@ public class MediaDataController extends BaseController {
}
editor.commit();
if (fromServer && (threadId == 0 || getMessagesController().isForum(dialogId))) {
if (draft != null && draft.reply_to != null && draft.reply_to.reply_to_msg_id != 0 && replyToMessage == null) {
if (draft != null && draft.reply_to != null && draft.reply_to.reply_to_msg_id != 0 && (replyToMessage == null || replyToMessage.reply_to instanceof TLRPC.TL_messageReplyHeader && replyToMessage.replyMessage == null)) {
final long replyDialogId = (draft.reply_to.flags & 2) != 0 ? DialogObject.getPeerDialogId(draft.reply_to.reply_to_peer_id) : dialogId;
TLRPC.User user = null;
TLRPC.Chat chat = null;
if (DialogObject.isUserDialog(dialogId)) {
user = getMessagesController().getUser(dialogId);
if (DialogObject.isUserDialog(replyDialogId)) {
user = getMessagesController().getUser(replyDialogId);
} else {
chat = getMessagesController().getChat(-dialogId);
chat = getMessagesController().getChat(-replyDialogId);
}
if (user != null || chat != null) {
long channelId = ChatObject.isChannel(chat) ? chat.id : 0;
@ -6838,7 +6874,7 @@ public class MediaDataController extends BaseController {
getMessagesStorage().getStorageQueue().postRunnable(() -> {
try {
TLRPC.Message message = null;
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data FROM messages_v2 WHERE mid = %d and uid = %d", messageId, dialogId));
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT data, replydata FROM messages_v2 WHERE mid = %d and uid = %d", messageId, replyDialogId));
if (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) {
@ -6846,6 +6882,33 @@ public class MediaDataController extends BaseController {
message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse();
}
if (message != null) {
ArrayList<Long> usersToLoad = new ArrayList<>();
ArrayList<Long> chatsToLoad = new ArrayList<>();
LongSparseArray<SparseArray<ArrayList<TLRPC.Message>>> replyMessageOwners = new LongSparseArray<>();
LongSparseArray<ArrayList<Integer>> dialogReplyMessagesIds = new LongSparseArray<>();
try {
if (message.reply_to != null && message.reply_to.reply_to_msg_id != 0) {
if (!cursor.isNull(1)) {
NativeByteBuffer data2 = cursor.byteBufferValue(1);
if (data2 != null) {
message.replyMessage = TLRPC.Message.TLdeserialize(data2, data2.readInt32(false), false);
message.replyMessage.readAttachPath(data2, getUserConfig().clientUserId);
data2.reuse();
if (message.replyMessage != null) {
MessagesStorage.addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad, null);
}
}
}
if (message.replyMessage == null) {
MessagesStorage.addReplyMessages(message, replyMessageOwners, dialogReplyMessagesIds);
}
}
} catch (Exception e) {
getMessagesStorage().checkSQLException(e);
}
getMessagesStorage().loadReplyMessages(replyMessageOwners, dialogReplyMessagesIds, usersToLoad, chatsToLoad, false);
}
}
cursor.dispose();
if (message == null) {

View file

@ -10,9 +10,10 @@ package org.telegram.messenger;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
@ -32,10 +33,10 @@ import android.text.style.ClickableSpan;
import android.text.style.URLSpan;
import android.text.util.Linkify;
import android.util.Base64;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray;
import androidx.core.graphics.ColorUtils;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.browser.Browser;
@ -56,6 +57,7 @@ import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.QuoteSpan;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.Reactions.ReactionsUtils;
import org.telegram.ui.Components.Text;
import org.telegram.ui.Components.TextStyleSpan;
import org.telegram.ui.Components.TranscribeButton;
import org.telegram.ui.Components.TypefaceSpan;
@ -675,6 +677,152 @@ public class MessageObject {
public boolean code;
public boolean quote;
public String language;
public Text languageLayout;
public int languageHeight; // included in padTop
public boolean hasCodeCopyButton;
public int copyIconColor;
public Drawable copyIcon;
public Text copyText;
public int copySelectorColor;
public Drawable copySelector;
public Paint copySeparator;
public void layoutCode(String lng, int codeLength) {
hasCodeCopyButton = codeLength >= 75;
if (hasCodeCopyButton) {
copyText = new Text(LocaleController.getString(R.string.CopyCode).toUpperCase(), SharedConfig.fontSize - 3, AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
copyIcon = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.msg_copy).mutate();
copyIcon.setColorFilter(new PorterDuffColorFilter(copyIconColor, PorterDuff.Mode.SRC_IN));
copySelector = Theme.createRadSelectorDrawable(copySelectorColor, 0, 0, Math.min(5, SharedConfig.bubbleRadius), 0);
copySeparator = new Paint(Paint.ANTI_ALIAS_FLAG);
}
if (TextUtils.isEmpty(lng)) {
language = null;
languageLayout = null;
return;
}
language = lng;
languageLayout = new Text(
capitalizeLanguage(lng),
SharedConfig.fontSize - 1 - CodeHighlighting.getTextSizeDecrement(codeLength) / 2,
AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)
);
languageHeight = (int) (languageLayout.getTextSize() * 1.714f) + dp(4);
}
public void drawCopyCodeButton(Canvas canvas, RectF bounds, int textColor, int backgroundColor, float alpha) {
if (!hasCodeCopyButton) {
return;
}
final int selectorColor = Theme.multAlpha(textColor, .10f);
if (copySelectorColor != selectorColor) {
Theme.setSelectorDrawableColor(copySelector, copySelectorColor = selectorColor, true);
}
copySelector.setBounds((int) bounds.left + dp(3), (int) (bounds.bottom - dp(38)), (int) bounds.right, (int) bounds.bottom);
copySelector.setAlpha((int) (0xFF * alpha));
copySelector.draw(canvas);
copySeparator.setColor(ColorUtils.setAlphaComponent(backgroundColor, 0x26));
canvas.drawRect(bounds.left + dp(10), bounds.bottom - dp(38) - AndroidUtilities.getShadowHeight(), bounds.right - dp(6.66f), bounds.bottom - dp(38), copySeparator);
final float iconScale = .8f;
final float contentWidth = Math.min(bounds.width() - dp(12), copyIcon.getIntrinsicWidth() * iconScale + dp(5) + copyText.getCurrentWidth());
float x = bounds.centerX() - contentWidth / 2f;
final float cy = bounds.bottom - dp(38) / 2f;
if (copyIconColor != textColor) {
copyIcon.setColorFilter(new PorterDuffColorFilter(copyIconColor = textColor, PorterDuff.Mode.SRC_IN));
}
copyIcon.setAlpha((int) (0xFF * alpha));
copyIcon.setBounds(
(int) x,
(int) (cy - copyIcon.getIntrinsicHeight() * iconScale / 2f),
(int) (x + copyIcon.getIntrinsicWidth() * iconScale),
(int) (cy + copyIcon.getIntrinsicHeight() * iconScale / 2f)
);
copyIcon.draw(canvas);
x += copyIcon.getIntrinsicWidth() * iconScale + dp(5);
copyText
.ellipsize((int) (contentWidth - (copyIcon.getIntrinsicWidth() * iconScale + dp(5))) + dp(12))
.draw(canvas, x, cy, textColor, alpha);
}
private static String capitalizeLanguage(String lng) {
if (lng == null) return null;
String llng = lng.toLowerCase().replaceAll("\\W", "");
switch (llng) {
case "js":
case "javascript":
return "JavaScript";
case "ts":
case "typescript":
return "TypeScript";
case "objc":
case "objectivec":
return "Objective-C";
case "md":
case "markdown":
return "Markdown";
case "rb":
case "ruby":
return "Ruby";
case "py":
case "python":
return "Python";
case "actionscript": return "ActionScript";
case "autohotkey": return "AutoHotKey";
case "cpp": return "C++";
case "csharp":
case "cs":
return "C#";
case "aspnet": return "ASP.NET";
case "c":
case "arduino":
case "swift":
case "rust":
case "pascal":
case "kotlin":
case "lua":
case "docker":
case "dockerfile":
case "dart":
case "java":
return capitalizeFirst(lng);
case "http":
case "html":
case "css":
case "scss":
case "less":
case "asm":
case "nasm":
case "wasm":
case "xml":
case "yaml":
case "yml":
case "php":
case "json":
case "json5":
case "r":
case "ini":
case "glsl":
case "hlsl":
case "csv":
case "cobol":
case "jsx":
case "tsx":
return lng.toUpperCase();
}
return lng;
}
private static String capitalizeFirst(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
}
public boolean isRtl() {
return (directionFlags & FLAG_RTL) != 0 && (directionFlags & FLAG_NOT_RTL) == 0;
}
@ -1249,6 +1397,7 @@ public class MessageObject {
public boolean hasCodeAtTop, hasCodeAtBottom;
public boolean hasQuote;
public boolean hasSingleQuote;
public boolean hasSingleCode;
public boolean hasQuoteAtBottom;
public MessageObject(int accountNum, TL_stories.StoryItem storyItem) {
@ -5777,7 +5926,7 @@ public class MessageObject {
}
generatedWithDensity = AndroidUtilities.density;
if (hasCode) {
maxWidth = generatedWithMinSize - dp(45);
maxWidth = generatedWithMinSize - dp(45 + 15);
if (needDrawAvatarInternal() && !isOutOwner() && !messageOwner.isThreadMessage) {
maxWidth -= dp(52);
}
@ -5802,7 +5951,7 @@ public class MessageObject {
maxWidth -= dp(52);
}
if (needDrawShareButton() && !isOutOwner()) {
maxWidth -= dp(20);
maxWidth -= dp(10);
}
if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) {
maxWidth -= dp(10);
@ -5894,6 +6043,7 @@ public class MessageObject {
hasCode = messageText instanceof Spanned && ((Spanned) messageText).getSpans(0, messageText.length(), CodeHighlighting.Span.class).length > 0;
hasQuote = messageText instanceof Spanned && ((Spanned) messageText).getSpans(0, messageText.length(), QuoteSpan.QuoteStyleSpan.class).length > 0;
hasSingleQuote = false;
hasSingleCode = false;
if (messageText instanceof Spanned) {
Spanned spanned = (Spanned) messageText;
@ -5902,6 +6052,9 @@ public class MessageObject {
quoteSpans[i].adaptLineHeight = false;
}
hasSingleQuote = quoteSpans.length == 1 && spanned.getSpanStart(quoteSpans[0]) == 0 && spanned.getSpanEnd(quoteSpans[0]) == spanned.length();
CodeHighlighting.Span[] codeSpans = spanned.getSpans(0, spanned.length(), CodeHighlighting.Span.class);
hasSingleCode = codeSpans.length == 1 && spanned.getSpanStart(codeSpans[0]) == 0 && spanned.getSpanEnd(codeSpans[0]) == spanned.length();
}
@ -5909,6 +6062,8 @@ public class MessageObject {
if (hasSingleQuote) {
maxWidth -= AndroidUtilities.dp(32);
} else if (hasSingleCode) {
maxWidth -= AndroidUtilities.dp(15);
}
StaticLayout textLayout;
@ -5948,6 +6103,8 @@ public class MessageObject {
if (hasSingleQuote) {
maxWidth += AndroidUtilities.dp(32);
} else if (hasSingleCode) {
maxWidth += AndroidUtilities.dp(15);
}
textHeight = 0;
@ -5996,6 +6153,7 @@ public class MessageObject {
hasCodeAtBottom = false;
hasQuoteAtBottom = false;
hasSingleQuote = false;
hasSingleCode = false;
float offset = 0;
for (int a = 0; a < textRanges.size(); a++) {
TextLayoutBlock block = new TextLayoutBlock();
@ -6016,17 +6174,19 @@ public class MessageObject {
hasCodeAtBottom = block.code;
}
hasSingleQuote = block.first && block.last && block.quote;
hasSingleCode = block.first && block.last && !block.quote && block.code;
if (block.quote) {
if (block.first && block.last) {
block.padTop = block.padBottom = AndroidUtilities.dp(6);
block.padTop = block.padBottom = dp(6);
} else {
block.padTop = AndroidUtilities.dp(block.first ? 8 : 6);
block.padBottom = AndroidUtilities.dp(7);
block.padTop = dp(block.first ? 8 : 6);
block.padBottom = dp(7);
}
} else if (block.code) {
block.padTop = block.first ? 0 : AndroidUtilities.dp(5);
block.padBottom = block.last ? 0 : AndroidUtilities.dp(5);
block.layoutCode(range.language, range.end - range.start);
block.padTop = dp(4) + block.languageHeight + (block.first ? 0 : dp(5));
block.padBottom = dp(4) + (block.last ? 0 : dp(7)) + (block.hasCodeCopyButton ? dp(38) : 0);
}
TextPaint layoutPaint = paint;
@ -6042,12 +6202,23 @@ public class MessageObject {
}
CharSequence blockText = messageText.subSequence(range.start, range.end);
int blockMaxWidth = maxWidth;
if (block.quote) {
blockMaxWidth -= dp(24);
} else if (block.code) {
blockMaxWidth -= dp(15);
}
if (blocksCount == 1) {
if (block.code && !block.quote && textLayout.getText() instanceof Spannable && !TextUtils.isEmpty(range.language)) {
SpannableString sb = CodeHighlighting.getHighlighted(blockText.toString(), range.language);
if (hasUrls && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (block.code && !block.quote && textLayout.getText() instanceof Spannable) {
SpannableString sb;
if (!TextUtils.isEmpty(range.language)) {
sb = CodeHighlighting.getHighlighted(blockText.toString(), range.language);
} else {
sb = new SpannableString(blockText.toString());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(sb, 0, sb.length(), layoutPaint, maxWidth - (block.quote ? dp(24) : 0) + dp(2))
StaticLayout.Builder.obtain(sb, 0, sb.length(), layoutPaint, blockMaxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
@ -6060,7 +6231,7 @@ public class MessageObject {
}
textLayout = builder.build();
} else {
textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, maxWidth - (block.quote ? dp(24) : 0), align, lineSpacing, lineAdd, false);
textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
}
}
@ -6102,22 +6273,16 @@ public class MessageObject {
} else {
sb = SpannableString.valueOf(blockText);
}
if (hasUrls && Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(sb, 0, sb.length(), layoutPaint, maxWidth - (block.quote ? dp(24) : 0) + dp(2))
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
if (emojiOnlyCount > 0) {
builder.setIncludePad(false);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
builder.setUseLineSpacingFromFallbacks(false);
}
}
StaticLayout.Builder.obtain(sb, 0, sb.length(), layoutPaint, blockMaxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
block.textLayout = builder.build();
} else {
block.textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, maxWidth - (block.quote ? dp(24) : 0), align, lineSpacing, lineAdd, false);
block.textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
}
block.textYOffset = offset;
@ -6162,6 +6327,8 @@ public class MessageObject {
}
if (block.quote) {
lastLine += AndroidUtilities.dp(32);
} else if (block.code) {
lastLine += AndroidUtilities.dp(15);
}
int linesMaxWidth = (int) Math.ceil(lastLine);
@ -6200,6 +6367,8 @@ public class MessageObject {
if (block.quote) {
lineWidth += AndroidUtilities.dp(32);
} else if (block.code) {
lineWidth += AndroidUtilities.dp(15);
}
try {
@ -6262,7 +6431,13 @@ public class MessageObject {
block.spoilers.clear();
if (!isSpoilersRevealed && !spoiledLoginCode) {
SpoilerEffect.addSpoilers(null, block.textLayout, -1, linesMaxWidthWithLeft, null, block.spoilers);
int right = linesMaxWidthWithLeft;
if (block.quote) {
right -= AndroidUtilities.dp(32);
} else if (block.code) {
right -= AndroidUtilities.dp(15);
}
SpoilerEffect.addSpoilers(null, block.textLayout, -1, right, null, block.spoilers);
}
}
@ -6278,11 +6453,8 @@ public class MessageObject {
public boolean hasRtl;
public float textXOffset;
public final ArrayList<TextLayoutBlock> textLayoutBlocks = new ArrayList<>();
public boolean hasCode;
public boolean hasCodeAtTop, hasCodeAtBottom;
public boolean hasQuote;
public boolean hasSingleQuote;
public boolean hasQuoteAtBottom;
public boolean hasCode, hasCodeAtTop, hasCodeAtBottom, hasSingleCode;
public boolean hasQuote, hasQuoteAtBottom, hasSingleQuote;
public TextLayoutBlocks(MessageObject messageObject, @NonNull CharSequence text, TextPaint textPaint, int width) {
this.text = text;
@ -6291,6 +6463,7 @@ public class MessageObject {
hasCode = text instanceof Spanned && ((Spanned) text).getSpans(0, text.length(), CodeHighlighting.Span.class).length > 0;
hasQuote = text instanceof Spanned && ((Spanned) text).getSpans(0, text.length(), QuoteSpan.QuoteStyleSpan.class).length > 0;
hasSingleQuote = false;
hasSingleCode = false;
if (text instanceof Spanned) {
Spanned spanned = (Spanned) text;
@ -6299,12 +6472,17 @@ public class MessageObject {
quoteSpans[i].adaptLineHeight = false;
}
hasSingleQuote = quoteSpans.length == 1 && spanned.getSpanStart(quoteSpans[0]) == 0 && spanned.getSpanEnd(quoteSpans[0]) == spanned.length();
CodeHighlighting.Span[] codeSpans = spanned.getSpans(0, spanned.length(), CodeHighlighting.Span.class);
hasSingleCode = codeSpans.length == 1 && spanned.getSpanStart(codeSpans[0]) == 0 && spanned.getSpanEnd(codeSpans[0]) == spanned.length();
}
StaticLayout textLayout;
if (hasSingleQuote) {
width -= AndroidUtilities.dp(32);
} else if (hasSingleCode) {
width -= AndroidUtilities.dp(15);
}
final float lineSpacing = 1f;
@ -6329,6 +6507,8 @@ public class MessageObject {
if (hasSingleQuote) {
width += AndroidUtilities.dp(32);
} else if (hasSingleCode) {
width += AndroidUtilities.dp(15);
}
textHeight = 0;
@ -6395,14 +6575,15 @@ public class MessageObject {
if (block.quote) {
if (block.first && block.last) {
block.padTop = block.padBottom = AndroidUtilities.dp(6);
block.padTop = block.padBottom = dp(6);
} else {
block.padTop = AndroidUtilities.dp(block.first ? 8 : 6);
block.padBottom = AndroidUtilities.dp(7);
block.padTop = dp(block.first ? 8 : 6);
block.padBottom = dp(7);
}
} else if (block.code) {
block.padTop = block.first ? 0 : AndroidUtilities.dp(5);
block.padBottom = block.last ? 0 : AndroidUtilities.dp(5);
block.layoutCode(range.language, range.end - range.start);
block.padTop = dp(4) + block.languageHeight + (block.first ? 0 : dp(5));
block.padBottom = dp(4) + (block.last ? 0 : dp(7)) + (block.hasCodeCopyButton ? dp(38) : 0);
}
TextPaint layoutPaint = textPaint;
@ -6417,19 +6598,30 @@ public class MessageObject {
}
}
int blockMaxWidth = width;
if (block.quote) {
blockMaxWidth -= dp(32);
} else if (block.code) {
blockMaxWidth -= dp(15);
}
if (blocksCount == 1) {
if (block.code && !block.quote && textLayout.getText() instanceof Spannable && !TextUtils.isEmpty(range.language)) {
SpannableString sb = CodeHighlighting.getHighlighted(text.subSequence(range.start, range.end).toString(), range.language);
if (block.code && !block.quote && textLayout.getText() instanceof Spannable) {
SpannableString sb;
if (!TextUtils.isEmpty(range.language)) {
sb = CodeHighlighting.getHighlighted(text.subSequence(range.start, range.end).toString(), range.language);
} else {
sb = new SpannableString(text.subSequence(range.start, range.end));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
StaticLayout.Builder builder =
StaticLayout.Builder.obtain(sb, 0, text.length(), layoutPaint, width)
StaticLayout.Builder.obtain(sb, 0, text.length(), layoutPaint, blockMaxWidth)
.setLineSpacing(lineAdd, lineSpacing)
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(align);
textLayout = builder.build();
} else {
textLayout = new StaticLayout(sb, layoutPaint, width, align, lineSpacing, lineAdd, false);
textLayout = new StaticLayout(sb, layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
}
}
@ -6455,7 +6647,7 @@ public class MessageObject {
} else {
sb = SpannableString.valueOf(text.subSequence(startCharacter, endCharacter));
}
block.textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, width - (block.quote ? dp(24) : 0), align, lineSpacing, lineAdd, false);
block.textLayout = new StaticLayout(sb, 0, sb.length(), layoutPaint, blockMaxWidth, align, lineSpacing, lineAdd, false);
block.textYOffset = offset;
if (a != 0) {
@ -6538,6 +6730,8 @@ public class MessageObject {
if (block.quote) {
lineWidth += AndroidUtilities.dp(32);
} else if (block.code) {
lineWidth += AndroidUtilities.dp(15);
}
try {
@ -6594,14 +6788,17 @@ public class MessageObject {
}
textWidth = Math.max(textWidth, Math.min(width, linesMaxWidth));
// if (block.quote && hasSingleQuote) {
// textWidth += AndroidUtilities.dp(32);
// }
}
linesOffset += currentBlockLinesCount;
if (messageObject != null && !messageObject.isSpoilersRevealed && !messageObject.spoiledLoginCode) {
SpoilerEffect.addSpoilers(null, block.textLayout, -1, linesMaxWidthWithLeft, null, block.spoilers);
int right = linesMaxWidthWithLeft;
if (block.quote) {
right -= AndroidUtilities.dp(32);
} else if (block.code) {
right -= AndroidUtilities.dp(15);
}
SpoilerEffect.addSpoilers(null, block.textLayout, -1, right, null, block.spoilers);
}
}
}
@ -6720,6 +6917,25 @@ public class MessageObject {
return false;
}
public static boolean peersEqual(TLRPC.InputPeer a, TLRPC.Peer b) {
if (a == null && b == null) {
return true;
}
if (a == null || b == null) {
return false;
}
if (a instanceof TLRPC.TL_inputPeerChat && b instanceof TLRPC.TL_peerChat) {
return a.chat_id == b.chat_id;
}
if (a instanceof TLRPC.TL_inputPeerChannel && b instanceof TLRPC.TL_peerChannel) {
return a.channel_id == b.channel_id;
}
if (a instanceof TLRPC.TL_inputPeerUser && b instanceof TLRPC.TL_peerUser) {
return a.user_id == b.user_id;
}
return false;
}
public static boolean peersEqual(TLRPC.Peer a, TLRPC.Peer b) {
if (a == null && b == null) {
return true;

View file

@ -14757,6 +14757,9 @@ public class MessagesController extends BaseController implements NotificationCe
} else {
break;
}
if (updates.updates.size() <= 0) {
break;
}
updates.updates.remove(a);
a--;
}

View file

@ -97,7 +97,7 @@ public class MessagesStorage extends BaseController {
}
}
public final static int LAST_DB_VERSION = 135;
public final static int LAST_DB_VERSION = 136;
private boolean databaseMigrationInProgress;
public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -597,7 +597,6 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE stickers_v2(id INTEGER PRIMARY KEY, data BLOB, date INTEGER, hash INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE stickers_featured(id INTEGER PRIMARY KEY, data BLOB, unread BLOB, date INTEGER, hash INTEGER, premium INTEGER, emoji INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE stickers_dice(emoji TEXT PRIMARY KEY, data BLOB, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE stickersets(id INTEGER PRIMATE KEY, data BLOB, hash INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE hashtag_recent_v2(id TEXT PRIMARY KEY, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE webpage_pending_v2(id INTEGER, mid INTEGER, uid INTEGER, PRIMARY KEY (id, mid, uid));").stepThis().dispose();
database.executeFast("CREATE TABLE sent_files_v2(uid TEXT, type INTEGER, data BLOB, parent TEXT, PRIMARY KEY (uid, type))").stepThis().dispose();
@ -609,6 +608,9 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE requested_holes(uid INTEGER, seq_out_start INTEGER, seq_out_end INTEGER, PRIMARY KEY (uid, seq_out_start, seq_out_end));").stepThis().dispose();
database.executeFast("CREATE TABLE sharing_locations(uid INTEGER PRIMARY KEY, mid INTEGER, date INTEGER, period INTEGER, message BLOB, proximity INTEGER);").stepThis().dispose();
database.executeFast("CREATE TABLE stickersets2(id INTEGER PRIMATE KEY, data BLOB, hash INTEGER, date INTEGER);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS stickersets2_id_index ON stickersets2(id);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS stickers_featured_emoji_index ON stickers_featured(emoji);").stepThis().dispose();
database.executeFast("CREATE TABLE shortcut_widget(id INTEGER, did INTEGER, ord INTEGER, PRIMARY KEY (id, did));").stepThis().dispose();
@ -1323,7 +1325,7 @@ public class MessagesStorage extends BaseController {
database.executeFast("DELETE FROM attach_menu_bots").stepThis().dispose();
database.executeFast("DELETE FROM animated_emoji").stepThis().dispose();
database.executeFast("DELETE FROM stickers_v2").stepThis().dispose();
database.executeFast("DELETE FROM stickersets").stepThis().dispose();
database.executeFast("DELETE FROM stickersets2").stepThis().dispose();
database.executeFast("DELETE FROM messages_holes_topics").stepThis().dispose();
database.executeFast("DELETE FROM messages_topics").stepThis().dispose();
database.executeFast("DELETE FROM topics").stepThis().dispose();

View file

@ -1,6 +1,7 @@
package org.telegram.messenger.utils;
import android.text.Spanned;
import android.text.TextUtils;
import org.telegram.messenger.CodeHighlighting;
import org.telegram.ui.Components.AnimatedEmojiSpan;
@ -164,7 +165,11 @@ public class CustomHtml {
for (int j = 0; j < spans.length; ++j) {
CodeHighlighting.Span span = spans[j];
if (span != null) {
out.append("<pre lang=\"").append(span.lng).append("\">");
if (TextUtils.isEmpty(span.lng)) {
out.append("<pre>");
} else {
out.append("<pre lang=\"").append(span.lng).append("\">");
}
}
}
}

View file

@ -1751,9 +1751,9 @@ public class Theme {
if (isDarkTheme && currentColors.get(key_chat_outBubbleGradient1) != 0) {
int outBubbleAverage = averageColor(currentColors, key_chat_outBubbleGradient1, key_chat_outBubbleGradient2, key_chat_outBubbleGradient3);
Color.colorToHSV(outBubbleAverage, tempHSV);
tempHSV[1] = Utilities.clamp(tempHSV[1] + .3f, 1, 0);
tempHSV[2] = Utilities.clamp(tempHSV[2] + -.4f, 1, 0);
currentColors.put(key_chat_outCodeBackground, Color.HSVToColor(0x70, tempHSV));
tempHSV[1] = Utilities.clamp(tempHSV[1] + .1f, 1, 0);
tempHSV[2] = Utilities.clamp(tempHSV[2] - .8f, 1, 0);
currentColors.put(key_chat_outCodeBackground, Color.HSVToColor(0x40, tempHSV));
} else {
currentColors.put(key_chat_outCodeBackground, codeBackground(outBubble, isDarkTheme));
}
@ -1817,13 +1817,16 @@ public class Theme {
private int codeBackground(int bubbleColor, boolean isDarkTheme) {
Color.colorToHSV(bubbleColor, tempHSV);
int alpha = 0x20;
if (tempHSV[1] <= 0 || tempHSV[2] >= 1 || tempHSV[2] <= 0) {
tempHSV[2] = Math.max(0, Math.min(1, tempHSV[2] + (isDarkTheme ? .3f : -.2f)));
if (isDarkTheme) {
alpha = 0x40;
tempHSV[1] = Utilities.clamp(tempHSV[1] - .08f, 1f, 0f);
tempHSV[2] = .03f;
} else {
tempHSV[1] = Math.max(0, Math.min(1, tempHSV[1] + (isDarkTheme ? -.3f : .28f)));
tempHSV[2] = Math.max(0, Math.min(1, tempHSV[2] + (isDarkTheme ? +.1f : -.1f)));
if (isDarkTheme) {
alpha = 0x60;
if (tempHSV[1] <= 0 || tempHSV[2] >= 1 || tempHSV[2] <= 0) {
tempHSV[2] = Math.max(0, Math.min(1, tempHSV[2] + -.2f));
} else {
tempHSV[1] = Math.max(0, Math.min(1, tempHSV[1] + .28f));
tempHSV[2] = Math.max(0, Math.min(1, tempHSV[2] + -.1f));
}
}
return Color.HSVToColor(alpha, tempHSV);

View file

@ -34,13 +34,11 @@ import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.Xfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@ -61,9 +59,7 @@ import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan;
import android.text.style.LeadingMarginSpan;
import android.text.style.LineHeightSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.util.Property;
import android.util.SparseArray;
import android.util.StateSet;
@ -127,7 +123,6 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.AdjustPanLayoutHelper;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
@ -450,6 +445,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
default void didPressExtendedMediaPreview(ChatMessageCell cell, TLRPC.KeyboardButton button) {
}
default void didPressUserStatus(ChatMessageCell cell, TLRPC.User user, TLRPC.Document document) {
}
default void didPressUserAvatar(ChatMessageCell cell, TLRPC.User user, float touchX, float touchY) {
}
@ -497,7 +496,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
default void didPressUrl(ChatMessageCell cell, CharacterStyle url, boolean longPress) {
}
default void didPressCode(ChatMessageCell cell, CharacterStyle span, boolean longPress) {
default void didPressCodeCopy(ChatMessageCell cell, MessageObject.TextLayoutBlock block) {
}
@ -883,6 +882,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private Path instantLinkArrowPath;
private Paint instantLinkArrowPaint;
private int nameLayoutSelectorColor;
private Drawable nameLayoutSelector;
private boolean nameLayoutPressed;
private int nameStatusSelectorColor;
private Drawable nameStatusSelector;
private boolean nameStatusPressed;
private RoundVideoPlayingDrawable roundVideoPlayingDrawable;
private StaticLayout docTitleLayout;
@ -955,6 +962,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private AnimatedEmojiSpan pressedEmoji;
private LinkSpanDrawable pressedLink;
private MessageObject.TextLayoutBlock pressedCopyCode;
private LinkSpanDrawable.LinkCollector links = new LinkSpanDrawable.LinkCollector(this);
private int pressedLinkType;
private boolean linkPreviewPressed;
@ -1109,6 +1117,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private int backgroundDrawableBottom;
private int viaWidth;
private int viaNameWidth;
private boolean viaOnly;
private TypefaceSpan viaSpan1;
private TypefaceSpan viaSpan2;
private int availableTimeWidth;
@ -1261,7 +1270,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private TLRPC.FileLocation currentPhoto;
private String currentNameString;
private Object currentNameStatus;
private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable currentNameStatusDrawable;
public AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable currentNameStatusDrawable;
private TLRPC.User currentForwardUser;
private TLRPC.User currentViaBotUser;
@ -1595,11 +1604,111 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return new int[]{start, end};
}
private boolean checkNameMotionEvent(MotionEvent event) {
if (!drawNameLayout || nameLayout == null || nameLayoutSelector == null || currentUser == null && currentChat == null) {
nameLayoutPressed = false;
return false;
}
final boolean pressed = nameLayoutSelector.getBounds().contains((int) event.getX(), (int) event.getY());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
nameLayoutPressed = pressed;
if (nameLayoutPressed) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
nameLayoutSelector.setHotspot((int) event.getX(), (int) event.getY());
}
nameLayoutSelector.setState(pressedState);
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (event.getAction() == MotionEvent.ACTION_UP && nameLayoutPressed) {
if (delegate != null) {
if (viaOnly) {
if (currentViaBotUser != null && currentViaBotUser.bot_inline_placeholder == null) {
delegate.didPressViaBotNotInline(this, currentViaBotUser != null ? currentViaBotUser.id : 0);
} else {
delegate.didPressViaBot(this, currentViaBotUser != null ? currentViaBotUser.username : currentMessageObject.messageOwner.via_bot_name);
}
} else if (currentUser != null) {
delegate.didPressUserAvatar(this, currentUser, event.getX(), event.getY());
} else if (currentChat != null) {
int id;
TLRPC.Chat chat = currentChat;
if (currentMessageObject.messageOwner.fwd_from != null) {
if ((currentMessageObject.messageOwner.fwd_from.flags & 16) != 0) {
id = currentMessageObject.messageOwner.fwd_from.saved_from_msg_id;
} else {
id = currentMessageObject.messageOwner.fwd_from.channel_post;
chat = currentForwardChannel;
}
} else {
id = 0;
}
delegate.didPressChannelAvatar(this, chat != null ? chat : currentChat, id, lastTouchX, lastTouchY);
}
}
}
nameLayoutSelector.setState(StateSet.NOTHING);
nameLayoutPressed = false;
}
return nameLayoutPressed;
}
private boolean checkNameStatusMotionEvent(MotionEvent event) {
if (!drawNameLayout || nameLayout == null || nameLayoutSelector == null || currentUser == null && currentChat == null || currentNameStatus == null || currentNameStatusDrawable == null) {
nameStatusPressed = false;
return false;
}
final boolean pressed = nameStatusSelector.getBounds().contains((int) event.getX(), (int) event.getY());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
nameStatusPressed = pressed;
if (nameStatusPressed) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
nameStatusSelector.setHotspot((int) event.getX(), (int) event.getY());
}
nameStatusSelector.setState(pressedState);
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (event.getAction() == MotionEvent.ACTION_UP && nameStatusPressed) {
if (delegate != null) {
if (currentUser != null) {
TLRPC.Document document = null;
if (currentNameStatusDrawable.getDrawable() instanceof AnimatedEmojiDrawable) {
document = ((AnimatedEmojiDrawable) currentNameStatusDrawable.getDrawable()).getDocument();
}
delegate.didPressUserStatus(this, currentUser, document);
invalidateOutbounds();
}
}
}
nameStatusSelector.setState(StateSet.NOTHING);
nameStatusPressed = false;
}
return nameStatusPressed;
}
private void resetCodeSelectors() {
if (currentMessageObject != null && currentMessageObject.textLayoutBlocks != null) {
for (int i = 0; i < currentMessageObject.textLayoutBlocks.size(); ++i) {
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(i);
if (block.copySelector != null) {
block.copySelector.setState(StateSet.NOTHING);
}
}
}
if (captionLayout != null) {
for (int i = 0; i < captionLayout.textLayoutBlocks.size(); ++i) {
MessageObject.TextLayoutBlock block = captionLayout.textLayoutBlocks.get(i);
if (block.copySelector != null) {
block.copySelector.setState(StateSet.NOTHING);
}
}
}
}
private boolean checkTextBlockMotionEvent(MotionEvent event) {
if (!(currentMessageObject.type == MessageObject.TYPE_TEXT || currentMessageObject.type == MessageObject.TYPE_EMOJIS || currentMessageObject.type == MessageObject.TYPE_STORY_MENTION) || currentMessageObject.textLayoutBlocks == null || currentMessageObject.textLayoutBlocks.isEmpty() || !(currentMessageObject.messageText instanceof Spannable)) {
return false;
}
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP && (pressedLinkType == 1)) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP && (pressedLinkType == 1 || pressedCopyCode != null)) {
int x = (int) event.getX();
int y = (int) event.getY();
if (x >= textX && y >= textY && x <= textX + currentMessageObject.textWidth && y <= textY + currentMessageObject.textHeight) {
@ -1615,6 +1724,24 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
MessageObject.TextLayoutBlock block = currentMessageObject.textLayoutBlocks.get(blockNum);
x -= textX - (block.isRtl() ? currentMessageObject.textXOffset : 0);
y -= block.textYOffset;
if (!block.quote && block.code && x > 0 && x <= currentMessageObject.textWidth && y >= block.padTop + block.height + block.padBottom - dp(38) && y <= block.padTop + block.height + block.padBottom) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (block == pressedCopyCode && delegate != null) {
delegate.didPressCodeCopy(this, block);
}
resetCodeSelectors();
pressedCopyCode = null;
} else {
pressedCopyCode = block;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
block.copySelector.setHotspot(x, y);
}
block.copySelector.setState(pressedState);
}
return true;
}
final int line = block.textLayout.getLineForVertical(y);
final int off = block.charactersOffset + block.textLayout.getOffsetForHorizontal(line, x);
@ -1734,6 +1861,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
resetPressedLink(1);
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
pressedCopyCode = null;
resetCodeSelectors();
}
return false;
}
@ -1742,7 +1872,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!(currentCaption instanceof Spannable) || captionLayout == null) {
return false;
}
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP && (pressedLinkType == 1)) {
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_UP && (pressedLinkType == 1 || pressedCopyCode != null)) {
int x = (int) event.getX();
int y = (int) event.getY();
if (x >= captionX && y >= captionY && x <= captionX + captionLayout.textWidth && y <= captionY + captionLayout.textHeight) {
@ -1758,6 +1888,24 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
MessageObject.TextLayoutBlock block = captionLayout.textLayoutBlocks.get(blockNum);
x -= captionX - (block.isRtl() ? captionLayout.textXOffset : 0);
y -= block.textYOffset;
if (!block.quote && block.code && x > 0 && x <= captionLayout.textWidth && y >= block.padTop + block.height + block.padBottom - dp(38) && y <= block.padTop + block.height + block.padBottom) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (block == pressedCopyCode && delegate != null) {
delegate.didPressCodeCopy(this, block);
}
resetCodeSelectors();
pressedCopyCode = null;
} else {
pressedCopyCode = block;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
block.copySelector.setHotspot(x, y);
}
block.copySelector.setState(pressedState);
}
return true;
}
final int line = block.textLayout.getLineForVertical(y);
final int off = block.charactersOffset + block.textLayout.getOffsetForHorizontal(line, x);
@ -1877,6 +2025,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
resetPressedLink(1);
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
pressedCopyCode = null;
resetCodeSelectors();
}
return false;
}
@ -3096,6 +3247,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!result) {
result = checkTextBlockMotionEvent(event);
}
if (!result) {
result = checkNameMotionEvent(event);
}
if (!result) {
result = checkNameStatusMotionEvent(event);
}
if (!result) {
result = checkPinchToZoom(event);
}
@ -3174,6 +3331,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewSelector.setState(StateSet.NOTHING);
}
}
if (nameStatusSelector != null) {
nameStatusSelector.setState(StateSet.NOTHING);
}
if (nameLayoutSelector != null) {
nameLayoutSelector.setState(StateSet.NOTHING);
}
resetCodeSelectors();
if (linkPreviewBounce != null) {
linkPreviewBounce.setPressed(false);
}
@ -4612,6 +4776,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyTextHeight = 0;
viaWidth = 0;
viaNameWidth = 0;
viaOnly = false;
addedCaptionHeight = 0;
currentReplyPhoto = null;
currentUser = null;
@ -4620,6 +4785,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
instantViewLayout = null;
drawNameLayout = false;
linkPreviewAbove = false;
isSmallImage = false;
lastLoadingSizeTotal = 0;
if (scheduledInvalidate) {
AndroidUtilities.cancelRunOnUIThread(invalidateRunnable);
@ -5135,12 +5301,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
setMessageObjectInternal(messageObject);
giveawayMessageCell.setMessageContent(messageObject, getParentWidth(), forwardedNameWidth);
backgroundWidth = messageObject.textWidth + getExtraTextX() * 2 + (hasGamePreview || hasInvoicePreview ? AndroidUtilities.dp(10) : 0);
totalHeight = messageObject.textHeight + AndroidUtilities.dp(19.5f) + namesOffset;
if (!reactionsLayoutInBubble.isSmall) {
reactionsLayoutInBubble.measure(maxWidth, Gravity.LEFT);
reactionsLayoutInBubble.measure(messageObject.isGiveaway() ? giveawayMessageCell.getMeasuredWidth() : maxWidth, Gravity.LEFT);
if (!reactionsLayoutInBubble.isEmpty) {
reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8);
if (reactionsLayoutInBubble.width > backgroundWidth) {
@ -5169,8 +5336,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
int maxWebWidth = 0;
giveawayMessageCell.setMessageContent(messageObject, getParentWidth(), forwardedNameWidth);
if (hasLinkPreview || hasGamePreview || hasInvoicePreview) {
int linkPreviewMaxWidth;
if (AndroidUtilities.isTablet()) {
@ -8424,6 +8589,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replySelector.setState(new int[]{});
invalidate();
}
if (nameStatusSelector != null) {
nameStatusSelector.setState(StateSet.NOTHING);
}
if (nameLayoutSelector != null) {
nameLayoutSelector.setState(StateSet.NOTHING);
}
resetCodeSelectors();
if (replyBounce != null) {
replyBounce.setPressed(false);
}
@ -8977,6 +9149,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (
currentMessageObject.hasCodeAtBottom && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) ||
currentMessageObject.hasQuoteAtBottom && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall)
|| currentMessageObject.isGiveaway()
) {
newLineForTime = true;
newLineForTimeDp = 18;
@ -9265,7 +9438,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
@Override
protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who) || who == selectorDrawable[0] || who == selectorDrawable[1] || who == linkPreviewSelector;
return super.verifyDrawable(who) || who == selectorDrawable[0] || who == selectorDrawable[1] || who == linkPreviewSelector || who == nameLayoutSelector || who == replySelector;
}
@Override
@ -11797,6 +11970,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (textLayoutBlocks == null || textLayoutBlocks.isEmpty() || alpha == 0) {
return;
}
int firstVisibleBlockNum;
int lastVisibleBlockNum;
if (origin && !drawAllBlocks) {
@ -11867,39 +12041,35 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
if (firstVisibleBlockNum >= 0) {
final float maxWidth;
if (caption) {
if (currentMessagesGroup != null) {
float endX = textX - getExtraTextX();
if (currentMessagesGroup != null && !currentMessageObject.isMusic() && !currentMessageObject.isDocument()) {
int dWidth = getGroupPhotosWidth();
if ((currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
endX += Math.ceil(currentPosition.pw / 1000.0f * dWidth);
} else {
int firstLineWidth = 0;
for (int i = 0; i < currentMessagesGroup.posArray.size(); i++) {
MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(i);
if (position.minY == 0) {
firstLineWidth += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
} else {
break;
}
}
endX += firstLineWidth - AndroidUtilities.dp(9);
}
} else {
endX += backgroundWidth - (mediaBackground ? 0 : AndroidUtilities.dp(9));
}
if (currentPosition != null && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) == 0 && !currentMessagesGroup.hasSibling) {
endX += AndroidUtilities.dp(14);
}
maxWidth = endX - textX - AndroidUtilities.dp(6 + 4 + (currentMessageObject.isOutOwner() && !drawPinnedBottom ? 6 : 0));
} else {
maxWidth = captionFullWidth - AndroidUtilities.dp(3 + (currentMessageObject.isOutOwner() && !drawPinnedBottom ? 6 : 0)) - 2 * getExtraTextX();
}
float right;
if (currentMessagesGroup == null || currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_RIGHT) != 0) {
right = getBackgroundDrawableRight() + transitionParams.deltaRight;
} else {
maxWidth = getCurrentBackgroundRight() - AndroidUtilities.dp(11 + (currentMessageObject.isOutOwner() && !drawPinnedBottom ? 6 : 0)) - getExtraTextX() - textX;
int end, dWidth;
if (AndroidUtilities.isTablet()) {
dWidth = AndroidUtilities.getMinTabletSide();
} else {
dWidth = getParentWidth();
}
int firstLineWidth = 0;
for (int a = 0; a < currentMessagesGroup.posArray.size(); a++) {
MessageObject.GroupedMessagePosition position = currentMessagesGroup.posArray.get(a);
if (position.minY == 0) {
firstLineWidth += Math.ceil((position.pw + position.leftSpanOffset) / 1000.0f * dWidth);
} else {
break;
}
}
if (!mediaBackground && currentMessageObject.isOutOwner()) {
end = backgroundDrawableLeft + firstLineWidth - AndroidUtilities.dp(6);
} else {
end = backgroundDrawableLeft + firstLineWidth;
}
end -= getExtraTextX() + AndroidUtilities.dp(8 + (isAvatarVisible ? 48 : 0));
right = end;
}
right -= AndroidUtilities.dp(10 + (currentMessageObject.isOutOwner() && !mediaBackground && !drawPinnedBottom ? 6 : 0)) + getExtraTextX();
final float maxWidth = right - textX;
int restore = Integer.MIN_VALUE;
int oldAlpha = 0;
int oldLinkAlpha = 0;
@ -11964,7 +12134,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
quoteLine.check(currentMessageObject, currentUser, currentChat, resourcesProvider, false);
final int width = (int) (block.maxRight + AndroidUtilities.dp(24) > maxWidth * .7f ? maxWidth : block.maxRight + AndroidUtilities.dp(24));
AndroidUtilities.rectTmp.set((block.isRtl() ? rtlOffset - AndroidUtilities.dp(10) : 0), -block.padTop + AndroidUtilities.dp(block.first ? 3 + 1.66f : 3), (block.isRtl() ? rtlOffset - AndroidUtilities.dp(10) : 0) + width, block.height + AndroidUtilities.dp(4));
AndroidUtilities.rectTmp.set(0, -block.padTop + AndroidUtilities.dp(block.first ? 3 + 1.66f : 3), width, block.height + AndroidUtilities.dp(4));
AndroidUtilities.rectTmp.offset((block.isRtl() ? rtlOffset - AndroidUtilities.dp(10) : 0), 0);
quoteLine.drawBackground(canvas, AndroidUtilities.rectTmp, 5, 5, 5, alpha);
quoteLine.drawLine(canvas, AndroidUtilities.rectTmp, alpha);
@ -11975,10 +12146,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyQuoteDrawable.setColorFilter(new PorterDuffColorFilter(replyQuoteDrawableColor = quoteLine.getColor(), PorterDuff.Mode.SRC_IN));
}
replyQuoteDrawable.setBounds(
(int) (AndroidUtilities.rectTmp.right - AndroidUtilities.dp(2 + (!drawPinnedTop ? 1 : 0)) - replyQuoteDrawable.getIntrinsicWidth()),
(int) (AndroidUtilities.rectTmp.top + AndroidUtilities.dp(2 + (!drawPinnedTop ? 1 : 0))),
(int) (AndroidUtilities.rectTmp.right - AndroidUtilities.dp(2 + (!drawPinnedTop ? 1 : 0))),
(int) (AndroidUtilities.rectTmp.top + AndroidUtilities.dp(2 + (!drawPinnedTop ? 1 : 0)) + replyQuoteDrawable.getIntrinsicHeight())
(int) (AndroidUtilities.rectTmp.right - dp(2 + (!drawPinnedTop ? 1 : 0)) - replyQuoteDrawable.getIntrinsicWidth()),
(int) (AndroidUtilities.rectTmp.top + dp(2 + (!drawPinnedTop ? 1 : 0))),
(int) (AndroidUtilities.rectTmp.right - dp(2 + (!drawPinnedTop ? 1 : 0))),
(int) (AndroidUtilities.rectTmp.top + dp(2 + (!drawPinnedTop ? 1 : 0)) + replyQuoteDrawable.getIntrinsicHeight())
);
replyQuoteDrawable.setAlpha((int) (0xFF * alpha));
replyQuoteDrawable.draw(canvas);
@ -11996,29 +12167,36 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
Theme.chat_msgTextPaint.linkColor = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_messageLinkOut : Theme.key_chat_messageLinkIn);
if (block.code) {
Theme.chat_msgCodeBgPaint.setColor(Theme.getColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outCodeBackground : Theme.key_chat_inCodeBackground, resourcesProvider));
Theme.chat_msgCodeBgPaint.setAlpha((int) (Theme.chat_msgCodeBgPaint.getAlpha() * alpha));
if (quoteLine == null) {
quoteLine = new ReplyMessageLine(this);
}
quoteLine.check(currentMessageObject, currentUser, currentChat, resourcesProvider, false);
if (currentMessageObject.isOutOwner() && (Theme.isCurrentThemeDark() || Theme.isCustomTheme())) {
quoteLine.setBackgroundColor(getThemedColor(Theme.key_chat_outCodeBackground));
}
AndroidUtilities.rectTmp.set(0, -dp(2 + 4) - block.languageHeight, maxWidth + dp(4), block.height + dp(2 + 4));
AndroidUtilities.rectTmp.offset((block.isRtl() ? rtlOffset : 0), 0);
if (block.hasCodeCopyButton) {
AndroidUtilities.rectTmp.bottom += dp(38);
}
final float rightRad = block.first && namesOffset <= 0 && !caption ? ((!currentMessageObject.isOutOwner() || !pinnedTop) ? SharedConfig.bubbleRadius / 3f * 2f : Math.min(6, SharedConfig.bubbleRadius)) : Math.min(5, SharedConfig.bubbleRadius);;
quoteLine.drawBackground(canvas, AndroidUtilities.rectTmp, 5, rightRad, Math.min(5, SharedConfig.bubbleRadius), alpha);
if (block.languageHeight > 0) {
float wasBottom = AndroidUtilities.rectTmp.bottom;
AndroidUtilities.rectTmp.bottom = AndroidUtilities.rectTmp.top + block.languageHeight;
quoteLine.drawBackground(canvas, AndroidUtilities.rectTmp, 5, rightRad, 0, (Theme.isCurrentThemeDark() ? .60f : .80f) * alpha);
AndroidUtilities.rectTmp.bottom = wasBottom;
}
quoteLine.drawLine(canvas, AndroidUtilities.rectTmp, alpha);
AndroidUtilities.rectTmp.set(-AndroidUtilities.dp(4), -AndroidUtilities.dp(2), maxWidth + AndroidUtilities.dp(4), block.height + AndroidUtilities.dp(2));
if (replyRoundRectPath == null) {
replyRoundRectPath = new Path();
} else {
replyRoundRectPath.rewind();
if (block.hasCodeCopyButton) {
block.drawCopyCodeButton(canvas, AndroidUtilities.rectTmp, quoteLine.getColor(), quoteLine.getBackgroundColor(), alpha);
}
if (replyBackgroundRadii == null) {
replyBackgroundRadii = new float[8];
canvas.translate(dp(10), 0);
if (block.languageLayout != null) {
block.languageLayout.ellipsize((int) (maxWidth - dp(8 + 4))).draw(canvas, 0, -dp(6) - block.languageHeight / 2f, quoteLine.getColor(), alpha);
}
final int rad = dp(SharedConfig.bubbleRadius);
final int nearRad = dp(Math.min(6, SharedConfig.bubbleRadius));
final int defrad = dp(Math.min(5, SharedConfig.bubbleRadius));
replyBackgroundRadii[0] = replyBackgroundRadii[1] = block.first && namesOffset <= 0 && !caption ? ((currentMessageObject.isOutOwner() || !pinnedTop) ? rad / 3f * 2f : nearRad) : defrad;
replyBackgroundRadii[2] = replyBackgroundRadii[3] = block.first && namesOffset <= 0 && !caption ? ((!currentMessageObject.isOutOwner() || !pinnedTop) ? rad / 3f * 2f : nearRad) : defrad;
replyBackgroundRadii[4] = replyBackgroundRadii[5] = replyBackgroundRadii[6] = replyBackgroundRadii[7] = defrad;
replyRoundRectPath.addRoundRect(AndroidUtilities.rectTmp, replyBackgroundRadii, Path.Direction.CW);
canvas.save();
canvas.translate((block.isRtl() ? rtlOffset - (block.quote ? AndroidUtilities.dp(10) : 0) : 0), 0);
canvas.drawPath(replyRoundRectPath, Theme.chat_msgCodeBgPaint);
canvas.restore();
}
}
if (a == linkSelectionBlockNum && quoteHighlight == null && !urlPathSelection.isEmpty() && !drawOnlyText) {
@ -13485,7 +13663,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
TLRPC.EncryptedChat echat = messagesController.getEncryptedChat(DialogObject.getEncryptedChatId(currentMessageObject.getDialogId()));
if (echat != null) {
currentUser = messagesController.getUser(echat.participant_id);
currentUser = messagesController.getUser(echat.user_id);
}
}
} else if (DialogObject.isUserDialog(fromId) && !currentMessageObject.messageOwner.post) {
@ -13590,9 +13768,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentNameString.length() > 0) {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format("%s %s %s", nameStringFinal, viaBotString, viaUsername));
stringBuilder.setSpan(viaSpan1 = new TypefaceSpan(Typeface.DEFAULT, 0, color), nameStringFinal.length() + 1, nameStringFinal.length() + 1 + viaBotString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (currentNameStatus != null) {
viaNameWidth += dp(4 + 20 + 4);
stringBuilder.setSpan(new DialogCell.FixedWidthSpan(dp(4 + 20 + 4)), nameStringFinal.length(), nameStringFinal.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
stringBuilder.setSpan(viaSpan2 = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, color), nameStringFinal.length() + 2 + viaBotString.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
nameStringFinal = stringBuilder;
} else {
viaOnly = true;
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(String.format("%s %s", viaBotString, viaUsername));
stringBuilder.setSpan(viaSpan1 = new TypefaceSpan(Typeface.DEFAULT, 0, color), 0, viaBotString.length() + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(viaSpan2 = new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf"), 0, color), 1 + viaBotString.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -13811,7 +13994,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int maxWidth = getMaxNameWidth();
if (!messageObject.shouldDrawWithoutBackground()) {
maxWidth -= AndroidUtilities.dp(messageObject.isOutOwner() ? 20 : 10);
if (messageObject.type != MessageObject.TYPE_TEXT) {
if (messageObject.type != MessageObject.TYPE_TEXT || messageObject.needDrawShareButton()) {
maxWidth -= AndroidUtilities.dp(10);
}
} else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
@ -13910,8 +14093,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (DialogObject.isEncryptedDialog(messageObject.getDialogId())) {
if (messageObject.replyMessageObject != null && messageObject.replyMessageObject.isOutOwner()) {
name = UserObject.getUserName(UserConfig.getInstance(currentAccount).getCurrentUser());
} else if (currentUser != null) {
name = UserObject.getUserName(currentUser);
} else {
TLRPC.EncryptedChat echat = MessagesController.getInstance(currentAccount).getEncryptedChat(DialogObject.getEncryptedChatId(currentMessageObject.getDialogId()));
if (echat != null) {
name = UserObject.getUserName(MessagesController.getInstance(currentAccount).getUser(echat.user_id));
}
}
} else if (hasReplyQuote && !DialogObject.isEncryptedDialog(messageObject.getDialogId())) {
name = messageObject.getReplyQuoteNameWithIcon();
@ -15205,9 +15391,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
nx = nameX;
}
currentNameStatusDrawable.setBounds(
(int) (Math.abs(nx) + nameLayoutWidth + AndroidUtilities.dp(2)),
(int) (Math.abs(nx) + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + AndroidUtilities.dp(2)),
(int) (nameY + nameLayout.getHeight() / 2 - AndroidUtilities.dp(10)),
(int) (Math.abs(nx) + nameLayoutWidth + AndroidUtilities.dp(22)),
(int) (Math.abs(nx) + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + AndroidUtilities.dp(22)),
(int) (nameY + nameLayout.getHeight() / 2 + AndroidUtilities.dp(10))
);
currentNameStatusDrawable.setColor(ColorUtils.setAlphaComponent(color, 115));
@ -15743,6 +15929,40 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
nx = nameX;
}
if (!currentMessageObject.isSponsored()) {
int selectorColor = Theme.multAlpha(Theme.chat_namePaint.getColor(), .12f);
if (nameLayoutSelector == null) {
nameLayoutSelector = Theme.createRadSelectorDrawable(nameLayoutSelectorColor = selectorColor, 6, 6);
nameLayoutSelector.setCallback(this);
} else if (nameLayoutSelectorColor != selectorColor) {
Theme.setSelectorDrawableColor(nameLayoutSelector, nameLayoutSelectorColor = selectorColor, true);
}
nameLayoutSelector.setBounds(
(int) (nx - dp(4)),
(int) (nameY - dp(1.33f)),
(int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(4)),
(int) (nameY + nameLayout.getHeight() + dp(1.33f))
);
nameLayoutSelector.draw(canvas);
if (currentNameStatus != null) {
if (nameStatusSelector == null) {
nameStatusSelector = Theme.createRadSelectorDrawable(nameStatusSelectorColor = selectorColor, 6, 6);
nameStatusSelector.setCallback(this);
} else if (nameStatusSelectorColor != selectorColor) {
Theme.setSelectorDrawableColor(nameStatusSelector, nameStatusSelectorColor = selectorColor, true);
}
nameStatusSelector.setBounds(
(int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth)),
(int) (nameY - dp(1.33f + 2)),
(int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(4 + 12 + 4 + 4)),
(int) (nameY + nameLayout.getHeight() + dp(1.33f + 2))
);
nameStatusSelector.draw(canvas);
}
}
canvas.translate(nx, nameY);
nameLayout.draw(canvas);
canvas.restore();
@ -16268,7 +16488,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (needReplyImage) {
replyImageReceiver.setAlpha(replyForwardAlpha);
replyImageSz = Math.min(replySelectorRect.height() - AndroidUtilities.dp(10), AndroidUtilities.dp(isReplyQuote ? 3 : 7) + Theme.chat_replyNamePaint.getTextSize() + Theme.chat_replyTextPaint.getTextSize());
replyImageReceiver.setImageCoords(replySelectorRect.left + AndroidUtilities.dp(8), replySelectorRect.top + AndroidUtilities.dp(5), replyImageSz, replyImageSz);
replyImageReceiver.setImageCoords(replySelectorRect.left + AndroidUtilities.dp(8), replySelectorRect.top + AndroidUtilities.dp((isReplyQuote && replyTextLayout != null && replyTextLayout.getLineCount() <= 1 ? 2 : 0) + 5), replyImageSz, replyImageSz);
replyImageReceiver.draw(canvas);
if (currentMessageObject != null && currentMessageObject.hasValidReplyMessageObject() && currentMessageObject.replyMessageObject.hasMediaSpoilers()) {
@ -16336,7 +16556,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (needReplyImage && (!isReplyQuote || replyTextRTL)) {
left += replyImageSz + AndroidUtilities.dp(3);
}
if (replyTextRTL) {
if (replyTextRTL && transitionParams.animateReplyTextOffset > 0) {
left = replySelectorRect.right - AndroidUtilities.dp(8) - transitionParams.animateReplyTextLayout.getWidth();
}
canvas.translate(left, replyStartY + offsetY - AndroidUtilities.dp(1) + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5));
@ -16357,7 +16577,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (needReplyImage && (!isReplyQuote || replyTextRTL)) {
left += replyImageSz + AndroidUtilities.dp(3);
}
if (replyTextRTL) {
if (replyTextRTL && replyTextOffset > 0) {
left = replySelectorRect.right - AndroidUtilities.dp(8) - replyTextLayout.getWidth();
}
canvas.translate(left, replyStartY + offsetY - AndroidUtilities.dp(1) + Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(5));
@ -20990,4 +21210,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
return fancyBlurFilter;
}
public int getNameStatusX() {
return (int) (nameX + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(2) + dp(4 + 12 + 4) / 2);
}
public int getNameStatusY() {
return (int) (nameY + (nameLayout == null ? 0 : nameLayout.getHeight()) / 2);
}
}

View file

@ -2171,6 +2171,15 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
try {
CharSequence messageStringFinal;
// Removing links and bold spans to get rid of underlining and boldness
if (messageString instanceof Spannable) {
Spannable messageStringSpannable = (Spannable) messageString;
for (Object span : messageStringSpannable.getSpans(0, messageStringSpannable.length(), Object.class)) {
if (span instanceof ClickableSpan || span instanceof CodeHighlighting.Span || span instanceof CodeHighlighting.ColorSpan || span instanceof QuoteSpan || span instanceof QuoteSpan.QuoteStyleSpan || (span instanceof StyleSpan && ((StyleSpan) span).getStyle() == android.graphics.Typeface.BOLD)) {
messageStringSpannable.removeSpan(span);
}
}
}
if ((useForceThreeLines || SharedConfig.useThreeLinesLayout) && currentDialogFolderId != 0 && currentDialogFolderDialogsCount > 1) {
messageStringFinal = messageNameString;
messageNameString = null;
@ -2184,15 +2193,6 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else {
messageStringFinal = messageString;
}
// Removing links and bold spans to get rid of underlining and boldness
if (messageStringFinal instanceof Spannable) {
Spannable messageStringSpannable = (Spannable) messageStringFinal;
for (Object span : messageStringSpannable.getSpans(0, messageStringSpannable.length(), Object.class)) {
if (span instanceof ClickableSpan || span instanceof CodeHighlighting.Span || span instanceof CodeHighlighting.ColorSpan || span instanceof QuoteSpan || span instanceof QuoteSpan.QuoteStyleSpan || (span instanceof StyleSpan && ((StyleSpan) span).getStyle() == android.graphics.Typeface.BOLD)) {
messageStringSpannable.removeSpan(span);
}
}
}
Layout.Alignment align = isForum && LocaleController.isRTL ? Layout.Alignment.ALIGN_OPPOSITE : Layout.Alignment.ALIGN_NORMAL;
if (useForceThreeLines || SharedConfig.useThreeLinesLayout) {

View file

@ -46,6 +46,10 @@ public class RecurrentPaymentsAcceptCell extends FrameLayout {
return textView;
}
public CheckBoxSquare getCheckBox() {
return checkBox;
}
public void setText(CharSequence text) {
textView.setText(text);
}

View file

@ -1,6 +1,7 @@
package org.telegram.ui.Cells;
import static com.google.zxing.common.detector.MathUtils.distance;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.ui.ActionBar.FloatingToolbar.STYLE_THEME;
import static org.telegram.ui.ActionBar.Theme.key_chat_inTextSelectionHighlight;
@ -156,7 +157,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (scrolling && (parentRecyclerView != null || parentNestedScrollView != null)) {
int dy;
if (multiselect && selectedView == null) {
dy = AndroidUtilities.dp(8);
dy = dp(8);
} else if (selectedView != null) {
dy = getLineHeight() >> 1;
} else {
@ -218,7 +219,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
int endLine = layoutBlock.layout.getLineCount() - 1;
x -= maybeTextX;
if (x < layoutBlock.layout.getLineRight(endLine) + AndroidUtilities.dp(4) && x > layoutBlock.layout.getLineLeft(endLine)) {
if (x < layoutBlock.layout.getLineRight(endLine) + dp(4) && x > layoutBlock.layout.getLineLeft(endLine)) {
offset = text.length() - 1;
}
}
@ -306,7 +307,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
public TextSelectionHelper() {
longpressDelay = ViewConfiguration.getLongPressTimeout();
touchSlop = ViewConfiguration.get(ApplicationLoader.applicationContext).getScaledTouchSlop();
selectionPaint.setPathEffect(new CornerPathEffect(cornerRadius = AndroidUtilities.dp(6)));
selectionPaint.setPathEffect(new CornerPathEffect(cornerRadius = dp(6)));
}
public void setInvalidateParent() {
@ -346,9 +347,9 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
capturedX = (int) event.getX();
capturedY = (int) event.getY();
tryCapture = false;
textArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8));
textArea.inset(-dp(8), -dp(8));
if (textArea.contains(capturedX, capturedY) && maybeSelectedView != null) {
textArea.inset(AndroidUtilities.dp(8), AndroidUtilities.dp(8));
textArea.inset(dp(8), dp(8));
int x = capturedX;
int y = capturedY;
if (x > textArea.right) x = textArea.right - 1;
@ -366,7 +367,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
int endLine = layoutBlock.layout.getLineCount() - 1;
x -= maybeTextX;
if (x < layoutBlock.layout.getLineRight(endLine) + AndroidUtilities.dp(4) && x > layoutBlock.layout.getLineLeft(endLine)) {
if (x < layoutBlock.layout.getLineRight(endLine) + dp(4) && x > layoutBlock.layout.getLineLeft(endLine)) {
offset = text.length() - 1;
}
}
@ -419,11 +420,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return;
}
int line = layout.getLineForOffset(offset);
int line = layout.getLineForOffset(Utilities.clamp(offset - layoutBlock.charOffset, layout.getText().length(), 0));
int lineHeight = layout.getLineBottom(line) - layout.getLineTop(line);
int[] coordsInParent = getCoordsInParent();
int newY = (int) (layout.getLineTop(line) + textY + coordsInParent[1]) - lineHeight - AndroidUtilities.dp(8);
int newY = (int) (layout.getLineTop(line) + textY + coordsInParent[1]) - lineHeight - dp(8);
newY += layoutBlock.yOffset;
int startLine;
@ -477,7 +478,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
magnifier.show(
magnifierXanimated, magnifierYanimated + lineHeight * 1.5f + AndroidUtilities.dp(8)
magnifierXanimated, magnifierYanimated + lineHeight * 1.5f + dp(8)
);
magnifier.update();
}
@ -543,7 +544,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (popupLayout == null) {
popupRect = new android.graphics.Rect();
popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(textSelectionOverlay.getContext());
popupLayout.setPadding(AndroidUtilities.dp(1), AndroidUtilities.dp(1), AndroidUtilities.dp(1), AndroidUtilities.dp(1));
popupLayout.setPadding(dp(1), dp(1), dp(1), dp(1));
popupLayout.setBackgroundDrawable(textSelectionOverlay.getContext().getResources().getDrawable(R.drawable.menu_copy));
popupLayout.setAnimationEnabled(false);
popupLayout.setOnTouchListener((v, event) -> {
@ -559,7 +560,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
deleteView = new TextView(textSelectionOverlay.getContext());
deleteView.setBackgroundDrawable(Theme.createSelectorDrawable(getThemedColor(Theme.key_listSelector), 2));
deleteView.setGravity(Gravity.CENTER_VERTICAL);
deleteView.setPadding(AndroidUtilities.dp(20), 0, AndroidUtilities.dp(20), 0);
deleteView.setPadding(dp(20), 0, dp(20), 0);
deleteView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
deleteView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
deleteView.setText(textSelectionOverlay.getContext().getString(android.R.string.copy));
@ -584,11 +585,11 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int lineHeight = -getLineHeight();
int[] coords = offsetToCord(selectionStart);
int[] coordsInParent = getCoordsInParent();
y = (int) (coords[1] + textY + coordsInParent[1]) + lineHeight / 2 - AndroidUtilities.dp(4);
y = (int) (coords[1] + textY + coordsInParent[1]) + lineHeight / 2 - dp(4);
if (y < 0) y = 0;
}
popupWindow.showAtLocation(textSelectionOverlay, Gravity.TOP, 0, y - AndroidUtilities.dp(48));
popupWindow.showAtLocation(textSelectionOverlay, Gravity.TOP, 0, y - dp(48));
popupWindow.startAnimation();
}
}
@ -1116,7 +1117,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
@Override
protected void onDraw(Canvas canvas) {
if (!isInSelectionMode()) return;
int handleViewSize = AndroidUtilities.dp(22);
int handleViewSize = dp(22);
int count = 0;
int top = topOffset;
@ -1169,7 +1170,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
xOffset + x, yOffset + y - handleViewSize,
xOffset + x + handleViewSize, yOffset + y + handleViewSize
);
endArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8));
endArea.inset(-dp(8), -dp(8));
count++;
} else {
canvas.save();
@ -1185,7 +1186,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
xOffset + x - handleViewSize, yOffset + y - handleViewSize,
xOffset + x, yOffset + y + handleViewSize
);
endArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8));
endArea.inset(-dp(8), -dp(8));
}
} else {
endArea.setEmpty();
@ -1231,7 +1232,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
xOffset + x - handleViewSize, yOffset + y - handleViewSize,
xOffset + x, yOffset + y + handleViewSize
);
startArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8));
startArea.inset(-dp(8), -dp(8));
count++;
} else {
canvas.save();
@ -1247,7 +1248,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
xOffset + x, yOffset + y - handleViewSize,
xOffset + x + handleViewSize, yOffset + y + handleViewSize
);
startArea.inset(-AndroidUtilities.dp(8), -AndroidUtilities.dp(8));
startArea.inset(-dp(8), -dp(8));
}
} else {
if (y + yOffset > 0 && y + yOffset - getLineHeight() < parentView.getMeasuredHeight()) {
@ -1543,7 +1544,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int lineHeight = -getLineHeight();
int[] coords = offsetToCord(selectionStart);
x1 = coords[0] + textX;
y1 = (int) (coords[1] + textY + coordsInParent[1]) + lineHeight / 2 - AndroidUtilities.dp(4);
y1 = (int) (coords[1] + textY + coordsInParent[1]) + lineHeight / 2 - dp(4);
if (y1 < 1) y1 = 1;
}
@ -2067,7 +2068,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
selectionPaint.setColor(getThemedColor(key_chat_inTextSelectionHighlight));
selectionHandlePaint.setColor(getThemedColor(key_chat_inTextSelectionHighlight));
}
drawSelection(canvas, block.textLayout, selectionStart, selectionEnd, true, true, block.quote ? AndroidUtilities.dp(10) : 0);
int offsetX = 0;
if (block.quote) {
offsetX = dp(10);
} else if (block.code) {
offsetX = dp(0);
}
drawSelection(canvas, block.textLayout, selectionStart, selectionEnd, true, true, offsetX);
}
}
}
@ -2093,7 +2100,13 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
selectionPaint.setColor(getThemedColor(key_chat_inTextSelectionHighlight));
selectionHandlePaint.setColor(getThemedColor(key_chat_inTextSelectionHighlight));
}
drawSelection(canvas, block.textLayout, selectionStart, selectionEnd, true, true, block.quote ? AndroidUtilities.dp(10) : 0);
int offsetX = 0;
if (block.quote) {
offsetX = dp(10);
} else if (block.code) {
offsetX = dp(0);
}
drawSelection(canvas, block.textLayout, selectionStart, selectionEnd, true, true, offsetX);
}
}
@ -2176,7 +2189,14 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (y >= block.textYOffset && y <= block.textYOffset + block.padTop + block.height) {
layoutBlock.layout = block.textLayout;
layoutBlock.yOffset = block.textYOffset + block.padTop;
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(captionLayout.textXOffset) - (block.quote ? AndroidUtilities.dp(10) : 0) : 0);
int offsetX = 0;
if (block.quote) {
offsetX = dp(10);
}
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(captionLayout.textXOffset) - offsetX : 0);
if (block.code && !block.quote) {
layoutBlock.xOffset += dp(8);
}
layoutBlock.charOffset = block.charactersOffset;
return;
}
@ -2189,7 +2209,16 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (y >= block.textYOffset && y <= block.textYOffset + block.padTop + block.height) {
layoutBlock.layout = block.textLayout;
layoutBlock.yOffset = block.textYOffset + block.padTop;
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(messageObject.textXOffset) - (block.quote ? AndroidUtilities.dp(10) : 0) : 0);
int offsetX = 0;
if (block.quote) {
offsetX = dp(10);
} else if (block.code) {
offsetX = dp(0);
}
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(messageObject.textXOffset) - offsetX : 0);
if (block.code && !block.quote) {
layoutBlock.xOffset += dp(8);
}
layoutBlock.charOffset = block.charactersOffset;
return;
}
@ -2215,9 +2244,18 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (selectedView.hasCaptionLayout()) {
MessageObject.TextLayoutBlocks captionLayout = selectedView.getCaptionLayout();
if (captionLayout.textLayoutBlocks.size() == 1) {
layoutBlock.layout = captionLayout.textLayoutBlocks.get(0).textLayout;
layoutBlock.yOffset = 0;
layoutBlock.xOffset = -(captionLayout.textLayoutBlocks.get(0).isRtl() ? (int) Math.ceil(captionLayout.textXOffset) - (captionLayout.textLayoutBlocks.get(0).quote ? AndroidUtilities.dp(10) : 0) : 0);
MessageObject.TextLayoutBlock block = captionLayout.textLayoutBlocks.get(0);
layoutBlock.layout = block.textLayout;
layoutBlock.yOffset = block.padTop;
MessageObject.TextLayoutBlock firstBlock = captionLayout.textLayoutBlocks.get(0);
int offsetX = 0;
if (firstBlock.quote) {
offsetX = dp(10);
}
layoutBlock.xOffset = -(firstBlock.isRtl() ? (int) Math.ceil(captionLayout.textXOffset) - offsetX : 0);
if (firstBlock.code && !firstBlock.quote) {
layoutBlock.xOffset += dp(8);
}
layoutBlock.charOffset = 0;
return;
}
@ -2228,7 +2266,14 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (blockOffset >= 0 && blockOffset <= block.textLayout.getText().length()) {
layoutBlock.layout = block.textLayout;
layoutBlock.yOffset = block.textYOffset + block.padTop;
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(captionLayout.textXOffset) - (block.quote ? AndroidUtilities.dp(10) : 0) : 0);
int offsetX = 0;
if (block.quote) {
offsetX = dp(10);
}
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(captionLayout.textXOffset) - offsetX : 0);
if (block.code && !block.quote) {
layoutBlock.xOffset += dp(8);
}
layoutBlock.charOffset = block.charactersOffset;
return;
}
@ -2243,9 +2288,18 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
}
if (messageObject.textLayoutBlocks.size() == 1) {
layoutBlock.layout = messageObject.textLayoutBlocks.get(0).textLayout;
layoutBlock.yOffset = 0;
layoutBlock.xOffset = -(messageObject.textLayoutBlocks.get(0).isRtl() ? (int) Math.ceil(messageObject.textXOffset) - (messageObject.textLayoutBlocks.get(0).quote ? AndroidUtilities.dp(10) : 0) : 0);
MessageObject.TextLayoutBlock textLayoutBlock = messageObject.textLayoutBlocks.get(0);
layoutBlock.layout = textLayoutBlock.textLayout;
layoutBlock.yOffset = textLayoutBlock.padTop;
MessageObject.TextLayoutBlock firstBlock = messageObject.textLayoutBlocks.get(0);
int offsetX = 0;
if (firstBlock.quote) {
offsetX = dp(10);
}
layoutBlock.xOffset = -(firstBlock.isRtl() ? (int) Math.ceil(messageObject.textXOffset) - offsetX : 0);
if (firstBlock.code && !firstBlock.quote) {
layoutBlock.xOffset += dp(8);
}
layoutBlock.charOffset = 0;
return;
}
@ -2256,7 +2310,14 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (blockOffset >= 0 && blockOffset <= block.textLayout.getText().length()) {
layoutBlock.layout = block.textLayout;
layoutBlock.yOffset = block.textYOffset + block.padTop;
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(messageObject.textXOffset) - (block.quote ? AndroidUtilities.dp(10) : 0) : 0);
int offsetX = 0;
if (block.quote) {
offsetX = dp(10);
}
layoutBlock.xOffset = -(block.isRtl() ? (int) Math.ceil(messageObject.textXOffset) - offsetX : 0);
if (block.code && !block.quote) {
layoutBlock.xOffset += dp(8);
}
layoutBlock.charOffset = block.charactersOffset;
return;
}
@ -2582,7 +2643,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
int row = arrayList.get(minIndex).getRow();
if (row > 0) {
if (minDistance < AndroidUtilities.dp(24)) {
if (minDistance < dp(24)) {
int minDistanceX = Integer.MAX_VALUE;
int minIndexX = minIndex;

View file

@ -289,8 +289,8 @@ public class ChannelBoostLayout extends FrameLayout {
ItemInternal item = items.get(position);
TL_stories.TL_prepaidGiveaway prepaidGiveaway = item.prepaidGiveaway;
GiveawayCell giveawayCell = (GiveawayCell) holder.itemView;
String name = LocaleController.formatString("TelegramPremiumCount", R.string.TelegramPremiumCount, prepaidGiveaway.quantity);
String info = LocaleController.formatString("SubscriptionsCount", R.string.SubscriptionsCount, LocaleController.formatPluralString("GiftMonths", prepaidGiveaway.months));
String name = LocaleController.formatPluralString("BoostingTelegramPremiumCountPlural", prepaidGiveaway.quantity);
String info = LocaleController.formatPluralString("BoostingSubscriptionsCountPlural", prepaidGiveaway.quantity, LocaleController.formatPluralString("PrepaidGiveawayMonths", prepaidGiveaway.months));
giveawayCell.setData(prepaidGiveaway, name, info, 0, !item.isLast);
giveawayCell.setImage(prepaidGiveaway);
giveawayCell.setAvatarPadding(5);
@ -352,6 +352,7 @@ public class ChannelBoostLayout extends FrameLayout {
giftCode.months = (boost.expires - boost.date) / 30 / 86400;
if (boost.unclaimed) {
giftCode.to_id = NO_USER_ID;
giftCode.flags = -1;
} else {
giftCode.boost = boost;
}

View file

@ -130,12 +130,14 @@ import org.telegram.messenger.ChatThemeController;
import org.telegram.messenger.CodeHighlighting;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.DownloadController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.EmojiData;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.FlagSecureReason;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LanguageDetector;
@ -153,6 +155,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SecretChatHelper;
import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.TranslateController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
@ -9117,7 +9120,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
float pendingViewH = 0;
View pendingRequestsView = pendingRequestsDelegate != null ? pendingRequestsDelegate.getView() : null;
if (pendingRequestsView != null && pendingRequestsView.getVisibility() == View.VISIBLE) {
pendingViewH = Math.max(0, pendingRequestsView.getHeight() + pendingRequestsDelegate.getViewEnterOffset());
pendingViewH = Math.max(0, pendingRequestsView.getHeight() + pendingRequestsDelegate.getViewEnterOffset() - AndroidUtilities.dp(4));
}
float oldPadding = chatListViewPaddingTop;
chatListViewPaddingTop = AndroidUtilities.dp(4) + contentPaddingTop + topPanelViewH + pinnedViewH + pendingViewH;
@ -11008,7 +11011,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
@Override
public boolean dismissDialogOnPause(Dialog dialog) {
return dialog != chatAttachAlert && dialog != chatThemeBottomSheet && super.dismissDialogOnPause(dialog);
return dialog != chatAttachAlert && dialog != chatThemeBottomSheet && !(dialog instanceof BotWebViewSheet) && super.dismissDialogOnPause(dialog);
}
int waitingForWebpageId;
@ -28624,6 +28627,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (!messageObject.isMusic() && messageObject.replyMessageObject != null) {
messageObject = messagesDict[messageObject.replyMessageObject.getDialogId() == dialog_id ? 0 : 1].get(messageObject.replyMessageObject.getId());
}
if (messageObject == null) {
return;
}
float progress = seekTime / (float) messageObject.getDuration();
MediaController mediaController = getMediaController();
if (mediaController.isPlayingMessage(messageObject)) {
@ -30391,6 +30397,69 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
showDialog(new PremiumFeatureBottomSheet(ChatActivity.this, PremiumPreviewFragment.PREMIUM_FEATURE_ADS, true));
}
@Override
public void didPressUserStatus(ChatMessageCell cell, TLRPC.User user, TLRPC.Document document) {
if (cell == null) {
return;
}
PremiumPreviewBottomSheet premiumPreviewBottomSheet = new PremiumPreviewBottomSheet(ChatActivity.this, currentAccount, user, themeDelegate);
int[] coords = new int[2];
cell.getLocationOnScreen(coords);
premiumPreviewBottomSheet.startEnterFromX = cell.getNameStatusX();
premiumPreviewBottomSheet.startEnterFromY = cell.getNameStatusY();
premiumPreviewBottomSheet.startEnterFromScale = cell.getScaleX();
premiumPreviewBottomSheet.startEnterFromX1 = cell.getLeft();
premiumPreviewBottomSheet.startEnterFromY1 = cell.getTop();
premiumPreviewBottomSheet.startEnterFromView = cell;
int colorId = user != null ? (int) (user.id % 7) : 0;
if (user != null && (user.flags2 & 128) != 0) {
colorId = user.color;
}
if (colorId < 7) {
premiumPreviewBottomSheet.accentColor = getThemedColor(Theme.keys_avatar_nameInMessage[colorId]);
} else {
final MessagesController.PeerColors peerColors = MessagesController.getInstance(currentAccount).peerColors;
final MessagesController.PeerColor peerColor = peerColors != null ? peerColors.getColor(colorId) : null;
premiumPreviewBottomSheet.accentColor = peerColor != null ? peerColor.getColor1() : null;
}
if (cell.currentNameStatusDrawable != null && cell.currentNameStatusDrawable.getDrawable() instanceof AnimatedEmojiDrawable) {
premiumPreviewBottomSheet.startEnterFromScale *= 0.95f;
if (document != null) {
BackupImageView icon = new BackupImageView(getContext());
String filter = "160_160";
ImageLocation mediaLocation;
String mediaFilter;
SvgHelper.SvgDrawable thumbDrawable = DocumentObject.getSvgThumb(document.thumbs, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f);
TLRPC.PhotoSize thumb = FileLoader.getClosestPhotoSizeWithSize(document.thumbs, 90);
if ("video/webm".equals(document.mime_type)) {
mediaLocation = ImageLocation.getForDocument(document);
mediaFilter = filter + "_" + ImageLoader.AUTOPLAY_FILTER;
if (thumbDrawable != null) {
thumbDrawable.overrideWidthAndHeight(512, 512);
}
} else {
if (thumbDrawable != null && MessageObject.isAnimatedStickerDocument(document, false)) {
thumbDrawable.overrideWidthAndHeight(512, 512);
}
mediaLocation = ImageLocation.getForDocument(document);
mediaFilter = filter;
}
icon.setLayerNum(7);
icon.setRoundRadius(AndroidUtilities.dp(4));
icon.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), "140_140", thumbDrawable, document);
if (MessageObject.isTextColorEmoji(document)) {
icon.setColorFilter(new PorterDuffColorFilter(premiumPreviewBottomSheet.accentColor != null ? premiumPreviewBottomSheet.accentColor : getThemedColor(Theme.key_windowBackgroundWhiteBlueIcon), PorterDuff.Mode.SRC_IN));
premiumPreviewBottomSheet.statusStickerSet = MessageObject.getInputStickerSet(document);
} else {
premiumPreviewBottomSheet.statusStickerSet = MessageObject.getInputStickerSet(document);
}
premiumPreviewBottomSheet.overrideTitleIcon = icon;
premiumPreviewBottomSheet.isEmojiStatus = true;
}
}
showDialog(premiumPreviewBottomSheet);
}
@Override
public void didPressUserAvatar(ChatMessageCell cell, TLRPC.User user, float touchX, float touchY) {
if (actionBar.isActionModeShowed() || reportType >= 0) {
@ -30547,7 +30616,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private void openChat(ChatMessageCell cell, TLRPC.Chat chat, int postId) {
if (currentChat != null && chat.id == currentChat.id) {
scrollToMessageId(postId, cell.getMessageObject().getId(), true, 0, true, 0);
if (avatarContainer != null && postId == 0) {
avatarContainer.openProfile(false);
} else {
scrollToMessageId(postId, cell.getMessageObject().getId(), true, 0, true, 0);
}
} else if (currentChat == null || chat.id != currentChat.id || isThreadChat()) {
Bundle args = new Bundle();
args.putLong("chat_id", chat.id);
@ -30847,16 +30920,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
@Override
public void didPressCode(ChatMessageCell cell, CharacterStyle _span, boolean longPress) {
if (!(_span instanceof CodeHighlighting.Span)) {
public void didPressCodeCopy(ChatMessageCell cell, MessageObject.TextLayoutBlock block) {
if (block == null || block.textLayout == null || block.textLayout.getText() == null) {
return;
}
final CodeHighlighting.Span span = (CodeHighlighting.Span) _span;
SpannableStringBuilder text = new SpannableStringBuilder(span.code);
text.setSpan(new CodeHighlighting.Span(false, 0, null, span.lng, span.code), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
AndroidUtilities.addToClipboard(text);
createUndoView();
undoView.showWithAction(0, UndoView.ACTION_TEXT_COPIED, null);
String string = block.textLayout.getText().toString();
SpannableString code = new SpannableString(string);
code.setSpan(new CodeHighlighting.Span(false, 0, null, block.language, string), 0, code.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
AndroidUtilities.addToClipboard(code);
BulletinFactory.of(ChatActivity.this).createCopyBulletin(LocaleController.getString(R.string.CodeCopied)).show();
}
@Override

View file

@ -376,7 +376,7 @@ public class ChatUsersActivity extends BaseFragment implements NotificationCente
if (slowmodeInfoRow == -1 && gigaHeaderRow == -1 || removedUsersRow != -1) {
participantsDividerRow = rowCount++;
}
if (ChatObject.canBlockUsers(currentChat) && (ChatObject.isChannel(currentChat) || currentChat.creator)) {
if (ChatObject.canBlockUsers(currentChat) && getParticipantsCount() > 1 && (ChatObject.isChannel(currentChat) || currentChat.creator)) {
addNewRow = rowCount++;
}

View file

@ -23,6 +23,7 @@ import android.graphics.Shader;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.util.Log;
import android.view.View;
import org.telegram.messenger.AndroidUtilities;
@ -32,6 +33,7 @@ import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.DispatchQueuePoolBackground;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.SharedConfig;
@ -353,6 +355,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
}
}
private int decoderTryCount = 0;
private Runnable loadFrameRunnable = new Runnable() {
@Override
public void run() {
@ -364,7 +367,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
nativePtr = 0;
}
updateScaleFactor();
decoderCreated = true;
decoderCreated = !isWebmSticker || nativePtr != 0 || (decoderTryCount++) > 15;
}
try {
if (bitmapsCache != null) {
@ -1077,7 +1080,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
}
public boolean isRecycled() {
return isRecycled;
return isRecycled || decoderTryCount >= 15;
}
public Bitmap getNextFrame() {

View file

@ -197,6 +197,10 @@ public class AnimatedFloat {
}
}
public float getTargetValue() {
return targetValue;
}
public void setParent(View parent) {
this.parent = parent;
}

View file

@ -10,6 +10,7 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
@ -400,7 +401,7 @@ public class AvatarConstructorFragment extends BaseFragment {
chooseEmojiHint.setGravity(Gravity.CENTER);
linearLayout.addView(chooseEmojiHint, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 21, 18, 21, 10));
selectAnimatedEmojiDialog = new SelectAnimatedEmojiDialog(this, getContext(), false, null, SelectAnimatedEmojiDialog.TYPE_AVATAR_CONSTRUCTOR, null) {
selectAnimatedEmojiDialog = new SelectAnimatedEmojiDialog(this, getContext(), false, null, SelectAnimatedEmojiDialog.TYPE_AVATAR_CONSTRUCTOR, true, null, 16, Theme.isCurrentThemeDark() ? Color.WHITE : getThemedColor(Theme.key_windowBackgroundWhiteBlueIcon)) {
private boolean firstLayout = true;
@ -685,6 +686,7 @@ public class AvatarConstructorFragment extends BaseFragment {
float changeBackgroundProgress = 1f;
BackgroundGradient backgroundGradient;
private ColorFilter colorFilter = new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
AnimatedFloat expandProgress = new AnimatedFloat(this, 200, CubicBezierInterpolator.EASE_OUT);
boolean expanded;
float overrideExpandProgress = -1f;
@ -791,8 +793,8 @@ public class AvatarConstructorFragment extends BaseFragment {
backupImageView.animatedEmojiDrawable.getImageReceiver().setRoundRadius((int) (imageSize * 2 * STICKER_DEFAULT_ROUND_RADIUS));
}
backupImageView.animatedEmojiDrawable.setBounds((int) (cx - imageSize), (int) (cy - imageSize), (int) (cx + imageSize), (int) (cy + imageSize));
backupImageView.animatedEmojiDrawable.setColorFilter(colorFilter);
backupImageView.animatedEmojiDrawable.draw(canvas);
} else {
backupImageView.imageReceiver.setImageCoords(cx - imageSize, cy - imageSize, imageSize * 2, imageSize * 2);
backupImageView.imageReceiver.setRoundRadius((int) (imageSize * 2 * STICKER_DEFAULT_ROUND_RADIUS));
@ -842,6 +844,9 @@ public class AvatarConstructorFragment extends BaseFragment {
ImageReceiver imageReceiver = backupImageView.getImageReceiver();
if (backupImageView.animatedEmojiDrawable != null) {
imageReceiver = backupImageView.animatedEmojiDrawable.getImageReceiver();
if (imageReceiver != null) {
imageReceiver.setColorFilter(colorFilter);
}
}
return imageReceiver;
}

View file

@ -320,7 +320,7 @@ public class BotCommandsMenuView extends View {
public BotCommandView(@NonNull Context context) {
super(context);
setOrientation(HORIZONTAL);
setPadding(AndroidUtilities.dp(16), 0, AndroidUtilities.dp(16), 0);
setPadding(AndroidUtilities.dp(16), AndroidUtilities.dp(8), AndroidUtilities.dp(16), AndroidUtilities.dp(8));
description = new TextView(context) {
@Override
@ -333,7 +333,7 @@ public class BotCommandsMenuView extends View {
description.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
description.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
description.setTag(Theme.key_windowBackgroundWhiteBlackText);
description.setLines(1);
description.setMaxLines(2);
description.setEllipsize(TextUtils.TruncateAt.END);
addView(description, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 1f, Gravity.CENTER_VERTICAL, 0, 0, AndroidUtilities.dp(8), 0));
@ -344,11 +344,6 @@ public class BotCommandsMenuView extends View {
addView(command, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0f, Gravity.CENTER_VERTICAL));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY));
}
public String getCommand() {
return commandStr;
}

View file

@ -847,7 +847,8 @@ public class BotWebViewSheet extends Dialog implements NotificationCenter.Notifi
public static JSONObject makeThemeParams(Theme.ResourcesProvider resourcesProvider) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("bg_color", Theme.getColor(Theme.key_dialogBackground, resourcesProvider));
final int backgroundColor = Theme.getColor(Theme.key_dialogBackground, resourcesProvider);
jsonObject.put("bg_color", backgroundColor);
jsonObject.put("section_bg_color", Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
jsonObject.put("secondary_bg_color", Theme.getColor(Theme.key_windowBackgroundGray, resourcesProvider));
jsonObject.put("text_color", Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
@ -856,10 +857,10 @@ public class BotWebViewSheet extends Dialog implements NotificationCenter.Notifi
jsonObject.put("button_color", Theme.getColor(Theme.key_featuredStickers_addButton, resourcesProvider));
jsonObject.put("button_text_color", Theme.getColor(Theme.key_featuredStickers_buttonText, resourcesProvider));
jsonObject.put("header_bg_color", Theme.getColor(Theme.key_actionBarDefault, resourcesProvider));
jsonObject.put("accent_text_color", Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4, resourcesProvider));
jsonObject.put("section_header_text_color", Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader, resourcesProvider));
jsonObject.put("subtitle_text_color", Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
jsonObject.put("destructive_text_color", Theme.getColor(Theme.key_text_RedRegular, resourcesProvider));
jsonObject.put("accent_text_color", Theme.blendOver(backgroundColor, Theme.getColor(Theme.key_windowBackgroundWhiteBlueText4, resourcesProvider)));
jsonObject.put("section_header_text_color", Theme.blendOver(backgroundColor, Theme.getColor(Theme.key_windowBackgroundWhiteBlueHeader, resourcesProvider)));
jsonObject.put("subtitle_text_color", Theme.blendOver(backgroundColor, Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider)));
jsonObject.put("destructive_text_color", Theme.blendOver(backgroundColor, Theme.getColor(Theme.key_text_RedRegular, resourcesProvider)));
return jsonObject;
} catch (Exception e) {
FileLog.e(e);

View file

@ -2590,7 +2590,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
containerView.addView(writeButtonContainer, LayoutHelper.createFrame(60, 60, Gravity.RIGHT | Gravity.BOTTOM, 0, 0, 6, 10));
writeButton = new ImageView(context);
writeButtonDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(56), getThemedColor(Theme.key_dialogFloatingButton), getThemedColor(Build.VERSION.SDK_INT >= 21 ? Theme.key_dialogFloatingButtonPressed : Theme.key_dialogFloatingButton));
writeButtonDrawable = Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(56), getThemedColor(Theme.key_chat_attachCheckBoxBackground), getThemedColor(Build.VERSION.SDK_INT >= 21 ? Theme.key_dialogFloatingButtonPressed : Theme.key_chat_attachCheckBoxBackground));
if (Build.VERSION.SDK_INT < 21) {
Drawable shadowDrawable = context.getResources().getDrawable(R.drawable.floating_shadow_profile).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(0xff000000, PorterDuff.Mode.MULTIPLY));
@ -2779,7 +2779,7 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
rect.set(cx - size / 2, 0, cx + size / 2, getMeasuredHeight());
canvas.drawRoundRect(rect, AndroidUtilities.dp(12), AndroidUtilities.dp(12), paint);
paint.setColor(getThemedColor(Theme.key_dialogRoundCheckBox));
paint.setColor(getThemedColor(Theme.key_chat_attachCheckBoxBackground));
rect.set(cx - size / 2 + AndroidUtilities.dp(2), AndroidUtilities.dp(2), cx + size / 2 - AndroidUtilities.dp(2), getMeasuredHeight() - AndroidUtilities.dp(2));
canvas.drawRoundRect(rect, AndroidUtilities.dp(10), AndroidUtilities.dp(10), paint);
@ -3713,8 +3713,8 @@ public class ChatAttachAlert extends BottomSheet implements NotificationCenter.N
}
}
Theme.setSelectorDrawableColor(writeButtonDrawable, getThemedColor(Theme.key_dialogFloatingButton), false);
Theme.setSelectorDrawableColor(writeButtonDrawable, getThemedColor(Build.VERSION.SDK_INT >= 21 ? Theme.key_dialogFloatingButtonPressed : Theme.key_dialogFloatingButton), true);
Theme.setSelectorDrawableColor(writeButtonDrawable, getThemedColor(Theme.key_chat_attachCheckBoxBackground), false);
Theme.setSelectorDrawableColor(writeButtonDrawable, getThemedColor(Build.VERSION.SDK_INT >= 21 ? Theme.key_dialogFloatingButtonPressed : Theme.key_chat_attachCheckBoxBackground), true);
writeButton.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_dialogFloatingIcon), PorterDuff.Mode.MULTIPLY));
actionBarShadow.setBackgroundColor(getThemedColor(Theme.key_dialogShadowLine));

View file

@ -1441,6 +1441,10 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
boolean isAnimatedSticker = MessageObject.isAnimatedStickerDocument(document, true);
mediaEntity.subType |= isAnimatedSticker ? 1 : 4;
}
if (MessageObject.isTextColorEmoji(document)) {
mediaEntity.color = 0xFFFFFFFF;
mediaEntity.subType |= 8;
}
photoEntry.editedInfo.mediaEntities = new ArrayList<>();
photoEntry.editedInfo.mediaEntities.add(mediaEntity);

View file

@ -863,12 +863,12 @@ public class EditTextBoldCursor extends EditTextEffects {
throw new RuntimeException(e);
}
}
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
if (!EditTextEffects.allowHackingTextCanvas()) {
ignoreTopCount = 1;
ignoreBottomCount = 1;
}
canvas.save();
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT_WATCH) {
if (!EditTextEffects.allowHackingTextCanvas()) {
canvas.translate(0, topPadding);
}
try {

View file

@ -271,7 +271,19 @@ public class EditTextEffects extends EditText {
return offsetY;
}
public boolean wrapCanvasToFixClipping = Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH;
private static Boolean allowHackingTextCanvasCache;
public static boolean allowHackingTextCanvas() {
if (allowHackingTextCanvasCache == null) {
allowHackingTextCanvasCache = Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT_WATCH && (
Build.MANUFACTURER == null ||
!Build.MANUFACTURER.equalsIgnoreCase("HONOR") &&
!Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")
);
}
return allowHackingTextCanvasCache;
}
public boolean wrapCanvasToFixClipping = allowHackingTextCanvas();
private NoClipCanvas wrappedCanvas;
@Override

View file

@ -563,6 +563,10 @@ public class LinkSpanDrawable<S extends CharacterStyle> {
return null;
}
public int overrideColor() {
return Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (links != null) {
@ -571,6 +575,7 @@ public class LinkSpanDrawable<S extends CharacterStyle> {
if ((span = hit((int) event.getX(), (int) event.getY())) != null) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
final LinkSpanDrawable link = new LinkSpanDrawable<ClickableSpan>(span, resourcesProvider, event.getX(), event.getY());
link.setColor(overrideColor());
pressedLink = link;
links.addLink(pressedLink);
Spannable buffer = new SpannableString(textLayout.getText());

View file

@ -613,4 +613,15 @@ public class NoClipCanvas extends Canvas {
public boolean quickReject(float left, float top, float right, float bottom, @NonNull EdgeType type) {
return canvas.quickReject(left, top, right, bottom, type);
}
@Override
public void concat(@Nullable Matrix matrix) {
canvas.concat(matrix);
}
@Override
public boolean isOpaque() {
return canvas.isOpaque();
}
}

View file

@ -770,8 +770,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
canApplyBoost.setMyBoosts(myBoosts);
onBoostSuccess();
String str = LocaleController.formatString("BoostingReassignedFrom", R.string.BoostingReassignedFrom,
LocaleController.formatPluralString("BoostingSubscriptionsCount", size),
String str = LocaleController.formatPluralString("BoostingReassignedFromPlural", size,
LocaleController.formatPluralString("BoostingFromOtherChannel", channels));
BulletinFactory bulletinFactory = BulletinFactory.of(container, resourcesProvider);
bulletinFactory.createSimpleBulletinWithIconSize(R.raw.forward, str, 30).setDuration(4000).show(true);

View file

@ -33,6 +33,7 @@ import androidx.recyclerview.widget.RecyclerView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.NotificationCenter;
@ -43,6 +44,7 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
@ -87,12 +89,13 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
ViewGroup iconContainer;
BaseFragment fragment;
public Integer accentColor;
public float startEnterFromX;
public float startEnterFromY;
public float startEnterFromX1;
public float startEnterFromY1;
public float startEnterFromScale;
public SimpleTextView startEnterFromView;
public View startEnterFromView;
public View overrideTitleIcon;
public TLRPC.InputStickerSet statusStickerSet;
public boolean isEmojiStatus;
@ -265,7 +268,10 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
if (statusStickerSet != null) {
final String stickerSetPlaceholder = "<STICKERSET>";
String string = LocaleController.formatString(R.string.TelegramPremiumUserStatusDialogTitle, ContactsController.formatName(user.first_name, user.last_name), stickerSetPlaceholder);
CharSequence charSequence = AndroidUtilities.replaceSingleTag(string, Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null);
CharSequence charSequence = AndroidUtilities.replaceSingleLink(string, accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueButton) : accentColor);
try {
charSequence = Emoji.replaceEmoji(charSequence, titleView[0].getPaint().getFontMetricsInt(), false);
} catch (Exception ignore) {}
SpannableStringBuilder title = charSequence instanceof SpannableStringBuilder ? ((SpannableStringBuilder) charSequence) : new SpannableStringBuilder(charSequence);
int index = charSequence.toString().indexOf(stickerSetPlaceholder);
if (index >= 0) {
@ -301,6 +307,9 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
if (accentColor != null) {
ds.setColor(accentColor);
}
}
@Override
public void onClick(@NonNull View view) {}
@ -356,24 +365,27 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.formatString(R.string.TelegramPremiumUserStatusDialogSubtitle, ContactsController.formatName(user.first_name, user.last_name))));
} else if (giftTier != null) {
if (isOutboundGift) {
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogTitleWithPlural, user != null ? user.first_name : "", LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
subtitleView.setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogSubtitle, user != null ? user.first_name : ""), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
titleView[0].setText(AndroidUtilities.replaceSingleLink(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogTitleWithPlural, user != null ? user.first_name : "", LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueButton) : accentColor));
subtitleView.setText(AndroidUtilities.replaceSingleLink(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumOutboundDialogSubtitle, user != null ? user.first_name : ""), accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueButton) : accentColor));
} else if (user == null || TextUtils.isEmpty(user.first_name) || user.id == 777000) {
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPluralSomeone, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
titleView[0].setText(AndroidUtilities.replaceSingleLink(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPluralSomeone, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueButton) : accentColor));
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserGiftedPremiumDialogSubtitle)));
} else {
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPlural, user.first_name, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
titleView[0].setText(AndroidUtilities.replaceSingleLink(LocaleController.formatString(R.string.TelegramPremiumUserGiftedPremiumDialogTitleWithPlural, user.first_name, LocaleController.formatPluralString("GiftMonths", giftTier.getMonths())), accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueButton) : accentColor));
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserGiftedPremiumDialogSubtitle)));
}
} else {
if(user == null) {
if (user == null) {
titleView[0].setText(LocaleController.getString(R.string.TelegramPremium));
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumSubscribedSubtitle)));
} else {
titleView[0].setText(AndroidUtilities.replaceSingleTag(LocaleController.formatString(R.string.TelegramPremiumUserDialogTitle, ContactsController.formatName(user.first_name, user.last_name)), Theme.key_windowBackgroundWhiteBlueButton, AndroidUtilities.REPLACING_TAG_TYPE_LINK, null));
titleView[0].setText(AndroidUtilities.replaceSingleLink(LocaleController.formatString(R.string.TelegramPremiumUserDialogTitle, ContactsController.formatName(user.first_name, user.last_name)), accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueButton) : accentColor));
subtitleView.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.TelegramPremiumUserDialogSubtitle)));
}
}
try {
titleView[0].setText(Emoji.replaceEmoji(titleView[0].getText(), titleView[0].getPaint().getFontMetricsInt(), false));
} catch (Exception ignore) {}
}
@Override
@ -439,7 +451,7 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
titleViewContainer = new FrameLayout(context);
titleViewContainer.setClipChildren(false);
final ColorFilter colorFilter = new PorterDuffColorFilter(getThemedColor(Theme.key_windowBackgroundWhiteBlueIcon), PorterDuff.Mode.SRC_IN);
final ColorFilter colorFilter = new PorterDuffColorFilter(accentColor == null ? getThemedColor(Theme.key_windowBackgroundWhiteBlueIcon) : accentColor, PorterDuff.Mode.SRC_IN);
titleView = new LinkSpanDrawable.LinksTextView[2];
for (int a = 0; a < 2; ++a) {
titleView[a] = new LinkSpanDrawable.LinksTextView(context, resourcesProvider) {
@ -466,6 +478,11 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(99999999, MeasureSpec.AT_MOST));
}
@Override
public int overrideColor() {
return accentColor != null ? Theme.multAlpha(accentColor, .10f) : super.overrideColor();
}
};
titleView[a].setVisibility(a == 0 ? View.VISIBLE : View.GONE);
titleView[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
@ -651,7 +668,16 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
float[] points = new float[]{startEnterFromX, startEnterFromY};
startEnterFromView.getMatrix().mapPoints(points);
Drawable startEnterFromDrawable = startEnterFromView.getRightDrawable();
Drawable startEnterFromDrawable = null;
if (startEnterFromView instanceof SimpleTextView) {
startEnterFromDrawable = ((SimpleTextView) startEnterFromView).getRightDrawable();
} else if (startEnterFromView instanceof ChatMessageCell) {
startEnterFromDrawable = ((ChatMessageCell) startEnterFromView).currentNameStatusDrawable;
}
if (startEnterFromDrawable == null) {
canvas.restore();
return;
}
float cxFrom = -coords[0] + startEnterFromX1 + points[0];
float cyFrom = -coords[1] + startEnterFromY1 + points[1];
@ -715,8 +741,23 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
enterTransitionProgress = 0f;
enterTransitionInProgress = true;
iconContainer.invalidate();
startEnterFromView.getRightDrawable().setAlpha(0);
startEnterFromView.invalidate();
final Drawable startEnterFromDrawable;
if (startEnterFromView instanceof SimpleTextView) {
startEnterFromDrawable = ((SimpleTextView) startEnterFromView).getRightDrawable();
} else if (startEnterFromView instanceof ChatMessageCell) {
startEnterFromDrawable = ((ChatMessageCell) startEnterFromView).currentNameStatusDrawable;
((ChatMessageCell) startEnterFromView).invalidateOutbounds();
} else {
startEnterFromDrawable = null;
}
if (startEnterFromDrawable != null) {
startEnterFromDrawable.setAlpha(0);
}
if (startEnterFromView instanceof ChatMessageCell) {
((ChatMessageCell) startEnterFromView).invalidateOutbounds();
} else {
startEnterFromView.invalidate();
}
if (iconTextureView != null) {
iconTextureView.startEnterAnimation(-360, 100);
}
@ -730,13 +771,18 @@ public class PremiumPreviewBottomSheet extends BottomSheetWithRecyclerListView i
enterTransitionInProgress = false;
enterTransitionProgress = 1f;
iconContainer.invalidate();
ValueAnimator iconAlphaBack = ValueAnimator.ofInt(0, 255);
Drawable drawable = startEnterFromView.getRightDrawable();
iconAlphaBack.addUpdateListener(animation1 -> {
drawable.setAlpha((Integer) animation1.getAnimatedValue());
startEnterFromView.invalidate();
});
iconAlphaBack.start();
if (startEnterFromDrawable != null) {
ValueAnimator iconAlphaBack = ValueAnimator.ofInt(0, 255);
iconAlphaBack.addUpdateListener(animation1 -> {
startEnterFromDrawable.setAlpha((Integer) animation1.getAnimatedValue());
if (startEnterFromView instanceof ChatMessageCell) {
((ChatMessageCell) startEnterFromView).invalidateOutbounds();
} else {
startEnterFromView.invalidate();
}
});
iconAlphaBack.start();
}
super.onAnimationEnd(animation);
}
});

View file

@ -39,7 +39,7 @@ public class BoostCounterView extends View {
countText.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
countText.setTextColor(Color.WHITE);
countText.setText("");
countText.setGravity(Gravity.CENTER_HORIZONTAL);
countText.setGravity(Gravity.CENTER);
bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bgPaint.setColor(0xFF967bff);

View file

@ -429,7 +429,7 @@ public class BoostDialogs {
AlertDialog.Builder builder = new AlertDialog.Builder(context, resourcesProvider);
builder.setTitle(getString("BoostingReduceQuantity", R.string.BoostingReduceQuantity));
builder.setMessage(replaceTags(formatString("BoostingReduceUsersText", R.string.BoostingReduceUsersText, current, downTo)));
builder.setMessage(replaceTags(formatPluralString("BoostingReduceUsersTextPlural", current, downTo)));
builder.setPositiveButton(getString("OK", R.string.OK), (dialogInterface, i) -> {
});
@ -439,11 +439,11 @@ public class BoostDialogs {
return false;
}
public static boolean checkReduceQuantity(Context context, Theme.ResourcesProvider resourcesProvider, List<TLRPC.TL_premiumGiftCodeOption> list, TLRPC.TL_premiumGiftCodeOption selected, Utilities.Callback<TLRPC.TL_premiumGiftCodeOption> onSuccess) {
public static boolean checkReduceQuantity(List<Integer> sliderValues, Context context, Theme.ResourcesProvider resourcesProvider, List<TLRPC.TL_premiumGiftCodeOption> list, TLRPC.TL_premiumGiftCodeOption selected, Utilities.Callback<TLRPC.TL_premiumGiftCodeOption> onSuccess) {
if (selected.store_product == null) {
List<TLRPC.TL_premiumGiftCodeOption> result = new ArrayList<>();
for (TLRPC.TL_premiumGiftCodeOption item : list) {
if (item.months == selected.months && item.store_product != null) {
if (item.months == selected.months && item.store_product != null && sliderValues.contains(item.users)) {
result.add(item);
}
}
@ -462,7 +462,7 @@ public class BoostDialogs {
int downTo = suggestion.users;
AlertDialog.Builder builder = new AlertDialog.Builder(context, resourcesProvider);
builder.setTitle(getString("BoostingReduceQuantity", R.string.BoostingReduceQuantity));
builder.setMessage(replaceTags(formatString("BoostingReduceQuantityText", R.string.BoostingReduceQuantityText, current, months, downTo)));
builder.setMessage(replaceTags(formatPluralString("BoostingReduceQuantityTextPlural", current, months, downTo)));
builder.setPositiveButton(getString("Reduce", R.string.Reduce), (dialogInterface, i) -> onSuccess.run(finalSuggestion));
builder.setNegativeButton(getString("Cancel", R.string.Cancel), (dialogInterface, i) -> {
@ -473,9 +473,7 @@ public class BoostDialogs {
return false;
}
public static void showAbout(long chatId, long msgDate, TLRPC.TL_payments_giveawayInfo giveawayInfo, TLRPC.TL_messageMediaGiveaway giveaway, Context context, Theme.ResourcesProvider resourcesProvider) {
TLRPC.Chat chat = MessagesController.getInstance(UserConfig.selectedAccount).getChat(-chatId);
String from = chat != null ? chat.title : "";
public static void showAbout(String from, long msgDate, TLRPC.TL_payments_giveawayInfo giveawayInfo, TLRPC.TL_messageMediaGiveaway giveaway, Context context, Theme.ResourcesProvider resourcesProvider) {
int quantity = giveaway.quantity;
String months = formatPluralString("BoldMonths", giveaway.months);
String endDate = LocaleController.getInstance().formatterGiveawayMonthDay.format(new Date(giveaway.until_date * 1000L));
@ -492,13 +490,15 @@ public class BoostDialogs {
if (giveaway.only_new_subscribers) {
if (isSeveralChats) {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextDateSeveral", quantity, endDate, quantity, from, giveaway.channels.size() - 1, fromTime, fromDate)));
String andStr = formatPluralString("BoostingGiveawayHowItWorksSubTextDateSeveral2", giveaway.channels.size() - 1, fromTime, fromDate);
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextDateSeveral1", quantity, endDate, quantity, from, andStr)));
} else {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextDate", quantity, endDate, quantity, from, fromTime, fromDate)));
}
} else {
if (isSeveralChats) {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextSeveral", quantity, endDate, quantity, from, giveaway.channels.size() - 1)));
String andStr = formatPluralString("BoostingGiveawayHowItWorksSubTextSeveral2", giveaway.channels.size() - 1);
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextSeveral1", quantity, endDate, quantity, from, andStr)));
} else {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubText", quantity, endDate, quantity, from)));
}
@ -508,7 +508,7 @@ public class BoostDialogs {
if (giveawayInfo.participating) {
if (isSeveralChats) {
stringBuilder.append(replaceTags(formatString("BoostingGiveawayParticipantMulti", R.string.BoostingGiveawayParticipantMulti, from, giveaway.channels.size() - 1)));
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayParticipantMultiPlural", giveaway.channels.size() - 1, from)));
} else {
stringBuilder.append(replaceTags(formatString("BoostingGiveawayParticipant", R.string.BoostingGiveawayParticipant, from)));
}
@ -523,7 +523,7 @@ public class BoostDialogs {
stringBuilder.append(replaceTags(formatString("BoostingGiveawayNotEligible", R.string.BoostingGiveawayNotEligible, date)));
} else {
if (isSeveralChats) {
stringBuilder.append(replaceTags(formatString("BoostingGiveawayTakePartMulti", R.string.BoostingGiveawayTakePartMulti, from, giveaway.channels.size() - 1, endDate)));
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayTakePartMultiPlural", giveaway.channels.size() - 1, from, endDate)));
} else {
stringBuilder.append(replaceTags(formatString("BoostingGiveawayTakePart", R.string.BoostingGiveawayTakePart, from, endDate)));
}
@ -536,9 +536,7 @@ public class BoostDialogs {
builder.show();
}
public static void showAboutEnd(long chatId, long msgDate, TLRPC.TL_payments_giveawayInfoResults giveawayInfo, TLRPC.TL_messageMediaGiveaway giveaway, Context context, Theme.ResourcesProvider resourcesProvider) {
TLRPC.Chat chat = MessagesController.getInstance(UserConfig.selectedAccount).getChat(-chatId);
String from = chat != null ? chat.title : "";
public static void showAboutEnd(String from, long msgDate, TLRPC.TL_payments_giveawayInfoResults giveawayInfo, TLRPC.TL_messageMediaGiveaway giveaway, Context context, Theme.ResourcesProvider resourcesProvider) {
int quantity = giveaway.quantity;
String months = formatPluralString("BoldMonths", giveaway.months);
String endDate = LocaleController.getInstance().formatterGiveawayMonthDay.format(new Date(giveaway.until_date * 1000L));
@ -555,13 +553,15 @@ public class BoostDialogs {
if (giveaway.only_new_subscribers) {
if (isSeveralChats) {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextDateSeveralEnd", quantity, endDate, quantity, from, giveaway.channels.size() - 1, fromTime, fromDate)));
String andStr = formatPluralString("BoostingGiveawayHowItWorksSubTextDateSeveral2", giveaway.channels.size() - 1, fromTime, fromDate);
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextDateSeveralEnd1", quantity, endDate, quantity, from, andStr)));
} else {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextDateEnd", quantity, endDate, quantity, from, fromTime, fromDate)));
}
} else {
if (isSeveralChats) {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextSeveralEnd", quantity, endDate, quantity, from, giveaway.channels.size() - 1)));
String andStr = formatPluralString("BoostingGiveawayHowItWorksSubTextSeveral2", giveaway.channels.size() - 1);
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextSeveralEnd1", quantity, endDate, quantity, from, andStr)));
} else {
stringBuilder.append(replaceTags(formatPluralString("BoostingGiveawayHowItWorksSubTextEnd", quantity, endDate, quantity, from)));
}
@ -583,7 +583,7 @@ public class BoostDialogs {
bottomTextView.setText(str);
bottomTextView.setTextColor(Theme.getColor(Theme.key_text_RedRegular, resourcesProvider));
bottomTextView.setBackground(Theme.createRoundRectDrawable(dp(10), dp(10), Theme.multAlpha(Theme.getColor(Theme.key_text_RedRegular, resourcesProvider), 0.1f)));
bottomTextView.setPadding(0, dp(12), 0, dp(12));
bottomTextView.setPadding(dp(8), dp(12), dp(8), dp(12));
builder.addBottomView(bottomTextView);
builder.setMessage(stringBuilder);
builder.setPositiveButton(getString("Close", R.string.Close), (dialogInterface, i) -> {
@ -639,7 +639,7 @@ public class BoostDialogs {
progress.init();
progress.onCancel(() -> isCanceled.set(true));
final TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) messageObject.messageOwner.media;
final long chatId = messageObject.getFromChatId();
final String fromName = getGiveawayCreatorName(messageObject);
final long msgDate = messageObject.messageOwner.date * 1000L;
BoostRepository.getGiveawayInfo(messageObject, result -> {
if (isCanceled.get()) {
@ -648,10 +648,10 @@ public class BoostDialogs {
progress.end();
if (result instanceof TLRPC.TL_payments_giveawayInfo) {
TLRPC.TL_payments_giveawayInfo giveawayInfo = (TLRPC.TL_payments_giveawayInfo) result;
showAbout(chatId, msgDate, giveawayInfo, giveaway, context, resourcesProvider);
showAbout(fromName, msgDate, giveawayInfo, giveaway, context, resourcesProvider);
} else if (result instanceof TLRPC.TL_payments_giveawayInfoResults) {
TLRPC.TL_payments_giveawayInfoResults giveawayInfoResults = (TLRPC.TL_payments_giveawayInfoResults) result;
showAboutEnd(chatId, msgDate, giveawayInfoResults, giveaway, context, resourcesProvider);
showAboutEnd(fromName, msgDate, giveawayInfoResults, giveaway, context, resourcesProvider);
}
}, error -> {
if (isCanceled.get()) {
@ -661,18 +661,34 @@ public class BoostDialogs {
});
}
private static String getGiveawayCreatorName(MessageObject messageObject) {
if (messageObject == null) {
return "";
}
String forwardedName = messageObject.getForwardedName();
final String name;
if (forwardedName == null) {
final long chatId = messageObject.getFromChatId();
TLRPC.Chat chat = MessagesController.getInstance(UserConfig.selectedAccount).getChat(-chatId);
name = chat != null ? chat.title : "";
} else {
name = forwardedName;
}
return name;
}
public static void showBulletinAbout(MessageObject messageObject) {
if (messageObject == null) {
return;
}
BoostRepository.getGiveawayInfo(messageObject, result -> {
final TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) messageObject.messageOwner.media;
final long chatId = messageObject.getFromChatId();
final long msgDate = messageObject.messageOwner.date * 1000L;
BaseFragment fragment = LaunchActivity.getLastFragment();
if (fragment == null) {
return;
}
final String fromName = getGiveawayCreatorName(messageObject);
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(fragment.getParentActivity(), fragment.getResourceProvider());
if (result instanceof TLRPC.TL_payments_giveawayInfoResults) {
@ -697,10 +713,10 @@ public class BoostDialogs {
.setUndoAction(() -> {
if (result instanceof TLRPC.TL_payments_giveawayInfo) {
TLRPC.TL_payments_giveawayInfo giveawayInfo = (TLRPC.TL_payments_giveawayInfo) result;
showAbout(chatId, msgDate, giveawayInfo, giveaway, fragment.getParentActivity(), fragment.getResourceProvider());
showAbout(fromName, msgDate, giveawayInfo, giveaway, fragment.getParentActivity(), fragment.getResourceProvider());
} else if (result instanceof TLRPC.TL_payments_giveawayInfoResults) {
TLRPC.TL_payments_giveawayInfoResults giveawayInfoResults = (TLRPC.TL_payments_giveawayInfoResults) result;
showAboutEnd(chatId, msgDate, giveawayInfoResults, giveaway, fragment.getParentActivity(), fragment.getResourceProvider());
showAboutEnd(fromName, msgDate, giveawayInfoResults, giveaway, fragment.getParentActivity(), fragment.getResourceProvider());
}
}));
Bulletin.make(fragment, layout, Bulletin.DURATION_LONG).show();

View file

@ -143,6 +143,14 @@ public class BoostPagerBottomSheet extends BottomSheet {
}
}
@Override
protected float getAvailableTranslationX() {
if (isTablet || isLandscapeOrientation) {
return getMeasuredWidth();
}
return super.getAvailableTranslationX();
}
@Override
protected boolean canScroll(MotionEvent e) {
return viewPager.getCurrentPosition() == 1;

View file

@ -21,6 +21,7 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
@ -432,6 +433,9 @@ public class BoostRepository {
for (int i = 0; i < help_countriesList.countries.size(); i++) {
TLRPC.TL_help_country country = help_countriesList.countries.get(i);
if (country.name != null) {
country.default_name = country.name;
}
if (country.iso2.equalsIgnoreCase("FT")) {
continue;
}
@ -550,7 +554,10 @@ public class BoostRepository {
for (int a = 0; a < res.participants.size(); a++) {
TLRPC.Peer peer = res.participants.get(a).peer;
if (MessageObject.getPeerId(peer) != selfId) {
result.add(controller.getInputPeer(peer));
TLRPC.User user = controller.getUser(peer.user_id);
if (user != null && !UserObject.isDeleted(user) && !user.bot) {
result.add(controller.getInputPeer(peer));
}
}
}
onDone.run(result);

View file

@ -117,6 +117,7 @@ public class BoostViaGiftsBottomSheet extends BottomSheetWithRecyclerListView im
}
}
selectedParticipantsType = tmpParticipantsType;
updateRows(false, false);
} else if (view instanceof DurationCell) {
selectedMonths = ((TLRPC.TL_premiumGiftCodeOption) ((DurationCell) view).getGifCode()).months;
updateRows(false, false);
@ -185,7 +186,7 @@ public class BoostViaGiftsBottomSheet extends BottomSheetWithRecyclerListView im
for (int i = 0; i < options.size(); i++) {
TLRPC.TL_premiumGiftCodeOption option = options.get(i);
if (option.months == selectedMonths) {
if (BoostRepository.isGoogleBillingAvailable() && BoostDialogs.checkReduceQuantity(getContext(), resourcesProvider, giftCodeOptions, option, arg -> {
if (BoostRepository.isGoogleBillingAvailable() && BoostDialogs.checkReduceQuantity(sliderValues, getContext(), resourcesProvider, giftCodeOptions, option, arg -> {
selectedSliderIndex = sliderValues.indexOf(arg.users);
updateRows(true, true);
updateActionButton(true);

View file

@ -29,6 +29,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
public class GiftInfoBottomSheet extends BottomSheetWithRecyclerListView {
public static void show(BaseFragment fragment, String slug, Browser.Progress progress) {
if (fragment == null) {
return;
}
final AtomicBoolean isCanceled = new AtomicBoolean(false);
if (progress != null) {
progress.init();
@ -38,12 +41,11 @@ public class GiftInfoBottomSheet extends BottomSheetWithRecyclerListView {
if (isCanceled.get()) {
return;
}
GiftInfoBottomSheet alert = new GiftInfoBottomSheet(fragment, false, true, giftCode, slug);
if (fragment != null && fragment.getParentActivity() != null) {
fragment.showDialog(alert);
} else {
alert.show();
if (fragment.getParentActivity() == null) {
return;
}
GiftInfoBottomSheet alert = new GiftInfoBottomSheet(fragment, false, true, giftCode, slug);
fragment.showDialog(alert);
if (progress != null) {
progress.end();
}

View file

@ -158,7 +158,7 @@ public class ReassignBoostBottomSheet extends BottomSheetWithRecyclerListView {
if (view instanceof SelectorUserCell) {
SelectorUserCell cell = ((SelectorUserCell) view);
if (cell.getBoost().cooldown_until_date > 0) {
SpannableStringBuilder text = AndroidUtilities.replaceTags(LocaleController.formatString("BoostingWaitWarning", R.string.BoostingWaitWarning, BoostRepository.boostsPerSentGift()));
SpannableStringBuilder text = AndroidUtilities.replaceTags(LocaleController.formatPluralString("BoostingWaitWarningPlural", BoostRepository.boostsPerSentGift()));
BulletinFactory.of(container, resourcesProvider).createSimpleBulletin(R.raw.chats_infotip, text, 5).show(true);
return;
}
@ -364,7 +364,7 @@ public class ReassignBoostBottomSheet extends BottomSheetWithRecyclerListView {
}
public void setData(TLRPC.Chat chat) {
description.setText(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingReassignBoostText", R.string.BoostingReassignBoostText, chat == null ? "" : chat.title, BoostRepository.boostsPerSentGift())));
description.setText(AndroidUtilities.replaceTags(LocaleController.formatPluralString("BoostingReassignBoostTextPlural", BoostRepository.boostsPerSentGift(), chat == null ? "" : chat.title)));
}
public void showBoosts(List<TL_stories.TL_myBoost> selectedBoosts, TLRPC.Chat currentChat) {

View file

@ -276,7 +276,7 @@ public class SelectorBottomSheet extends BottomSheetWithRecyclerListView {
linearSmoothScroller.setOffset(AndroidUtilities.dp(38));
recyclerListView.getLayoutManager().startSmoothScroll(linearSmoothScroller);
} else {
recyclerListView.scrollToPosition(1);
recyclerListView.scrollToPosition(0);
}
}
@ -409,13 +409,14 @@ public class SelectorBottomSheet extends BottomSheetWithRecyclerListView {
updateList(false, true);
headerView.setText(getTitle());
updateActionButton(false);
scrollToTop(false);
}
private void updateSection() {
String text;
switch (type) {
case TYPE_CHANNEL:
text = LocaleController.formatString("BoostingSelectUpTo", R.string.BoostingSelectUpTo, BoostRepository.giveawayAddPeersMax());
text = LocaleController.formatPluralString("BoostingSelectUpToPlural", (int) BoostRepository.giveawayAddPeersMax());
sectionCell.setLayerHeight(32);
break;
case TYPE_USER:
@ -423,7 +424,7 @@ public class SelectorBottomSheet extends BottomSheetWithRecyclerListView {
sectionCell.setLayerHeight(32);
break;
case TYPE_COUNTRY:
text = LocaleController.formatString("BoostingSelectUpTo", R.string.BoostingSelectUpToCountries, BoostRepository.giveawayCountriesMax());
text = LocaleController.formatPluralString("BoostingSelectUpToCountriesPlural", (int) BoostRepository.giveawayCountriesMax());
sectionCell.setLayerHeight(1);
break;
default:
@ -436,13 +437,13 @@ public class SelectorBottomSheet extends BottomSheetWithRecyclerListView {
String text = "";
switch (type) {
case TYPE_CHANNEL:
text = LocaleController.formatString("BoostingSelectUpToWarningChannels", R.string.BoostingSelectUpToWarningChannels, BoostRepository.giveawayAddPeersMax());
text = LocaleController.formatPluralString("BoostingSelectUpToWarningChannelsPlural", (int) BoostRepository.giveawayAddPeersMax());
break;
case TYPE_USER:
text = LocaleController.getString("BoostingSelectUpToWarningUsers", R.string.BoostingSelectUpToWarningUsers);
break;
case TYPE_COUNTRY:
text = LocaleController.formatString("BoostingSelectUpToWarningCountries", R.string.BoostingSelectUpToWarningCountries, BoostRepository.giveawayCountriesMax());
text = LocaleController.formatPluralString("BoostingSelectUpToWarningCountriesPlural", (int) BoostRepository.giveawayCountriesMax());
break;
}
if (selectedObjectsListener != null) {

View file

@ -140,7 +140,7 @@ public abstract class GiftInfoAdapter extends RecyclerListView.SelectionAdapter
case HOLDER_TYPE_LINK: {
LinkCell cell = (LinkCell) holder.itemView;
cell.setSlug(slug);
if (giftCode.boost != null) {
if (giftCode.boost != null && slug == null) {
cell.hideSlug(this::onHiddenLinkClicked);
}
//unclaimed and slug visible only for giveaway creator
@ -230,7 +230,7 @@ public abstract class GiftInfoAdapter extends RecyclerListView.SelectionAdapter
dismiss();
}
});
if (giftCode.boost != null || giftCode.to_id == NO_USER_ID) {
if (giftCode.boost != null || giftCode.flags == -1) {
cell.setCloseStyle();
cell.setOnClickListener(v -> dismiss());
}

View file

@ -25,7 +25,7 @@ public class BoostTypeSingleCell extends BoostTypeCell {
subtitleTextView.setTextColor(Theme.getColor(Theme.key_dialogTextGray3, resourcesProvider));
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_GIFT);
titleTextView.setText(LocaleController.formatString("BoostingPreparedGiveawayOne", R.string.BoostingPreparedGiveawayOne));
String subtitle = LocaleController.formatString("BoostingPreparedGiveawaySubscriptions", R.string.BoostingPreparedGiveawaySubscriptions, prepaidGiveaway.quantity, LocaleController.formatPluralString("Months", prepaidGiveaway.months));
String subtitle = LocaleController.formatPluralString("BoostingPreparedGiveawaySubscriptionsPlural", prepaidGiveaway.quantity, LocaleController.formatPluralString("Months", prepaidGiveaway.months));
setSubtitle(subtitle);
if (prepaidGiveaway.months == 12) {
avatarDrawable.setColor(0xFFff8560, 0xFFd55246);

View file

@ -34,7 +34,7 @@ public class SubtitleWithCounterCell extends org.telegram.ui.Cells.HeaderCell {
}
public void updateCounter(boolean animated, int count) {
CharSequence text = LocaleController.formatPluralString("BoostingSubscriptionsCount", count, count);
CharSequence text = LocaleController.formatPluralString("BoostingBoostsCountTitle", count, count);
counterTextView.setText(text, animated);
}
}

View file

@ -2,6 +2,8 @@ package org.telegram.ui.Components.Premium.boosts.cells.msg;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.replaceTags;
import static org.telegram.messenger.LocaleController.formatPluralString;
import static org.telegram.messenger.LocaleController.formatPluralStringComma;
import static org.telegram.messenger.LocaleController.formatString;
import static org.telegram.messenger.LocaleController.getString;
@ -71,10 +73,10 @@ public class GiveawayMessageCell {
private final ChatMessageCell parentView;
private final ImageReceiver giftReceiver;
private final CharSequence[] chatTitles = new CharSequence[10];
private final float[] chatTitleWidths = new float[10];
private final boolean[] needNewRow = new boolean[10];
private final Rect[] clickRect = new Rect[10];
private CharSequence[] chatTitles = new CharSequence[10];
private float[] chatTitleWidths = new float[10];
private boolean[] needNewRow = new boolean[10];
private Rect[] clickRect = new Rect[10];
private boolean[] avatarVisible;
private int measuredHeight = 0;
private int measuredWidth = 0;
@ -218,6 +220,7 @@ public class GiveawayMessageCell {
createImages();
setGiftImage(messageObject);
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) messageObject.messageOwner.media;
checkArraysLimits(giveaway.channels.size());
int giftSize = AndroidUtilities.dp(148);
int maxWidth;
@ -231,8 +234,13 @@ public class GiveawayMessageCell {
SpannableStringBuilder topStringBuilder = new SpannableStringBuilder(giveawayPrizes);
topStringBuilder.setSpan(new RelativeSizeSpan(1.05f), 0, giveawayPrizes.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
topStringBuilder.append("\n");
CharSequence subTitle = replaceTags(formatString("BoostingGiveawayMsgInfo", R.string.BoostingGiveawayMsgInfo, giveaway.quantity, LocaleController.formatPluralString("BoldMonths", giveaway.months)));
topStringBuilder.append(subTitle);
SpannableStringBuilder subTitleBuilder = new SpannableStringBuilder();
subTitleBuilder.append(replaceTags(formatPluralStringComma("BoostingGiveawayMsgInfoPlural1", giveaway.quantity)));
subTitleBuilder.append("\n");
subTitleBuilder.append(replaceTags(formatPluralString("BoostingGiveawayMsgInfoPlural2", giveaway.quantity, LocaleController.formatPluralString("BoldMonths", giveaway.months))));
CharSequence subTitle = subTitleBuilder;
topStringBuilder.append(subTitleBuilder);
topStringBuilder.append("\n\n");
topStringBuilder.setSpan(new RelativeSizeSpan(0.5f), topStringBuilder.length() - 1, topStringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -243,9 +251,9 @@ public class GiveawayMessageCell {
topStringBuilder.append("\n");
if (giveaway.only_new_subscribers) {
topStringBuilder.append(getString("BoostingGiveawayMsgNewSubs", R.string.BoostingGiveawayMsgNewSubs));
topStringBuilder.append(formatPluralString("BoostingGiveawayMsgNewSubsPlural", giveaway.channels.size()));
} else {
topStringBuilder.append(getString("BoostingGiveawayMsgAllSubs", R.string.BoostingGiveawayMsgAllSubs));
topStringBuilder.append(formatPluralString("BoostingGiveawayMsgAllSubsPlural", giveaway.channels.size()));
}
CharSequence dateTitle = replaceTags(getString("BoostingWinnersDate", R.string.BoostingWinnersDate));
@ -268,6 +276,10 @@ public class GiveawayMessageCell {
maxRowLength = (int) Math.max(maxRowLength, Math.ceil(bottomLayout.getLineWidth(a)));
}
if (maxRowLength < dp(180)) {
maxRowLength = dp(180);
}
if (giveaway.countries_iso2.size() > 0) {
List<CharSequence> countriesWithFlags = new ArrayList<>();
for (String iso2 : giveaway.countries_iso2) {
@ -275,7 +287,7 @@ public class GiveawayMessageCell {
String flag = LocaleController.getLanguageFlag(iso2);
SpannableStringBuilder builder = new SpannableStringBuilder();
if (flag != null) {
builder.append(flag).append(" ");
builder.append(flag).append("\u00A0");
}
builder.append(countryName);
countriesWithFlags.add(builder);
@ -529,6 +541,28 @@ public class GiveawayMessageCell {
}
}
private void checkArraysLimits(int channelsCount) {
if (avatarImageReceivers.length < channelsCount) {
int oldLength = avatarImageReceivers.length;
avatarImageReceivers = Arrays.copyOf(avatarImageReceivers, channelsCount);
avatarDrawables = Arrays.copyOf(avatarDrawables, channelsCount);
avatarVisible = Arrays.copyOf(avatarVisible, channelsCount);
chatTitles = Arrays.copyOf(chatTitles, channelsCount);
chatTitleWidths = Arrays.copyOf(chatTitleWidths, channelsCount);
needNewRow = Arrays.copyOf(needNewRow, channelsCount);
clickRect = Arrays.copyOf(clickRect, channelsCount);
for (int i = oldLength - 1; i < channelsCount; i++) {
avatarImageReceivers[i] = new ImageReceiver(parentView);
avatarImageReceivers[i].setAllowLoadingOnAttachedOnly(true);
avatarImageReceivers[i].setRoundRadius(AndroidUtilities.dp(12));
avatarDrawables[i] = new AvatarDrawable();
avatarDrawables[i].setTextSize(AndroidUtilities.dp(18));
clickRect[i] = new Rect();
}
}
}
private void setGiftImage(MessageObject messageObject) {
TLRPC.TL_messageMediaGiveaway giveaway = (TLRPC.TL_messageMediaGiveaway) messageObject.messageOwner.media;
TLRPC.TL_messages_stickerSet set;

View file

@ -67,25 +67,14 @@ public class SelectorCountryCell extends BaseCell {
private CharSequence getCountryNameWithFlag(TLRPC.TL_help_country country) {
SpannableStringBuilder sb = new SpannableStringBuilder();
String flag = LocaleController.getLanguageFlag(country.iso2);
if (!LocaleController.isRTL) {
if (flag != null) {
sb.append(flag).append(" ");
sb.setSpan(new SpaceDrawable(16), flag.length(), flag.length() + 1, 0);
} else {
sb.append(" ");
sb.setSpan(new SpaceDrawable(34), 0, 1, 0);
}
sb.append(country.default_name);
if (flag != null) {
sb.append(flag).append(" ");
sb.setSpan(new SpaceDrawable(16), flag.length(), flag.length() + 1, 0);
} else {
sb.append(country.default_name);
if (flag != null) {
sb.append(" ").append(flag);
sb.setSpan(new SpaceDrawable(16), country.default_name.length(), country.default_name.length() + 1, 0);
} else {
sb.append(" ");
sb.setSpan(new SpaceDrawable(34), country.default_name.length(), country.default_name.length() + 1, 0);
}
sb.append(" ");
sb.setSpan(new SpaceDrawable(34), 0, 1, 0);
}
sb.append(country.default_name);
return sb;
}

View file

@ -105,8 +105,8 @@ public class GiftedUserCell extends UserCell {
avatarImageView.setForUserOrChat(null, avatarDrawable);
nameTextView.setRightDrawable(null);
}
String date = LocaleController.getInstance().formatterScheduleDay.format(new Date(boost.date * 1000L));
String time = LocaleController.getInstance().formatterDay.format(new Date(boost.date * 1000L));
String date = LocaleController.getInstance().formatterScheduleDay.format(new Date(boost.expires * 1000L));
String time = LocaleController.getInstance().formatterDay.format(new Date(boost.expires * 1000L));
statusTextView.setText(LocaleController.formatString("BoostingShortMonths", R.string.BoostingShortMonths, months) + "" + LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, date, time));

View file

@ -76,6 +76,9 @@ public class QuoteHighlight extends Path {
final int blockEnd = Math.min(end - block.charactersOffset, block.charactersEnd - block.charactersOffset);
currentOffsetX = -offsetX;
if (block.code && !block.quote) {
currentOffsetX += dp(10);
}
currentOffsetY = block.textYOffset + block.padTop;
minX = block.quote ? dp(10) : 0;

View file

@ -45,6 +45,7 @@ public class ReplyMessageLine {
private float lastHeight;
private Path color2Path = new Path();
private Path color3Path = new Path();
private int switchedCount = 0;
private AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable emoji;
@ -58,6 +59,7 @@ public class ReplyMessageLine {
public final AnimatedFloat color3Alpha;
public final AnimatedFloat emojiLoadedT;
public final AnimatedFloat loadingStateT;
public final AnimatedFloat switchStateT;
public ReplyMessageLine(View view) {
this.parentView = view;
@ -85,6 +87,7 @@ public class ReplyMessageLine {
color3Alpha = new AnimatedFloat(view, 0, 400, CubicBezierInterpolator.EASE_OUT_QUINT);
emojiLoadedT = new AnimatedFloat(view, 0, 440, CubicBezierInterpolator.EASE_OUT_QUINT);
loadingStateT = new AnimatedFloat(view, 0, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
switchStateT = new AnimatedFloat(view, 0, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
}
public int getColor() {
@ -95,7 +98,21 @@ public class ReplyMessageLine {
return backgroundColor;
}
public void setBackgroundColor(int backgroundColor) {
this.backgroundColor = backgroundColor;
}
private int wasMessageId;
private int wasColorId;
private void resolveColor(MessageObject messageObject, int colorId, Theme.ResourcesProvider resourcesProvider) {
if (wasColorId != colorId) {
final int msgId = messageObject != null ? messageObject.getId() : 0;
if (msgId == wasMessageId) {
switchedCount++;
}
wasColorId = colorId;
wasMessageId = msgId;
}
if (colorId < 7) {
color1 = color2 = color3 = Theme.getColor(Theme.keys_avatar_nameInMessage[colorId], resourcesProvider);
hasColor2 = hasColor3 = false;
@ -351,8 +368,6 @@ public class ReplyMessageLine {
canvas.drawPaint(color1Paint);
color1Paint.setAlpha(wasAlpha);
canvas.clipPath(lineClipPath);
incrementLoadingT();
float x = (float) Math.pow(loadingT / 240f / 4f, .85f) * 4f;
@ -372,7 +387,6 @@ public class ReplyMessageLine {
parentView.invalidate();
}
canvas.drawPaint(color1Paint);
final float color2Alpha = this.color2Alpha.set(hasColor2);
if (color2Alpha > 0) {
@ -387,7 +401,8 @@ public class ReplyMessageLine {
} else {
fh = rect.height() - Math.floorMod((int) rect.height(), dp(6.33f + 3 + 3.33f));
}
canvas.translate(0, -((loadingTranslationT + (reversedOut ? 100 : 0)) / 1000f * dp(30) % fh));
canvas.translate(0, -((loadingTranslationT + switchStateT.set(switchedCount * 425) + (reversedOut ? 100 : 0)) / 1000f * dp(30) % fh));
checkColorPathes(rect.height() * 2);
int wasAlpha = color2Paint.getAlpha();

View file

@ -42,6 +42,10 @@ public class Text {
left = layout.getLineCount() > 0 ? layout.getLineLeft(0) : 0;
}
public float getTextSize() {
return paint.getTextSize();
}
public boolean isEmpty() {
return layout == null || TextUtils.isEmpty(layout.getText());
}
@ -121,6 +125,10 @@ public class Text {
return ellipsizeWidth >= 0 ? Math.min(ellipsizeWidth, width) : width;
}
public float getCurrentWidth() {
return width;
}
@NonNull
public CharSequence getText() {
if (layout == null || layout.getText() == null) {

View file

@ -337,10 +337,13 @@ public class TranslateAlert2 extends BottomSheet implements NotificationCenter.N
newEntity.length = entity.length;
received.entities.set(i, newEntity);
}
} else if (entity instanceof TLRPC.TL_messageEntityPre) {
if (source != null && source.entities != null && i < source.entities.size() && source.entities.get(i) instanceof TLRPC.TL_messageEntityPre) {
entity.language = source.entities.get(i).language;
}
}
}
if (source != null && source.text != null && !source.entities.isEmpty()) {
HashMap<String, ArrayList<Emoji.EmojiSpanRange>> srcIndexes = groupEmojiRanges(source.text);
HashMap<String, ArrayList<Emoji.EmojiSpanRange>> destIndexes = groupEmojiRanges(received.text);

View file

@ -1373,13 +1373,13 @@ public class UndoView extends FrameLayout {
infoTextView.setText(LocaleController.getString("BoostingSelectUpToWarningUsers", R.string.BoostingSelectUpToWarningUsers));
break;
case ACTION_BOOSTING_SELECTOR_WARNING_CHANNEL:
infoTextView.setText(LocaleController.formatString("BoostingSelectUpToWarningChannels", R.string.BoostingSelectUpToWarningChannels, BoostRepository.giveawayAddPeersMax()));
infoTextView.setText(LocaleController.formatPluralString("BoostingSelectUpToWarningChannelsPlural", (int) BoostRepository.giveawayAddPeersMax()));
break;
case ACTION_BOOSTING_SELECTOR_WARNING_COUNTRY:
infoTextView.setText(LocaleController.formatString("BoostingSelectUpToWarningCountries", R.string.BoostingSelectUpToWarningCountries, BoostRepository.giveawayCountriesMax()));
infoTextView.setText(LocaleController.formatPluralString("BoostingSelectUpToWarningCountriesPlural", (int) BoostRepository.giveawayCountriesMax()));
break;
case ACTION_BOOSTING_AWAIT:
infoTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("BoostingWaitWarning", R.string.BoostingWaitWarning, BoostRepository.boostsPerSentGift())));
infoTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatPluralString("BoostingWaitWarningPlural", BoostRepository.boostsPerSentGift())));
break;
}
layoutParams.leftMargin = AndroidUtilities.dp(58);

View file

@ -110,16 +110,20 @@ public class ViewPagerFixed extends FrameLayout {
public float getPositionAnimated() {
float position = 0;
if (viewPages[0] != null && viewPages[0].getVisibility() == View.VISIBLE) {
final float t = Utilities.clamp(1f - Math.abs(viewPages[0].getTranslationX() / (float) AndroidUtilities.displaySize.x), 1, 0);
final float t = Utilities.clamp(1f - Math.abs(viewPages[0].getTranslationX() / getAvailableTranslationX()), 1, 0);
position += currentPosition * t;
}
if (viewPages[1] != null && viewPages[1].getVisibility() == View.VISIBLE) {
final float t = Utilities.clamp(1f - Math.abs(viewPages[1].getTranslationX() / (float) AndroidUtilities.displaySize.x), 1, 0);
final float t = Utilities.clamp(1f - Math.abs(viewPages[1].getTranslationX() / getAvailableTranslationX()), 1, 0);
position += nextPosition * t;
}
return position;
}
protected float getAvailableTranslationX() {
return (float) AndroidUtilities.displaySize.x;
}
protected boolean canScroll(MotionEvent e) {
return true;
}

View file

@ -768,7 +768,7 @@ public class SpoilerEffect extends Drawable {
layout = StaticLayout.Builder.obtain(sb, 0, sb.length(), textLayout.getPaint(), textLayout.getWidth())
.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY)
.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_NONE)
.setAlignment(Layout.Alignment.ALIGN_NORMAL)
.setAlignment(textLayout.getAlignment())
.setLineSpacing(textLayout.getSpacingAdd(), textLayout.getSpacingMultiplier())
.build();
} else {

View file

@ -5589,7 +5589,9 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
notificationsLocker.unlock();
authHintCellAnimating = false;
authHintCellProgress = visible ? 1f : 0;
fragmentView.requestLayout();
if (fragmentView != null) {
fragmentView.requestLayout();
}
viewPages[0].listView.requestLayout();
viewPages[0].listView.setTranslationY(0);
if (!visible) {

View file

@ -6359,8 +6359,12 @@ public class LaunchActivity extends BasePermissionsActivity implements INavigati
}
actionBarLayout.animateThemedValues(theme, accentId, nightTheme, instant, calcInBackgroundEnd);
if (AndroidUtilities.isTablet()) {
layersActionBarLayout.animateThemedValues(theme, accentId, nightTheme, instant);
rightActionBarLayout.animateThemedValues(theme, accentId, nightTheme, instant);
if (layersActionBarLayout != null) {
layersActionBarLayout.animateThemedValues(theme, accentId, nightTheme, instant);
}
if (rightActionBarLayout != null) {
rightActionBarLayout.animateThemedValues(theme, accentId, nightTheme, instant);
}
}
} else if (id == NotificationCenter.notificationsCountUpdated) {
if (sideMenu != null) {

View file

@ -244,7 +244,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
private PaymentInfoCell paymentInfoCell;
private TextDetailSettingsCell[] detailSettingsCell = new TextDetailSettingsCell[7];
private boolean isAcceptTermsChecked;
private float shiftDp = -4.5f;
private TLRPC.account_Password currentPassword;
private boolean waitingForEmail;
@ -1743,7 +1743,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
inputFields[a].setImeOptions(EditorInfo.IME_ACTION_DONE | EditorInfo.IME_FLAG_NO_EXTRACT_UI);
switch (a) {
case FIELD_SAVEDCARD:
inputFields[a].setText(savedCredentialsCard.title);
inputFields[a].setText(savedCredentialsCard == null ? "" : savedCredentialsCard.title);
break;
case FIELD_SAVEDPASSWORD:
inputFields[a].setHint(LocaleController.getString("LoginPassword", R.string.LoginPassword));
@ -2246,7 +2246,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
if (currentStep == STEP_CHECKOUT) {
recurrentAccepted = isAcceptTermsChecked = !isCheckoutPreview;
recurrentAccepted = !isCheckoutPreview;
bottomLayout = new BottomFrameLayout(context, paymentForm);
if (Build.VERSION.SDK_INT >= 21) {
View selectorView = new View(context);
@ -2255,8 +2255,10 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
frameLayout.addView(bottomLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM));
bottomLayout.setOnClickListener(v -> {
if (paymentForm.invoice.recurring && !recurrentAccepted) {
AndroidUtilities.shakeViewSpring(recurrentAcceptCell.getTextView(), 4.5f);
if (recurrentAcceptCell != null && !recurrentAccepted) {
shiftDp = -shiftDp;
AndroidUtilities.shakeViewSpring(recurrentAcceptCell.getTextView(), shiftDp);
AndroidUtilities.shakeViewSpring(recurrentAcceptCell.getCheckBox(), shiftDp);
try {
recurrentAcceptCell.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignored) {}
@ -2340,8 +2342,8 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
progressViewButton.setColors(color & 0x2fffffff, color);
bottomLayout.addView(progressViewButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
bottomLayout.setChecked(!paymentForm.invoice.recurring || isAcceptTermsChecked);
payTextView.setAlpha(paymentForm.invoice.recurring && !isAcceptTermsChecked ? 0.8f : 1f);
bottomLayout.setChecked(recurrentAccepted, false);
payTextView.setAlpha(!recurrentAccepted ? 0.8f : 1f);
doneItem.setEnabled(false);
doneItem.getContentView().setVisibility(View.INVISIBLE);
@ -2407,9 +2409,10 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
}
});
recurrentAcceptCell = null;
if (paymentForm.invoice.terms_url != null) {
recurrentAcceptCell = new RecurrentPaymentsAcceptCell(context, getResourceProvider());
recurrentAcceptCell.setChecked(paymentForm.invoice.recurring && isAcceptTermsChecked);
recurrentAcceptCell.setChecked(recurrentAccepted);
String str = LocaleController.getString(R.string.PaymentCheckoutAcceptRecurrent);
SpannableStringBuilder sb = new SpannableStringBuilder(str);
int firstIndex = str.indexOf('*'), lastIndex = str.lastIndexOf('*');
@ -2437,7 +2440,7 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
recurrentAccepted = !recurrentAccepted;
recurrentAcceptCell.setChecked(recurrentAccepted);
bottomLayout.setChecked(recurrentAccepted);
bottomLayout.setChecked(recurrentAccepted, true);
});
frameLayout.addView(recurrentAcceptCell, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM, 0, 0, 0, 48));
}
@ -4497,8 +4500,6 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
public BottomFrameLayout(@NonNull Context context, TLRPC.TL_payments_paymentForm paymentForm) {
super(context);
progress = paymentForm.invoice.recurring && !isAcceptTermsChecked ? 0f : 1f;
setWillNotDraw(false);
}
@ -4511,31 +4512,39 @@ public class PaymentFormActivity extends BaseFragment implements NotificationCen
canvas.drawCircle(LocaleController.isRTL ? getWidth() - AndroidUtilities.dp(28) : AndroidUtilities.dp(28), -AndroidUtilities.dp(28), Math.max(getWidth(), getHeight()) * progress, paint);
}
public void setChecked(boolean checked) {
public void setChecked(boolean checked, boolean animated) {
if (springAnimation != null) {
springAnimation.cancel();
}
float to = checked ? 1f : 0f;
if (progress == to) {
return;
}
springAnimation = new SpringAnimation(new FloatValueHolder(progress * 100f))
.setSpring(new SpringForce(to * 100f)
.setStiffness(checked ? 500f : 650f)
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY));
springAnimation.addUpdateListener((animation, value, velocity) -> {
progress = value / 100f;
if (animated) {
if (progress == to) {
return;
}
springAnimation = new SpringAnimation(new FloatValueHolder(progress * 100f))
.setSpring(new SpringForce(to * 100f)
.setStiffness(checked ? 500f : 650f)
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY));
springAnimation.addUpdateListener((animation, value, velocity) -> {
progress = value / 100f;
if (payTextView != null) {
payTextView.setAlpha(0.8f + 0.2f * progress);
}
invalidate();
});
springAnimation.addEndListener((animation, canceled1, value, velocity) -> {
if (animation == springAnimation) {
springAnimation = null;
}
});
springAnimation.start();
} else {
progress = to;
if (payTextView != null) {
payTextView.setAlpha(0.8f + 0.2f * progress);
}
invalidate();
});
springAnimation.addEndListener((animation, canceled1, value, velocity) -> {
if (animation == springAnimation) {
springAnimation = null;
}
});
springAnimation.start();
}
}
}
}

View file

@ -3,6 +3,7 @@ package org.telegram.ui;
import static android.content.DialogInterface.BUTTON_NEGATIVE;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.dpf2;
import static org.telegram.messenger.AndroidUtilities.getPath;
import static org.telegram.ui.Components.Premium.LimitReachedBottomSheet.TYPE_BOOSTS_FOR_COLOR;
import static org.telegram.ui.Components.Premium.LimitReachedBottomSheet.TYPE_BOOSTS_FOR_USERS;
@ -16,7 +17,9 @@ import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.icu.util.Measure;
import android.os.Build;
import android.os.Bundle;
import android.text.SpannableStringBuilder;
@ -47,6 +50,7 @@ import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.AlertDialog;
@ -84,7 +88,7 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
private RecyclerView.Adapter listAdapter;
private FrameLayout buttonContainer;
private ButtonWithCounterView button;
private PeerColorPicker peerColorPicker;
private PeerColorGrid peerColorPicker;
private int selectedColor;
private long selectedEmoji;
@ -98,6 +102,7 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
int infoRow;
int iconRow;
int info2Row;
int buttonRow;
int rowCount;
@ -105,6 +110,7 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
private static final int VIEW_TYPE_COLOR_PICKER = 1;
private static final int VIEW_TYPE_INFO = 2;
private static final int VIEW_TYPE_ICON = 3;
private static final int VIEW_TYPE_BUTTONPAD = 5;
public PeerColorActivity(long dialogId) {
super();
@ -183,13 +189,25 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
FrameLayout frameLayout = new FrameLayout(context);
listView = new RecyclerListView(context);
((DefaultItemAnimator)listView.getItemAnimator()).setSupportsChangeAnimations(false);
listView = new RecyclerListView(context) {
@Override
protected void onMeasure(int widthSpec, int heightSpec) {
super.onMeasure(widthSpec, heightSpec);
updateButtonY();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
updateButtonY();
}
};
((DefaultItemAnimator) listView.getItemAnimator()).setSupportsChangeAnimations(false);
listView.setLayoutManager(new LinearLayoutManager(context));
listView.setAdapter(listAdapter = new RecyclerListView.SelectionAdapter() {
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
return holder.getItemViewType() == VIEW_TYPE_COLOR_PICKER || holder.getItemViewType() == VIEW_TYPE_ICON;
return holder.getItemViewType() == VIEW_TYPE_ICON;
}
@NonNull
@ -211,18 +229,12 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
view = cell;
break;
case VIEW_TYPE_COLOR_PICKER:
PeerColorPicker colorPicker = peerColorPicker = new PeerColorPicker(context, currentAccount, getResourceProvider());
colorPicker.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite, getResourceProvider()));
PeerColorGrid colorPicker = peerColorPicker = new PeerColorGrid(context, currentAccount);
colorPicker.setBackgroundColor(getThemedColor(Theme.key_windowBackgroundWhite));
colorPicker.setSelected(selectedColor);
colorPicker.layoutManager.scrollToPositionWithOffset(colorPicker.selectedPosition, AndroidUtilities.displaySize.x / 2);
colorPicker.setOnItemClickListener((item, position) -> {
selectedColor = colorPicker.toColorId(position);
colorPicker.setSelectedPosition(position);
if (item.getLeft() - colorPicker.getPaddingLeft() < AndroidUtilities.dp(24)) {
colorPicker.smoothScrollBy(position == 0 ? Math.max(-(item.getLeft() - colorPicker.getPaddingLeft()), -AndroidUtilities.dp(64)) : -AndroidUtilities.dp(64), 0);
} else if (item.getRight() - colorPicker.getPaddingLeft() > AndroidUtilities.displaySize.x - colorPicker.getPaddingLeft() - colorPicker.getPaddingRight() - AndroidUtilities.dp(24)) {
colorPicker.smoothScrollBy(position == colorPicker.adapter.getItemCount() - 1 ? Math.min(AndroidUtilities.displaySize.x - item.getRight() - colorPicker.getPaddingRight(), AndroidUtilities.dp(64)) : AndroidUtilities.dp(64), 0);
}
colorPicker.setOnColorClick(colorId -> {
selectedColor = colorId;
colorPicker.setSelected(colorId);
updateMessages();
if (setReplyIconCell != null) {
setReplyIconCell.invalidate();
@ -230,6 +242,14 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
});
view = colorPicker;
break;
case VIEW_TYPE_BUTTONPAD:
view = new View(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp(14 + 48 + 14), MeasureSpec.EXACTLY));
}
};
break;
case VIEW_TYPE_ICON:
SetReplyIconCell setcell = setReplyIconCell = new SetReplyIconCell(context);
setcell.update(false);
@ -285,6 +305,9 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
if (position == iconRow) {
return VIEW_TYPE_ICON;
}
if (position == buttonRow) {
return VIEW_TYPE_BUTTONPAD;
}
if (position == getItemCount() - 1) {
return 4;
}
@ -314,6 +337,12 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
buttonContainer.addView(button, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48));
frameLayout.addView(buttonContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
updateButtonY();
}
});
fragmentView = contentView = frameLayout;
@ -323,6 +352,29 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
return contentView;
}
private void updateButtonY() {
if (buttonContainer == null) {
return;
}
final int lastPosition = listAdapter.getItemCount() - 1;
boolean foundLastPosition = false;
int maxTop = 0;
for (int i = 0; i < listView.getChildCount(); ++i) {
View child = listView.getChildAt(i);
final int position = listView.getChildAdapterPosition(child);
if (position != RecyclerListView.NO_POSITION && position <= lastPosition) {
maxTop = Math.max(maxTop, child.getTop());
if (position == lastPosition) {
foundLastPosition = true;
}
}
}
if (!foundLastPosition) {
maxTop = listView.getMeasuredHeight();
}
buttonContainer.setTranslationY(Math.max(0, maxTop - (listView.getMeasuredHeight() - dp(14 + 48 + 14))));
}
private void showBoostLimit(boolean error) {
getMessagesController().getBoostsController().getBoostsStats(dialogId, boostsStatus -> {
if (error || boostsStatus.level < getMessagesController().channelColorLevelMin) {
@ -688,9 +740,9 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
rowCount = 0;
previewRow = rowCount++;
colorPickerRow = rowCount++;
infoRow = rowCount++;
iconRow = rowCount++;
info2Row = rowCount++;
infoRow = rowCount++;
buttonRow = rowCount++;
}
@Override
@ -1136,6 +1188,276 @@ public class PeerColorActivity extends BaseFragment implements NotificationCente
}
}
public static class PeerColorGrid extends View {
public class ColorButton {
private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint paint1 = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint paint3 = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path circlePath = new Path();
private final Path color2Path = new Path();
private boolean hasColor2, hasColor3;
private final ButtonBounce bounce = new ButtonBounce(PeerColorGrid.this);
public ColorButton() {
backgroundPaint.setStyle(Paint.Style.STROKE);
}
public void setBackgroundColor(int backgroundColor) {
backgroundPaint.setColor(backgroundColor);
}
public void set(int color) {
hasColor2 = hasColor3 = false;
paint1.setColor(color);
}
public void set(int color1, int color2) {
hasColor2 = true;
hasColor3 = false;
paint1.setColor(color1);
paint2.setColor(color2);
}
public void set(MessagesController.PeerColor color) {
if (color == null) {
return;
}
if (Theme.isCurrentThemeDark() && color.hasColor2() && !color.hasColor3()) {
paint1.setColor(color.getColor2());
paint2.setColor(color.getColor1());
} else {
paint1.setColor(color.getColor1());
paint2.setColor(color.getColor2());
}
paint3.setColor(color.getColor3());
hasColor2 = color.hasColor2();
hasColor3 = color.hasColor3();
}
private boolean selected;
private final AnimatedFloat selectedT = new AnimatedFloat(PeerColorGrid.this, 0, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
public void setSelected(boolean selected, boolean animated) {
this.selected = selected;
if (!animated) {
selectedT.set(selected, true);
}
invalidate();
}
private static final int VIEW_SIZE_DP = 56;
private static final int CIRCLE_RADIUS_DP = 20;
public int id;
private final RectF bounds = new RectF();
public final RectF clickBounds = new RectF();
public void layout(int id, RectF bounds) {
this.id = id;
this.bounds.set(bounds);
}
public void layoutClickBounds(RectF bounds) {
this.clickBounds.set(bounds);
}
protected void draw(Canvas canvas) {
canvas.save();
final float s = bounce.getScale(.05f);
canvas.scale(s, s, bounds.centerX(), bounds.centerY());
canvas.save();
circlePath.rewind();
circlePath.addCircle(bounds.centerX(), bounds.centerY(), Math.min(bounds.height() / 2f, bounds.width() / 2f), Path.Direction.CW);
canvas.clipPath(circlePath);
canvas.drawPaint(paint1);
if (hasColor2) {
color2Path.rewind();
color2Path.moveTo(bounds.right, bounds.top);
color2Path.lineTo(bounds.right, bounds.bottom);
color2Path.lineTo(bounds.left, bounds.bottom);
color2Path.close();
canvas.drawPath(color2Path, paint2);
}
canvas.restore();
if (hasColor3) {
canvas.save();
final float color3Size = (bounds.width() * .315f);
AndroidUtilities.rectTmp.set(
bounds.centerX() - color3Size / 2f,
bounds.centerY() - color3Size / 2f,
bounds.centerX() + color3Size / 2f,
bounds.centerY() + color3Size / 2f
);
canvas.rotate(45f, bounds.centerX(), bounds.centerY());
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(2.33f), dp(2.33f), paint3);
canvas.restore();
}
final float selectT = selectedT.set(selected);
if (selectT > 0) {
backgroundPaint.setStrokeWidth(dpf2(2));
canvas.drawCircle(
bounds.centerX(), bounds.centerY(),
Math.min(bounds.height() / 2f, bounds.width() / 2f) + backgroundPaint.getStrokeWidth() * AndroidUtilities.lerp(.5f, -2f, selectT),
backgroundPaint
);
}
canvas.restore();
}
private boolean pressed;
public boolean isPressed() {
return pressed;
}
public void setPressed(boolean pressed) {
bounce.setPressed(this.pressed = pressed);
}
}
private int currentAccount;
private ColorButton[] buttons;
public PeerColorGrid(Context context, int currentAccount) {
super(context);
this.currentAccount = currentAccount;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int width = MeasureSpec.getSize(widthMeasureSpec);
final MessagesController.PeerColors peerColors = MessagesController.getInstance(currentAccount).peerColors;
final int colorsCount = 7 + (peerColors == null ? 0 : peerColors.colors.size());
final int columns = 7;
final float iconSize = Math.min(dp(38 + 16), width / (columns + (columns + 1) * .28947f));
final float horizontalSeparator = iconSize * .28947f;
final float verticalSeparator = iconSize * .315789474f;
final int rows = colorsCount / columns;
final int height = (int) (iconSize * rows + verticalSeparator * (rows + 1));
setMeasuredDimension(width, height);
if (buttons == null || buttons.length != colorsCount) {
buttons = new ColorButton[colorsCount];
for (int i = 0; i < colorsCount; ++i) {
buttons[i] = new ColorButton();
buttons[i].setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
if (i < 7) {
buttons[i].set(Theme.getColor(Theme.keys_avatar_nameInMessage[i]));
} else if (peerColors != null) {
buttons[i].set(peerColors.getColor(i));
}
}
}
final float itemsWidth = iconSize * columns + horizontalSeparator * (columns + 1);
final float startX = (width - itemsWidth) / 2f + horizontalSeparator;
if (buttons != null) {
float x = startX, y = verticalSeparator;
for (int i = 0; i < buttons.length; ++i) {
AndroidUtilities.rectTmp.set(x, y, x + iconSize, y + iconSize);
buttons[i].layout(i, AndroidUtilities.rectTmp);
AndroidUtilities.rectTmp.inset(-horizontalSeparator / 2, -verticalSeparator / 2);
buttons[i].layoutClickBounds(AndroidUtilities.rectTmp);
buttons[i].setSelected(i == selectedColorId, false);
if (i % columns == (columns - 1)) {
x = startX;
y += iconSize + verticalSeparator;
} else {
x += iconSize + horizontalSeparator;
}
}
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (buttons != null) {
for (int i = 0; i < buttons.length; ++i) {
buttons[i].draw(canvas);
}
}
canvas.drawRect(dp(21), getMeasuredHeight() - 1, getMeasuredWidth() - dp(21), getMeasuredHeight(), Theme.dividerPaint);
}
private int selectedColorId = 0;
public void setSelected(int colorId) {
selectedColorId = colorId;
if (buttons != null) {
for (int i = 0; i < buttons.length; ++i) {
buttons[i].setSelected(i == colorId, true);
}
}
}
public int getColorId() {
return selectedColorId;
}
private Utilities.Callback<Integer> onColorClick;
public void setOnColorClick(Utilities.Callback<Integer> onColorClick) {
this.onColorClick = onColorClick;
}
private ColorButton pressedButton;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
ColorButton button = null;
if (buttons != null) {
for (int i = 0; i < buttons.length; ++i) {
if (buttons[i].clickBounds.contains(event.getX(), event.getY())) {
button = buttons[i];
break;
}
}
}
if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressedButton = button;
if (button != null) {
button.setPressed(true);
}
if (getParent() != null) {
getParent().requestDisallowInterceptTouchEvent(true);
}
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
if (pressedButton != button) {
if (pressedButton != null) {
pressedButton.setPressed(false);
}
if (button != null) {
button.setPressed(true);
}
if (pressedButton != null && button != null) {
if (onColorClick != null) {
onColorClick.run(button.id);
}
}
pressedButton = button;
}
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (event.getAction() == MotionEvent.ACTION_UP && pressedButton != null) {
if (onColorClick != null) {
onColorClick.run(pressedButton.id);
}
}
if (buttons != null) {
for (int i = 0; i < buttons.length; ++i) {
buttons[i].setPressed(false);
}
}
pressedButton = null;
}
return true;
}
}
public static class PeerColorDrawable extends Drawable {
public static PeerColorDrawable from(int currentAccount, int colorId) {

View file

@ -7672,7 +7672,9 @@ public class PhotoViewer implements NotificationCenter.NotificationCenterDelegat
}
if (usedSurfaceView) {
videoPlayer.player.setVideoTextureView(null);
if (videoPlayer.player != null) {
videoPlayer.player.setVideoTextureView(null);
}
videoPlayer.setSurfaceView(videoSurfaceView);
videoSurfaceView.setVisibility(View.INVISIBLE);
waitingForFirstTextureUpload = 2;

View file

@ -927,7 +927,7 @@ public class PremiumPreviewFragment extends BaseFragment implements Notification
if (isPremium) {
resId = isYearTier ? R.string.UpgradePremiumPerYear : R.string.UpgradePremiumPerMonth;
} else {
price = tier.getFormattedPricePerMonthRounded();
price = tier.getFormattedPricePerMonth();
resId = R.string.SubscribeToPremium;
}
return LocaleController.formatString(resId, price);
@ -1834,14 +1834,6 @@ public class PremiumPreviewFragment extends BaseFragment implements Notification
return googlePlayProductDetails == null ? "" : BillingController.getInstance().formatCurrency(getPricePerYear(), getCurrency(), 6);
}
public String getFormattedPricePerMonthRounded() {
if (BuildVars.useInvoiceBilling() || subscriptionOption.store_product == null) {
return BillingController.getInstance().formatCurrency(getPricePerMonth(), getCurrency(), BillingController.getInstance().getCurrencyExp(getCurrency()), true);
}
return googlePlayProductDetails == null ? "" : BillingController.getInstance().formatCurrency(getPricePerMonth(), getCurrency(), 6, true);
}
public String getFormattedPricePerMonth() {
if (BuildVars.useInvoiceBilling() || subscriptionOption.store_product == null) {
return BillingController.getInstance().formatCurrency(getPricePerMonth(), getCurrency());

View file

@ -1942,8 +1942,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
Bundle args = new Bundle();
args.putLong("user_id", user.id);
args.putBoolean("addContact", true);
presentFragment(new ContactAddActivity(args, resourcesProvider));
wentToAddContacts = true;
openAddToContact(user, args);
} else if (id == share_contact) {
Bundle args = new Bundle();
args.putBoolean("onlySelect", true);
@ -1957,7 +1956,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
Bundle args = new Bundle();
args.putLong("user_id", userId);
presentFragment(new ContactAddActivity(args, resourcesProvider));
wentToAddContacts = true;
} else if (id == delete_contact) {
final TLRPC.User user = getMessagesController().getUser(userId);
if (user == null || getParentActivity() == null) {
@ -3163,8 +3161,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
args.putString("phone", vcardPhone);
args.putString("first_name_card", vcardFirstName);
args.putString("last_name_card", vcardLastName);
presentFragment(new ContactAddActivity(args, resourcesProvider));
wentToAddContacts = true;
openAddToContact(user, args);
} else if (position == reportReactionRow) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity(), resourcesProvider);
builder.setTitle(LocaleController.getString("ReportReaction", R.string.ReportReaction));
@ -11155,8 +11152,6 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
}
}
private boolean wentToAddContacts;
@Override
public void onBecomeFullyVisible() {
super.onBecomeFullyVisible();
@ -11170,11 +11165,48 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
combinedDrawable.setIconSize(AndroidUtilities.dp(56), AndroidUtilities.dp(56));
writeButton.setBackground(combinedDrawable);
} catch (Exception e) {}
}
if (wentToAddContacts) {
updateListAnimated(false);
wentToAddContacts = false;
}
@SuppressLint("NotifyDataSetChanged")
private void openAddToContact(TLRPC.User user, Bundle args) {
ContactAddActivity contactAddActivity = new ContactAddActivity(args, resourcesProvider);
contactAddActivity.setDelegate(() -> {
int currentAddToContactsRow = addToContactsRow;
if (currentAddToContactsRow >= 0) {
if (sharedMediaRow == -1) {
updateRowsIds();
listAdapter.notifyDataSetChanged();
} else {
updateListAnimated(false);
}
}
if (sharedMediaRow == -1) {
if (isInLandscapeMode || AndroidUtilities.isTablet()) {
listView.setPadding(0, AndroidUtilities.dp(88), 0, 0);
expandAnimator.cancel();
expandAnimatorValues[0] = 1f;
expandAnimatorValues[1] = 0f;
setAvatarExpandProgress(1f);
extraHeight = AndroidUtilities.dp(88);
} else {
final int actionBarHeight = ActionBar.getCurrentActionBarHeight() + (actionBar.getOccupyStatusBar() ? AndroidUtilities.statusBarHeight : 0);
int ws = View.MeasureSpec.makeMeasureSpec(listView.getMeasuredWidth(), View.MeasureSpec.EXACTLY);
int hs = View.MeasureSpec.makeMeasureSpec(listView.getMeasuredHeight(), View.MeasureSpec.UNSPECIFIED);
int contentHeight = 0;
for (int i = 0; i < listAdapter.getItemCount(); i++) {
RecyclerView.ViewHolder holder = listAdapter.createViewHolder(null, listAdapter.getItemViewType(i));
listAdapter.onBindViewHolder(holder, i);
holder.itemView.measure(ws, hs);
contentHeight += holder.itemView.getMeasuredHeight();
}
int paddingBottom = Math.max(0, fragmentView.getMeasuredHeight() - (contentHeight + AndroidUtilities.dp(88) + actionBarHeight));
listView.setPadding(0, listView.getPaddingTop(), 0, paddingBottom);
}
}
undoView.showWithAction(dialogId, UndoView.ACTION_CONTACT_ADDED, user);
});
presentFragment(contactAddActivity);
}
private boolean isQrNeedVisible() {

View file

@ -694,7 +694,7 @@ public class StatisticActivity extends BaseFragment implements NotificationCente
});
avatarContainer.setTitleColors(Theme.getColor(Theme.key_player_actionBarTitle), Theme.getColor(Theme.key_player_actionBarSubtitle));
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), false);
actionBar.setItemsColor(Theme.getColor(Theme.key_player_actionBarTitle), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), false);
actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));

View file

@ -2551,6 +2551,17 @@ public class PeerStoriesView extends SizeNotifierFrameLayout implements Notifica
avatarDrawable.setInfo(chat);
headerView.backupImageView.getImageReceiver().setForUserOrChat(chat, avatarDrawable);
headerView.titleView.setText(chat.title);
if (chat != null && chat.verified) {
Drawable verifyDrawable = ContextCompat.getDrawable(getContext(), R.drawable.verified_profile).mutate();
verifyDrawable.setAlpha(255);
CombinedDrawable drawable = new CombinedDrawable(verifyDrawable, null);
drawable.setFullsize(true);
drawable.setCustomSize(AndroidUtilities.dp(16), AndroidUtilities.dp(16));
headerView.titleView.setRightDrawable(drawable);
} else {
headerView.titleView.setRightDrawable(null);
}
}
if (isActive && (isSelf || isChannel)) {
storiesController.pollViewsForSelfStories(dialogId, true);

View file

@ -639,7 +639,7 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
replyImageSz = AndroidUtilities.lerp(AndroidUtilities.dp(35), sz, progressX);
messageView.replyImageReceiver.setImageCoords(
AndroidUtilities.lerp(replyX, replySelectorRect.left + AndroidUtilities.dp(8), progressX),
AndroidUtilities.lerp(replyY, replySelectorRect.top + AndroidUtilities.dp(5), progressX),
AndroidUtilities.lerp(replyY, replySelectorRect.top + AndroidUtilities.dp((messageView.isReplyQuote && messageView.replyTextLayout != null && messageView.replyTextLayout.getLineCount() <= 1 ? 2 : 0) + 5), progressX),
replyImageSz, replyImageSz
);
messageView.replyImageReceiver.draw(canvas);
@ -690,8 +690,17 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
if (messageView.replyTextLayout != null) {
canvas.save();
final float offsetX2 = (messageView.needReplyImage && (!messageView.isReplyQuote || messageView.replyTextRTL) ? replyImageSz + AndroidUtilities.dp(3) : 0) + AndroidUtilities.dp(messageView.isReplyQuote && messageView.needReplyImage ? -2 : 0);
canvas.translate(replyMessageX + offsetX2, replyY + AndroidUtilities.lerp(AndroidUtilities.dp(19), Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(4) + offsetY, progressX));
float left = replyToMessageX;
if (messageView.isReplyQuote && messageView.needReplyImage) {
left -= AndroidUtilities.dp(2);
}
if (messageView.needReplyImage && (!messageView.isReplyQuote || messageView.replyTextRTL)) {
left += replyImageSz + AndroidUtilities.dp(3);
}
if (messageView.replyTextRTL && messageView.replyTextOffset > 0) {
left = replySelectorRect.right - AndroidUtilities.dp(8) - messageView.replyTextLayout.getWidth() - offset * progressX;
}
canvas.translate(AndroidUtilities.lerp(fromReplayX - messageView.replyTextOffset, left, progressX), replyY + AndroidUtilities.lerp(AndroidUtilities.dp(19), Theme.chat_replyNamePaint.getTextSize() + AndroidUtilities.dp(4) + offsetY, progressX));
canvas.save();
SpoilerEffect.clipOutCanvas(canvas, messageView.replySpoilers);

View file

@ -1266,6 +1266,7 @@
<string name="DeleteForUser">Delete for %1$s</string>
<string name="DeleteForAll">Delete for all members</string>
<string name="TextCopied">Text copied to clipboard</string>
<string name="CodeCopied">Code copied to clipboard</string>
<string name="HoldToAudioOnly">Hold to record audio.</string>
<string name="HoldToAudio">Hold to record audio. Tap to switch to video.</string>
<string name="HoldToVideo">Hold to record video. Tap to switch to audio.</string>
@ -4717,6 +4718,12 @@
<string name="GiftMonths_few">%1$d-months</string>
<string name="GiftMonths_many">%1$d-months</string>
<string name="GiftMonths_other">%1$d-months</string>
<string name="PrepaidGiveawayMonths_zero">%1$d-month</string>
<string name="PrepaidGiveawayMonths_one">%1$d-month</string>
<string name="PrepaidGiveawayMonths_two">%1$d-month</string>
<string name="PrepaidGiveawayMonths_few">%1$d-month</string>
<string name="PrepaidGiveawayMonths_many">%1$d-month</string>
<string name="PrepaidGiveawayMonths_other">%1$d-month</string>
<string name="BoldMonths_one">**%1$d** month</string>
<string name="BoldMonths_two">**%1$d** months</string>
<string name="BoldMonths_few">**%1$d** months</string>
@ -5879,8 +5886,6 @@
<string name="GiftTelegramPremiumTitle">Gift Telegram Premium</string>
<string name="GiftTelegramPremiumDescription">Let **%1$s** enjoy exclusive features of Telegram with **Telegram Premium**.</string>
<string name="TelegramPremium">Telegram Premium</string>
<string name="SubscriptionsCount">%1$s subscriptions</string>
<string name="TelegramPremiumCount">%1$d Telegram Premium</string>
<string name="TelegramPremiumSubtitle">Go **beyond the limits**, get exclusive features and support us by subscribing to **Telegram Premium**.</string>
<string name="TelegramPremiumSubscribedTitle">You are all set!</string>
<string name="TelegramPremiumSubscribedSubtitle">Thank you for subscribing to **Telegram Premium**.\nHeres what is now unlocked.</string>
@ -7165,7 +7170,8 @@
<string name="AllViewers">All viewers</string>
<string name="SortByReactions">Reactions First</string>
<string name="SortByTime">Newest First</string>
<string name="StoryViewsSortDescription">Choose the order for the list of viewers.</string>
<string name="StoryViewsSortDescription">Choose the order for the
list of viewers.</string>
<string name="NoContactsViewed">None of your contacts viewed this story.</string>
<string name="Viewers">Viewers</string>
<string name="StealthModeConfirmTitle">You are in Stealth Mode now</string>
@ -7227,7 +7233,7 @@
<string name="BoostingCongratulations">Congratulations!</string>
<string name="BoostingReceivedGiftFrom">You\'ve received a gift\nfrom **%s**.</string>
<string name="BoostingReceivedGiftNoName">You\'ve received a gift.</string>
<string name="BoostingReceivedGiftDuration">Your gift is a **Telegram Premium**\n subscription for %s.</string>
<string name="BoostingReceivedGiftDuration">Your gift is a **Telegram Premium**\nsubscription for %s.</string>
<string name="BoostingUnclaimedPrize">Unclaimed Prize</string>
<string name="BoostingYouHaveUnclaimedPrize">You have an unclaimed prize from a giveaway by **%s**.</string>
<string name="BoostingUnclaimedPrizeDuration">This prize is a **Telegram Premium** subscription for %s.</string>
@ -7236,12 +7242,22 @@
<string name="BoostingReceivedGiftOpenBtn">Open Gift Link</string>
<string name="BoostingSaveRecipients">Save Recipients</string>
<string name="BoostingGiveawayJustStarted">%s just started a giveaway of Telegram Premium subscriptions to its followers.</string>
<string name="BoostingSubscriptionsCount_zero">%d boost</string>
<string name="BoostingSubscriptionsCount_one">%d boost</string>
<string name="BoostingSubscriptionsCount_two">%d boosts</string>
<string name="BoostingSubscriptionsCount_few">%d boosts</string>
<string name="BoostingSubscriptionsCount_many">%d boosts</string>
<string name="BoostingSubscriptionsCount_other">%d boosts</string>
<string name="BoostingBoostsCountTitle_zero">%d boost</string>
<string name="BoostingBoostsCountTitle_one">%d boost</string>
<string name="BoostingBoostsCountTitle_two">%d boosts</string>
<string name="BoostingBoostsCountTitle_few">%d boosts</string>
<string name="BoostingBoostsCountTitle_many">%d boosts</string>
<string name="BoostingBoostsCountTitle_other">%d boosts</string>
<string name="BoostingSubscriptionsCountPlural_one">%2$s subscription</string>
<string name="BoostingSubscriptionsCountPlural_two">%2$s subscriptions</string>
<string name="BoostingSubscriptionsCountPlural_few">%2$s subscriptions</string>
<string name="BoostingSubscriptionsCountPlural_many">%2$s subscriptions</string>
<string name="BoostingSubscriptionsCountPlural_other">%2$s subscriptions</string>
<string name="BoostingTelegramPremiumCountPlural_one">%1$d Telegram Premium</string>
<string name="BoostingTelegramPremiumCountPlural_two">%1$d Telegram Premium</string>
<string name="BoostingTelegramPremiumCountPlural_few">%1$d Telegram Premium</string>
<string name="BoostingTelegramPremiumCountPlural_many">%1$d Telegram Premium</string>
<string name="BoostingTelegramPremiumCountPlural_other">%1$d Telegram Premium</string>
<string name="BoostingGetBoostsViaGifts">Get Boosts via Gifts</string>
<string name="BoostingUseLink">Use Link</string>
<string name="BoostingShareThisLink">Share this link with your subsсribers to get more boosts.</string>
@ -7263,7 +7279,7 @@
<string name="BoostingGiftsCount_many">%1$d Gifts</string>
<string name="BoostingGiftsCount_other">%1$d Gifts</string>
<string name="BoostingBoostsCount_zero">%1$d Boosts</string>
<string name="BoostingBoostsCount_one">%1$d Boosts</string>
<string name="BoostingBoostsCount_one">%1$d Boost</string>
<string name="BoostingBoostsCount_two">%1$d Boosts</string>
<string name="BoostingBoostsCount_few">%1$d Boosts</string>
<string name="BoostingBoostsCount_many">%1$d Boosts</string>
@ -7312,7 +7328,11 @@
<string name="BoostingDate">Date</string>
<string name="BoostingPreparedGiveaways">Prepaid giveaways</string>
<string name="BoostingPreparedGiveawayOne">Prepaid giveaway</string>
<string name="BoostingPreparedGiveawaySubscriptions">%1$d subscriptions for %2$s</string>
<string name="BoostingPreparedGiveawaySubscriptionsPlural_one">%1$d subscription for %2$s</string>
<string name="BoostingPreparedGiveawaySubscriptionsPlural_two">%1$d subscriptions for %2$s</string>
<string name="BoostingPreparedGiveawaySubscriptionsPlural_few">%1$d subscriptions for %2$s</string>
<string name="BoostingPreparedGiveawaySubscriptionsPlural_many">%1$d subscriptions for %2$s</string>
<string name="BoostingPreparedGiveawaySubscriptionsPlural_other">%1$d subscriptions for %2$s</string>
<string name="BoostingSelectRecipients">select recipients</string>
<string name="BoostingFromAllCountries">from all countries</string>
<string name="BoostingFromAllCountries1">from %1$s</string>
@ -7325,7 +7345,7 @@
<string name="BoostingFromCountriesCount_many">from %1$d countries</string>
<string name="BoostingFromCountriesCount_other">from %1$d countries</string>
<string name="BoostingSendLinkToFriends">You can also **send this link** to a friend as a gift.</string>
<string name="BoostingSendLinkToAnyone">You can also **send this link** to a anyone as a gift.</string>
<string name="BoostingSendLinkToAnyone">You can also **send this link** to anyone as a gift.</string>
<string name="BoostingUsedLinkDate">This link was used on %s.</string>
<string name="BoostingQuantityPrizes">Quantity of prizes</string>
<string name="BoostingChooseHowMany">Choose how many Premium subscriptions to give away and boosts to receive.</string>
@ -7355,21 +7375,41 @@
<string name="BoostingGiveawayHowItWorksSubText_few">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s**.</string>
<string name="BoostingGiveawayHowItWorksSubText_many">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s**.</string>
<string name="BoostingGiveawayHowItWorksSubText_other">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral_one">On **%2$s**, Telegram will automatically select **%3$s** random user that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral_two">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral_few">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral_many">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral_other">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral1_one">On **%2$s**, Telegram will automatically select **%3$s** random user that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral1_two">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral1_few">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral1_many">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral1_other">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd1_one">On **%2$s**, Telegram automatically selected **%3$s** random user that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd1_two">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd1_few">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd1_many">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd1_other">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral2_one">and **%1$d** other listed channel</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral2_two">and **%1$d** other listed channels</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral2_few">and **%1$d** other listed channels</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral2_many">and **%1$d** other listed channels</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveral2_other">and **%1$d** other listed channels</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral1_one">On **%2$s**, Telegram will automatically select **%3$s** random user that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral1_two">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral1_few">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral1_many">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral1_other">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd1_one">On **%2$s**, Telegram automatically selected **%3$s** random user that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd1_two">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd1_few">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd1_many">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd1_other">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** %5$s.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral2_one">and **%1$d** other listed channel after **%2$s** on **%3$s**</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral2_two">and **%1$d** other listed channels after **%2$s** on **%3$s**</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral2_few">and **%1$d** other listed channels after **%2$s** on **%3$s**</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral2_many">and **%1$d** other listed channels after **%2$s** on **%3$s**</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral2_other">and **%1$d** other listed channels after **%2$s** on **%3$s**</string>
<string name="BoostingGiveawayHowItWorksSubTextDate_one">On **%2$s**, Telegram will automatically select **%3$s** random user that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDate_two">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDate_few">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDate_many">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDate_other">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral_one">On **%2$s**, Telegram will automatically select **%3$s** random user that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral_two">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral_few">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral_many">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveral_other">On **%2$s**, Telegram will automatically select **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksTextEnd_one">This giveaway was sponsored by the admins of **%2$s**, who acquired **%3$s Telegram Premium** subscription for %4$s for its followers.</string>
<string name="BoostingGiveawayHowItWorksTextEnd_two">This giveaway was sponsored by the admins of **%2$s**, who acquired **%3$s Telegram Premium** subscriptions for %4$s for its followers.</string>
<string name="BoostingGiveawayHowItWorksTextEnd_few">This giveaway was sponsored by the admins of **%2$s**, who acquired **%3$s Telegram Premium** subscriptions for %4$s for its followers.</string>
@ -7380,21 +7420,11 @@
<string name="BoostingGiveawayHowItWorksSubTextEnd_few">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextEnd_many">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextEnd_other">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd_one">On **%2$s**, Telegram automatically selected **%3$s** random user that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd_two">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd_few">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd_many">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextSeveralEnd_other">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateEnd_one">On **%2$s**, Telegram automatically selected **%3$s** random user that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateEnd_two">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateEnd_few">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateEnd_many">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateEnd_other">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** after **%5$s** on **%6$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd_one">On **%2$s**, Telegram automatically selected **%3$s** random user that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd_two">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd_few">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd_many">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingGiveawayHowItWorksSubTextDateSeveralEnd_other">On **%2$s**, Telegram automatically selected **%3$s** random users that joined **%4$s** and **%5$s** other listed channels after **%6$s** on **%7$s**.</string>
<string name="BoostingReduceQuantity">Reduce Quantity</string>
<string name="BoostingGiveawayEnd">Giveaway ended</string>
<string name="BoostingGiveawayPrivateChannel">Channel is Private</string>
@ -7408,30 +7438,70 @@
<string name="BoostingGiveawayUsedLinksPlural_few">**%1$d** of the winners already used their gift links.</string>
<string name="BoostingGiveawayUsedLinksPlural_many">**%1$d** of the winners already used their gift links.</string>
<string name="BoostingGiveawayUsedLinksPlural_other">**%1$d** of the winners already used their gift links.</string>
<string name="BoostingReduceQuantityText">You cant purchase **%1$d** %2$s subscriptions in the app. Do you want to reduce the prize quantity to **%3$d**?</string>
<string name="BoostingReduceUsersText">You cant purchase **%1$d** subscriptions in the app. Only **%2$s** available.</string>
<string name="BoostingSelectUpTo">Select up to %1$d channels</string>
<string name="BoostingSelectUpToCountries">Select up to %1$d countries</string>
<string name="BoostingReduceQuantityTextPlural_one">You cant purchase **%1$d** %2$s subscription in the app. Do you want to reduce the prize quantity to **%3$d**?</string>
<string name="BoostingReduceQuantityTextPlural_two">You cant purchase **%1$d** %2$s subscriptions in the app. Do you want to reduce the prize quantity to **%3$d**?</string>
<string name="BoostingReduceQuantityTextPlural_few">You cant purchase **%1$d** %2$s subscriptions in the app. Do you want to reduce the prize quantity to **%3$d**?</string>
<string name="BoostingReduceQuantityTextPlural_many">You cant purchase **%1$d** %2$s subscriptions in the app. Do you want to reduce the prize quantity to **%3$d**?</string>
<string name="BoostingReduceQuantityTextPlural_other">You cant purchase **%1$d** %2$s subscriptions in the app. Do you want to reduce the prize quantity to **%3$d**?</string>
<string name="BoostingReduceUsersTextPlural_one">You cant purchase **%1$d** subscription in the app. Only **%2$s** available.</string>
<string name="BoostingReduceUsersTextPlural_two">You cant purchase **%1$d** subscriptions in the app. Only **%2$s** available.</string>
<string name="BoostingReduceUsersTextPlural_few">You cant purchase **%1$d** subscriptions in the app. Only **%2$s** available.</string>
<string name="BoostingReduceUsersTextPlural_many">You cant purchase **%1$d** subscriptions in the app. Only **%2$s** available.</string>
<string name="BoostingReduceUsersTextPlural_other">You cant purchase **%1$d** subscriptions in the app. Only **%2$s** available.</string>
<string name="BoostingSelectUpToPlural_one">Select up to %1$d channel</string>
<string name="BoostingSelectUpToPlural_two">Select up to %1$d channels</string>
<string name="BoostingSelectUpToPlural_few">Select up to %1$d channels</string>
<string name="BoostingSelectUpToPlural_many">Select up to %1$d channels</string>
<string name="BoostingSelectUpToPlural_other">Select up to %1$d channels</string>
<string name="BoostingSelectUpToCountriesPlural_one">Select up to %1$d country</string>
<string name="BoostingSelectUpToCountriesPlural_two">Select up to %1$d countries</string>
<string name="BoostingSelectUpToCountriesPlural_few">Select up to %1$d countries</string>
<string name="BoostingSelectUpToCountriesPlural_many">Select up to %1$d countries</string>
<string name="BoostingSelectUpToCountriesPlural_other">Select up to %1$d countries</string>
<string name="BoostingApplyChangesUsers">You have changed the list of users. Apply changes?</string>
<string name="BoostingApplyChangesChannels">You have changed the list of channels. Apply changes?</string>
<string name="BoostingApplyChangesCountries">You have changed the list of countries. Apply changes?</string>
<string name="BoostingGiveawayParticipant">You are participating in this giveaway, because you have joined channel **%1$s**.</string>
<string name="BoostingGiveawayParticipantMulti">You are participating in this giveaway, because you have joined channel **%1$s** (and **%2$d** other listed channels).</string>
<string name="BoostingGiveawayParticipantMultiPlural_one">You are participating in this giveaway, because you have joined channel **%2$s** (and **%1$d** other listed channel).</string>
<string name="BoostingGiveawayParticipantMultiPlural_two">You are participating in this giveaway, because you have joined channel **%2$s** (and **%1$d** other listed channels).</string>
<string name="BoostingGiveawayParticipantMultiPlural_few">You are participating in this giveaway, because you have joined channel **%2$s** (and **%1$d** other listed channels).</string>
<string name="BoostingGiveawayParticipantMultiPlural_many">You are participating in this giveaway, because you have joined channel **%2$s** (and **%1$d** other listed channels).</string>
<string name="BoostingGiveawayParticipantMultiPlural_other">You are participating in this giveaway, because you have joined channel **%2$s** (and **%1$d** other listed channels).</string>
<string name="BoostingGiveawayTakePartMultiPlural_one">To take part in this giveaway please join channel **%2$s** (and **%1$d** other listed channel) before **%3$s**.</string>
<string name="BoostingGiveawayTakePartMultiPlural_two">To take part in this giveaway please join channel **%2$s** (and **%1$d** other listed channels) before **%3$s**.</string>
<string name="BoostingGiveawayTakePartMultiPlural_few">To take part in this giveaway please join channel **%2$s** (and **%1$d** other listed channels) before **%3$s**.</string>
<string name="BoostingGiveawayTakePartMultiPlural_many">To take part in this giveaway please join channel **%2$s** (and **%1$d** other listed channels) before **%3$s**.</string>
<string name="BoostingGiveawayTakePartMultiPlural_other">To take part in this giveaway please join channel **%2$s** (and **%1$d** other listed channels) before **%3$s**.</string>
<string name="BoostingGiveawayTakePart">To take part in this giveaway please join channel **%1$s** before **%2$s**.</string>
<string name="BoostingGiveawayTakePartMulti">To take part in this giveaway please join channel **%1$s** (and **%2$d** other listed channels) before **%3$s**.</string>
<string name="BoostingGiveawayNotEligible">You are not eligible to participate in this giveaway, because you joined this channel on **%1$s**, which is before the contest started.</string>
<string name="BoostingGiveawayNotEligibleAdmin">You are not eligible to participate in this giveaway, because you are an admin of participating channel (**%1$s**).</string>
<string name="BoostingGiveawayNotEligibleCountry">You are not eligible to participate in this giveaway, because your country is not included in the terms of the giveaway.</string>
<string name="BoostingOnlyRecipientCode">Only the recipient can see the link.</string>
<string name="BoostingOnlyGiveawayCreatorSeeLink">Only giveaway creator can see the link.</string>
<string name="BoostingSelectUpToWarningUsers">You can select maximum 10 users.</string>
<string name="BoostingSelectUpToWarningChannels">You can select maximum %1$d channels.</string>
<string name="BoostingSelectUpToWarningCountries">You can select maximum %1$d countries.</string>
<string name="BoostingWaitWarning">Wait until the boost is available or get **%1$d** more boosts by gifting a **Telegram Premium** subscription.</string>
<string name="BoostingSelectUpToWarningChannelsPlural_one">You can select maximum %1$d channel.</string>
<string name="BoostingSelectUpToWarningChannelsPlural_two">You can select maximum %1$d channels.</string>
<string name="BoostingSelectUpToWarningChannelsPlural_few">You can select maximum %1$d channels.</string>
<string name="BoostingSelectUpToWarningChannelsPlural_many">You can select maximum %1$d channels.</string>
<string name="BoostingSelectUpToWarningChannelsPlural_other">You can select maximum %1$d channels.</string>
<string name="BoostingSelectUpToWarningCountriesPlural_one">You can select maximum %1$d country.</string>
<string name="BoostingSelectUpToWarningCountriesPlural_two">You can select maximum %1$d countries.</string>
<string name="BoostingSelectUpToWarningCountriesPlural_few">You can select maximum %1$d countries.</string>
<string name="BoostingSelectUpToWarningCountriesPlural_many">You can select maximum %1$d countries.</string>
<string name="BoostingSelectUpToWarningCountriesPlural_other">You can select maximum %1$d countries.</string>
<string name="BoostingWaitWarningPlural_one">Wait until the boost is available or get **%1$d** more boost by gifting a **Telegram Premium** subscription.</string>
<string name="BoostingWaitWarningPlural_two">Wait until the boost is available or get **%1$d** more boosts by gifting a **Telegram Premium** subscription.</string>
<string name="BoostingWaitWarningPlural_few">Wait until the boost is available or get **%1$d** more boosts by gifting a **Telegram Premium** subscription.</string>
<string name="BoostingWaitWarningPlural_many">Wait until the boost is available or get **%1$d** more boosts by gifting a **Telegram Premium** subscription.</string>
<string name="BoostingWaitWarningPlural_other">Wait until the boost is available or get **%1$d** more boosts by gifting a **Telegram Premium** subscription.</string>
<string name="BoostingBoostAgain">Boost Again</string>
<string name="BoostingReassignBoost">Reassign Boost</string>
<string name="BoostingMoreBoostsNeeded">More Boosts Needed</string>
<string name="BoostingReassignedFrom">%1$s reassigned from %2$s</string>
<string name="BoostingReassignedFromPlural_one">%1$d boost reassigned from %2$s</string>
<string name="BoostingReassignedFromPlural_two">%1$d boosts reassigned from %2$s</string>
<string name="BoostingReassignedFromPlural_few">%1$d boosts reassigned from %2$s</string>
<string name="BoostingReassignedFromPlural_many">%1$d boosts reassigned from %2$s</string>
<string name="BoostingReassignedFromPlural_other">%1$d boosts reassigned from %2$s</string>
<string name="BoostingFromOtherChannel_zero">%d other channels</string>
<string name="BoostingFromOtherChannel_one">%d other channel</string>
<string name="BoostingFromOtherChannel_two">%d other channels</string>
@ -7440,7 +7510,11 @@
<string name="BoostingFromOtherChannel_other">%d other channels</string>
<string name="BoostingGetMoreBoostByGifting">To boost **%1$s**, get more boosts by gifting **Telegram Premium** to a friend.</string>
<string name="BoostingReassignBoosts">Reassign Boosts</string>
<string name="BoostingReassignBoostText">To boost **%1$s**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%2$d** additional boosts.</string>
<string name="BoostingReassignBoostTextPlural_one">To boost **%2$s**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%1$d** additional boost.</string>
<string name="BoostingReassignBoostTextPlural_two">To boost **%2$s**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%1$d** additional boosts.</string>
<string name="BoostingReassignBoostTextPlural_few">To boost **%2$s**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%1$d** additional boosts.</string>
<string name="BoostingReassignBoostTextPlural_many">To boost **%2$s**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%1$d** additional boosts.</string>
<string name="BoostingReassignBoostTextPlural_other">To boost **%2$s**, reassign a previous boost or gift **Telegram Premium** to a friend to get **%1$d** additional boosts.</string>
<string name="BoostingRemoveBoostFrom">Remove your boost from</string>
<string name="BoostingAvailableIn">available in %1$s</string>
<string name="BoostingDurationOfPremium">Duration of Premium subscriptions</string>
@ -7449,10 +7523,21 @@
<string name="BoostingGiveAwayFromCountries">from %1$s</string>
<string name="BoostingWinnersDate">**Winners Selection Date**</string>
<string name="BoostingGiveawayPrizes">**Giveaway Prizes**</string>
<string name="BoostingGiveawayMsgInfo">**%1$d** Telegram Premium\nSubscription for %2$s.</string>
<string name="BoostingGiveawayMsgInfoPlural1_one">**%1$d** Telegram Premium</string>
<string name="BoostingGiveawayMsgInfoPlural1_two">**%1$d** Telegram Premium</string>
<string name="BoostingGiveawayMsgInfoPlural1_few">**%1$d** Telegram Premium</string>
<string name="BoostingGiveawayMsgInfoPlural1_many">**%1$d** Telegram Premium</string>
<string name="BoostingGiveawayMsgInfoPlural1_other">**%1$d** Telegram Premium</string>
<string name="BoostingGiveawayMsgInfoPlural2_one">Subscription for %2$s.</string>
<string name="BoostingGiveawayMsgInfoPlural2_two">Subscriptions for %2$s.</string>
<string name="BoostingGiveawayMsgInfoPlural2_few">Subscriptions for %2$s.</string>
<string name="BoostingGiveawayMsgInfoPlural2_many">Subscriptions for %2$s.</string>
<string name="BoostingGiveawayMsgInfoPlural2_other">Subscriptions for %2$s.</string>
<string name="BoostingGiveawayMsgParticipants">**Participants**</string>
<string name="BoostingGiveawayMsgAllSubs">All subscribers of the channel:</string>
<string name="BoostingGiveawayMsgNewSubs">New subscribers of the channel:</string>
<string name="BoostingGiveawayMsgAllSubsPlural_one">All subscribers of the channel:</string>
<string name="BoostingGiveawayMsgAllSubsPlural_other">All subscribers of the channels:</string>
<string name="BoostingGiveawayMsgNewSubsPlural_one">New subscribers of the channel:</string>
<string name="BoostingGiveawayMsgNewSubsPlural_other">New subscribers of the channels:</string>
<string name="StoryReactionsWidgetLimit">You cant add up more than 5 reactions tags to a story.</string>
<string name="UnconfirmedAuthTitle">Someone just got access to your messages!</string>
<string name="UnconfirmedAuthConfirm">Yes, its me</string>
@ -7610,4 +7695,5 @@
<string name="OpenGift">OPEN</string>
<string name="UserColorApplied">Your name color has been updated!</string>
<string name="ChannelColorApplied">Your channel color has been updated!</string>
<string name="CopyCode">Copy Code</string>
</resources>

View file

@ -13,8 +13,8 @@
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Sat Mar 12 05:53:50 MSK 2016
APP_VERSION_CODE=4075
APP_VERSION_NAME=10.2.3
APP_VERSION_CODE=4082
APP_VERSION_NAME=10.2.6
APP_PACKAGE=org.telegram.messenger
RELEASE_KEY_PASSWORD=android
RELEASE_KEY_ALIAS=androidkey