update to 10.3.2 (4145)

This commit is contained in:
dkaraush 2023-12-04 22:17:50 +04:00
parent 220f6b4d73
commit 33a48d8945
277 changed files with 17900 additions and 4142 deletions

View file

@ -1339,7 +1339,7 @@ extern "C" JNIEXPORT int JNICALL Java_org_telegram_ui_Components_AnimatedFileDra
} }
} }
extern "C" JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_AnimatedFileDrawable_getVideoFrame(JNIEnv *env, jclass clazz, jlong ptr, jobject bitmap, jintArray data, jint stride, jboolean preview, jfloat start_time, jfloat end_time) { extern "C" JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_AnimatedFileDrawable_getVideoFrame(JNIEnv *env, jclass clazz, jlong ptr, jobject bitmap, jintArray data, jint stride, jboolean preview, jfloat start_time, jfloat end_time, jboolean loop) {
if (ptr == NULL || bitmap == nullptr) { if (ptr == NULL || bitmap == nullptr) {
return 0; return 0;
} }
@ -1408,18 +1408,19 @@ extern "C" JNIEXPORT jint JNICALL Java_org_telegram_ui_Components_AnimatedFileDr
LOGE("can't decode packet flushed %s", info->src); LOGE("can't decode packet flushed %s", info->src);
return 0; return 0;
} }
if (!preview && got_frame == 0) { if (!preview && got_frame == 0 && info->has_decoded_frames) {
if (info->has_decoded_frames) { if (!loop) {
int64_t start_from = 0; return 0;
if (start_time > 0) { }
start_from = (int64_t)(start_time / av_q2d(info->video_stream->time_base)); int64_t start_from = 0;
} if (start_time > 0) {
if ((ret = av_seek_frame(info->fmt_ctx, info->video_stream_idx, start_from, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME)) < 0) { start_from = (int64_t)(start_time / av_q2d(info->video_stream->time_base));
LOGE("can't seek to begin of file %s, %s", info->src, av_err2str(ret)); }
return 0; if ((ret = av_seek_frame(info->fmt_ctx, info->video_stream_idx, start_from, AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_FRAME)) < 0) {
} else { LOGE("can't seek to begin of file %s, %s", info->src, av_err2str(ret));
avcodec_flush_buffers(info->video_dec_ctx); return 0;
} } else {
avcodec_flush_buffers(info->video_dec_ctx);
} }
} }
} }

View file

@ -518,11 +518,15 @@ void TL_user::readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &er
if ((flags2 & 32) != 0) { if ((flags2 & 32) != 0) {
stories_max_id = stream->readInt32(&error); stories_max_id = stream->readInt32(&error);
} }
if ((flags2 & 128) != 0) { if ((flags2 & 256) != 0) {
color = stream->readInt32(&error); int magic = stream->readInt32(&error);
color_color = stream->readInt32(&error);
color_background_emoji_id = stream->readInt64(&error);
} }
if ((flags2 & 64) != 0) { if ((flags2 & 512) != 0) {
background_emoji_id = stream->readInt64(&error); int magic = stream->readInt32(&error);
profile_color_color = stream->readInt32(&error);
profile_color_background_emoji_id = stream->readInt64(&error);
} }
} }
@ -591,11 +595,15 @@ void TL_user::serializeToStream(NativeByteBuffer *stream) {
if ((flags2 & 32) != 0) { if ((flags2 & 32) != 0) {
stream->writeInt32(stories_max_id); stream->writeInt32(stories_max_id);
} }
if ((flags2 & 128) != 0) { if ((flags2 & 256) != 0) {
stream->writeInt32(color); stream->writeInt32(0xba278146);
stream->writeInt32(color_color);
stream->writeInt32(color_background_emoji_id);
} }
if ((flags2 & 64) != 0) { if ((flags2 & 512) != 0) {
stream->writeInt64(background_emoji_id); stream->writeInt32(0xba278146);
stream->writeInt32(profile_color_color);
stream->writeInt32(profile_color_background_emoji_id);
} }
} }

View file

@ -339,8 +339,10 @@ public:
int32_t emojiStatusMagic; int32_t emojiStatusMagic;
int64_t emojiStatusDocumentId; int64_t emojiStatusDocumentId;
int32_t emojiStatusUntil; int32_t emojiStatusUntil;
int32_t color; int32_t color_color;
int64_t background_emoji_id; int64_t color_background_emoji_id;
int32_t profile_color_color;
int64_t profile_color_background_emoji_id;
static User *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error); static User *TLdeserialize(NativeByteBuffer *stream, uint32_t constructor, int32_t instanceNum, bool &error);
}; };
@ -357,7 +359,7 @@ public:
class TL_user : public User { class TL_user : public User {
public: public:
static const uint32_t constructor = 0xeb602f25; static const uint32_t constructor = 0x215c4438;
void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error); void readParams(NativeByteBuffer *stream, int32_t instanceNum, bool &error);
void serializeToStream(NativeByteBuffer *stream); void serializeToStream(NativeByteBuffer *stream);

View file

@ -21,6 +21,7 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.BotHelpCell; import org.telegram.ui.Cells.BotHelpCell;
import org.telegram.ui.Cells.ChatActionCell;
import org.telegram.ui.Cells.ChatMessageCell; import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.ChatGreetingsView; import org.telegram.ui.Components.ChatGreetingsView;

View file

@ -454,11 +454,11 @@ public class AndroidUtilities {
return null; return null;
} }
public static CharSequence premiumText(String str, Runnable runnable) { public static SpannableStringBuilder premiumText(String str, Runnable runnable) {
return replaceSingleTag(str, -1, REPLACING_TAG_TYPE_LINKBOLD, runnable); return replaceSingleTag(str, -1, REPLACING_TAG_TYPE_LINKBOLD, runnable);
} }
public static CharSequence replaceSingleTag(String str, Runnable runnable) { public static SpannableStringBuilder replaceSingleTag(String str, Runnable runnable) {
return replaceSingleTag(str, -1, 0, runnable); return replaceSingleTag(str, -1, 0, runnable);
} }
@ -516,6 +516,10 @@ public class AndroidUtilities {
} }
public static SpannableStringBuilder replaceSingleLink(String str, int color) { public static SpannableStringBuilder replaceSingleLink(String str, int color) {
return replaceSingleLink(str, color, null);
}
public static SpannableStringBuilder replaceSingleLink(String str, int color, Runnable onClick) {
int startIndex = str.indexOf("**"); int startIndex = str.indexOf("**");
int endIndex = str.indexOf("**", startIndex + 1); int endIndex = str.indexOf("**", startIndex + 1);
str = str.replace("**", ""); str = str.replace("**", "");
@ -537,7 +541,9 @@ public class AndroidUtilities {
@Override @Override
public void onClick(@NonNull View view) { public void onClick(@NonNull View view) {
if (onClick != null) {
onClick.run();
}
} }
}, index, index + len, 0); }, index, index + len, 0);
} }
@ -1061,7 +1067,7 @@ public class AndroidUtilities {
public static int[] calcDrawableColor(Drawable drawable) { public static int[] calcDrawableColor(Drawable drawable) {
if (drawable instanceof ChatBackgroundDrawable) { if (drawable instanceof ChatBackgroundDrawable) {
ChatBackgroundDrawable chatBackgroundDrawable = (ChatBackgroundDrawable) drawable; ChatBackgroundDrawable chatBackgroundDrawable = (ChatBackgroundDrawable) drawable;
return calcDrawableColor(chatBackgroundDrawable.getDrawable()); return calcDrawableColor(chatBackgroundDrawable.getDrawable(true));
} }
int bitmapColor = 0xff000000; int bitmapColor = 0xff000000;
int[] result = new int[4]; int[] result = new int[4];
@ -5461,6 +5467,9 @@ public class AndroidUtilities {
} }
public static void forEachViews(RecyclerView recyclerView, Consumer<View> consumer) { public static void forEachViews(RecyclerView recyclerView, Consumer<View> consumer) {
if (recyclerView == null) {
return;
}
for (int i = 0; i < recyclerView.getChildCount(); i++) { for (int i = 0; i < recyclerView.getChildCount(); i++) {
consumer.accept(recyclerView.getChildAt(i)); consumer.accept(recyclerView.getChildAt(i));
} }

View file

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

View file

@ -2086,4 +2086,34 @@ public class ChatObject {
} }
} }
} }
public static MessagesController.PeerColor getPeerColorForAvatar(int currentAccount, TLRPC.Chat chat) {
// if (chat != null && chat.profile_color != null && chat.profile_color.color >= 0 && MessagesController.getInstance(currentAccount).profilePeerColors != null) {
// return MessagesController.getInstance(currentAccount).profilePeerColors.getColor(chat.profile_color.color);
// }
return null;
}
public static int getColorId(TLRPC.Chat chat) {
if (chat == null) return 0;
if (chat.color != null && (chat.color.flags & 1) != 0) return chat.color.color;
return (int) (chat.id % 7);
}
public static long getEmojiId(TLRPC.Chat chat) {
if (chat != null && chat.color != null && (chat.color.flags & 2) != 0) return chat.color.background_emoji_id;
return 0;
}
public static int getProfileColorId(TLRPC.Chat chat) {
if (chat == null) return 0;
// if (chat.profile_color != null && (chat.profile_color.flags & 1) != 0) return chat.profile_color.color;
return -1;
}
public static long getProfileEmojiId(TLRPC.Chat chat) {
// if (chat != null && chat.profile_color != null && (chat.profile_color.flags & 2) != 0) return chat.profile_color.background_emoji_id;
return -1;
}
} }

View file

@ -403,20 +403,59 @@ public class ChatThemeController extends BaseController {
getSharedPreferences().edit().clear().apply(); getSharedPreferences().edit().clear().apply();
} }
public void processUpdate(TLRPC.TL_updatePeerWallpaper update) {
if (update.peer instanceof TLRPC.TL_peerUser) {
TLRPC.UserFull userFull = getMessagesController().getUserFull(update.peer.user_id);
if (userFull != null) {
if (wallpaperEquals(userFull.wallpaper, update.wallpaper)) {
return;
}
final long dialogId = userFull.id;
userFull.wallpaper_overridden = update.wallpaper_overridden;
userFull.wallpaper = update.wallpaper;
userFull.flags |= 16777216;
getMessagesStorage().updateUserInfo(userFull, false);
saveChatWallpaper(dialogId, null);
AndroidUtilities.runOnUIThread(() -> {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, dialogId, userFull);
});
}
} else {
// todo
}
}
public static boolean wallpaperEquals(TLRPC.WallPaper a, TLRPC.WallPaper b) {
if ((a == null || a instanceof TLRPC.TL_wallPaperNoFile) && (b == null || b instanceof TLRPC.TL_wallPaperNoFile)) {
return true;
}
if (a instanceof TLRPC.TL_wallPaper && b instanceof TLRPC.TL_wallPaper) {
return a.id == b.id;
}
return false;
}
public void clearWallpaper(long dialogId, boolean notify) { public void clearWallpaper(long dialogId, boolean notify) {
clearWallpaper(dialogId, notify, false);
}
public void clearWallpaper(long dialogId, boolean notify, boolean onlyRevert) {
TLRPC.TL_messages_setChatWallPaper req = new TLRPC.TL_messages_setChatWallPaper(); TLRPC.TL_messages_setChatWallPaper req = new TLRPC.TL_messages_setChatWallPaper();
if (dialogId > 0) { if (dialogId >= 0) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId);
req.peer = MessagesController.getInputPeer(user); req.peer = MessagesController.getInputPeer(user);
TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId); req.revert = onlyRevert;
if (userFull != null) { if (!onlyRevert) {
userFull.wallpaper = null; TLRPC.UserFull userFull = getMessagesController().getUserFull(dialogId);
userFull.flags &= ~16777216; if (userFull != null) {
getMessagesStorage().updateUserInfo(userFull, false); userFull.wallpaper = null;
} userFull.flags &= ~16777216;
saveChatWallpaper(dialogId, null); getMessagesStorage().updateUserInfo(userFull, false);
if (notify) { }
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, dialogId, userFull); saveChatWallpaper(dialogId, null);
if (notify) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.userInfoDidLoad, dialogId, userFull);
}
} }
} else { } else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
@ -438,6 +477,7 @@ public class ChatThemeController extends BaseController {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
req.peer = MessagesController.getInputPeer(chat); req.peer = MessagesController.getInputPeer(chat);
} }
req.for_both = wallpaperInfo.forBoth;
boolean applyOnRequest = true; boolean applyOnRequest = true;
if (serverWallpaper != null && serverWallpaper.messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) { if (serverWallpaper != null && serverWallpaper.messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) {
applyOnRequest = false; applyOnRequest = false;

View file

@ -150,7 +150,8 @@ class ChatsRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED); avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
} }
} else { } else {
avatarDrawable = new AvatarDrawable(chat); avatarDrawable = new AvatarDrawable();
avatarDrawable.setInfo(accountInstance.getCurrentAccount(), chat);
} }
avatarDrawable.setBounds(0, 0, size, size); avatarDrawable.setBounds(0, 0, size, size);
avatarDrawable.draw(canvas); avatarDrawable.draw(canvas);

View file

@ -420,7 +420,7 @@ public class CodeHighlighting {
StringToken wrapped; StringToken wrapped;
if (pattern.insideTokenPatterns != null) { if (pattern.insideTokenPatterns != null) {
wrapped = new StringToken(pattern.group, tokenize(match.string, pattern.insideTokenPatterns, depth + 1), match.length); wrapped = new StringToken(pattern.group, tokenize(match.string, pattern.insideTokenPatterns, pattern, depth + 1), match.length);
} else if (pattern.insideLanguage != null) { } else if (pattern.insideLanguage != null) {
wrapped = new StringToken(pattern.group, tokenize(match.string, compiledPatterns.get(pattern.insideLanguage), pattern, depth + 1), match.length); wrapped = new StringToken(pattern.group, tokenize(match.string, compiledPatterns.get(pattern.insideLanguage), pattern, depth + 1), match.length);
} else { } else {

View file

@ -155,7 +155,8 @@ class ContactsRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactor
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED); avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SAVED);
} }
} else { } else {
avatarDrawable = new AvatarDrawable(chat); avatarDrawable = new AvatarDrawable();
avatarDrawable.setInfo(accountInstance.getCurrentAccount(), chat);
} }
avatarDrawable.setBounds(0, 0, size, size); avatarDrawable.setBounds(0, 0, size, size);
avatarDrawable.draw(canvas); avatarDrawable.draw(canvas);

View file

@ -1113,25 +1113,6 @@ public class ImageReceiver implements NotificationCenter.NotificationCenterDeleg
return false; return false;
} }
private int bufferedFrame;
public void incrementFrames(int inc) {
if (currentMediaDrawable instanceof RLottieDrawable) {
// RLottieDrawable rlottie = (RLottieDrawable) currentMediaDrawable;
// inc = (int) Math.round((float) rlottie.getFramesCount() / rlottie.getDuration() * (1f / 30f));
// rlottie.setCurrentFrame(
// (rlottie.getCurrentFrame() + inc) % (int) rlottie.getFramesCount()
// );
} else if (currentMediaDrawable instanceof AnimatedFileDrawable) {
int lastFrame = (int) bufferedFrame;
bufferedFrame += inc;
int currentFrame = (int) bufferedFrame;
while (lastFrame != currentFrame) {
((AnimatedFileDrawable) currentMediaDrawable).getNextFrame();
currentFrame--;
}
}
}
public boolean onAttachedToWindow() { public boolean onAttachedToWindow() {
if (attachedToWindow) { if (attachedToWindow) {
return false; return false;

View file

@ -1170,6 +1170,11 @@ public class LocaleController {
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName()); int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(param, "string", ApplicationLoader.applicationContext.getPackageName());
value = ApplicationLoader.applicationContext.getString(resourceId); value = ApplicationLoader.applicationContext.getString(resourceId);
} }
if (value == null) {
int resourceId = ApplicationLoader.applicationContext.getResources().getIdentifier(key + "_other", "string", ApplicationLoader.applicationContext.getPackageName());
value = ApplicationLoader.applicationContext.getString(resourceId);
}
value = value.replace("%d", "%1$s");
value = value.replace("%1$d", "%1$s"); value = value.replace("%1$d", "%1$s");
if (getInstance().currentLocale != null) { if (getInstance().currentLocale != null) {
@ -1685,6 +1690,42 @@ public class LocaleController {
return "LOC_ERR"; return "LOC_ERR";
} }
public static String formatShortDate(long date) {
try {
date *= 1000;
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
long timeInMillis = rightNow.getTimeInMillis();
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (timeInMillis - date < 1000 * 60) {
return LocaleController.getString(R.string.ShortNow);
} else if (timeInMillis - date < 1000 * 60 * 60) {
int minutesAgo = (int) ((timeInMillis - date) / (1000 * 60));
return LocaleController.formatPluralString("ShortMinutesAgo", minutesAgo);
} else if (dateDay == day && year == dateYear) {
if (timeInMillis - date < 12 * 1000 * 60 * 60) {
int hoursAgo = (int) ((timeInMillis - date) / (1000 * 60 * 60));
return LocaleController.formatPluralString("ShortHoursAgo", hoursAgo);
} else {
return LocaleController.getString(R.string.ShortToday);
}
} else if (dateDay + 1 == day && year == dateYear) {
return LocaleController.getString(R.string.ShortYesterday);
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
return getInstance().formatterDayMonth.format(new Date(date));
} else {
return LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, getInstance().formatterYear.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
public static String formatStoryDate(long date) { public static String formatStoryDate(long date) {
try { try {
date *= 1000; date *= 1000;

View file

@ -613,7 +613,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public final static int VIDEO_BITRATE_360 = 750_000; public final static int VIDEO_BITRATE_360 = 750_000;
public final static String VIDEO_MIME_TYPE = "video/avc"; public final static String VIDEO_MIME_TYPE = "video/avc";
public final static String AUIDO_MIME_TYPE = "audio/mp4a-latm"; public final static String AUDIO_MIME_TYPE = "audio/mp4a-latm";
private final Object videoConvertSync = new Object(); private final Object videoConvertSync = new Object();

View file

@ -408,7 +408,7 @@ public class MediaDataController extends BaseController {
public void checkReactions() { public void checkReactions() {
if (!isLoadingReactions && Math.abs(System.currentTimeMillis() / 1000 - reactionsUpdateDate) >= 60 * 60) { if (!isLoadingReactions && Math.abs(System.currentTimeMillis() / 1000 - reactionsUpdateDate) >= 60 * 60) {
loadReactions(true, false); loadReactions(true, null);
} }
} }
@ -701,7 +701,7 @@ public class MediaDataController extends BaseController {
return reactionsList; return reactionsList;
} }
public void loadReactions(boolean cache, boolean force) { public void loadReactions(boolean cache, Integer lastHash) {
isLoadingReactions = true; isLoadingReactions = true;
if (cache) { if (cache) {
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
@ -741,7 +741,7 @@ public class MediaDataController extends BaseController {
}); });
} else { } else {
TLRPC.TL_messages_getAvailableReactions req = new TLRPC.TL_messages_getAvailableReactions(); TLRPC.TL_messages_getAvailableReactions req = new TLRPC.TL_messages_getAvailableReactions();
req.hash = force ? 0 : reactionsUpdateHash; req.hash = lastHash != null ? lastHash : reactionsUpdateHash;
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> { getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
int date = (int) (System.currentTimeMillis() / 1000); int date = (int) (System.currentTimeMillis() / 1000);
if (response instanceof TLRPC.TL_messages_availableReactionsNotModified) { if (response instanceof TLRPC.TL_messages_availableReactionsNotModified) {
@ -781,7 +781,7 @@ public class MediaDataController extends BaseController {
if (!cache) { if (!cache) {
putReactionsToCache(reactions, hash, date); putReactionsToCache(reactions, hash, date);
} else if (Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60) { } else if (Math.abs(System.currentTimeMillis() / 1000 - date) >= 60 * 60) {
loadReactions(false, true); loadReactions(false, hash);
} }
} }
@ -6344,6 +6344,9 @@ public class MediaDataController extends BaseController {
} }
} else { } else {
if (start + 1 != index) { if (start + 1 != index) {
if (message[0] instanceof Spanned && ((Spanned) message[0]).getSpans(Utilities.clamp(start, message[0].length(), 0), Utilities.clamp(start + 1, message[0].length(), 0), CodeHighlighting.Span.class).length > 0) {
continue;
}
message[0] = AndroidUtilities.concat(substring(message[0], 0, start), substring(message[0], start + 1, index), substring(message[0], index + 1, message[0].length())); message[0] = AndroidUtilities.concat(substring(message[0], 0, start), substring(message[0], start + 1, index), substring(message[0], index + 1, message[0].length()));
TLRPC.TL_messageEntityCode entity = new TLRPC.TL_messageEntityCode(); TLRPC.TL_messageEntityCode entity = new TLRPC.TL_messageEntityCode();
entity.offset = start; entity.offset = start;
@ -6630,12 +6633,7 @@ public class MediaDataController extends BaseController {
if (threads == null || threads.size() <= 0) { if (threads == null || threads.size() <= 0) {
return null; return null;
} }
for (int i = 0; i < threads.size(); ++i) { return new Pair(threads.keyAt(0), threads.valueAt(0));
if (threads.keyAt(i) != 0) {
return new Pair(threads.keyAt(i), threads.valueAt(i));
}
}
return null;
} }
public TLRPC.Message getDraftMessage(long dialogId, int threadId) { public TLRPC.Message getDraftMessage(long dialogId, int threadId) {
@ -6671,6 +6669,8 @@ public class MediaDataController extends BaseController {
draftMessage.reply_to.quote_text = quote.getText(); draftMessage.reply_to.quote_text = quote.getText();
if (draftMessage.reply_to.quote_text != null) { if (draftMessage.reply_to.quote_text != null) {
draftMessage.reply_to.flags |= 4; draftMessage.reply_to.flags |= 4;
draftMessage.reply_to.flags |= 16;
draftMessage.reply_to.quote_offset = quote.start;
} }
draftMessage.reply_to.quote_entities = quote.getEntities(); draftMessage.reply_to.quote_entities = quote.getEntities();
if (draftMessage.reply_to.quote_entities != null && !draftMessage.reply_to.quote_entities.isEmpty()) { if (draftMessage.reply_to.quote_entities != null && !draftMessage.reply_to.quote_entities.isEmpty()) {

View file

@ -121,6 +121,7 @@ public class MessageObject {
public static final int TYPE_STORY_MENTION = 24; public static final int TYPE_STORY_MENTION = 24;
public static final int TYPE_GIFT_PREMIUM_CHANNEL = 25; public static final int TYPE_GIFT_PREMIUM_CHANNEL = 25;
public static final int TYPE_GIVEAWAY = 26; public static final int TYPE_GIVEAWAY = 26;
public static final int TYPE_JOINED_CHANNEL = 27; // recommendations list
public int localType; public int localType;
public String localName; public String localName;
@ -205,10 +206,15 @@ public class MessageObject {
public boolean sponsoredRecommended; public boolean sponsoredRecommended;
public String sponsoredInfo, sponsoredAdditionalInfo; public String sponsoredInfo, sponsoredAdditionalInfo;
public TLRPC.TL_sponsoredWebPage sponsoredWebPage; public TLRPC.TL_sponsoredWebPage sponsoredWebPage;
public TLRPC.BotApp sponsoredBotApp;
public String sponsoredButtonText;
public boolean replyTextEllipsized; public boolean replyTextEllipsized;
public boolean replyTextRevealed; public boolean replyTextRevealed;
public int overrideLinkColor = -1; public int overrideLinkColor = -1;
public long overrideLinkEmoji = -1; public long overrideLinkEmoji = -1;
public MessagesController.PeerColor overrideProfilePeerColor;
private boolean channelJoined;
public boolean channelJoinedExpanded;
public TLRPC.TL_forumTopic replyToForumTopic; // used only for reply message in view all messages public TLRPC.TL_forumTopic replyToForumTopic; // used only for reply message in view all messages
@ -417,6 +423,19 @@ public class MessageObject {
return type == TYPE_ACTION_WALLPAPER || (messageOwner != null && messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper); return type == TYPE_ACTION_WALLPAPER || (messageOwner != null && messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper);
} }
public boolean isWallpaperForBoth() {
return isWallpaperAction() && messageOwner != null && messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper && ((TLRPC.TL_messageActionSetChatWallPaper) messageOwner.action).for_both;
}
public boolean isCurrentWallpaper() {
if (!isWallpaperAction() || messageOwner == null || messageOwner.action == null || messageOwner.action.wallpaper == null)
return false;
TLRPC.UserFull userFull = MessagesController.getInstance(currentAccount).getUserFull(getDialogId());
if (userFull == null || userFull.wallpaper == null || !userFull.wallpaper_overridden)
return false;
return messageOwner.action.wallpaper.id == userFull.wallpaper.id;
}
public int getEmojiOnlyCount() { public int getEmojiOnlyCount() {
return emojiOnlyCount; return emojiOnlyCount;
} }
@ -506,6 +525,9 @@ public class MessageObject {
public ArrayList<ReactionsLayoutInBubble.VisibleReaction> getChoosenReactions() { public ArrayList<ReactionsLayoutInBubble.VisibleReaction> getChoosenReactions() {
ArrayList<ReactionsLayoutInBubble.VisibleReaction> choosenReactions = new ArrayList<>(); ArrayList<ReactionsLayoutInBubble.VisibleReaction> choosenReactions = new ArrayList<>();
TLRPC.ReactionCount newReaction = null; TLRPC.ReactionCount newReaction = null;
if (messageOwner.reactions == null) {
return choosenReactions;
}
for (int i = 0; i < messageOwner.reactions.results.size(); i++) { for (int i = 0; i < messageOwner.reactions.results.size(); i++) {
if (messageOwner.reactions.results.get(i).chosen) { if (messageOwner.reactions.results.get(i).chosen) {
choosenReactions.add(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(messageOwner.reactions.results.get(i).reaction)); choosenReactions.add(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(messageOwner.reactions.results.get(i).reaction));
@ -791,6 +813,7 @@ public class MessageObject {
case "dockerfile": case "dockerfile":
case "dart": case "dart":
case "java": case "java":
case "fift":
return capitalizeFirst(lng); return capitalizeFirst(lng);
case "http": case "http":
case "html": case "html":
@ -814,7 +837,13 @@ public class MessageObject {
case "cobol": case "cobol":
case "jsx": case "jsx":
case "tsx": case "tsx":
case "tl":
return lng.toUpperCase(); return lng.toUpperCase();
case "tl-b":
case "tlb":
return "TL-B";
case "func":
return "FunC";
} }
return lng; return lng;
} }
@ -1772,9 +1801,9 @@ public class MessageObject {
} }
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantJoin) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantJoin) {
if (chat.megagroup) { if (chat.megagroup) {
messageText = replaceWithLink(LocaleController.getString("EventLogGroupJoined", R.string.EventLogGroupJoined), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString(R.string.EventLogGroupJoined), "un1", fromUser);
} else { } else {
messageText = replaceWithLink(LocaleController.getString("EventLogChannelJoined", R.string.EventLogChannelJoined), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString(R.string.EventLogChannelJoined), "un1", fromUser);
} }
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantLeave) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionParticipantLeave) {
messageOwner = new TLRPC.TL_messageService(); messageOwner = new TLRPC.TL_messageService();
@ -1798,9 +1827,9 @@ public class MessageObject {
} }
if (messageOwner.from_id instanceof TLRPC.TL_peerUser && peerId == messageOwner.from_id.user_id) { if (messageOwner.from_id instanceof TLRPC.TL_peerUser && peerId == messageOwner.from_id.user_id) {
if (chat.megagroup) { if (chat.megagroup) {
messageText = replaceWithLink(LocaleController.getString("EventLogGroupJoined", R.string.EventLogGroupJoined), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString(R.string.EventLogGroupJoined), "un1", fromUser);
} else { } else {
messageText = replaceWithLink(LocaleController.getString("EventLogChannelJoined", R.string.EventLogChannelJoined), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString(R.string.EventLogChannelJoined), "un1", fromUser);
} }
} else { } else {
messageText = replaceWithLink(LocaleController.getString("EventLogAdded", R.string.EventLogAdded), "un2", whoUser); messageText = replaceWithLink(LocaleController.getString("EventLogAdded", R.string.EventLogAdded), "un2", whoUser);
@ -3507,11 +3536,12 @@ public class MessageObject {
TLObject fromObject = fromUser != null ? fromUser : fromChat; TLObject fromObject = fromUser != null ? fromUser : fromChat;
drawServiceWithDefaultTypeface = false; drawServiceWithDefaultTypeface = false;
channelJoined = false;
if (messageOwner instanceof TLRPC.TL_messageService) { if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action != null) { if (messageOwner.action != null) {
if (messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper) { if (messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper) {
contentType = 1; contentType = 1;
type = TYPE_TEXT; type = TYPE_DATE;
TLRPC.TL_messageActionSetSameChatWallPaper action = (TLRPC.TL_messageActionSetSameChatWallPaper) messageOwner.action; TLRPC.TL_messageActionSetSameChatWallPaper action = (TLRPC.TL_messageActionSetSameChatWallPaper) messageOwner.action;
TLRPC.User user = getUser(users, sUsers, isOutOwner() ? 0 : getDialogId()); TLRPC.User user = getUser(users, sUsers, isOutOwner() ? 0 : getDialogId());
photoThumbs = new ArrayList<>(); photoThumbs = new ArrayList<>();
@ -3521,26 +3551,47 @@ public class MessageObject {
} }
if (user != null) { if (user != null) {
if (user.id == UserConfig.getInstance(currentAccount).clientUserId) { if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
messageText = LocaleController.formatString("ActionSetSameWallpaperForThisChatSelf", R.string.ActionSetSameWallpaperForThisChatSelf); messageText = LocaleController.formatString(R.string.ActionSetSameWallpaperForThisChatSelf);
} else { } else {
messageText = LocaleController.formatString("ActionSetSameWallpaperForThisChat", R.string.ActionSetSameWallpaperForThisChat, user.first_name); messageText = LocaleController.formatString(R.string.ActionSetSameWallpaperForThisChat, user.first_name);
} }
} }
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) {
contentType = 1; contentType = 1;
type = TYPE_ACTION_WALLPAPER;
TLRPC.TL_messageActionSetChatWallPaper wallPaper = (TLRPC.TL_messageActionSetChatWallPaper) messageOwner.action; TLRPC.TL_messageActionSetChatWallPaper wallPaper = (TLRPC.TL_messageActionSetChatWallPaper) messageOwner.action;
type = TYPE_ACTION_WALLPAPER;
photoThumbs = new ArrayList<>(); photoThumbs = new ArrayList<>();
if (wallPaper.wallpaper.document != null) { if (wallPaper.wallpaper.document != null) {
photoThumbs.addAll(wallPaper.wallpaper.document.thumbs); photoThumbs.addAll(wallPaper.wallpaper.document.thumbs);
photoThumbsObject = wallPaper.wallpaper.document; photoThumbsObject = wallPaper.wallpaper.document;
} }
TLRPC.User user = getUser(users, sUsers, isOutOwner() ? 0 : getDialogId()); TLRPC.User user = getUser(users, sUsers, isOutOwner() ? 0 : getDialogId());
TLRPC.User partner = getUser(users, sUsers, getDialogId());
if (user != null) { if (user != null) {
if (user.id == UserConfig.getInstance(currentAccount).clientUserId) { if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
messageText = LocaleController.formatString("ActionSetWallpaperForThisChatSelf", R.string.ActionSetWallpaperForThisChatSelf); if (wallPaper.same) {
type = TYPE_DATE;
messageText = LocaleController.formatString(R.string.ActionSetSameWallpaperForThisChatSelf);
} else if (wallPaper.for_both && partner != null) {
messageText = LocaleController.getString(R.string.ActionSetWallpaperForThisChatSelfBoth);
CharSequence partnerName = new SpannableString(UserObject.getFirstName(partner));
((SpannableString) partnerName).setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, partnerName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
messageText = AndroidUtilities.replaceCharSequence("%s", messageText, partnerName);
} else {
messageText = LocaleController.getString(R.string.ActionSetWallpaperForThisChatSelf);
}
} else { } else {
messageText = LocaleController.formatString("ActionSetWallpaperForThisChat", R.string.ActionSetWallpaperForThisChat, user.first_name); CharSequence userName = new SpannableString(UserObject.getFirstName(user));
((SpannableString) userName).setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, userName.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
if (wallPaper.same) {
type = TYPE_DATE;
messageText = LocaleController.getString(R.string.ActionSetSameWallpaperForThisChat);
} else if (wallPaper.for_both) {
messageText = LocaleController.getString(R.string.ActionSetWallpaperForThisChatBoth);
} else {
messageText = LocaleController.getString(R.string.ActionSetWallpaperForThisChat);
}
messageText = AndroidUtilities.replaceCharSequence("%s", messageText, userName);
} }
} }
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGroupCallScheduled) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGroupCallScheduled) {
@ -3680,6 +3731,7 @@ public class MessageObject {
} }
if (messageOwner.from_id != null && singleUserId == messageOwner.from_id.user_id) { if (messageOwner.from_id != null && singleUserId == messageOwner.from_id.user_id) {
if (ChatObject.isChannel(chat) && !chat.megagroup) { if (ChatObject.isChannel(chat) && !chat.megagroup) {
channelJoined = true;
messageText = LocaleController.getString("ChannelJoined", R.string.ChannelJoined); messageText = LocaleController.getString("ChannelJoined", R.string.ChannelJoined);
} else { } else {
if (messageOwner.peer_id.channel_id != 0) { if (messageOwner.peer_id.channel_id != 0) {
@ -3729,6 +3781,15 @@ public class MessageObject {
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiveawayLaunch) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiveawayLaunch) {
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null; TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(chats, sChats, messageOwner.peer_id.channel_id) : null;
messageText = LocaleController.formatString("BoostingGiveawayJustStarted", R.string.BoostingGiveawayJustStarted, chat != null ? chat.title : ""); messageText = LocaleController.formatString("BoostingGiveawayJustStarted", R.string.BoostingGiveawayJustStarted, chat != null ? chat.title : "");
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiveawayResults) {
TLRPC.TL_messageActionGiveawayResults giveawayResults = (TLRPC.TL_messageActionGiveawayResults) messageOwner.action;
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
stringBuilder.append(LocaleController.formatPluralString("BoostingGiveawayServiceWinnersSelected", giveawayResults.winners_count));
if (giveawayResults.unclaimed_count > 0) {
stringBuilder.append("\n");
stringBuilder.append(LocaleController.formatPluralString("BoostingGiveawayServiceUndistributed", giveawayResults.unclaimed_count));
}
messageText = stringBuilder;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftCode) {
messageText = LocaleController.getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName); messageText = LocaleController.getString("BoostingReceivedGiftNoName", R.string.BoostingReceivedGiftNoName);
} else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionGiftPremium) {
@ -4435,7 +4496,10 @@ public class MessageObject {
int oldType = type; int oldType = type;
type = 1000; type = 1000;
isRoundVideoCached = 0; isRoundVideoCached = 0;
if (messageOwner instanceof TLRPC.TL_message || messageOwner instanceof TLRPC.TL_messageForwarded_old2) { if (channelJoined) {
type = TYPE_JOINED_CHANNEL;
channelJoinedExpanded = MessagesController.getInstance(currentAccount).getMainSettings().getBoolean("c" + getDialogId() + "_rec", true);
} else if (messageOwner instanceof TLRPC.TL_message || messageOwner instanceof TLRPC.TL_messageForwarded_old2) {
if (isRestrictedMessage) { if (isRestrictedMessage) {
type = TYPE_TEXT; type = TYPE_TEXT;
} else if (emojiAnimatedSticker != null || emojiAnimatedStickerId != null) { } else if (emojiAnimatedSticker != null || emojiAnimatedStickerId != null) {
@ -4444,7 +4508,7 @@ public class MessageObject {
} else { } else {
type = TYPE_ANIMATED_STICKER; type = TYPE_ANIMATED_STICKER;
} }
} else if (isMediaEmpty(false) && !isDice() && emojiOnlyCount >= 1 && !hasUnwrappedEmoji && messageOwner != null && !hasNonEmojiEntities()) { } else if (isMediaEmpty(false) && !isDice() && !isSponsored() && emojiOnlyCount >= 1 && !hasUnwrappedEmoji && messageOwner != null && !hasNonEmojiEntities()) {
type = TYPE_EMOJIS; type = TYPE_EMOJIS;
} else if (isMediaEmpty()) { } else if (isMediaEmpty()) {
type = TYPE_TEXT; type = TYPE_TEXT;
@ -4518,7 +4582,7 @@ public class MessageObject {
} else if (messageOwner instanceof TLRPC.TL_messageService) { } else if (messageOwner instanceof TLRPC.TL_messageService) {
if (messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper) { if (messageOwner.action instanceof TLRPC.TL_messageActionSetSameChatWallPaper) {
contentType = 1; contentType = 1;
type = TYPE_TEXT; type = TYPE_DATE;
} else if (messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) { } else if (messageOwner.action instanceof TLRPC.TL_messageActionSetChatWallPaper) {
contentType = 1; contentType = 1;
type = TYPE_ACTION_WALLPAPER; type = TYPE_ACTION_WALLPAPER;
@ -4893,6 +4957,16 @@ public class MessageObject {
} }
} }
} }
} else if (sponsoredWebPage != null && sponsoredWebPage.photo != null) {
if (!update || photoThumbs == null) {
photoThumbs = new ArrayList<>(sponsoredWebPage.photo.sizes);
} else if (!photoThumbs.isEmpty()) {
updatePhotoSizeLocations(photoThumbs, sponsoredWebPage.photo.sizes);
}
photoThumbsObject = sponsoredWebPage.photo;
if (strippedThumb == null) {
createStrippedThumb();
}
} }
} }
@ -5202,7 +5276,6 @@ public class MessageObject {
public boolean isVoiceTranscriptionOpen() { public boolean isVoiceTranscriptionOpen() {
return ( return (
UserConfig.getInstance(currentAccount).isPremium() &&
messageOwner != null && messageOwner != null &&
(isVoice() || isRoundVideo() && TranscribeButton.isVideoTranscriptionOpen(this)) && (isVoice() || isRoundVideo() && TranscribeButton.isVideoTranscriptionOpen(this)) &&
messageOwner.voiceTranscriptionOpen && messageOwner.voiceTranscriptionOpen &&
@ -5864,7 +5937,9 @@ public class MessageObject {
} }
public boolean needDrawShareButton() { public boolean needDrawShareButton() {
if (isSponsored()) { if (type == TYPE_JOINED_CHANNEL) {
return false;
} else if (isSponsored()) {
return false; return false;
} else if (hasCode) { } else if (hasCode) {
return false; return false;
@ -6846,9 +6921,6 @@ public class MessageObject {
if (forceAvatar || customAvatarDrawable != null) { if (forceAvatar || customAvatarDrawable != null) {
return true; return true;
} }
if (isSponsored() && (isFromChat() || sponsoredShowPeerPhoto)) {
return true;
}
return !isSponsored() && (isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null); return !isSponsored() && (isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
} }
@ -6856,9 +6928,6 @@ public class MessageObject {
if (forceAvatar || customAvatarDrawable != null) { if (forceAvatar || customAvatarDrawable != null) {
return true; return true;
} }
if (isSponsored() && (isFromChat() || sponsoredShowPeerPhoto)) {
return true;
}
return !isSponsored() && (isFromChat() && isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null); return !isSponsored() && (isFromChat() && isFromUser() || isFromGroup() || eventId != 0 || messageOwner.fwd_from != null && messageOwner.fwd_from.saved_from_peer != null);
} }
@ -7963,7 +8032,7 @@ public class MessageObject {
} }
public boolean shouldDrawWithoutBackground() { public boolean shouldDrawWithoutBackground() {
return type == TYPE_STICKER || type == TYPE_ANIMATED_STICKER || type == TYPE_ROUND_VIDEO || type == TYPE_EMOJIS || isExpiredStory(); return !isSponsored() && (type == TYPE_STICKER || type == TYPE_ANIMATED_STICKER || type == TYPE_ROUND_VIDEO || type == TYPE_EMOJIS || isExpiredStory());
} }
public boolean isAnimatedEmojiStickers() { public boolean isAnimatedEmojiStickers() {
@ -9101,17 +9170,25 @@ public class MessageObject {
return type == MessageObject.TYPE_GIFT_PREMIUM || type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL; return type == MessageObject.TYPE_GIFT_PREMIUM || type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL;
} }
private static CharSequence userSpan; private static CharSequence[] userSpan;
public static CharSequence userSpan() { public static CharSequence userSpan() {
return userSpan(0);
}
public static CharSequence userSpan(int a) {
if (userSpan == null) { if (userSpan == null) {
userSpan = new SpannableStringBuilder("u"); userSpan = new CharSequence[2];
}
if (userSpan[a] == null) {
userSpan[a] = new SpannableStringBuilder("u");
ColoredImageSpan span = new ColoredImageSpan(R.drawable.mini_reply_user); ColoredImageSpan span = new ColoredImageSpan(R.drawable.mini_reply_user);
span.spaceScaleX = .9f; span.spaceScaleX = .9f;
span.translate(0, AndroidUtilities.dp(1)); if (a == 0) {
span.translate(0, AndroidUtilities.dp(1));
}
// span.setScale(.7f, .7f); // span.setScale(.7f, .7f);
((SpannableStringBuilder) userSpan).setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); ((SpannableStringBuilder) userSpan[a]).setSpan(span, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} }
return userSpan; return userSpan[a];
} }
private static CharSequence groupSpan; private static CharSequence groupSpan;
public static CharSequence groupSpan() { public static CharSequence groupSpan() {
@ -9353,9 +9430,8 @@ public class MessageObject {
final int type = cutToType.get(cutIndex); final int type = cutToType.get(cutIndex);
if (from != cutIndex) { if (from != cutIndex) {
int to = cutIndex;
if (cutIndex - 1 >= 0 && cutIndex - 1 < text.length() && text.charAt(cutIndex - 1) == '\n') { if (cutIndex - 1 >= 0 && cutIndex - 1 < text.length() && text.charAt(cutIndex - 1) == '\n') {
to--; cutIndex--;
} }
String lng = null; String lng = null;
@ -9364,7 +9440,7 @@ public class MessageObject {
codeSpanIndex++; codeSpanIndex++;
} }
ranges.add(new TextRange(from, to, quoteCount > 0, codeCount > 0, lng)); ranges.add(new TextRange(from, cutIndex, quoteCount > 0, codeCount > 0, lng));
from = cutIndex; from = cutIndex;
if (from + 1 < text.length() && text.charAt(from) == '\n') { if (from + 1 < text.length() && text.charAt(from) == '\n') {
from++; from++;
@ -9380,4 +9456,34 @@ public class MessageObject {
ranges.add(new TextRange(from, text.length(), quoteCount > 0, codeCount > 0, null)); ranges.add(new TextRange(from, text.length(), quoteCount > 0, codeCount > 0, null));
} }
} }
public void toggleChannelRecommendations() {
expandChannelRecommendations(!channelJoinedExpanded);
}
public void expandChannelRecommendations(boolean expand) {
MessagesController.getInstance(currentAccount).getMainSettings().edit()
.putBoolean("c" + getDialogId() + "_rec", channelJoinedExpanded = expand)
.apply();
}
public static int findQuoteStart(String text, String quote, int quote_offset) {
if (text == null || quote == null) {
return -1;
}
if (quote_offset == -1) {
return text.indexOf(quote);
}
if (quote_offset + quote.length() < text.length() && text.startsWith(quote, quote_offset)) {
return quote_offset;
}
int nextIndex = text.indexOf(quote, quote_offset);
int prevIndex = text.lastIndexOf(quote, quote_offset);
if (nextIndex == -1) return prevIndex;
if (prevIndex == -1) return nextIndex;
if (nextIndex - quote_offset < quote_offset - prevIndex) {
return nextIndex;
}
return prevIndex;
}
} }

View file

@ -37,6 +37,7 @@ import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.util.Consumer; import androidx.core.util.Consumer;
import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteCursor;
@ -518,6 +519,14 @@ public class MessagesController extends BaseController implements NotificationCe
public int quoteLengthMax; public int quoteLengthMax;
public boolean giveawayGiftsPurchaseAvailable; public boolean giveawayGiftsPurchaseAvailable;
public PeerColors peerColors; public PeerColors peerColors;
public PeerColors profilePeerColors;
public int transcribeAudioTrialWeeklyNumber;
public int transcribeAudioTrialDurationMax;
public int transcribeAudioTrialCooldownUntil;
public int transcribeAudioTrialCurrentNumber;
public int recommendedChannelsLimitDefault;
public int recommendedChannelsLimitPremium;
public int boostsChannelLevelMax;
public int channelsLimitDefault; public int channelsLimitDefault;
public int channelsLimitPremium; public int channelsLimitPremium;
@ -1420,7 +1429,16 @@ public class MessagesController extends BaseController implements NotificationCe
channelColorLevelMin = mainPreferences.getInt("channelColorLevelMin", 1); channelColorLevelMin = mainPreferences.getInt("channelColorLevelMin", 1);
quoteLengthMax = mainPreferences.getInt("quoteLengthMax", 1024); quoteLengthMax = mainPreferences.getInt("quoteLengthMax", 1024);
giveawayGiftsPurchaseAvailable = mainPreferences.getBoolean("giveawayGiftsPurchaseAvailable", false); giveawayGiftsPurchaseAvailable = mainPreferences.getBoolean("giveawayGiftsPurchaseAvailable", false);
peerColors = PeerColors.fromString(mainPreferences.getString("peerColors", "")); peerColors = PeerColors.fromString(PeerColors.TYPE_NAME, mainPreferences.getString("peerColors", ""));
profilePeerColors = PeerColors.fromString(PeerColors.TYPE_PROFILE, mainPreferences.getString("profilePeerColors", ""));
transcribeAudioTrialWeeklyNumber = mainPreferences.getInt("transcribeAudioTrialWeeklyNumber", BuildVars.DEBUG_PRIVATE_VERSION ? 2 : 0);
transcribeAudioTrialCurrentNumber = mainPreferences.getInt("transcribeAudioTrialCurrentNumber", transcribeAudioTrialWeeklyNumber);
transcribeAudioTrialDurationMax = mainPreferences.getInt("transcribeAudioTrialDurationMax", 300);
transcribeAudioTrialCooldownUntil = mainPreferences.getInt("transcribeAudioTrialCooldownUntil", 0);
recommendedChannelsLimitDefault = mainPreferences.getInt("recommendedChannelsLimitDefault", 10);
recommendedChannelsLimitPremium = mainPreferences.getInt("recommendedChannelsLimitPremium", 100);
boostsChannelLevelMax = mainPreferences.getInt("boostsChannelLevelMax", 100);
scheduleTranscriptionUpdate();
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID); BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
if (mainPreferences.contains("dcDomainName2")) { if (mainPreferences.contains("dcDomainName2")) {
dcDomainName = mainPreferences.getString("dcDomainName2", "apv3.stel.com"); dcDomainName = mainPreferences.getString("dcDomainName2", "apv3.stel.com");
@ -1561,6 +1579,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
AndroidUtilities.runOnUIThread(this::loadAppConfig, 2000); AndroidUtilities.runOnUIThread(this::loadAppConfig, 2000);
AndroidUtilities.runOnUIThread(() -> checkPeerColors(false), 400);
topicsController = new TopicsController(num); topicsController = new TopicsController(num);
cacheByChatsController = new CacheByChatsController(num); cacheByChatsController = new CacheByChatsController(num);
@ -2187,8 +2206,8 @@ public class MessagesController extends BaseController implements NotificationCe
boolean keelAliveChanged = false; boolean keelAliveChanged = false;
resetAppConfig(); resetAppConfig();
TLRPC.TL_jsonObject liteAppOptions = null; TLRPC.TL_jsonObject liteAppOptions = null;
TLRPC.TL_jsonObject peer_colors = null, dark_peer_colors = null; int transcribeAudioTrialWeeklyNumber = 0;
TLRPC.TL_jsonArray peer_colors_available = null; int transcribeAudioTrialCooldownUntil = 0;
for (int a = 0, N = object.value.size(); a < N; a++) { for (int a = 0, N = object.value.size(); a < N; a++) {
TLRPC.TL_jsonObjectValue value = object.value.get(a); TLRPC.TL_jsonObjectValue value = object.value.get(a);
switch (value.key) { switch (value.key) {
@ -3483,24 +3502,6 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "peer_colors": {
if (value.value instanceof TLRPC.TL_jsonObject) {
peer_colors = (TLRPC.TL_jsonObject) value.value;
}
break;
}
case "dark_peer_colors": {
if (value.value instanceof TLRPC.TL_jsonObject) {
dark_peer_colors = (TLRPC.TL_jsonObject) value.value;
}
break;
}
case "peer_colors_available": {
if (value.value instanceof TLRPC.TL_jsonArray) {
peer_colors_available = (TLRPC.TL_jsonArray) value.value;
}
break;
}
case "giveaway_gifts_purchase_available": { case "giveaway_gifts_purchase_available": {
if (value.value instanceof TLRPC.TL_jsonBool) { if (value.value instanceof TLRPC.TL_jsonBool) {
if (giveawayGiftsPurchaseAvailable != ((TLRPC.TL_jsonBool) value.value).value) { if (giveawayGiftsPurchaseAvailable != ((TLRPC.TL_jsonBool) value.value).value) {
@ -3511,15 +3512,85 @@ public class MessagesController extends BaseController implements NotificationCe
} }
break; break;
} }
case "transcribe_audio_trial_weekly_number": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
transcribeAudioTrialWeeklyNumber = (int) num.value;
}
break;
}
case "transcribe_audio_trial_duration_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (transcribeAudioTrialDurationMax != num.value) {
transcribeAudioTrialDurationMax = (int) num.value;
editor.putInt("transcribeAudioTrialDurationMax", transcribeAudioTrialDurationMax);
changed = true;
}
}
break;
}
case "transcribe_audio_trial_cooldown_until": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
transcribeAudioTrialCooldownUntil = (int) num.value;
}
break;
}
case "recommended_channels_limit_default": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (recommendedChannelsLimitDefault != num.value) {
recommendedChannelsLimitDefault = (int) num.value;
editor.putInt("recommendedChannelsLimitDefault", recommendedChannelsLimitDefault);
changed = true;
}
}
break;
}
case "recommended_channels_limit_premium": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (recommendedChannelsLimitPremium != num.value) {
recommendedChannelsLimitPremium = (int) num.value;
editor.putInt("recommendedChannelsLimitPremium", recommendedChannelsLimitPremium);
changed = true;
}
}
break;
}
case "boosts_channel_level_max": {
if (value.value instanceof TLRPC.TL_jsonNumber) {
TLRPC.TL_jsonNumber num = (TLRPC.TL_jsonNumber) value.value;
if (boostsChannelLevelMax != num.value) {
boostsChannelLevelMax = (int) num.value;
editor.putInt("boostsChannelLevelMax", boostsChannelLevelMax);
changed = true;
}
}
break;
}
} }
} }
PeerColors newPeerColors = PeerColors.fromJSON(peer_colors, dark_peer_colors, peer_colors_available); if (transcribeAudioTrialWeeklyNumber != this.transcribeAudioTrialWeeklyNumber) {
if (peerColors == null || !TextUtils.equals(peerColors.toString(), newPeerColors.toString())) { this.transcribeAudioTrialWeeklyNumber = transcribeAudioTrialWeeklyNumber;
peerColors = newPeerColors; editor.putInt("transcribeAudioTrialWeeklyNumber", transcribeAudioTrialWeeklyNumber);
editor.putString("peerColors", peerColors.toString()); if (transcribeAudioTrialCurrentNumber <= 0 && (transcribeAudioTrialCooldownUntil == 0 || getConnectionsManager().getCurrentTime() > transcribeAudioTrialCooldownUntil)) {
transcribeAudioTrialCurrentNumber = transcribeAudioTrialWeeklyNumber;
editor.putInt("transcribeAudioTrialCurrentNumber", transcribeAudioTrialCurrentNumber);
} else if (transcribeAudioTrialCurrentNumber > transcribeAudioTrialWeeklyNumber) {
transcribeAudioTrialCurrentNumber = transcribeAudioTrialWeeklyNumber;
editor.putInt("transcribeAudioTrialCurrentNumber", transcribeAudioTrialCurrentNumber);
}
changed = true; changed = true;
} }
if (transcribeAudioTrialCooldownUntil != this.transcribeAudioTrialCooldownUntil) {
this.transcribeAudioTrialCooldownUntil = transcribeAudioTrialCooldownUntil;
editor.putInt("transcribeAudioTrialCooldownUntil", transcribeAudioTrialCooldownUntil);
changed = true;
scheduleTranscriptionUpdate();
}
if (changed) { if (changed) {
editor.apply(); editor.apply();
@ -3540,12 +3611,51 @@ public class MessagesController extends BaseController implements NotificationCe
logDeviceStats(); logDeviceStats();
} }
public void updateTranscribeAudioTrialCurrentNumber(int num) {
if (num != transcribeAudioTrialCurrentNumber) {
transcribeAudioTrialCurrentNumber = num;
mainPreferences.edit()
.putInt("transcribeAudioTrialCurrentNumber", transcribeAudioTrialCurrentNumber)
.apply();
}
}
public void updateTranscribeAudioTrialCooldownUntil(int until) {
if (until != transcribeAudioTrialCooldownUntil) {
transcribeAudioTrialCooldownUntil = until;
mainPreferences.edit()
.putInt("transcribeAudioTrialCooldownUntil", transcribeAudioTrialCooldownUntil)
.apply();
scheduleTranscriptionUpdate();
}
}
private void scheduleTranscriptionUpdate() {
AndroidUtilities.runOnUIThread(() -> {
AndroidUtilities.cancelRunOnUIThread(notifyTranscriptionAudioCooldownUpdate);
final long wait = transcribeAudioTrialCooldownUntil - getConnectionsManager().getCurrentTime();
if (wait > 0) {
AndroidUtilities.runOnUIThread(notifyTranscriptionAudioCooldownUpdate, wait);
}
});
}
private final Runnable notifyTranscriptionAudioCooldownUpdate = () -> getNotificationCenter().postNotificationName(NotificationCenter.updateTranscriptionLock);
public static class PeerColors { public static class PeerColors {
public static final int TYPE_NAME = 0;
public static final int TYPE_PROFILE = 1;
public final int type;
public final int hash;
public final ArrayList<PeerColor> colors = new ArrayList<>(); public final ArrayList<PeerColor> colors = new ArrayList<>();
private final LongSparseArray<PeerColor> colorsById = new LongSparseArray<>(); private final LongSparseArray<PeerColor> colorsById = new LongSparseArray<>();
private PeerColors() {} private PeerColors(int type, int hash) {
this.type = type;
this.hash = hash;
}
@Nullable @Nullable
public PeerColor getColor(int colorId) { public PeerColor getColor(int colorId) {
@ -3555,6 +3665,9 @@ public class MessagesController extends BaseController implements NotificationCe
@NonNull @NonNull
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (hash != 0) {
sb.append("@").append(hash).append("^");
}
for (int i = 0; i < colors.size(); ++i) { for (int i = 0; i < colors.size(); ++i) {
PeerColor color = colors.get(i); PeerColor color = colors.get(i);
if (i > 0) sb.append(";"); if (i > 0) sb.append(";");
@ -3563,15 +3676,24 @@ public class MessagesController extends BaseController implements NotificationCe
return sb.toString(); return sb.toString();
} }
public static PeerColors fromString(String str) { public static PeerColors fromString(int type, String str) {
if (str == null) return null; if (str == null) return null;
final PeerColors peerColors = new PeerColors(); int hash = 0;
if (str.startsWith("@")) {
int index = str.indexOf("^");
if (index >= 0) {
hash = Utilities.parseInt(str.substring(1, index));
str = str.substring(index + 1);
}
}
final PeerColors peerColors = new PeerColors(type, hash);
final String[] colorParts = str.split(";"); final String[] colorParts = str.split(";");
for (int i = 0; i < colorParts.length; ++i) { for (int i = 0; i < colorParts.length; ++i) {
PeerColor peerColor = PeerColor.fromString(colorParts[i]); PeerColor peerColor = PeerColor.fromString(colorParts[i]);
if (peerColor == null) if (peerColor == null)
continue; continue;
peerColors.colors.add(peerColor); if (!peerColor.hidden)
peerColors.colors.add(peerColor);
peerColors.colorsById.put(peerColor.id, peerColor); peerColors.colorsById.put(peerColor.id, peerColor);
} }
return peerColors; return peerColors;
@ -3581,13 +3703,33 @@ public class MessagesController extends BaseController implements NotificationCe
return Integer.parseUnsignedInt("ff" + str, 16); return Integer.parseUnsignedInt("ff" + str, 16);
} }
public static PeerColors fromTL(int type, TLRPC.TL_help_peerColors tl) {
if (tl == null) return null;
try {
PeerColors peerColors = new PeerColors(type, tl.hash);
for (int i = 0; i < tl.colors.size(); ++i) {
PeerColor peerColor = PeerColor.fromTL(tl.colors.get(i));
if (peerColor == null) continue;
if (peerColor.id < 7 && type == TYPE_NAME) continue;
if (!peerColor.hidden)
peerColors.colors.add(peerColor);
peerColors.colorsById.put(peerColor.id, peerColor);
}
return peerColors;
} catch (Exception e) {
FileLog.e(e);
}
return null;
}
public static PeerColors fromJSON( public static PeerColors fromJSON(
int type,
TLRPC.TL_jsonObject peer_colors, TLRPC.TL_jsonObject peer_colors,
TLRPC.TL_jsonObject dark_peer_colors, TLRPC.TL_jsonObject dark_peer_colors,
TLRPC.TL_jsonArray peer_colors_available TLRPC.TL_jsonArray peer_colors_available
) { ) {
try { try {
PeerColors peerColors = new PeerColors(); PeerColors peerColors = new PeerColors(type, 0);
if (peer_colors != null) { if (peer_colors != null) {
for (TLRPC.TL_jsonObjectValue pair : peer_colors.value) { for (TLRPC.TL_jsonObjectValue pair : peer_colors.value) {
final int id = Utilities.parseInt(pair.key); final int id = Utilities.parseInt(pair.key);
@ -3600,14 +3742,13 @@ public class MessagesController extends BaseController implements NotificationCe
PeerColor peerColor = new PeerColor(); PeerColor peerColor = new PeerColor();
try { try {
peerColor.id = id; peerColor.id = id;
peerColor.color1 = peerColor.darkColor1 = color(((TLRPC.TL_jsonString) val.get(0)).value); for (int i = 0; i < 6; ++i)
peerColor.color2 = peerColor.darkColor2 = val.size() > 1 ? color(((TLRPC.TL_jsonString) val.get(1)).value) : peerColor.color1; peerColor.colors[i] = peerColor.darkColors[i] = val.size() > i ? color(((TLRPC.TL_jsonString) val.get(i)).value) : peerColor.colors[0];
peerColor.color3 = peerColor.darkColor3 = val.size() > 2 ? color(((TLRPC.TL_jsonString) val.get(2)).value) : peerColor.color1;
} catch (Exception e2) { } catch (Exception e2) {
FileLog.e(e2); FileLog.e(e2);
continue; continue;
} }
if (peerColor.id < 7) continue; if (type == TYPE_NAME && peerColor.id < 7) continue;
peerColors.colorsById.put(id, peerColor); peerColors.colorsById.put(id, peerColor);
} }
} }
@ -3624,9 +3765,8 @@ public class MessagesController extends BaseController implements NotificationCe
if (peerColor == null) continue; if (peerColor == null) continue;
try { try {
peerColor.id = id; peerColor.id = id;
peerColor.darkColor1 = color(((TLRPC.TL_jsonString) val.get(0)).value); for (int i = 0; i < 6; ++i)
peerColor.darkColor2 = val.size() > 1 ? color(((TLRPC.TL_jsonString) val.get(1)).value) : peerColor.darkColor1; peerColor.darkColors[i] = val.size() > i ? color(((TLRPC.TL_jsonString) val.get(i)).value) : peerColor.darkColors[0];
peerColor.darkColor3 = val.size() > 2 ? color(((TLRPC.TL_jsonString) val.get(2)).value) : peerColor.darkColor1;
} catch (Exception e2) { } catch (Exception e2) {
FileLog.e(e2); FileLog.e(e2);
continue; continue;
@ -3655,16 +3795,44 @@ public class MessagesController extends BaseController implements NotificationCe
public static class PeerColor { public static class PeerColor {
public int id; public int id;
private int color1, color2, color3; public boolean hidden;
private int darkColor1, darkColor2, darkColor3; private final int[] colors = new int[6];
private final int[] darkColors = new int[6];
public int getColor1(boolean isDark) {
return (isDark ? darkColors : colors)[0];
}
public int getColor2(boolean isDark) {
return (isDark ? darkColors : colors)[1];
}
public int getColor3(boolean isDark) {
return (isDark ? darkColors : colors)[2];
}
public int getColor4(boolean isDark) {
return (isDark ? darkColors : colors)[3];
}
public int getColor5(boolean isDark) {
return (isDark ? darkColors : colors)[4];
}
public int getColor6(boolean isDark) {
return (isDark ? darkColors : colors)[5];
}
public int getColor1() { public int getColor1() {
return Theme.isCurrentThemeDark() ? darkColor1 : color1; return (Theme.isCurrentThemeDark() ? darkColors : colors)[0];
} }
public int getColor2() { public int getColor2() {
return Theme.isCurrentThemeDark() ? darkColor2 : color2; return (Theme.isCurrentThemeDark() ? darkColors : colors)[1];
} }
public int getColor3() { public int getColor3() {
return Theme.isCurrentThemeDark() ? darkColor3 : color3; return (Theme.isCurrentThemeDark() ? darkColors : colors)[2];
}
public int getColor4() {
return (Theme.isCurrentThemeDark() ? darkColors : colors)[3];
}
public int getColor5() {
return (Theme.isCurrentThemeDark() ? darkColors : colors)[4];
}
public int getColor6() {
return (Theme.isCurrentThemeDark() ? darkColors : colors)[5];
} }
public boolean hasColor2() { public boolean hasColor2() {
return getColor2() != getColor1(); return getColor2() != getColor1();
@ -3672,55 +3840,149 @@ public class MessagesController extends BaseController implements NotificationCe
public boolean hasColor3() { public boolean hasColor3() {
return getColor3() != getColor1(); return getColor3() != getColor1();
} }
public boolean hasColor2(boolean isDark) {
return getColor2(isDark) != getColor1(isDark);
}
public boolean hasColor3(boolean isDark) {
return getColor3(isDark) != getColor1(isDark);
}
public boolean hasColor6(boolean isDark) {
return getColor6(isDark) != getColor1(isDark);
}
public int getBgColor1(boolean isDark) {
return hasColor6(isDark) ? getColor3(isDark) : getColor2(isDark);
}
public int getBgColor2(boolean isDark) {
return hasColor6(isDark) ? getColor4(isDark) : getColor2(isDark);
}
public int getStoryColor1(boolean isDark) {
return hasColor6(isDark) ? getColor5(isDark) : getColor3(isDark);
}
public int getStoryColor2(boolean isDark) {
return hasColor6(isDark) ? getColor6(isDark) : getColor4(isDark);
}
public int getAvatarColor1() {
return ColorUtils.blendARGB(getBgColor2(false), getStoryColor2(false), .5f);
}
public int getAvatarColor2() {
return ColorUtils.blendARGB(getBgColor1(false), getStoryColor1(false), .5f);
}
public void appendString(StringBuilder sb) { public void appendString(StringBuilder sb) {
sb.append("#"); sb.append("#");
if (hidden) sb.append("H");
sb.append(id); sb.append(id);
sb.append("{"); sb.append("{");
sb.append(color1); sb.append(colors[0]);
if (color2 != color1) { if (colors[1] != colors[0]) {
sb.append(","); sb.append(",");
sb.append(color2); sb.append(colors[1]);
if (color3 != color1) { if (colors[2] != colors[0] || colors[3] != colors[0]) {
sb.append(","); sb.append(",");
sb.append(color3); sb.append(colors[2]);
sb.append(",");
sb.append(colors[3]);
if (colors[4] != colors[0] || colors[5] != colors[0]) {
sb.append(",");
sb.append(colors[4]);
sb.append(",");
sb.append(colors[5]);
}
} }
} }
if (darkColor1 != color1 || darkColor2 != color2 || darkColor3 != color3) { if (darkColors[0] != colors[0] || darkColors[1] != colors[1] || darkColors[2] != colors[2]) {
sb.append("@"); sb.append("@");
sb.append(darkColor1); sb.append(darkColors[0]);
if (darkColor2 != darkColor1) { if (darkColors[1] != darkColors[0]) {
sb.append(","); sb.append(",");
sb.append(darkColor2); sb.append(darkColors[1]);
if (darkColor3 != darkColor1) { if (darkColors[2] != darkColors[0] || darkColors[3] != darkColors[0]) {
sb.append(","); sb.append(",");
sb.append(darkColor3); sb.append(darkColors[2]);
sb.append(",");
sb.append(darkColors[3]);
if (darkColors[4] != darkColors[0] || darkColors[5] != darkColors[0]) {
sb.append(",");
sb.append(darkColors[4]);
sb.append(",");
sb.append(darkColors[5]);
}
} }
} }
} }
sb.append("}"); sb.append("}");
} }
public static PeerColor fromTL(TLRPC.TL_help_peerColorOption tl) {
if (tl == null) return null;
final PeerColor peerColor = new PeerColor();
peerColor.id = tl.color_id;
peerColor.hidden = tl.hidden;
System.arraycopy(optionToColors(tl.colors), 0, peerColor.colors, 0, 6);
System.arraycopy(optionToColors(tl.dark_colors), 0, peerColor.darkColors, 0, 6);
return peerColor;
}
public static int[] optionToColors(TLRPC.help_PeerColorSet set) {
final int[] colors = new int[] {0, 0, 0, 0, 0, 0};
ArrayList<Integer> finalColorList = null;
if (set instanceof TLRPC.TL_help_peerColorSet) {
finalColorList = ((TLRPC.TL_help_peerColorSet) set).colors;
} else if (set instanceof TLRPC.TL_help_peerColorProfileSet) {
ArrayList<Integer> colorList1 = ((TLRPC.TL_help_peerColorProfileSet) set).palette_colors;
ArrayList<Integer> colorList2 = ((TLRPC.TL_help_peerColorProfileSet) set).bg_colors;
ArrayList<Integer> colorList3 = ((TLRPC.TL_help_peerColorProfileSet) set).story_colors;
finalColorList = new ArrayList<Integer>();
if (colorList1 != null) {
for (int i = 0; i < Math.min(2, colorList1.size()); ++i)
finalColorList.add(colorList1.get(i));
}
if (colorList2 != null) {
for (int i = 0; i < Math.min(2, colorList2.size()); ++i)
finalColorList.add(colorList2.get(i));
}
if (colorList3 != null) {
for (int i = 0; i < Math.min(2, colorList3.size()); ++i)
finalColorList.add(colorList3.get(i));
}
}
if (finalColorList != null) {
if (finalColorList.size() > 0) {
Arrays.fill(colors, 0xFF000000 | finalColorList.get(0));
}
for (int i = 0; i < Math.min(colors.length, finalColorList.size()); ++i) {
colors[i] = 0xFF000000 | finalColorList.get(i);
}
}
return colors;
}
public static PeerColor fromString(String string) { public static PeerColor fromString(String string) {
if (string == null || string.isEmpty() || string.charAt(0) != '#') if (string == null || string.isEmpty() || string.charAt(0) != '#')
return null; return null;
int startIndex = 1;
boolean hidden = string.length() > 1 && string.charAt(1) == 'H';
if (hidden) {
startIndex++;
}
int index = string.indexOf('{'); int index = string.indexOf('{');
if (index < 0) return null; if (index < 0) return null;
try { try {
final PeerColor peerColor = new PeerColor(); final PeerColor peerColor = new PeerColor();
peerColor.id = Utilities.parseInt(string.substring(1, index)); peerColor.id = Utilities.parseInt(string.substring(startIndex, index));
peerColor.hidden = hidden;
final String[] parts = string.substring(index + 1, string.length() - 1).split("@"); final String[] parts = string.substring(index + 1, string.length() - 1).split("@");
String[] colorsString = parts[0].split(","); String[] colorsString = parts[0].split(",");
peerColor.color1 = Utilities.parseInt(colorsString[0]); for (int i = 0; i < 6; ++i)
peerColor.color2 = colorsString.length >= 2 ? Utilities.parseInt(colorsString[1]) : peerColor.color1; peerColor.colors[i] = colorsString.length >= i + 1 ? Utilities.parseInt(colorsString[i]) : peerColor.colors[0];
peerColor.color3 = colorsString.length >= 3 ? Utilities.parseInt(colorsString[2]) : peerColor.color1;
if (parts.length >= 2) { if (parts.length >= 2) {
colorsString = parts[1].split(","); colorsString = parts[1].split(",");
peerColor.darkColor1 = Utilities.parseInt(colorsString[0]); for (int i = 0; i < 6; ++i)
peerColor.darkColor2 = colorsString.length >= 2 ? Utilities.parseInt(colorsString[1]) : peerColor.color1; peerColor.darkColors[i] = colorsString.length >= i + 1 ? Utilities.parseInt(colorsString[i]) : peerColor.darkColors[0];
peerColor.darkColor3 = colorsString.length >= 3 ? Utilities.parseInt(colorsString[2]) : peerColor.color1;
} else { } else {
peerColor.darkColor1 = peerColor.color1; for (int i = 0; i < 6; ++i)
peerColor.darkColor2 = peerColor.color2; peerColor.darkColors[i] = peerColor.colors[i];
peerColor.darkColor3 = peerColor.color3;
} }
return peerColor; return peerColor;
} catch (Exception e) { } catch (Exception e) {
@ -3808,9 +4070,9 @@ public class MessagesController extends BaseController implements NotificationCe
public void updateConfig(final TLRPC.TL_config config) { public void updateConfig(final TLRPC.TL_config config) {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
// TODO: receive those removed parameters from appconfig
getDownloadController().loadAutoDownloadConfig(false); getDownloadController().loadAutoDownloadConfig(false);
loadAppConfig(true); loadAppConfig(true);
checkPeerColors(true);
remoteConfigLoaded = true; remoteConfigLoaded = true;
maxMegagroupCount = config.megagroup_size_max; maxMegagroupCount = config.megagroup_size_max;
maxGroupCount = config.chat_size_max; maxGroupCount = config.chat_size_max;
@ -4180,7 +4442,7 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (uploadingWallpaper != null && wallPaper != null) { if (uploadingWallpaper != null && uploadingWallpaperInfo.requestIds != null && wallPaper != null) {
wallPaper.settings = settings; wallPaper.settings = settings;
wallPaper.flags |= 4; wallPaper.flags |= 4;
overrideWallpaperInfo.slug = wallPaper.slug; overrideWallpaperInfo.slug = wallPaper.slug;
@ -4195,7 +4457,7 @@ public class MessagesController extends BaseController implements NotificationCe
ImageLoader.getInstance().replaceImageInCache(oldKey, newKey, ImageLocation.getForDocument(image, wallPaper.document), false); ImageLoader.getInstance().replaceImageInCache(oldKey, newKey, ImageLocation.getForDocument(image, wallPaper.document), false);
} }
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.wallpapersNeedReload, wallPaper.slug); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.wallpapersNeedReload, wallPaper.slug);
if (overrideWallpaperInfo.dialogId != 0) { if (uploadingWallpaperInfo.requestIds != null && overrideWallpaperInfo.dialogId != 0) {
uploadingWallpaperInfo.requestIds.add(ChatThemeController.getInstance(currentAccount).setWallpaperToUser(overrideWallpaperInfo.dialogId, uploadingWallpaperFinal, overrideWallpaperInfo, null, null)); uploadingWallpaperInfo.requestIds.add(ChatThemeController.getInstance(currentAccount).setWallpaperToUser(overrideWallpaperInfo.dialogId, uploadingWallpaperFinal, overrideWallpaperInfo, null, null));
} }
} }
@ -5518,6 +5780,7 @@ public class MessagesController extends BaseController implements NotificationCe
dialog.ttl_period = res.full_chat.ttl_period; dialog.ttl_period = res.full_chat.ttl_period;
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload); getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
} }
dialog.view_forum_as_messages = res.full_chat.view_forum_as_messages;
} }
}); });
} else { } else {
@ -14064,14 +14327,18 @@ public class MessagesController extends BaseController implements NotificationCe
public void generateJoinMessage(long chatId, boolean ignoreLeft) { public void generateJoinMessage(long chatId, boolean ignoreLeft) {
TLRPC.Chat chat = getChat(chatId); TLRPC.Chat chat = getChat(chatId);
if (chat == null || !ChatObject.isChannel(chatId, currentAccount) || (chat.left || chat.kicked) && !ignoreLeft) { if (chat == null || !ChatObject.isChannel(chatId, currentAccount) || ChatObject.isNotInChat(chat) && !ignoreLeft || chat.creator) {
return; return;
} }
TLRPC.TL_messageService message = new TLRPC.TL_messageService(); TLRPC.TL_messageService message = new TLRPC.TL_messageService();
message.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID; message.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
message.local_id = message.id = getUserConfig().getNewMessageId(); message.local_id = message.id = getUserConfig().getNewMessageId();
message.date = getConnectionsManager().getCurrentTime(); if (chat instanceof TLRPC.TL_channel && !ignoreLeft) {
message.date = chat.date;
} else {
message.date = getConnectionsManager().getCurrentTime();
}
message.from_id = new TLRPC.TL_peerUser(); message.from_id = new TLRPC.TL_peerUser();
message.from_id.user_id = getUserConfig().getClientUserId(); message.from_id.user_id = getUserConfig().getClientUserId();
message.peer_id = new TLRPC.TL_peerChannel(); message.peer_id = new TLRPC.TL_peerChannel();
@ -14144,67 +14411,65 @@ public class MessagesController extends BaseController implements NotificationCe
TLRPC.TL_channels_channelParticipant res = (TLRPC.TL_channels_channelParticipant) response; TLRPC.TL_channels_channelParticipant res = (TLRPC.TL_channels_channelParticipant) response;
if (res != null && res.participant instanceof TLRPC.TL_channelParticipantSelf) { if (res != null && res.participant instanceof TLRPC.TL_channelParticipantSelf) {
TLRPC.TL_channelParticipantSelf selfParticipant = (TLRPC.TL_channelParticipantSelf) res.participant; TLRPC.TL_channelParticipantSelf selfParticipant = (TLRPC.TL_channelParticipantSelf) res.participant;
if (selfParticipant.inviter_id != getUserConfig().getClientUserId() || selfParticipant.via_invite) { if (chat.megagroup && getMessagesStorage().isMigratedChat(chat.id)) {
if (chat.megagroup && getMessagesStorage().isMigratedChat(chat.id)) { return;
return;
}
AndroidUtilities.runOnUIThread(() -> {
putUsers(res.users, false);
putChats(res.chats, false);
});
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
ArrayList<MessageObject> pushMessages;
if (createMessage && Math.abs(getConnectionsManager().getCurrentTime() - res.participant.date) < 24 * 60 * 60 && !getMessagesStorage().hasInviteMeMessage(chatId)) {
TLRPC.TL_messageService message = new TLRPC.TL_messageService();
message.media_unread = true;
message.unread = true;
message.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
message.post = true;
message.local_id = message.id = getUserConfig().getNewMessageId();
message.date = res.participant.date;
if (selfParticipant.inviter_id != getUserConfig().getClientUserId()) {
message.action = new TLRPC.TL_messageActionChatAddUser();
} else if (selfParticipant.via_invite) {
message.action = new TLRPC.TL_messageActionChatJoinedByRequest();
}
message.from_id = new TLRPC.TL_peerUser();
message.from_id.user_id = res.participant.inviter_id;
message.action.users.add(getUserConfig().getClientUserId());
message.peer_id = new TLRPC.TL_peerChannel();
message.peer_id.channel_id = chatId;
message.dialog_id = -chatId;
getUserConfig().saveConfig(false);
pushMessages = new ArrayList<>();
ArrayList<TLRPC.Message> messagesArr = new ArrayList<>();
ConcurrentHashMap<Long, TLRPC.User> usersDict = new ConcurrentHashMap<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User user = res.users.get(a);
usersDict.put(user.id, user);
}
messagesArr.add(message);
MessageObject obj = new MessageObject(currentAccount, message, usersDict, true, false);
pushMessages.add(obj);
getMessagesStorage().getStorageQueue().postRunnable(() -> AndroidUtilities.runOnUIThread(() -> getNotificationsController().processNewMessages(pushMessages, true, false, null)));
getMessagesStorage().putMessages(messagesArr, true, true, false, 0, false, 0);
} else {
pushMessages = null;
}
getMessagesStorage().saveChatInviter(chatId, res.participant.inviter_id);
AndroidUtilities.runOnUIThread(() -> {
gettingChatInviters.delete(chatId);
if (pushMessages != null) {
updateInterfaceWithMessages(-chatId, pushMessages, false);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
getNotificationCenter().postNotificationName(NotificationCenter.didLoadChatInviter, chatId, res.participant.inviter_id);
});
} }
AndroidUtilities.runOnUIThread(() -> {
putUsers(res.users, false);
putChats(res.chats, false);
});
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
ArrayList<MessageObject> pushMessages;
if (createMessage && Math.abs(getConnectionsManager().getCurrentTime() - res.participant.date) < 24 * 60 * 60 && !getMessagesStorage().hasInviteMeMessage(chatId)) {
TLRPC.TL_messageService message = new TLRPC.TL_messageService();
message.flags = TLRPC.MESSAGE_FLAG_HAS_FROM_ID;
message.local_id = message.id = getUserConfig().getNewMessageId();
message.date = res.participant.date;
message.from_id = new TLRPC.TL_peerUser();
message.from_id.user_id = res.participant.inviter_id;
message.peer_id = new TLRPC.TL_peerChannel();
message.peer_id.channel_id = chatId;
message.media_unread = true;
message.unread = true;
message.post = true;
if (!selfParticipant.via_invite || selfParticipant.inviter_id != getUserConfig().getClientUserId()) {
message.action = new TLRPC.TL_messageActionChatAddUser();
} else {
message.action = new TLRPC.TL_messageActionChatJoinedByRequest();
}
message.action.users.add(getUserConfig().getClientUserId());
message.dialog_id = -chatId;
getUserConfig().saveConfig(false);
pushMessages = new ArrayList<>();
ArrayList<TLRPC.Message> messagesArr = new ArrayList<>();
ConcurrentHashMap<Long, TLRPC.User> usersDict = new ConcurrentHashMap<>();
for (int a = 0; a < res.users.size(); a++) {
TLRPC.User user = res.users.get(a);
usersDict.put(user.id, user);
}
messagesArr.add(message);
MessageObject obj = new MessageObject(currentAccount, message, usersDict, true, false);
pushMessages.add(obj);
getMessagesStorage().getStorageQueue().postRunnable(() -> AndroidUtilities.runOnUIThread(() -> getNotificationsController().processNewMessages(pushMessages, true, false, null)));
getMessagesStorage().putMessages(messagesArr, true, true, false, 0, false, 0);
} else {
pushMessages = null;
}
getMessagesStorage().saveChatInviter(chatId, res.participant.inviter_id);
AndroidUtilities.runOnUIThread(() -> {
gettingChatInviters.delete(chatId);
if (pushMessages != null) {
updateInterfaceWithMessages(-chatId, pushMessages, false);
getNotificationCenter().postNotificationName(NotificationCenter.dialogsNeedReload);
}
getNotificationCenter().postNotificationName(NotificationCenter.didLoadChatInviter, chatId, res.participant.inviter_id);
});
} }
}); });
} }
@ -14339,6 +14604,8 @@ public class MessagesController extends BaseController implements NotificationCe
return ((TLRPC.TL_updateChannelUserTyping) update).channel_id; return ((TLRPC.TL_updateChannelUserTyping) update).channel_id;
} else if (update instanceof TLRPC.TL_updatePinnedChannelMessages) { } else if (update instanceof TLRPC.TL_updatePinnedChannelMessages) {
return ((TLRPC.TL_updatePinnedChannelMessages) update).channel_id; return ((TLRPC.TL_updatePinnedChannelMessages) update).channel_id;
} else if (update instanceof TLRPC.TL_updateChannelViewForumAsMessages) {
return ((TLRPC.TL_updateChannelViewForumAsMessages) update).channel_id;
} else { } else {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.e("trying to get unknown update channel_id for " + update); FileLog.e("trying to get unknown update channel_id for " + update);
@ -15394,6 +15661,11 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread = new ArrayList<>(); updatesOnMainThread = new ArrayList<>();
} }
updatesOnMainThread.add(baseUpdate); updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updatePeerWallpaper) {
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateUserEmojiStatus) { } else if (baseUpdate instanceof TLRPC.TL_updateUserEmojiStatus) {
interfaceUpdateMask |= UPDATE_MASK_EMOJI_STATUS; interfaceUpdateMask |= UPDATE_MASK_EMOJI_STATUS;
if (updatesOnMainThread == null) { if (updatesOnMainThread == null) {
@ -16153,6 +16425,11 @@ public class MessagesController extends BaseController implements NotificationCe
updatesOnMainThread = new ArrayList<>(); updatesOnMainThread = new ArrayList<>();
} }
updatesOnMainThread.add(baseUpdate); updatesOnMainThread.add(baseUpdate);
} else if (baseUpdate instanceof TLRPC.TL_updateChannelViewForumAsMessages) {
if (updatesOnMainThread == null) {
updatesOnMainThread = new ArrayList<>();
}
updatesOnMainThread.add(baseUpdate);
} }
} }
if (messages != null) { if (messages != null) {
@ -16285,6 +16562,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (update.user_id == getUserConfig().getClientUserId()) { if (update.user_id == getUserConfig().getClientUserId()) {
getNotificationsController().setLastOnlineFromOtherDevice(update.status.expires); getNotificationsController().setLastOnlineFromOtherDevice(update.status.expires);
} }
} else if (baseUpdate instanceof TLRPC.TL_updatePeerWallpaper) {
TLRPC.TL_updatePeerWallpaper update = (TLRPC.TL_updatePeerWallpaper) baseUpdate;
ChatThemeController.getInstance(currentAccount).processUpdate(update);
} else if (baseUpdate instanceof TLRPC.TL_updateUserEmojiStatus) { } else if (baseUpdate instanceof TLRPC.TL_updateUserEmojiStatus) {
TLRPC.TL_updateUserEmojiStatus update = (TLRPC.TL_updateUserEmojiStatus) baseUpdate; TLRPC.TL_updateUserEmojiStatus update = (TLRPC.TL_updateUserEmojiStatus) baseUpdate;
TLRPC.User currentUser = getUser(update.user_id); TLRPC.User currentUser = getUser(update.user_id);
@ -16958,6 +17238,27 @@ public class MessagesController extends BaseController implements NotificationCe
TLRPC.TL_updateSentStoryReaction updateReaction = (TLRPC.TL_updateSentStoryReaction) baseUpdate; TLRPC.TL_updateSentStoryReaction updateReaction = (TLRPC.TL_updateSentStoryReaction) baseUpdate;
long dialogId = DialogObject.getPeerDialogId(updateReaction.peer); long dialogId = DialogObject.getPeerDialogId(updateReaction.peer);
getStoriesController().updateStoryReaction(dialogId, updateReaction.story_id, updateReaction.reaction); getStoriesController().updateStoryReaction(dialogId, updateReaction.story_id, updateReaction.reaction);
} else if (baseUpdate instanceof TLRPC.TL_updateChannelViewForumAsMessages) {
TLRPC.TL_updateChannelViewForumAsMessages update = (TLRPC.TL_updateChannelViewForumAsMessages) baseUpdate;
TLRPC.ChatFull chatFull = getChatFull(update.channel_id);
if (chatFull != null) {
if (chatFull.view_forum_as_messages != update.enabled) {
chatFull.view_forum_as_messages = update.enabled;
if (update.enabled) {
chatFull.flags2 |= 64;
} else {
chatFull.flags2 &= ~64;
}
getMessagesStorage().updateChatInfo(chatFull, false);
}
} else {
getMessagesController().loadFullChat(update.channel_id, 0, true);
}
TLRPC.Dialog dialog = getDialog(-update.channel_id);
if (dialog != null) {
dialog.view_forum_as_messages = update.enabled;
}
getMessagesStorage().setDialogViewThreadAsMessages(-update.channel_id, update.enabled);
} }
} }
if (editor != null) { if (editor != null) {
@ -17616,6 +17917,8 @@ public class MessagesController extends BaseController implements NotificationCe
messageObject.sponsoredInfo = sponsoredMessage.sponsor_info; messageObject.sponsoredInfo = sponsoredMessage.sponsor_info;
messageObject.sponsoredAdditionalInfo = sponsoredMessage.additional_info; messageObject.sponsoredAdditionalInfo = sponsoredMessage.additional_info;
messageObject.sponsoredWebPage = sponsoredMessage.webpage; messageObject.sponsoredWebPage = sponsoredMessage.webpage;
messageObject.sponsoredBotApp = sponsoredMessage.app;
messageObject.sponsoredButtonText = sponsoredMessage.button_text;
result.add(messageObject); result.add(messageObject);
} }
} }
@ -18436,13 +18739,13 @@ public class MessagesController extends BaseController implements NotificationCe
fragment.presentFragment(new ProfileActivity(args)); fragment.presentFragment(new ProfileActivity(args));
} else if (type == 2) { } else if (type == 2) {
if (ChatObject.isForum(chat)) { if (ChatObject.isForum(chat)) {
fragment.presentFragment(new TopicsFragment(args), true, true); fragment.presentFragment(TopicsFragment.getTopicsOrChat(fragment, args), true, true);
} else { } else {
fragment.presentFragment(new ChatActivity(args), true, true); fragment.presentFragment(new ChatActivity(args), true, true);
} }
} else { } else {
if (ChatObject.isForum(chat)) { if (ChatObject.isForum(chat)) {
fragment.presentFragment(new TopicsFragment(args), closeLast); fragment.presentFragment(TopicsFragment.getTopicsOrChat(fragment, args), closeLast);
} else { } else {
fragment.presentFragment(new ChatActivity(args), closeLast); fragment.presentFragment(new ChatActivity(args), closeLast);
} }
@ -18656,6 +18959,48 @@ public class MessagesController extends BaseController implements NotificationCe
}); });
} }
public void setCustomChatReactions(long chatId, int type, List<TLRPC.Reaction> reactions, Utilities.Callback<TLRPC.TL_error> onError, Runnable onSuccess) {
TLRPC.TL_messages_setChatAvailableReactions req = new TLRPC.TL_messages_setChatAvailableReactions();
req.peer = getInputPeer(-chatId);
if (type == ChatReactionsEditActivity.SELECT_TYPE_NONE || reactions.isEmpty()) {
req.available_reactions = new TLRPC.TL_chatReactionsNone();
} else if (type == ChatReactionsEditActivity.SELECT_TYPE_ALL) {
req.available_reactions = new TLRPC.TL_chatReactionsAll();
} else {
TLRPC.TL_chatReactionsSome someReactions = new TLRPC.TL_chatReactionsSome();
req.available_reactions = someReactions;
someReactions.reactions.addAll(reactions);
}
getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
processUpdates((TLRPC.Updates) response, false);
TLRPC.ChatFull full = getChatFull(chatId);
if (full != null) {
if (full instanceof TLRPC.TL_chatFull) {
full.flags |= 262144;
}
if (full instanceof TLRPC.TL_channelFull) {
full.flags |= 1073741824;
}
full.available_reactions = req.available_reactions;
getMessagesStorage().updateChatInfo(full, false);
}
AndroidUtilities.runOnUIThread(() -> {
if (onSuccess != null) {
onSuccess.run();
}
getNotificationCenter().postNotificationName(NotificationCenter.chatAvailableReactionsUpdated, chatId, 0);
});
} else {
AndroidUtilities.runOnUIThread(() -> {
if (onError != null) {
onError.run(error);
}
});
}
});
}
public void setChatReactions(long chatId, int type, List<String> reactions) { public void setChatReactions(long chatId, int type, List<String> reactions) {
TLRPC.TL_messages_setChatAvailableReactions req = new TLRPC.TL_messages_setChatAvailableReactions(); TLRPC.TL_messages_setChatAvailableReactions req = new TLRPC.TL_messages_setChatAvailableReactions();
req.peer = getInputPeer(-chatId); req.peer = getInputPeer(-chatId);
@ -19143,4 +19488,85 @@ public class MessagesController extends BaseController implements NotificationCe
return false; return false;
} }
} }
public static class ChannelRecommendations {
public boolean wasPremium;
public final ArrayList<TLRPC.Chat> chats = new ArrayList<>();
public int more;
public static boolean hasRecommendations(ChannelRecommendations rec) {
return rec != null && !rec.chats.isEmpty();
}
public static boolean hasRecommendations(int currentAccount, long chatId) {
return hasRecommendations(MessagesController.getInstance(currentAccount).getChannelRecommendations(chatId));
}
}
private HashMap<Long, ChannelRecommendations> cachedChannelRecommendations;
public ChannelRecommendations getChannelRecommendations(long chatId) {
TLRPC.InputChannel inputChannel = getInputChannel(chatId);
if (inputChannel == null) {
return null;
}
if (cachedChannelRecommendations == null) {
cachedChannelRecommendations = new HashMap<>();
}
final boolean isPremium = getUserConfig().isPremium();
ChannelRecommendations rec = null;
if (cachedChannelRecommendations.containsKey(chatId)) {
rec = cachedChannelRecommendations.get(chatId);
if (rec != null && rec.wasPremium == isPremium) {
return rec;
}
}
cachedChannelRecommendations.put(chatId, null);
TLRPC.TL_channels_getChannelRecommendations req = new TLRPC.TL_channels_getChannelRecommendations();
req.channel = inputChannel;
getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.messages_Chats) {
ArrayList<TLRPC.Chat> chats = ((TLRPC.messages_Chats) res).chats;
putChats(chats, false);
ChannelRecommendations newrec = new ChannelRecommendations();
newrec.wasPremium = isPremium;
newrec.chats.addAll(chats);
if (res instanceof TLRPC.TL_messages_chatsSlice) {
newrec.more = Math.max(0, ((TLRPC.TL_messages_chatsSlice) res).count - chats.size());
} else if (!getUserConfig().isPremium() && BuildVars.DEBUG_PRIVATE_VERSION) {
newrec.more = 90;
}
cachedChannelRecommendations.put(chatId, newrec);
getNotificationCenter().postNotificationName(NotificationCenter.channelRecommendationsLoaded, chatId);
}
}));
return rec;
}
public void checkPeerColors(boolean force) {
if (peerColors == null || force) {
TLRPC.TL_help_getPeerColors req = new TLRPC.TL_help_getPeerColors();
req.hash = peerColors != null ? peerColors.hash : 0;
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.TL_help_peerColors) {
AndroidUtilities.runOnUIThread(() -> {
peerColors = PeerColors.fromTL(PeerColors.TYPE_NAME, (TLRPC.TL_help_peerColors) res);
mainPreferences.edit().putString("peerColors", peerColors.toString()).apply();
});
}
});
}
if (profilePeerColors == null || force) {
TLRPC.TL_help_getPeerProfileColors req = new TLRPC.TL_help_getPeerProfileColors();
req.hash = profilePeerColors != null ? profilePeerColors.hash : 0;
getConnectionsManager().sendRequest(req, (res, err) -> {
if (res instanceof TLRPC.TL_help_peerColors) {
AndroidUtilities.runOnUIThread(() -> {
profilePeerColors = PeerColors.fromTL(PeerColors.TYPE_PROFILE, (TLRPC.TL_help_peerColors) res);
mainPreferences.edit().putString("profilePeerColors", profilePeerColors.toString()).apply();
});
}
});
}
}
} }

View file

@ -2070,6 +2070,7 @@ public class MessagesStorage extends BaseController {
dialog.unread_mentions_count = cursor.intValue(15); dialog.unread_mentions_count = cursor.intValue(15);
int dialog_flags = cursor.intValue(16); int dialog_flags = cursor.intValue(16);
dialog.unread_mark = (dialog_flags & 1) != 0; dialog.unread_mark = (dialog_flags & 1) != 0;
dialog.view_forum_as_messages = (dialog_flags & 64) != 0;
long flags = cursor.longValue(8); long flags = cursor.longValue(8);
int low_flags = (int) flags; int low_flags = (int) flags;
dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); dialog.notify_settings = new TLRPC.TL_peerNotifySettings();
@ -8400,6 +8401,9 @@ public class MessagesStorage extends BaseController {
data = cursor.byteBufferValue(6); data = cursor.byteBufferValue(6);
if (data != null) { if (data != null) {
message.replyStory = TL_stories.StoryItem.TLdeserialize(data, data.readInt32(false), false); message.replyStory = TL_stories.StoryItem.TLdeserialize(data, data.readInt32(false), false);
if (message.replyStory != null && message.replyStory.fwd_from != null) {
addLoadPeerInfo(message.replyStory.fwd_from.from, usersToLoad, chatsToLoad);
}
data.reuse(); data.reuse();
} }
} }
@ -11264,7 +11268,7 @@ public class MessagesStorage extends BaseController {
dids.add(key); dids.add(key);
if (exists) { if (exists) {
if (messageId >= last_mid || DialogObject.isEncryptedDialog(key)) { if (message == null || message.date > dialog_date || DialogObject.isEncryptedDialog(key)) {
state_dialogs_update.requery(); state_dialogs_update.requery();
state_dialogs_update.bindInteger(1, message != null && (!doNotUpdateDialogDate || dialog_date == 0) ? message.date : dialog_date); state_dialogs_update.bindInteger(1, message != null && (!doNotUpdateDialogDate || dialog_date == 0) ? message.date : dialog_date);
state_dialogs_update.bindInteger(2, old_unread_count + unread_count); state_dialogs_update.bindInteger(2, old_unread_count + unread_count);
@ -11561,7 +11565,7 @@ public class MessagesStorage extends BaseController {
forumTopic.topicStartMessage = message; forumTopic.topicStartMessage = message;
forumTopic.top_message = message.id; forumTopic.top_message = message.id;
forumTopic.topMessage = message; forumTopic.topMessage = message;
forumTopic.from_id = getMessagesController().getPeer(getUserConfig().clientUserId); forumTopic.from_id = message.from_id;
forumTopic.notify_settings = new TLRPC.TL_peerNotifySettings(); forumTopic.notify_settings = new TLRPC.TL_peerNotifySettings();
forumTopic.unread_count = 0; forumTopic.unread_count = 0;
@ -12764,6 +12768,7 @@ public class MessagesStorage extends BaseController {
dialog.pinned = dialog.pinnedNum != 0; dialog.pinned = dialog.pinnedNum != 0;
int dialog_flags = cursor.intValue(14); int dialog_flags = cursor.intValue(14);
dialog.unread_mark = (dialog_flags & 1) != 0; dialog.unread_mark = (dialog_flags & 1) != 0;
dialog.view_forum_as_messages = (dialog_flags & 64) != 0;
dialog.folder_id = cursor.intValue(15); dialog.folder_id = cursor.intValue(15);
dialog.unread_reactions_count = cursor.intValue(17); dialog.unread_reactions_count = cursor.intValue(17);
long groupMessagesId = cursor.longValue(18); long groupMessagesId = cursor.longValue(18);
@ -14163,6 +14168,19 @@ public class MessagesStorage extends BaseController {
} }
} }
} }
if (message.media instanceof TLRPC.TL_messageMediaStory && message.media.storyItem != null && message.media.storyItem.fwd_from != null) {
addLoadPeerInfo(message.media.storyItem.fwd_from.from, usersToLoad, chatsToLoad);
}
if (message.media instanceof TLRPC.TL_messageMediaWebPage && message.media.webpage != null && message.media.webpage.attributes != null) {
for (int i = 0; i < message.media.webpage.attributes.size(); ++i) {
if (message.media.webpage.attributes.get(i) instanceof TLRPC.TL_webPageAttributeStory) {
TLRPC.TL_webPageAttributeStory attr = (TLRPC.TL_webPageAttributeStory) message.media.webpage.attributes.get(i);
if (attr.storyItem != null && attr.storyItem.fwd_from != null) {
addLoadPeerInfo(attr.storyItem.fwd_from.from, usersToLoad, chatsToLoad);
}
}
}
}
if (message.media.peer != null) { if (message.media.peer != null) {
addLoadPeerInfo(message.media.peer, usersToLoad, chatsToLoad); addLoadPeerInfo(message.media.peer, usersToLoad, chatsToLoad);
} }
@ -14195,7 +14213,7 @@ public class MessagesStorage extends BaseController {
} }
} }
private static void addLoadPeerInfo(TLRPC.Peer peer, ArrayList<Long> usersToLoad, ArrayList<Long> chatsToLoad) { public static void addLoadPeerInfo(TLRPC.Peer peer, ArrayList<Long> usersToLoad, ArrayList<Long> chatsToLoad) {
if (peer instanceof TLRPC.TL_peerUser) { if (peer instanceof TLRPC.TL_peerUser) {
if (!usersToLoad.contains(peer.user_id)) { if (!usersToLoad.contains(peer.user_id)) {
usersToLoad.add(peer.user_id); usersToLoad.add(peer.user_id);
@ -14296,6 +14314,7 @@ public class MessagesStorage extends BaseController {
dialog.unread_mentions_count = cursor.intValue(15); dialog.unread_mentions_count = cursor.intValue(15);
int dialog_flags = cursor.intValue(16); int dialog_flags = cursor.intValue(16);
dialog.unread_mark = (dialog_flags & 1) != 0; dialog.unread_mark = (dialog_flags & 1) != 0;
dialog.view_forum_as_messages = (dialog_flags & 64) != 0;
long flags = cursor.longValue(8); long flags = cursor.longValue(8);
int low_flags = (int) flags; int low_flags = (int) flags;
dialog.notify_settings = new TLRPC.TL_peerNotifySettings(); dialog.notify_settings = new TLRPC.TL_peerNotifySettings();
@ -14804,6 +14823,9 @@ public class MessagesStorage extends BaseController {
if (dialog.unread_mark) { if (dialog.unread_mark) {
flags |= 1; flags |= 1;
} }
if (dialog.view_forum_as_messages) {
flags |= 64;
}
state_dialogs.bindInteger(12, flags); state_dialogs.bindInteger(12, flags);
state_dialogs.bindInteger(13, dialog.folder_id); state_dialogs.bindInteger(13, dialog.folder_id);
NativeByteBuffer data; NativeByteBuffer data;
@ -15113,6 +15135,46 @@ public class MessagesStorage extends BaseController {
}); });
} }
public void setDialogViewThreadAsMessages(long did, boolean enabled) {
storageQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
try {
int flags = 0;
SQLiteCursor cursor = null;
try {
cursor = database.queryFinalized("SELECT flags FROM dialogs WHERE did = " + did);
if (cursor.next()) {
flags = cursor.intValue(0);
}
} catch (Exception e) {
checkSQLException(e);
} finally {
if (cursor != null) {
cursor.dispose();
}
}
if (enabled) {
flags |= 64;
} else {
flags &= ~64;
}
state = database.executeFast("UPDATE dialogs SET flags = ? WHERE did = ?");
state.bindInteger(1, flags);
state.bindLong(2, did);
state.step();
state.dispose();
} catch (Exception e) {
checkSQLException(e);
} finally {
if (state != null) {
state.dispose();
}
}
});
}
public void resetAllUnreadCounters(boolean muted) { public void resetAllUnreadCounters(boolean muted) {
for (int a = 0, N = dialogFilters.size(); a < N; a++) { for (int a = 0, N = dialogFilters.size(); a < N; a++) {
MessagesController.DialogFilter filter = dialogFilters.get(a); MessagesController.DialogFilter filter = dialogFilters.get(a);

View file

@ -137,6 +137,7 @@ public class NotificationCenter {
public static final int animatedEmojiDocumentLoaded = totalEvents++; public static final int animatedEmojiDocumentLoaded = totalEvents++;
public static final int recentEmojiStatusesUpdate = totalEvents++; public static final int recentEmojiStatusesUpdate = totalEvents++;
public static final int updateSearchSettings = totalEvents++; public static final int updateSearchSettings = totalEvents++;
public static final int updateTranscriptionLock = totalEvents++;
public static final int messageTranslated = totalEvents++; public static final int messageTranslated = totalEvents++;
public static final int messageTranslating = totalEvents++; public static final int messageTranslating = totalEvents++;
@ -219,6 +220,7 @@ public class NotificationCenter {
public static final int storiesSendAsUpdate = totalEvents++; public static final int storiesSendAsUpdate = totalEvents++;
public static final int unconfirmedAuthUpdate = totalEvents++; public static final int unconfirmedAuthUpdate = totalEvents++;
public static final int dialogPhotosUpdate = totalEvents++; public static final int dialogPhotosUpdate = totalEvents++;
public static final int channelRecommendationsLoaded = totalEvents++;
//global //global
public static final int pushMessagesUpdated = totalEvents++; public static final int pushMessagesUpdated = totalEvents++;

View file

@ -156,6 +156,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
replyTo.quote_entities = new ArrayList<>(replyTo.quote_entities); replyTo.quote_entities = new ArrayList<>(replyTo.quote_entities);
replyTo.flags |= 8; replyTo.flags |= 8;
} }
replyTo.flags |= 16;
replyTo.quote_offset = replyQuote.start;
} }
} }
if (replyQuote != null && replyQuote.message != null) { if (replyQuote != null && replyQuote.message != null) {
@ -189,6 +191,10 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
replyTo.flags |= 8; replyTo.flags |= 8;
replyTo.quote_entities = replyHeader.quote_entities; replyTo.quote_entities = replyHeader.quote_entities;
} }
if ((replyHeader.flags & 1024) != 0) {
replyTo.flags |= 16;
replyTo.quote_offset = replyHeader.quote_offset;
}
} }
return replyTo; return replyTo;
} }
@ -3864,6 +3870,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (!TextUtils.isEmpty(newMsg.reply_to.quote_text)) { if (!TextUtils.isEmpty(newMsg.reply_to.quote_text)) {
newMsg.reply_to.quote = true; newMsg.reply_to.quote = true;
newMsg.reply_to.flags |= 64; newMsg.reply_to.flags |= 64;
newMsg.reply_to.flags |= 1024;
newMsg.reply_to.quote_offset = replyQuote.start;
newMsg.reply_to.quote_entities = replyQuote.getEntities(); newMsg.reply_to.quote_entities = replyQuote.getEntities();
if (newMsg.reply_to.quote_entities != null && !newMsg.reply_to.quote_entities.isEmpty()) { if (newMsg.reply_to.quote_entities != null && !newMsg.reply_to.quote_entities.isEmpty()) {
newMsg.reply_to.quote_entities = new ArrayList<>(newMsg.reply_to.quote_entities); newMsg.reply_to.quote_entities = new ArrayList<>(newMsg.reply_to.quote_entities);
@ -3984,6 +3992,8 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
if (replyQuote.getText() != null) { if (replyQuote.getText() != null) {
newMsg.reply_to.flags |= 64; newMsg.reply_to.flags |= 64;
newMsg.reply_to.quote_text = replyQuote.getText(); newMsg.reply_to.quote_text = replyQuote.getText();
newMsg.reply_to.flags |= 1024;
newMsg.reply_to.quote_offset = replyQuote.start;
} }
if (replyQuote.getEntities() != null) { if (replyQuote.getEntities() != null) {
newMsg.reply_to.flags |= 128; newMsg.reply_to.flags |= 128;

View file

@ -335,6 +335,7 @@ public class SharedConfig {
public static int storiesColumnsCount = 3; public static int storiesColumnsCount = 3;
public static int fastScrollHintCount = 3; public static int fastScrollHintCount = 3;
public static boolean dontAskManageStorage; public static boolean dontAskManageStorage;
public static boolean multipleReactionsPromoShowed;
public static boolean translateChats = true; public static boolean translateChats = true;
@ -649,6 +650,7 @@ public class SharedConfig {
useSurfaceInStories = preferences.getBoolean("useSurfaceInStories", Build.VERSION.SDK_INT >= 30); useSurfaceInStories = preferences.getBoolean("useSurfaceInStories", Build.VERSION.SDK_INT >= 30);
payByInvoice = preferences.getBoolean("payByInvoice", false); payByInvoice = preferences.getBoolean("payByInvoice", false);
photoViewerBlur = preferences.getBoolean("photoViewerBlur", true); photoViewerBlur = preferences.getBoolean("photoViewerBlur", true);
multipleReactionsPromoShowed = preferences.getBoolean("multipleReactionsPromoShowed", false);
loadDebugConfig(preferences); loadDebugConfig(preferences);
@ -862,6 +864,14 @@ public class SharedConfig {
saveConfig(); saveConfig();
} }
public static void setMultipleReactionsPromoShowed(boolean val) {
multipleReactionsPromoShowed = val;
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("multipleReactionsPromoShowed", multipleReactionsPromoShowed);
editor.apply();
}
public static void setSuggestStickers(int type) { public static void setSuggestStickers(int type) {
suggestStickers = type; suggestStickers = type;
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();

View file

@ -658,6 +658,13 @@ public class TopicsController extends BaseController {
}); });
} }
public void toggleViewForumAsMessages(long channelId, boolean enabled) {
TLRPC.TL_channels_toggleViewForumAsMessages request = new TLRPC.TL_channels_toggleViewForumAsMessages();
request.channel_id = getMessagesController().getInputChannel(channelId);
request.enabled = enabled;
getConnectionsManager().sendRequest(request, null);
}
public void pinTopic(long chatId, int topicId, boolean pin, BaseFragment fragment) { public void pinTopic(long chatId, int topicId, boolean pin, BaseFragment fragment) {
TLRPC.TL_channels_updatePinnedForumTopic req = new TLRPC.TL_channels_updatePinnedForumTopic(); TLRPC.TL_channels_updatePinnedForumTopic req = new TLRPC.TL_channels_updatePinnedForumTopic();
req.channel = getMessagesController().getInputChannel(chatId); req.channel = getMessagesController().getInputChannel(chatId);

View file

@ -271,7 +271,7 @@ public class UserConfig extends BaseController {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.premiumStatusChangedGlobal); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.premiumStatusChangedGlobal);
getMediaDataController().loadPremiumPromo(false); getMediaDataController().loadPremiumPromo(false);
getMediaDataController().loadReactions(false, true); getMediaDataController().loadReactions(false, null);
getMessagesController().getStoriesController().invalidateStoryLimit(); getMessagesController().getStoriesController().invalidateStoryLimit();
}); });
} }

View file

@ -142,4 +142,33 @@ public class UserObject {
public static boolean isService(long user_id) { public static boolean isService(long user_id) {
return user_id == 333000 || user_id == 777000 || user_id == 42777; return user_id == 333000 || user_id == 777000 || user_id == 42777;
} }
public static MessagesController.PeerColor getPeerColorForAvatar(int currentAccount, TLRPC.User user) {
if (user != null && user.profile_color != null && user.profile_color.color >= 0 && MessagesController.getInstance(currentAccount).profilePeerColors != null) {
return MessagesController.getInstance(currentAccount).profilePeerColors.getColor(user.profile_color.color);
}
return null;
}
public static int getColorId(TLRPC.User user) {
if (user == null) return 0;
if (user.color != null && (user.color.flags & 1) != 0) return user.color.color;
return (int) (user.id % 7);
}
public static long getEmojiId(TLRPC.User user) {
if (user != null && user.color != null && (user.color.flags & 2) != 0) return user.color.background_emoji_id;
return 0;
}
public static int getProfileColorId(TLRPC.User user) {
if (user == null) return 0;
if (user.profile_color != null && (user.profile_color.flags & 1) != 0) return user.profile_color.color;
return -1;
}
public static long getProfileEmojiId(TLRPC.User user) {
if (user != null && user.profile_color != null && (user.profile_color.flags & 2) != 0) return user.profile_color.background_emoji_id;
return 0;
}
} }

View file

@ -109,11 +109,12 @@ public class VideoEditedInfo {
public static class MediaEntity { public static class MediaEntity {
public static final int TYPE_STICKER = 0; public static final byte TYPE_STICKER = 0;
public static final int TYPE_TEXT = 1; public static final byte TYPE_TEXT = 1;
public static final int TYPE_PHOTO = 2; public static final byte TYPE_PHOTO = 2;
public static final int TYPE_LOCATION = 3; public static final byte TYPE_LOCATION = 3;
public static final byte TYPE_REACTION = 4; public static final byte TYPE_REACTION = 4;
public static final byte TYPE_ROUND = 5;
public byte type; public byte type;
public byte subType; public byte subType;
@ -152,12 +153,19 @@ public class VideoEditedInfo {
public View view; public View view;
public Canvas canvas; public Canvas canvas;
public AnimatedFileDrawable animatedFileDrawable; public AnimatedFileDrawable animatedFileDrawable;
public boolean looped;
public Canvas roundRadiusCanvas; public Canvas roundRadiusCanvas;
public boolean firstSeek;
public TL_stories.MediaArea mediaArea; public TL_stories.MediaArea mediaArea;
public TLRPC.MessageMedia mediaGeo; public TLRPC.MessageMedia mediaGeo;
public float density; public float density;
public long roundOffset;
public long roundLeft;
public long roundRight;
public long roundDuration;
public int W, H; public int W, H;
public ReactionsLayoutInBubble.VisibleReaction visibleReaction; public ReactionsLayoutInBubble.VisibleReaction visibleReaction;
@ -217,6 +225,12 @@ public class VideoEditedInfo {
if (type == TYPE_REACTION) { if (type == TYPE_REACTION) {
mediaArea = TL_stories.MediaArea.TLdeserialize(data, data.readInt32(false), false); mediaArea = TL_stories.MediaArea.TLdeserialize(data, data.readInt32(false), false);
} }
if (type == TYPE_ROUND) {
roundOffset = data.readInt64(false);
roundLeft = data.readInt64(false);
roundRight = data.readInt64(false);
roundDuration = data.readInt64(false);
}
} }
public void serializeTo(AbstractSerializedData data, boolean full) { public void serializeTo(AbstractSerializedData data, boolean full) {
@ -273,6 +287,12 @@ public class VideoEditedInfo {
if (type == TYPE_REACTION) { if (type == TYPE_REACTION) {
mediaArea.serializeToStream(data); mediaArea.serializeToStream(data);
} }
if (type == TYPE_ROUND) {
data.writeInt64(roundOffset);
data.writeInt64(roundLeft);
data.writeInt64(roundRight);
data.writeInt64(roundDuration);
}
} }
public MediaEntity copy() { public MediaEntity copy() {
@ -320,6 +340,10 @@ public class VideoEditedInfo {
entity.W = W; entity.W = W;
entity.H = H; entity.H = H;
entity.visibleReaction = visibleReaction; entity.visibleReaction = visibleReaction;
entity.roundOffset = roundOffset;
entity.roundDuration = roundDuration;
entity.roundLeft = roundLeft;
entity.roundRight = roundRight;
return entity; return entity;
} }
} }

View file

@ -66,6 +66,7 @@ import org.telegram.messenger.DispatchQueue;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader; import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
@ -677,6 +678,10 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
} }
} }
protected boolean square() {
return false;
}
private void updateCameraInfoSize(int i) { private void updateCameraInfoSize(int i) {
ArrayList<CameraInfo> cameraInfos = CameraController.getInstance().getCameras(); ArrayList<CameraInfo> cameraInfos = CameraController.getInstance().getCameras();
if (cameraInfos == null) { if (cameraInfos == null) {
@ -706,7 +711,11 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
int photoMaxWidth; int photoMaxWidth;
int photoMaxHeight; int photoMaxHeight;
if (initialFrontface) { if (square()) {
aspectRatio = new Size(1, 1);
photoMaxWidth = wantedWidth = 720;
photoMaxHeight = wantedHeight = 720;
} else if (initialFrontface) {
aspectRatio = new Size(16, 9); aspectRatio = new Size(16, 9);
photoMaxWidth = wantedWidth = 1280; photoMaxWidth = wantedWidth = 1280;
photoMaxHeight = wantedHeight = 720; photoMaxHeight = wantedHeight = 720;
@ -1962,6 +1971,10 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
}); });
} }
protected void receivedAmplitude(double amplitude) {
}
private class VideoRecorder implements Runnable { private class VideoRecorder implements Runnable {
@ -2078,7 +2091,17 @@ public class CameraView extends FrameLayout implements TextureView.SurfaceTextur
ByteBuffer byteBuffer = buffer.buffer[a]; ByteBuffer byteBuffer = buffer.buffer[a];
byteBuffer.rewind(); byteBuffer.rewind();
readResult = audioRecorder.read(byteBuffer, 2048); readResult = audioRecorder.read(byteBuffer, 2048);
if (readResult > 0 && a % 2 == 0) {
byteBuffer.limit(readResult);
double s = 0;
for (int i = 0; i < readResult / 2; i++) {
short p = byteBuffer.getShort();
s += p * p;
}
double amplitude = Math.sqrt(s / readResult / 2);
AndroidUtilities.runOnUIThread(() -> receivedAmplitude(amplitude));
byteBuffer.position(0);
}
if (readResult <= 0) { if (readResult <= 0) {
buffer.results = a; buffer.results = a;
if (!running) { if (!running) {

View file

@ -1,16 +1,12 @@
package org.telegram.messenger.video; package org.telegram.messenger.video;
import android.media.MediaCodec; import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.os.Build; import android.os.Build;
import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.MediaController; import org.telegram.messenger.MediaController;
import org.telegram.messenger.video.audio_input.AudioInput; import org.telegram.messenger.video.audio_input.AudioInput;
import org.telegram.messenger.video.audio_input.GeneralAudioInput;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -60,12 +56,12 @@ public class AudioRecoder {
} }
} }
encoder = MediaCodec.createEncoderByType(MediaController.AUIDO_MIME_TYPE); encoder = MediaCodec.createEncoderByType(MediaController.AUDIO_MIME_TYPE);
format = MediaFormat.createAudioFormat(MediaController.AUIDO_MIME_TYPE, format = MediaFormat.createAudioFormat(MediaController.AUDIO_MIME_TYPE,
sampleRate, sampleRate,
channelCount channelCount
); );
format.setInteger(MediaFormat.KEY_BIT_RATE, 64 * 1024); format.setInteger(MediaFormat.KEY_BIT_RATE, DEFAULT_BIT_RATE);
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start(); encoder.start();

View file

@ -307,8 +307,8 @@ public class MediaCodecVideoConvertor {
} }
if (!decoderDone) { if (!decoderDone) {
outputSurface.drawImage();
long presentationTime = (long) (framesCount / 30.0f * 1000L * 1000L * 1000L); long presentationTime = (long) (framesCount / 30.0f * 1000L * 1000L * 1000L);
outputSurface.drawImage(presentationTime);
inputSurface.setPresentationTime(presentationTime); inputSurface.setPresentationTime(presentationTime);
inputSurface.swapBuffers(); inputSurface.swapBuffers();
framesCount++; framesCount++;
@ -532,7 +532,7 @@ public class MediaCodecVideoConvertor {
mediaMuxer = new MP4Builder().createMovie(movie, isSecret, outputMimeType.equals("video/hevc")); mediaMuxer = new MP4Builder().createMovie(movie, isSecret, outputMimeType.equals("video/hevc"));
if (audioIndex >= 0) { if (audioIndex >= 0) {
MediaFormat audioFormat = extractor.getTrackFormat(audioIndex); MediaFormat audioFormat = extractor.getTrackFormat(audioIndex);
copyAudioBuffer = convertVideoParams.soundInfos.isEmpty() && audioFormat.getString(MediaFormat.KEY_MIME).equals(MediaController.AUIDO_MIME_TYPE) || audioFormat.getString(MediaFormat.KEY_MIME).equals("audio/mpeg"); copyAudioBuffer = convertVideoParams.soundInfos.isEmpty() && audioFormat.getString(MediaFormat.KEY_MIME).equals(MediaController.AUDIO_MIME_TYPE) || audioFormat.getString(MediaFormat.KEY_MIME).equals("audio/mpeg");
if (audioFormat.getString(MediaFormat.KEY_MIME).equals("audio/unknown")) { if (audioFormat.getString(MediaFormat.KEY_MIME).equals("audio/unknown")) {
audioIndex = -1; audioIndex = -1;
@ -830,7 +830,7 @@ public class MediaCodecVideoConvertor {
FileLog.e(e); FileLog.e(e);
} }
if (!errorWait) { if (!errorWait) {
outputSurface.drawImage(); outputSurface.drawImage(info.presentationTimeUs * 1000);
inputSurface.setPresentationTime(info.presentationTimeUs * 1000); inputSurface.setPresentationTime(info.presentationTimeUs * 1000);
inputSurface.swapBuffers(); inputSurface.swapBuffers();
} }

View file

@ -148,8 +148,8 @@ public class OutputSurface implements SurfaceTexture.OnFrameAvailableListener {
mSurfaceTexture.updateTexImage(); mSurfaceTexture.updateTexImage();
} }
public void drawImage() { public void drawImage(long time) {
mTextureRender.drawFrame(mSurfaceTexture); mTextureRender.drawFrame(mSurfaceTexture, time);
} }
@Override @Override

View file

@ -62,6 +62,7 @@ import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable; import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.BlurringShader; import org.telegram.ui.Components.BlurringShader;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextEffects; import org.telegram.ui.Components.EditTextEffects;
import org.telegram.ui.Components.FilterShaders; import org.telegram.ui.Components.FilterShaders;
import org.telegram.ui.Components.Paint.Views.EditTextOutline; import org.telegram.ui.Components.Paint.Views.EditTextOutline;
@ -206,6 +207,12 @@ public class TextureRenderer {
private Canvas stickerCanvas; private Canvas stickerCanvas;
private float videoFps; private float videoFps;
private Bitmap roundBitmap;
private Canvas roundCanvas;
private final android.graphics.Rect roundSrc = new android.graphics.Rect();
private final RectF roundDst = new RectF();
private Path roundClipPath;
private int imageOrientation; private int imageOrientation;
private boolean blendEnabled; private boolean blendEnabled;
@ -473,7 +480,7 @@ public class TextureRenderer {
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
} }
public void drawFrame(SurfaceTexture st) { public void drawFrame(SurfaceTexture st, long time) {
boolean blurred = false; boolean blurred = false;
if (isPhoto) { if (isPhoto) {
drawGradient(); drawGradient();
@ -609,13 +616,13 @@ public class TextureRenderer {
} }
if (stickerTexture != null) { if (stickerTexture != null) {
for (int a = 0, N = mediaEntities.size(); a < N; a++) { for (int a = 0, N = mediaEntities.size(); a < N; a++) {
drawEntity(mediaEntities.get(a), mediaEntities.get(a).color); drawEntity(mediaEntities.get(a), mediaEntities.get(a).color, time);
} }
} }
GLES20.glFinish(); GLES20.glFinish();
} }
private void drawEntity(VideoEditedInfo.MediaEntity entity, int textColor) { private void drawEntity(VideoEditedInfo.MediaEntity entity, int textColor, long time) {
if (entity.ptr != 0) { if (entity.ptr != 0) {
if (entity.bitmap == null || entity.W <= 0 || entity.H <= 0) { if (entity.bitmap == null || entity.W <= 0 || entity.H <= 0) {
return; return;
@ -631,26 +638,102 @@ public class TextureRenderer {
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0); drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
} else if (entity.animatedFileDrawable != null) { } else if (entity.animatedFileDrawable != null) {
int lastFrame = (int) entity.currentFrame; int lastFrame = (int) entity.currentFrame;
entity.currentFrame += entity.framesPerDraw; float scale = 1f;
int currentFrame = (int) entity.currentFrame; if (entity.type == VideoEditedInfo.MediaEntity.TYPE_ROUND) {
while (lastFrame != currentFrame) { long vstart, vend;
entity.animatedFileDrawable.getNextFrame(); if (isPhoto) {
currentFrame--; vstart = 0;
vend = entity.roundDuration;
} else {
vstart = entity.roundOffset;
vend = entity.roundOffset + (long) (entity.roundRight - entity.roundLeft);
}
final long ms = time / 1_000_000L;
if (ms < vstart) {
scale = CubicBezierInterpolator.EASE_OUT_QUINT.getInterpolation(Utilities.clamp(1f - (vstart - ms) / 400f, 1, 0));
} else if (ms > vend) {
scale = CubicBezierInterpolator.EASE_OUT_QUINT.getInterpolation(Utilities.clamp(1f - (ms - vend) / 400f, 1, 0));
}
if (scale > 0) {
long roundMs;
if (isPhoto) {
roundMs = Utilities.clamp(ms, entity.roundDuration, 0);
} else {
roundMs = Utilities.clamp(ms - entity.roundOffset + entity.roundLeft, entity.roundDuration, 0);
}
while (!entity.looped && entity.animatedFileDrawable.getProgressMs() < Math.min(roundMs, entity.animatedFileDrawable.getDurationMs())) {
int wasProgressMs = entity.animatedFileDrawable.getProgressMs();
entity.animatedFileDrawable.getNextFrame(false);
if (entity.animatedFileDrawable.getProgressMs() <= wasProgressMs && !(entity.animatedFileDrawable.getProgressMs() == 0 && wasProgressMs == 0)) {
entity.looped = true;
break;
}
}
}
} else {
entity.currentFrame += entity.framesPerDraw;
int currentFrame = (int) entity.currentFrame;
while (lastFrame != currentFrame) {
entity.animatedFileDrawable.getNextFrame(true);
currentFrame--;
}
} }
Bitmap frameBitmap = entity.animatedFileDrawable.getBackgroundBitmap(); Bitmap frameBitmap = entity.animatedFileDrawable.getBackgroundBitmap();
if (frameBitmap != null) { if (frameBitmap != null) {
if (stickerCanvas == null && stickerBitmap != null) { Bitmap endBitmap;
stickerCanvas = new Canvas(stickerBitmap); if (entity.type == VideoEditedInfo.MediaEntity.TYPE_ROUND) {
if (stickerBitmap.getHeight() != frameBitmap.getHeight() || stickerBitmap.getWidth() != frameBitmap.getWidth()) { if (roundBitmap == null) {
stickerCanvas.scale(stickerBitmap.getWidth() / (float) frameBitmap.getWidth(), stickerBitmap.getHeight() / (float) frameBitmap.getHeight()); final int side = Math.min(frameBitmap.getWidth(), frameBitmap.getHeight());
roundBitmap = Bitmap.createBitmap(side, side, Bitmap.Config.ARGB_8888);
roundCanvas = new Canvas(roundBitmap);
} }
if (roundBitmap != null) {
roundBitmap.eraseColor(Color.TRANSPARENT);
roundCanvas.save();
if (roundClipPath == null) {
roundClipPath = new Path();
}
roundClipPath.rewind();
roundClipPath.addCircle(roundBitmap.getWidth() / 2f, roundBitmap.getHeight() / 2f, roundBitmap.getWidth() / 2f * scale, Path.Direction.CW);
roundCanvas.clipPath(roundClipPath);
if (frameBitmap.getWidth() >= frameBitmap.getHeight()) {
roundSrc.set(
(frameBitmap.getWidth() - frameBitmap.getHeight()) / 2,
0,
frameBitmap.getWidth() - (frameBitmap.getWidth() - frameBitmap.getHeight()) / 2,
frameBitmap.getHeight()
);
} else {
roundSrc.set(
0,
(frameBitmap.getHeight() - frameBitmap.getWidth()) / 2,
frameBitmap.getWidth(),
frameBitmap.getHeight() - (frameBitmap.getHeight() - frameBitmap.getWidth()) / 2
);
}
roundDst.set(0, 0, roundBitmap.getWidth(), roundBitmap.getHeight());
roundCanvas.drawBitmap(frameBitmap, roundSrc, roundDst, null);
roundCanvas.restore();
}
endBitmap = roundBitmap;
} else {
if (stickerCanvas == null && stickerBitmap != null) {
stickerCanvas = new Canvas(stickerBitmap);
if (stickerBitmap.getHeight() != frameBitmap.getHeight() || stickerBitmap.getWidth() != frameBitmap.getWidth()) {
stickerCanvas.scale(stickerBitmap.getWidth() / (float) frameBitmap.getWidth(), stickerBitmap.getHeight() / (float) frameBitmap.getHeight());
}
}
if (stickerBitmap != null) {
stickerBitmap.eraseColor(Color.TRANSPARENT);
stickerCanvas.drawBitmap(frameBitmap, 0, 0, null);
applyRoundRadius(entity, stickerBitmap, (entity.subType & 8) != 0 ? textColor : 0);
}
endBitmap = stickerBitmap;
} }
if (stickerBitmap != null) { if (endBitmap != null) {
stickerBitmap.eraseColor(Color.TRANSPARENT);
stickerCanvas.drawBitmap(frameBitmap, 0, 0, null);
applyRoundRadius(entity, stickerBitmap, (entity.subType & 8) != 0 ? textColor : 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, stickerTexture[0]);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, stickerBitmap, 0); GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, endBitmap, 0);
drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0); drawTexture(false, stickerTexture[0], entity.x, entity.y, entity.width, entity.height, entity.rotation, (entity.subType & 2) != 0);
} }
} }
@ -670,7 +753,7 @@ public class TextureRenderer {
if (entity1 == null) { if (entity1 == null) {
continue; continue;
} }
drawEntity(entity1, entity.color); drawEntity(entity1, entity.color, time);
} }
} }
} }
@ -1040,7 +1123,11 @@ public class TextureRenderer {
GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
for (int a = 0, N = mediaEntities.size(); a < N; a++) { for (int a = 0, N = mediaEntities.size(); a < N; a++) {
VideoEditedInfo.MediaEntity entity = mediaEntities.get(a); VideoEditedInfo.MediaEntity entity = mediaEntities.get(a);
if (entity.type == VideoEditedInfo.MediaEntity.TYPE_STICKER || entity.type == VideoEditedInfo.MediaEntity.TYPE_PHOTO) { if (
entity.type == VideoEditedInfo.MediaEntity.TYPE_STICKER ||
entity.type == VideoEditedInfo.MediaEntity.TYPE_PHOTO ||
entity.type == VideoEditedInfo.MediaEntity.TYPE_ROUND
) {
initStickerEntity(entity); initStickerEntity(entity);
} else if (entity.type == VideoEditedInfo.MediaEntity.TYPE_TEXT) { } else if (entity.type == VideoEditedInfo.MediaEntity.TYPE_TEXT) {
EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext); EditTextOutline editText = new EditTextOutline(ApplicationLoader.applicationContext);
@ -1239,10 +1326,14 @@ public class TextureRenderer {
entity.ptr = RLottieDrawable.create(entity.text, null, entity.W, entity.H, entity.metadata, false, null, false, 0); entity.ptr = RLottieDrawable.create(entity.text, null, entity.W, entity.H, entity.metadata, false, null, false, 0);
entity.framesPerDraw = entity.metadata[1] / videoFps; entity.framesPerDraw = entity.metadata[1] / videoFps;
} else if ((entity.subType & 4) != 0) { } else if ((entity.subType & 4) != 0) {
entity.looped = false;
entity.animatedFileDrawable = new AnimatedFileDrawable(new File(entity.text), true, 0, 0, null, null, null, 0, UserConfig.selectedAccount, true, 512, 512, null); entity.animatedFileDrawable = new AnimatedFileDrawable(new File(entity.text), true, 0, 0, null, null, null, 0, UserConfig.selectedAccount, true, 512, 512, null);
entity.framesPerDraw = entity.animatedFileDrawable.getFps() / videoFps; entity.framesPerDraw = entity.animatedFileDrawable.getFps() / videoFps;
entity.currentFrame = 0; entity.currentFrame = 1;
entity.animatedFileDrawable.getNextFrame(); entity.animatedFileDrawable.getNextFrame(true);
if (entity.type == VideoEditedInfo.MediaEntity.TYPE_ROUND) {
entity.firstSeek = true;
}
} else { } else {
if (Build.VERSION.SDK_INT >= 19) { if (Build.VERSION.SDK_INT >= 19) {
BitmapFactory.Options opts = new BitmapFactory.Options(); BitmapFactory.Options opts = new BitmapFactory.Options();

File diff suppressed because it is too large Load diff

View file

@ -462,11 +462,12 @@ public class TL_stories {
} }
public static class TL_stories_sendStory extends TLObject { public static class TL_stories_sendStory extends TLObject {
public static final int constructor = 0xbcb73644; public static final int constructor = 0xe4e6694b;
public int flags; public int flags;
public boolean pinned; public boolean pinned;
public boolean noforwards; public boolean noforwards;
public boolean fwd_modified;
public TLRPC.InputPeer peer; public TLRPC.InputPeer peer;
public TLRPC.InputMedia media; public TLRPC.InputMedia media;
public ArrayList<MediaArea> media_areas = new ArrayList<>(); public ArrayList<MediaArea> media_areas = new ArrayList<>();
@ -475,6 +476,8 @@ public class TL_stories {
public ArrayList<TLRPC.InputPrivacyRule> privacy_rules = new ArrayList<>(); public ArrayList<TLRPC.InputPrivacyRule> privacy_rules = new ArrayList<>();
public long random_id; public long random_id;
public int period; public int period;
public TLRPC.InputPeer fwd_from_id;
public int fwd_from_story;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) { public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TLRPC.Updates.TLdeserialize(stream, constructor, exception); return TLRPC.Updates.TLdeserialize(stream, constructor, exception);
@ -484,6 +487,7 @@ public class TL_stories {
stream.writeInt32(constructor); stream.writeInt32(constructor);
flags = pinned ? (flags | 4) : (flags &~ 4); flags = pinned ? (flags | 4) : (flags &~ 4);
flags = noforwards ? (flags | 16) : (flags &~ 16); flags = noforwards ? (flags | 16) : (flags &~ 16);
flags = fwd_modified ? (flags | 128) : (flags &~ 128);
stream.writeInt32(flags); stream.writeInt32(flags);
peer.serializeToStream(stream); peer.serializeToStream(stream);
media.serializeToStream(stream); media.serializeToStream(stream);
@ -516,6 +520,12 @@ public class TL_stories {
if ((flags & 8) != 0) { if ((flags & 8) != 0) {
stream.writeInt32(period); stream.writeInt32(period);
} }
if ((flags & 64) != 0) {
fwd_from_id.serializeToStream(stream);
}
if ((flags & 64) != 0) {
stream.writeInt32(fwd_from_story);
}
} }
} }
@ -1755,6 +1765,7 @@ public class TL_stories {
public boolean out; public boolean out;
public int id; public int id;
public int date; public int date;
public StoryFwdHeader fwd_from;
public int expire_date; public int expire_date;
public String caption; public String caption;
public boolean edited; public boolean edited;
@ -1781,9 +1792,12 @@ public class TL_stories {
public static StoryItem TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { public static StoryItem TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
StoryItem result = null; StoryItem result = null;
switch (constructor) { switch (constructor) {
case 0x44c457ce: case 0xaf6365a1:
result = new TL_storyItem(); result = new TL_storyItem();
break; break;
case 0x44c457ce:
result = new TL_storyItem_layer166();
break;
case 0x562aa637: case 0x562aa637:
result = new TL_storyItem_layer160(); result = new TL_storyItem_layer160();
break; break;
@ -1959,7 +1973,7 @@ public class TL_stories {
public void serializeToStream(AbstractSerializedData stream) { public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor); stream.writeInt32(constructor);
flags = has_viewers ? (flags | 2) : (flags &~ 2); flags = has_viewers ? (flags | 2) : (flags & ~2);
stream.writeInt32(flags); stream.writeInt32(flags);
stream.writeInt32(views_count); stream.writeInt32(views_count);
if ((flags & 4) != 0) { if ((flags & 4) != 0) {
@ -1987,7 +2001,223 @@ public class TL_stories {
} }
} }
public static class TL_publicForwardStory extends TLRPC.PublicForward {
public static final int constructor = 0xedf3add0;
public TLRPC.Peer peer;
public StoryItem story;
public void readParams(AbstractSerializedData stream, boolean exception) {
peer = TLRPC.Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
story = StoryItem.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
peer.serializeToStream(stream);
story.serializeToStream(stream);
}
}
public static class StoryFwdHeader extends TLObject {
public int flags;
public boolean modified;
public TLRPC.Peer from;
public String from_name;
public int story_id;
public static StoryFwdHeader TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
StoryFwdHeader result = null;
switch (constructor) {
case TL_storyFwdHeader.constructor:
result = new TL_storyFwdHeader();
break;
}
if (result == null && exception) {
throw new RuntimeException(String.format("can't parse magic %x in StoryFwdHeader", constructor));
}
if (result != null) {
result.readParams(stream, exception);
}
return result;
}
}
public static class TL_storyFwdHeader extends StoryFwdHeader {
public static final int constructor = 0xb826e150;
@Override
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
modified = (flags & 8) != 0;
if ((flags & 1) != 0) {
from = TLRPC.Peer.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 2) != 0) {
from_name = stream.readString(exception);
}
if ((flags & 4) != 0) {
story_id = stream.readInt32(exception);
}
}
@Override
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = modified ? (flags | 8) : (flags &~ 8);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
from.serializeToStream(stream);
}
if ((flags & 2) != 0) {
stream.writeString(from_name);
}
if ((flags & 4) != 0) {
stream.writeInt32(story_id);
}
}
}
public static class TL_storyItem extends StoryItem { public static class TL_storyItem extends StoryItem {
public static final int constructor = 0xaf6365a1;
public void readParams(AbstractSerializedData stream, boolean exception) {
flags = stream.readInt32(exception);
pinned = (flags & 32) != 0;
isPublic = (flags & 128) != 0;
close_friends = (flags & 256) != 0;
min = (flags & 512) != 0;
noforwards = (flags & 1024) != 0;
edited = (flags & 2048) != 0;
contacts = (flags & 4096) != 0;
selected_contacts = (flags & 8192) != 0;
out = (flags & 65536) != 0;
id = stream.readInt32(exception);
date = stream.readInt32(exception);
if ((flags & 131072) != 0) {
fwd_from = TL_storyFwdHeader.TLdeserialize(stream, stream.readInt32(exception), exception);
}
expire_date = stream.readInt32(exception);
if ((flags & 1) != 0) {
caption = stream.readString(exception);
}
if ((flags & 2) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.MessageEntity object = TLRPC.MessageEntity.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
entities.add(object);
}
}
media = TLRPC.MessageMedia.TLdeserialize(stream, stream.readInt32(exception), exception);
if ((flags & 16384) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
MediaArea object = MediaArea.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
media_areas.add(object);
}
}
if ((flags & 4) != 0) {
int magic = stream.readInt32(exception);
if (magic != 0x1cb5c415) {
if (exception) {
throw new RuntimeException(String.format("wrong Vector magic, got %x", magic));
}
return;
}
int count = stream.readInt32(exception);
for (int a = 0; a < count; a++) {
TLRPC.PrivacyRule object = TLRPC.PrivacyRule.TLdeserialize(stream, stream.readInt32(exception), exception);
if (object == null) {
return;
}
privacy.add(object);
}
}
if ((flags & 8) != 0) {
views = StoryViews.TLdeserialize(stream, stream.readInt32(exception), exception);
}
if ((flags & 32768) != 0) {
sent_reaction = TLRPC.Reaction.TLdeserialize(stream, stream.readInt32(exception), exception);
}
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = pinned ? (flags | 32) : (flags &~ 32);
flags = isPublic ? (flags | 128) : (flags &~ 128);
flags = close_friends ? (flags | 256) : (flags &~ 256);
flags = min ? (flags | 512) : (flags &~ 512);
flags = noforwards ? (flags | 1024) : (flags &~ 1024);
flags = edited ? (flags | 2048) : (flags &~ 2048);
flags = contacts ? (flags | 4096) : (flags &~ 4096);
flags = selected_contacts ? (flags | 8192) : (flags &~ 8192);
flags = out ? (flags | 65536) : (flags &~ 65536);
stream.writeInt32(flags);
stream.writeInt32(id);
stream.writeInt32(date);
if ((flags & 131072) != 0) {
fwd_from.serializeToStream(stream);
}
stream.writeInt32(expire_date);
if ((flags & 1) != 0) {
stream.writeString(caption);
}
if ((flags & 2) != 0) {
stream.writeInt32(0x1cb5c415);
int count = entities.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
entities.get(a).serializeToStream(stream);
}
}
media.serializeToStream(stream);
if ((flags & 16384) != 0) {
stream.writeInt32(0x1cb5c415);
int count = media_areas.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
media_areas.get(a).serializeToStream(stream);
}
}
if ((flags & 4) != 0) {
stream.writeInt32(0x1cb5c415);
int count = privacy.size();
stream.writeInt32(count);
for (int a = 0; a < count; a++) {
privacy.get(a).serializeToStream(stream);
}
}
if ((flags & 8) != 0) {
views.serializeToStream(stream);
}
if ((flags & 32768) != 0) {
sent_reaction.serializeToStream(stream);
}
}
}
public static class TL_storyItem_layer166 extends TL_storyItem {
public static final int constructor = 0x44c457ce; public static final int constructor = 0x44c457ce;
public void readParams(AbstractSerializedData stream, boolean exception) { public void readParams(AbstractSerializedData stream, boolean exception) {
@ -2459,4 +2689,56 @@ public class TL_stories {
stream.writeInt32(date); stream.writeInt32(date);
} }
} }
public static class TL_stats_storyStats extends TLObject {
public final static int constructor = 0x50cd067c;
public TLRPC.StatsGraph views_graph;
public TLRPC.StatsGraph reactions_by_emotion_graph;
public static TL_stats_storyStats TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_stats_storyStats.constructor != constructor) {
if (exception) {
throw new RuntimeException(String.format("can't parse magic %x in TL_stats_storyStats", constructor));
} else {
return null;
}
}
TL_stats_storyStats result = new TL_stats_storyStats();
result.readParams(stream, exception);
return result;
}
public void readParams(AbstractSerializedData stream, boolean exception) {
views_graph = TLRPC.StatsGraph.TLdeserialize(stream, stream.readInt32(exception), exception);
reactions_by_emotion_graph = TLRPC.StatsGraph.TLdeserialize(stream, stream.readInt32(exception), exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
views_graph.serializeToStream(stream);
reactions_by_emotion_graph.serializeToStream(stream);
}
}
public static class TL_stats_getStoryStats extends TLObject {
public final static int constructor = 0x374fef40;
public int flags;
public boolean dark;
public TLRPC.InputPeer peer;
public int id;
public TLObject deserializeResponse(AbstractSerializedData stream, int constructor, boolean exception) {
return TL_stats_storyStats.TLdeserialize(stream, constructor, exception);
}
public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor);
flags = dark ? (flags | 1) : (flags & ~1);
stream.writeInt32(flags);
peer.serializeToStream(stream);
stream.writeInt32(id);
}
}
} }

View file

@ -63,6 +63,7 @@ import org.telegram.ui.Components.FloatingDebug.FloatingDebugController;
import org.telegram.ui.Components.FloatingDebug.FloatingDebugProvider; import org.telegram.ui.Components.FloatingDebug.FloatingDebugProvider;
import org.telegram.ui.Components.GroupCallPip; import org.telegram.ui.Components.GroupCallPip;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.Stories.StoryViewer; import org.telegram.ui.Stories.StoryViewer;
import java.util.ArrayList; import java.util.ArrayList;
@ -250,10 +251,27 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
invalidate(); invalidate();
} }
float lastY, startY;
// for menu buttons to be clicked by hover: // for menu buttons to be clicked by hover:
private float pressX, pressY; private float pressX, pressY;
private boolean allowToPressByHover; private boolean allowToPressByHover;
public void processMenuButtonsTouch(MotionEvent event) { public void processMenuButtonsTouch(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startY = event.getY();
}
if (isInPreviewMode() && previewMenu == null) {
lastY = event.getY();
if (event.getAction() == MotionEvent.ACTION_UP) {
finishPreviewFragment();
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
float dy = startY - lastY;
movePreviewFragment(dy);
if (dy < 0) {
startY = lastY;
}
}
return;
}
if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressX = event.getX(); pressX = event.getX();
pressY = event.getY(); pressY = event.getY();
@ -1237,14 +1255,16 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
return false; return false;
} }
BaseFragment lastFragment = getLastFragment(); BaseFragment lastFragment = getLastFragment();
if (lastFragment != null && lastFragment.getVisibleDialog() != null) { Dialog dialog = lastFragment != null ? lastFragment.getVisibleDialog() : null;
if (shouldOpenFragmentOverlay(lastFragment.getVisibleDialog())) { if (dialog == null && LaunchActivity.instance != null && LaunchActivity.instance.visibleDialog != null) {
BaseFragment.BottomSheetParams bottomSheetParams = new BaseFragment.BottomSheetParams(); dialog = LaunchActivity.instance.visibleDialog;
bottomSheetParams.transitionFromLeft = true; }
bottomSheetParams.allowNestedScroll = false; if (shouldOpenFragmentOverlay(dialog)) {
lastFragment.showAsSheet(fragment, bottomSheetParams); BaseFragment.BottomSheetParams bottomSheetParams = new BaseFragment.BottomSheetParams();
return true; bottomSheetParams.transitionFromLeft = true;
} bottomSheetParams.allowNestedScroll = false;
lastFragment.showAsSheet(fragment, bottomSheetParams);
return true;
} }
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("present fragment " + fragment.getClass().getSimpleName() + " args=" + fragment.getArguments()); FileLog.d("present fragment " + fragment.getClass().getSimpleName() + " args=" + fragment.getArguments());
@ -2052,7 +2072,7 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
for (int i = 0, N = presentingFragmentDescriptions.size(); i < N; i++) { for (int i = 0, N = presentingFragmentDescriptions.size(); i < N; i++) {
ThemeDescription description = presentingFragmentDescriptions.get(i); ThemeDescription description = presentingFragmentDescriptions.get(i);
int key = description.getCurrentKey(); int key = description.getCurrentKey();
description.setColor(Theme.getColor(key), false, false); description.setColor(Theme.getColor(key, description.resourcesProvider), false, false);
} }
} }
if (animationProgressListener != null) { if (animationProgressListener != null) {

View file

@ -1864,6 +1864,17 @@ public class ActionBarMenuItem extends FrameLayout {
} }
} }
public boolean hasSubItem(int id) {
Item lazyItem = findLazyItem(id);
if (lazyItem != null) {
return true;
}
if (popupLayout == null) {
return false;
}
return popupLayout.findViewWithTag(id) != null;
}
/** /**
* Hides this menu item if no subitems are available * Hides this menu item if no subitems are available
*/ */

View file

@ -22,6 +22,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
@ -81,7 +82,7 @@ public abstract class BaseFragment {
protected boolean fragmentBeginToShow; protected boolean fragmentBeginToShow;
private boolean removingFromStack; private boolean removingFromStack;
private PreviewDelegate previewDelegate; private PreviewDelegate previewDelegate;
private Theme.ResourcesProvider resourceProvider; protected Theme.ResourcesProvider resourceProvider;
public StoryViewer storyViewer; public StoryViewer storyViewer;
public StoryViewer overlayStoryViewer; public StoryViewer overlayStoryViewer;
@ -822,7 +823,8 @@ public abstract class BaseFragment {
fragment.onTransitionAnimationStart(true, false); fragment.onTransitionAnimationStart(true, false);
bottomSheet[0] = new BottomSheet(getParentActivity(), true, fragment.getResourceProvider()) { bottomSheet[0] = new BottomSheet(getParentActivity(), true, fragment.getResourceProvider()) {
{ {
drawNavigationBar = true; occupyNavigationBar = params != null && params.occupyNavigationBar;
drawNavigationBar = !occupyNavigationBar;
actionBarLayout[0].setFragmentStack(new ArrayList<>()); actionBarLayout[0].setFragmentStack(new ArrayList<>());
actionBarLayout[0].addFragmentToStack(fragment); actionBarLayout[0].addFragmentToStack(fragment);
actionBarLayout[0].showLastFragment(); actionBarLayout[0].showLastFragment();
@ -843,8 +845,13 @@ public abstract class BaseFragment {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
actionBarLayout[0].setWindow(bottomSheet[0].getWindow()); actionBarLayout[0].setWindow(bottomSheet[0].getWindow());
fixNavigationBar(Theme.getColor(Theme.key_dialogBackgroundGray, fragment.getResourceProvider())); if (params == null || !params.occupyNavigationBar) {
fixNavigationBar(Theme.getColor(Theme.key_dialogBackgroundGray, fragment.getResourceProvider()));
} else {
AndroidUtilities.setLightNavigationBar(bottomSheet[0].getWindow(), true);
}
AndroidUtilities.setLightStatusBar(getWindow(), fragment.isLightStatusBar()); AndroidUtilities.setLightStatusBar(getWindow(), fragment.isLightStatusBar());
fragment.onBottomSheetCreated();
} }
@Override @Override
@ -853,8 +860,17 @@ public abstract class BaseFragment {
} }
@Override @Override
protected boolean canSwipeToBack() { protected boolean canSwipeToBack(MotionEvent event) {
return params != null && params.transitionFromLeft && actionBarLayout[0] != null && actionBarLayout[0].getFragmentStack().size() <= 1; if (params != null && params.transitionFromLeft && actionBarLayout[0] != null && actionBarLayout[0].getFragmentStack().size() <= 1) {
if (actionBarLayout[0].getFragmentStack().size() == 1) {
BaseFragment lastFragment = actionBarLayout[0].getFragmentStack().get(0);
if (!lastFragment.isSwipeBackEnabled(event)) {
return false;
}
}
return true;
}
return false;
} }
@Override @Override
@ -902,6 +918,7 @@ public abstract class BaseFragment {
bottomSheet[0].transitionFromRight(params.transitionFromLeft); bottomSheet[0].transitionFromRight(params.transitionFromLeft);
} }
fragment.setParentDialog(bottomSheet[0]); fragment.setParentDialog(bottomSheet[0]);
bottomSheet[0].setOpenNoDelay(true);
bottomSheet[0].show(); bottomSheet[0].show();
return actionBarLayout; return actionBarLayout;
@ -928,7 +945,7 @@ public abstract class BaseFragment {
} }
public int getNavigationBarColor() { public int getNavigationBarColor() {
int color = Theme.getColor(Theme.key_windowBackgroundGray, resourceProvider); int color = Theme.getColor(Theme.key_windowBackgroundGray, getResourceProvider());
if (storyViewer != null && storyViewer.attachedToParent()) { if (storyViewer != null && storyViewer.attachedToParent()) {
return storyViewer.getNavigationBarColor(color); return storyViewer.getNavigationBarColor(color);
} }
@ -1093,12 +1110,17 @@ public abstract class BaseFragment {
return overlayStoryViewer; return overlayStoryViewer;
} }
public void onBottomSheetCreated() {
}
public static class BottomSheetParams { public static class BottomSheetParams {
public boolean transitionFromLeft; public boolean transitionFromLeft;
public boolean allowNestedScroll; public boolean allowNestedScroll;
public Runnable onDismiss; public Runnable onDismiss;
public Runnable onOpenAnimationFinished; public Runnable onOpenAnimationFinished;
public Runnable onPreFinished; public Runnable onPreFinished;
public boolean occupyNavigationBar;
} }
} }

View file

@ -29,6 +29,7 @@ import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -342,6 +343,7 @@ public class BottomSheet extends Dialog {
private float y = 0f; private float y = 0f;
private float swipeBackX = 0f; private float swipeBackX = 0f;
private boolean allowedSwipeToBack;
public boolean processTouchEvent(MotionEvent ev, boolean intercept) { public boolean processTouchEvent(MotionEvent ev, boolean intercept) {
if (dismissed) { if (dismissed) {
return false; return false;
@ -349,8 +351,9 @@ public class BottomSheet extends Dialog {
if (onContainerTouchEvent(ev)) { if (onContainerTouchEvent(ev)) {
return true; return true;
} }
if (canSwipeToBack()) { if (canSwipeToBack(ev) || allowedSwipeToBack) {
if (ev != null && (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_MOVE) && (!startedTracking && !maybeStartTracking && ev.getPointerCount() == 1)) { if (ev != null && (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_MOVE) && (!startedTracking && !maybeStartTracking && ev.getPointerCount() == 1)) {
allowedSwipeToBack = true;
startedTrackingX = (int) ev.getX(); startedTrackingX = (int) ev.getX();
startedTrackingY = (int) ev.getY(); startedTrackingY = (int) ev.getY();
startedTrackingPointerId = ev.getPointerId(0); startedTrackingPointerId = ev.getPointerId(0);
@ -418,6 +421,7 @@ public class BottomSheet extends Dialog {
maybeStartTracking = false; maybeStartTracking = false;
startedTracking = false; startedTracking = false;
startedTrackingPointerId = -1; startedTrackingPointerId = -1;
allowedSwipeToBack = false;
} }
} else { } else {
if (canDismissWithTouchOutside() && ev != null && (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_MOVE) && (!startedTracking && !maybeStartTracking && ev.getPointerCount() == 1)) { if (canDismissWithTouchOutside() && ev != null && (ev.getAction() == MotionEvent.ACTION_DOWN || ev.getAction() == MotionEvent.ACTION_MOVE) && (!startedTracking && !maybeStartTracking && ev.getPointerCount() == 1)) {
@ -434,7 +438,7 @@ public class BottomSheet extends Dialog {
if (velocityTracker != null) { if (velocityTracker != null) {
velocityTracker.clear(); velocityTracker.clear();
} }
} else if (ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && ev.getPointerId(0) == startedTrackingPointerId) { } else if (canDismissWithSwipe() && ev != null && ev.getAction() == MotionEvent.ACTION_MOVE && ev.getPointerId(0) == startedTrackingPointerId) {
if (velocityTracker == null) { if (velocityTracker == null) {
velocityTracker = VelocityTracker.obtain(); velocityTracker = VelocityTracker.obtain();
} }
@ -474,7 +478,7 @@ public class BottomSheet extends Dialog {
startedTrackingPointerId = -1; startedTrackingPointerId = -1;
} }
} }
return (!intercept && maybeStartTracking) || startedTracking || !(canDismissWithSwipe() || canSwipeToBack()); return (!intercept && maybeStartTracking) || startedTracking || !(canDismissWithSwipe() || canSwipeToBack(ev));
} }
@Override @Override
@ -566,7 +570,7 @@ public class BottomSheet extends Dialog {
right -= getRightInset(); right -= getRightInset();
if (useSmoothKeyboard) { if (useSmoothKeyboard) {
t = 0; t = 0;
} else { } else if (!occupyNavigationBar) {
t -= lastInsets.getSystemWindowInsetBottom() * (1f - hideSystemVerticalInsetsProgress) - (drawNavigationBar ? 0 : getBottomInset()); t -= lastInsets.getSystemWindowInsetBottom() * (1f - hideSystemVerticalInsetsProgress) - (drawNavigationBar ? 0 : getBottomInset());
if (Build.VERSION.SDK_INT >= 29) { if (Build.VERSION.SDK_INT >= 29) {
t -= getAdditionalMandatoryOffsets(); t -= getAdditionalMandatoryOffsets();
@ -668,7 +672,7 @@ public class BottomSheet extends Dialog {
@Override @Override
public boolean onInterceptTouchEvent(MotionEvent event) { public boolean onInterceptTouchEvent(MotionEvent event) {
if (canDismissWithSwipe() || canSwipeToBack()) { if (canDismissWithSwipe() || canSwipeToBack(event)) {
return processTouchEvent(event, true); return processTouchEvent(event, true);
} }
return super.onInterceptTouchEvent(event); return super.onInterceptTouchEvent(event);
@ -758,7 +762,7 @@ public class BottomSheet extends Dialog {
restore = true; restore = true;
} }
super.onDraw(canvas); super.onDraw(canvas);
if (lastInsets != null && keyboardHeight != 0) { if (drawNavigationBar && lastInsets != null && keyboardHeight != 0) {
backgroundPaint.setColor(behindKeyboardColorKey >= 0 ? getThemedColor(behindKeyboardColorKey) : behindKeyboardColor); backgroundPaint.setColor(behindKeyboardColorKey >= 0 ? getThemedColor(behindKeyboardColorKey) : behindKeyboardColor);
canvas.drawRect(containerView.getLeft() + backgroundPaddingLeft, getMeasuredHeight() - keyboardHeight - (drawNavigationBar ? getBottomInset() : 0), containerView.getRight() - backgroundPaddingLeft, getMeasuredHeight() - (drawNavigationBar ? getBottomInset() : 0), backgroundPaint); canvas.drawRect(containerView.getLeft() + backgroundPaddingLeft, getMeasuredHeight() - keyboardHeight - (drawNavigationBar ? getBottomInset() : 0), containerView.getRight() - backgroundPaddingLeft, getMeasuredHeight() - (drawNavigationBar ? getBottomInset() : 0), backgroundPaint);
} }
@ -1113,7 +1117,7 @@ public class BottomSheet extends Dialog {
} }
public void fixNavigationBar(int bgColor) { public void fixNavigationBar(int bgColor) {
drawNavigationBar = true; drawNavigationBar = !occupyNavigationBar;
drawDoubleNavigationBar = true; drawDoubleNavigationBar = true;
scrollNavBar = true; scrollNavBar = true;
navBarColorKey = -1; navBarColorKey = -1;
@ -1324,7 +1328,10 @@ public class BottomSheet extends Dialog {
} }
dismissed = false; dismissed = false;
cancelSheetAnimation(); cancelSheetAnimation();
containerView.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x + backgroundPaddingLeft * 2, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, View.MeasureSpec.AT_MOST)); containerView.measure(
View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.x + backgroundPaddingLeft * 2, View.MeasureSpec.AT_MOST),
View.MeasureSpec.makeMeasureSpec(AndroidUtilities.displaySize.y, View.MeasureSpec.AT_MOST)
);
if (showWithoutAnimation) { if (showWithoutAnimation) {
backDrawable.setAlpha(dimBehind ? dimBehindAlpha : 0); backDrawable.setAlpha(dimBehind ? dimBehindAlpha : 0);
containerView.setTranslationY(0); containerView.setTranslationY(0);
@ -1664,7 +1671,7 @@ public class BottomSheet extends Dialog {
return containerView.getMeasuredHeight(); return containerView.getMeasuredHeight();
} }
protected boolean canSwipeToBack() { protected boolean canSwipeToBack(MotionEvent event) {
return false; return false;
} }

View file

@ -367,7 +367,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
string = TextUtils.ellipsize(string, textPaint, width, TextUtils.TruncateAt.END); string = TextUtils.ellipsize(string, textPaint, width, TextUtils.TruncateAt.END);
} }
if (!ellipsizeByGradient && !string.equals(text)) { if (!ellipsizeByGradient && !string.equals(text)) {
fullLayout = StaticLayoutEx.createStaticLayout(text, 0, text.length(), textPaint, width, getAlignment(), 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, fullTextMaxLines, false); fullLayout = StaticLayoutEx.createStaticLayout(text, textPaint, width, getAlignment(), 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, fullTextMaxLines, false);
if (fullLayout != null) { if (fullLayout != null) {
int end = fullLayout.getLineEnd(0); int end = fullLayout.getLineEnd(0);
int start = fullLayout.getLineStart(1); int start = fullLayout.getLineStart(1);
@ -386,7 +386,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
part = "\u200F" + part; part = "\u200F" + part;
} }
partLayout = new StaticLayout(part, 0, part.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), getAlignment(), 1.0f, 0.0f, false); partLayout = new StaticLayout(part, 0, part.length(), textPaint, scrollNonFitText ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), getAlignment(), 1.0f, 0.0f, false);
fullLayout = StaticLayoutEx.createStaticLayout(full, 0, full.length(), textPaint, width + AndroidUtilities.dp(8) + fullLayoutAdditionalWidth, getAlignment(), 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width + fullLayoutAdditionalWidth, fullTextMaxLines, false); fullLayout = StaticLayoutEx.createStaticLayout(full, textPaint, width + AndroidUtilities.dp(8) + fullLayoutAdditionalWidth, getAlignment(), 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width + fullLayoutAdditionalWidth, fullTextMaxLines, false);
} }
} else { } else {
layout = new StaticLayout(string, 0, string.length(), textPaint, scrollNonFitText || ellipsizeByGradient ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), getAlignment(), 1.0f, 0.0f, false); layout = new StaticLayout(string, 0, string.length(), textPaint, scrollNonFitText || ellipsizeByGradient ? AndroidUtilities.dp(2000) : width + AndroidUtilities.dp(8), getAlignment(), 1.0f, 0.0f, false);
@ -395,7 +395,7 @@ public class SimpleTextView extends View implements Drawable.Callback {
firstLineLayout = null; firstLineLayout = null;
} }
} else if (maxLines > 1) { } else if (maxLines > 1) {
layout = StaticLayoutEx.createStaticLayout(text, 0, text.length(), textPaint, width, getAlignment(), 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, maxLines, false); layout = StaticLayoutEx.createStaticLayout(text, textPaint, width, getAlignment(), 1.0f, 0.0f, false, TextUtils.TruncateAt.END, width, maxLines, false);
} else { } else {
CharSequence string; CharSequence string;
if (scrollNonFitText || ellipsizeByGradient) { if (scrollNonFitText || ellipsizeByGradient) {

View file

@ -126,11 +126,13 @@ import org.telegram.ui.Components.TypingDotsDrawable;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.RoundVideoProgressShadow; import org.telegram.ui.RoundVideoProgressShadow;
import org.telegram.ui.ThemeActivity; import org.telegram.ui.ThemeActivity;
import org.telegram.ui.ThemePreviewActivity;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
@ -1453,7 +1455,7 @@ public class Theme {
} else { } else {
color = currentColorsNoAccent.valueAt(index); color = currentColorsNoAccent.valueAt(index);
} }
int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme); int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme, color);
if (newColor != color) { if (newColor != color) {
currentColors.put(key, newColor); currentColors.put(key, newColor);
} }
@ -1466,7 +1468,7 @@ public class Theme {
if (color == 0) { if (color == 0) {
color = defaultColors[key_chat_outBubble]; color = defaultColors[key_chat_outBubble];
} }
int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme); int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme, color);
int distance1 = AndroidUtilities.getColorDistance(firstColor, newColor); int distance1 = AndroidUtilities.getColorDistance(firstColor, newColor);
int distance2 = AndroidUtilities.getColorDistance(firstColor, myMessagesGradientAccentColor1); int distance2 = AndroidUtilities.getColorDistance(firstColor, myMessagesGradientAccentColor1);
@ -1508,7 +1510,7 @@ public class Theme {
} else { } else {
color = currentColorsNoAccent.valueAt(index); color = currentColorsNoAccent.valueAt(index);
} }
int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme); int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme, color);
if (newColor != color) { if (newColor != color) {
currentColors.put(key, newColor); currentColors.put(key, newColor);
} }
@ -1528,7 +1530,7 @@ public class Theme {
} else { } else {
color = currentColorsNoAccent.valueAt(index); color = currentColorsNoAccent.valueAt(index);
} }
int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme); int newColor = changeColorAccent(hsvTemp1, hsvTemp2, color, isDarkTheme, color);
if (newColor != color) { if (newColor != color) {
currentColors.put(key, newColor); currentColors.put(key, newColor);
} }
@ -1994,7 +1996,9 @@ public class Theme {
public static int adaptHSV(int color, float sat, float val) { public static int adaptHSV(int color, float sat, float val) {
float[] tempHSV = getTempHsv(5); float[] tempHSV = getTempHsv(5);
Color.colorToHSV(color, tempHSV); Color.colorToHSV(color, tempHSV);
tempHSV[1] = MathUtils.clamp(tempHSV[1] + sat, 0, 1); if (tempHSV[1] > .1f && tempHSV[1] < .9f) { // otherwise, saturation would reveal some random hue there
tempHSV[1] = MathUtils.clamp(tempHSV[1] + sat, 0, 1);
}
tempHSV[2] = MathUtils.clamp(tempHSV[2] + val, 0, 1); tempHSV[2] = MathUtils.clamp(tempHSV[2] + val, 0, 1);
return Color.HSVToColor(Color.alpha(color), tempHSV); return Color.HSVToColor(Color.alpha(color), tempHSV);
} }
@ -2045,6 +2049,7 @@ public class Theme {
public long wallpaperId; public long wallpaperId;
public long accessHash; public long accessHash;
public long dialogId; public long dialogId;
public boolean forBoth;
public ThemeInfo parentTheme; public ThemeInfo parentTheme;
public ThemeAccent parentAccent; public ThemeAccent parentAccent;
@ -2971,6 +2976,12 @@ public class Theme {
return false; return false;
} }
default boolean isDark() {
// used only in PeerColorActivity
// support in other implementations to use
return Theme.isCurrentThemeDark();
}
default void applyServiceShaderMatrix(int w, int h, float translationX, float translationY) { default void applyServiceShaderMatrix(int w, int h, float translationX, float translationY) {
Theme.applyServiceShaderMatrix(w, h, translationX, translationY); Theme.applyServiceShaderMatrix(w, h, translationX, translationY);
} }
@ -3070,8 +3081,6 @@ public class Theme {
private static int serviceSelectedMessageColor; private static int serviceSelectedMessageColor;
public static int serviceMessageColorBackup; public static int serviceMessageColorBackup;
public static int serviceSelectedMessageColorBackup; public static int serviceSelectedMessageColorBackup;
private static int serviceMessage2Color;
private static int serviceSelectedMessage2Color;
public static int currentColor; public static int currentColor;
private static Drawable wallpaper; private static Drawable wallpaper;
private static Drawable themedWallpaper; private static Drawable themedWallpaper;
@ -3090,7 +3099,7 @@ public class Theme {
public static Paint avatar_backgroundPaint; public static Paint avatar_backgroundPaint;
public static Drawable listSelector; public static Drawable listSelector;
public static Drawable[] avatarDrawables = new Drawable[17]; public static Drawable[] avatarDrawables = new Drawable[18];
public static Drawable moveUpDrawable; public static Drawable moveUpDrawable;
@ -3176,8 +3185,6 @@ public class Theme {
public static Paint chat_messageBackgroundSelectedPaint; public static Paint chat_messageBackgroundSelectedPaint;
public static Paint chat_actionBackgroundPaint; public static Paint chat_actionBackgroundPaint;
public static Paint chat_actionBackgroundSelectedPaint; public static Paint chat_actionBackgroundSelectedPaint;
public static Paint chat_actionBackgroundPaint2;
public static Paint chat_actionBackgroundSelectedPaint2;
public static Paint chat_actionBackgroundGradientDarkenPaint; public static Paint chat_actionBackgroundGradientDarkenPaint;
public static Paint chat_timeBackgroundPaint; public static Paint chat_timeBackgroundPaint;
public static Paint chat_composeBackgroundPaint; public static Paint chat_composeBackgroundPaint;
@ -3293,6 +3300,7 @@ public class Theme {
public static Drawable chat_contextResult_shadowUnderSwitchDrawable; public static Drawable chat_contextResult_shadowUnderSwitchDrawable;
public static Drawable chat_shareIconDrawable; public static Drawable chat_shareIconDrawable;
public static Drawable chat_replyIconDrawable; public static Drawable chat_replyIconDrawable;
public static Drawable chat_closeIconDrawable;
public static Drawable chat_goIconDrawable; public static Drawable chat_goIconDrawable;
public static Drawable chat_botLinkDrawable; public static Drawable chat_botLinkDrawable;
public static Drawable chat_botCardDrawable; public static Drawable chat_botCardDrawable;
@ -4174,6 +4182,7 @@ public class Theme {
public static final String key_drawable_msgStickerViews = "drawableMsgStickerViews"; public static final String key_drawable_msgStickerViews = "drawableMsgStickerViews";
public static final String key_drawable_replyIcon = "drawableReplyIcon"; public static final String key_drawable_replyIcon = "drawableReplyIcon";
public static final String key_drawable_shareIcon = "drawableShareIcon"; public static final String key_drawable_shareIcon = "drawableShareIcon";
public static final String key_drawable_closeIcon = "drawableCloseIcon";
public static final String key_drawable_muteIconDrawable = "drawableMuteIcon"; public static final String key_drawable_muteIconDrawable = "drawableMuteIcon";
public static final String key_drawable_lockIconDrawable = "drawableLockIcon"; public static final String key_drawable_lockIconDrawable = "drawableLockIcon";
public static final String key_drawable_chat_pollHintDrawableOut = "drawable_chat_pollHintDrawableOut"; public static final String key_drawable_chat_pollHintDrawableOut = "drawable_chat_pollHintDrawableOut";
@ -4183,6 +4192,7 @@ public class Theme {
private static final HashMap<String, Integer> defaultChatDrawableColorKeys = new HashMap<>(); private static final HashMap<String, Integer> defaultChatDrawableColorKeys = new HashMap<>();
public static final String key_paint_chatActionBackground = "paintChatActionBackground"; public static final String key_paint_chatActionBackground = "paintChatActionBackground";
public static final String key_paint_chatActionBackgroundDarken = "paintChatActionBackgroundDarken";
public static final String key_paint_chatActionBackgroundSelected = "paintChatActionBackgroundSelected"; public static final String key_paint_chatActionBackgroundSelected = "paintChatActionBackgroundSelected";
public static final String key_paint_chatMessageBackgroundSelected = "paintChatMessageBackgroundSelected"; public static final String key_paint_chatMessageBackgroundSelected = "paintChatMessageBackgroundSelected";
public static final String key_paint_chatActionText = "paintChatActionText"; public static final String key_paint_chatActionText = "paintChatActionText";
@ -4202,11 +4212,11 @@ public class Theme {
private static SparseIntArray animatingColors; private static SparseIntArray animatingColors;
private static boolean shouldDrawGradientIcons; private static boolean shouldDrawGradientIcons;
private static ThreadLocal<float[]> hsvTemp1Local = new ThreadLocal<>(); private static final ThreadLocal<float[]> hsvTemp1Local = new ThreadLocal<>();
private static ThreadLocal<float[]> hsvTemp2Local = new ThreadLocal<>(); private static final ThreadLocal<float[]> hsvTemp2Local = new ThreadLocal<>();
private static ThreadLocal<float[]> hsvTemp3Local = new ThreadLocal<>(); private static final ThreadLocal<float[]> hsvTemp3Local = new ThreadLocal<>();
private static ThreadLocal<float[]> hsvTemp4Local = new ThreadLocal<>(); private static final ThreadLocal<float[]> hsvTemp4Local = new ThreadLocal<>();
private static ThreadLocal<float[]> hsvTemp5Local = new ThreadLocal<>(); private static final ThreadLocal<float[]> hsvTemp5Local = new ThreadLocal<>();
private static FragmentContextViewWavesDrawable fragmentContextViewWavesDrawable; private static FragmentContextViewWavesDrawable fragmentContextViewWavesDrawable;
private static RoundVideoProgressShadow roundPlayDrawable; private static RoundVideoProgressShadow roundPlayDrawable;
@ -4515,7 +4525,7 @@ public class Theme {
new int[] { 0, 52, 46, 57, 45, 64, 52, 35, 36, 41, 50, 50, 35, 38, 37, 30 } new int[] { 0, 52, 46, 57, 45, 64, 52, 35, 36, 41, 50, 50, 35, 38, 37, 30 }
); );
sortAccents(themeInfo); sortAccents(themeInfo);
themes.add(currentDayTheme = currentTheme = defaultTheme = themeInfo); themes.add(currentDayTheme = defaultTheme = themeInfo);
themesDict.put("Blue", themeInfo); themesDict.put("Blue", themeInfo);
themeInfo = new ThemeInfo(); themeInfo = new ThemeInfo();
@ -5290,6 +5300,14 @@ public class Theme {
} }
public static Drawable createServiceDrawable(int rad, View view, View containerView, Paint backgroundPaint) { public static Drawable createServiceDrawable(int rad, View view, View containerView, Paint backgroundPaint) {
return createServiceDrawable(rad, view, containerView, backgroundPaint, null);
}
public static Drawable createServiceDrawable(int rad, View view, View containerView, Theme.ResourcesProvider resourcesProvider) {
return createServiceDrawable(rad, view, containerView, null, resourcesProvider);
}
public static Drawable createServiceDrawable(int rad, View view, View containerView, Paint backgroundPaint, Theme.ResourcesProvider resourcesProvider) {
return new Drawable() { return new Drawable() {
private RectF rect = new RectF(); private RectF rect = new RectF();
@ -5299,9 +5317,9 @@ public class Theme {
Rect bounds = getBounds(); Rect bounds = getBounds();
rect.set(bounds.left, bounds.top, bounds.right, bounds.bottom); rect.set(bounds.left, bounds.top, bounds.right, bounds.bottom);
applyServiceShaderMatrixForView(view, containerView); applyServiceShaderMatrixForView(view, containerView);
canvas.drawRoundRect(rect, rad, rad, backgroundPaint); canvas.drawRoundRect(rect, rad, rad, backgroundPaint != null ? backgroundPaint : Theme.getThemePaint(Theme.key_paint_chatActionBackground, resourcesProvider));
if (hasGradientService()) { if (resourcesProvider != null ? resourcesProvider.hasGradientService() : hasGradientService()) {
canvas.drawRoundRect(rect, rad, rad, chat_actionBackgroundGradientDarkenPaint); canvas.drawRoundRect(rect, rad, rad, Theme.getThemePaint(Theme.key_paint_chatActionBackgroundDarken, resourcesProvider));
} }
} }
@ -6542,6 +6560,24 @@ public class Theme {
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didSetNewTheme, false, checkNavigationBarColor)); AndroidUtilities.runOnUIThread(() -> NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didSetNewTheme, false, checkNavigationBarColor));
} }
public static boolean hasHue(int color) {
float[] hsvTemp3 = getTempHsv(3);
Color.colorToHSV(color, hsvTemp3);
return hsvTemp3[1] > .1f && hsvTemp3[1] < .9f;
}
public static int changeColorAccent(int themeBaseAccent, int accent, int color, boolean isDark) {
return changeColorAccent(themeBaseAccent, accent, color, isDark, color);
}
public static int changeColorAccent(int themeBaseAccent, int accent, int color, boolean isDark, int fallback) {
float[] hsvTemp3 = getTempHsv(3);
float[] hsvTemp4 = getTempHsv(4);
Color.colorToHSV(themeBaseAccent, hsvTemp3);
Color.colorToHSV(accent, hsvTemp4);
return changeColorAccent(hsvTemp3, hsvTemp4, color, isDark, fallback);
}
public static int changeColorAccent(ThemeInfo themeInfo, int accent, int color) { public static int changeColorAccent(ThemeInfo themeInfo, int accent, int color) {
if (accent == 0 || themeInfo.accentBaseColor == 0 || accent == themeInfo.accentBaseColor || themeInfo.firstAccentIsDefault && themeInfo.currentAccentId == DEFALT_THEME_ACCENT_ID) { if (accent == 0 || themeInfo.accentBaseColor == 0 || accent == themeInfo.accentBaseColor || themeInfo.firstAccentIsDefault && themeInfo.currentAccentId == DEFALT_THEME_ACCENT_ID) {
return color; return color;
@ -6551,7 +6587,7 @@ public class Theme {
Color.colorToHSV(themeInfo.accentBaseColor, hsvTemp3); Color.colorToHSV(themeInfo.accentBaseColor, hsvTemp3);
Color.colorToHSV(accent, hsvTemp4); Color.colorToHSV(accent, hsvTemp4);
return changeColorAccent(hsvTemp3, hsvTemp4, color, themeInfo.isDark()); return changeColorAccent(hsvTemp3, hsvTemp4, color, themeInfo.isDark(), color);
} }
public static float[] getTempHsv(int num) { public static float[] getTempHsv(int num) {
@ -6609,7 +6645,7 @@ public class Theme {
} }
private static float[] tmpHSV5; private static float[] tmpHSV5;
public static int changeColorAccent(float[] baseHsv, float[] accentHsv, int color, boolean isDarkTheme) { public static int changeColorAccent(float[] baseHsv, float[] accentHsv, int color, boolean isDarkTheme, int fallback) {
if (tmpHSV5 == null) { if (tmpHSV5 == null) {
tmpHSV5 = new float[3]; tmpHSV5 = new float[3];
} }
@ -6618,7 +6654,7 @@ public class Theme {
final float diffH = Math.min(abs(colorHsv[0] - baseHsv[0]), abs(colorHsv[0] - baseHsv[0] - 360f)); final float diffH = Math.min(abs(colorHsv[0] - baseHsv[0]), abs(colorHsv[0] - baseHsv[0] - 360f));
if (diffH > 30f) { if (diffH > 30f) {
return color; return fallback;
} }
float dist = Math.min(1.5f * colorHsv[1] / baseHsv[1], 1f); float dist = Math.min(1.5f * colorHsv[1] / baseHsv[1], 1f);
@ -8098,6 +8134,7 @@ public class Theme {
avatarDrawables[14] = resources.getDrawable(R.drawable.filled_gift_premium); avatarDrawables[14] = resources.getDrawable(R.drawable.filled_gift_premium);
avatarDrawables[15] = resources.getDrawable(R.drawable.filled_unknown); avatarDrawables[15] = resources.getDrawable(R.drawable.filled_unknown);
avatarDrawables[16] = resources.getDrawable(R.drawable.filled_unclaimed); avatarDrawables[16] = resources.getDrawable(R.drawable.filled_unclaimed);
avatarDrawables[17] = resources.getDrawable(R.drawable.large_repost_story);
if (dialogs_archiveAvatarDrawable != null) { if (dialogs_archiveAvatarDrawable != null) {
dialogs_archiveAvatarDrawable.setCallback(null); dialogs_archiveAvatarDrawable.setCallback(null);
@ -8503,7 +8540,7 @@ public class Theme {
chat_unlockExtendedMediaTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); chat_unlockExtendedMediaTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_unlockExtendedMediaTextPaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)); chat_unlockExtendedMediaTextPaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
chat_actionBackgroundGradientDarkenPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chat_actionBackgroundGradientDarkenPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
chat_actionBackgroundGradientDarkenPaint.setColor(0x2a000000); chat_actionBackgroundGradientDarkenPaint.setColor(0x15000000);
chat_timeBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chat_timeBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
chat_contextResult_titleTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); chat_contextResult_titleTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_contextResult_titleTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); chat_contextResult_titleTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
@ -8513,13 +8550,12 @@ public class Theme {
chat_radialProgressPausedSeekbarPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chat_radialProgressPausedSeekbarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
chat_messageBackgroundSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chat_messageBackgroundSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
chat_actionBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chat_actionBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
chat_actionBackgroundSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG); chat_actionBackgroundSelectedPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
chat_actionBackgroundPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
chat_actionBackgroundSelectedPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
addChatPaint(key_paint_chatMessageBackgroundSelected, chat_messageBackgroundSelectedPaint, key_chat_selectedBackground); addChatPaint(key_paint_chatMessageBackgroundSelected, chat_messageBackgroundSelectedPaint, key_chat_selectedBackground);
addChatPaint(key_paint_chatActionBackground, chat_actionBackgroundPaint, key_chat_serviceBackground); addChatPaint(key_paint_chatActionBackground, chat_actionBackgroundPaint, key_chat_serviceBackground);
addChatPaint(key_paint_chatActionBackgroundDarken, chat_actionBackgroundGradientDarkenPaint, key_chat_serviceBackground);
addChatPaint(key_paint_chatActionBackgroundSelected, chat_actionBackgroundSelectedPaint, key_chat_serviceBackgroundSelected); addChatPaint(key_paint_chatActionBackgroundSelected, chat_actionBackgroundSelectedPaint, key_chat_serviceBackgroundSelected);
addChatPaint(key_paint_chatActionText, chat_actionTextPaint, key_chat_serviceText); addChatPaint(key_paint_chatActionText, chat_actionTextPaint, key_chat_serviceText);
addChatPaint(key_paint_chatActionText2, chat_actionTextPaint2, key_chat_serviceText); addChatPaint(key_paint_chatActionText2, chat_actionTextPaint2, key_chat_serviceText);
@ -8647,6 +8683,7 @@ public class Theme {
chat_shareIconDrawable = resources.getDrawable(R.drawable.filled_button_share).mutate(); chat_shareIconDrawable = resources.getDrawable(R.drawable.filled_button_share).mutate();
chat_replyIconDrawable = resources.getDrawable(R.drawable.filled_button_reply); chat_replyIconDrawable = resources.getDrawable(R.drawable.filled_button_reply);
chat_closeIconDrawable = resources.getDrawable(R.drawable.msg_voiceclose).mutate();
chat_goIconDrawable = resources.getDrawable(R.drawable.message_arrow); chat_goIconDrawable = resources.getDrawable(R.drawable.message_arrow);
int rad = AndroidUtilities.dp(2); int rad = AndroidUtilities.dp(2);
@ -8741,6 +8778,7 @@ public class Theme {
addChatDrawable(key_drawable_msgStickerReplies, chat_msgStickerRepliesDrawable, key_chat_serviceText); addChatDrawable(key_drawable_msgStickerReplies, chat_msgStickerRepliesDrawable, key_chat_serviceText);
addChatDrawable(key_drawable_msgStickerViews, chat_msgStickerViewsDrawable, key_chat_serviceText); addChatDrawable(key_drawable_msgStickerViews, chat_msgStickerViewsDrawable, key_chat_serviceText);
addChatDrawable(key_drawable_replyIcon, chat_replyIconDrawable, key_chat_serviceIcon); addChatDrawable(key_drawable_replyIcon, chat_replyIconDrawable, key_chat_serviceIcon);
addChatDrawable(key_drawable_closeIcon, chat_closeIconDrawable, key_chat_serviceIcon);
addChatDrawable(key_drawable_shareIcon, chat_shareIconDrawable, key_chat_serviceIcon); addChatDrawable(key_drawable_shareIcon, chat_shareIconDrawable, key_chat_serviceIcon);
addChatDrawable(key_drawable_muteIconDrawable, chat_muteIconDrawable, key_chat_muteIcon); addChatDrawable(key_drawable_muteIconDrawable, chat_muteIconDrawable, key_chat_muteIcon);
addChatDrawable(key_drawable_lockIconDrawable, chat_lockIconDrawable, key_chat_lockIcon); addChatDrawable(key_drawable_lockIconDrawable, chat_lockIconDrawable, key_chat_lockIcon);
@ -8994,6 +9032,18 @@ public class Theme {
int x = viewPos[0]; int x = viewPos[0];
int y = viewPos[1]; int y = viewPos[1];
background.getLocationOnScreen(viewPos); background.getLocationOnScreen(viewPos);
if (background instanceof ThemePreviewActivity.BackgroundView) {
if (serviceBitmap != null) {
float bitmapWidth = serviceBitmap.getWidth();
float bitmapHeight = serviceBitmap.getHeight();
float maxScale = Math.max(background.getMeasuredWidth() / bitmapWidth, background.getMeasuredHeight() / bitmapHeight);
float width = bitmapWidth * maxScale;
x += ((background.getMeasuredWidth() - width) / 2) -((ThemePreviewActivity.BackgroundView) background).tx;
} else {
x += -((ThemePreviewActivity.BackgroundView) background).tx;
}
y += -((ThemePreviewActivity.BackgroundView) background).ty;
}
if (resourcesProvider != null) { if (resourcesProvider != null) {
resourcesProvider.applyServiceShaderMatrix(background.getMeasuredWidth(), background.getMeasuredHeight(), x, y - viewPos[1]); resourcesProvider.applyServiceShaderMatrix(background.getMeasuredWidth(), background.getMeasuredHeight(), x, y - viewPos[1]);
} else { } else {
@ -9006,7 +9056,7 @@ public class Theme {
} }
public static void applyServiceShaderMatrix(Bitmap bitmap, BitmapShader shader, Matrix matrix, int w, int h, float translationX, float translationY) { public static void applyServiceShaderMatrix(Bitmap bitmap, BitmapShader shader, Matrix matrix, int w, int h, float translationX, float translationY) {
if (shader == null) { if (shader == null || matrix == null) {
return; return;
} }
@ -9033,40 +9083,44 @@ public class Theme {
return; return;
} }
int serviceColor; int serviceColor;
int serviceColor2;
int servicePressedColor; int servicePressedColor;
int servicePressedColor2;
serviceMessageColor = serviceMessageColorBackup; serviceMessageColor = serviceMessageColorBackup;
serviceSelectedMessageColor = serviceSelectedMessageColorBackup; serviceSelectedMessageColor = serviceSelectedMessageColorBackup;
if (custom != null && custom.length >= 2) { if (custom != null && custom.length >= 2) {
serviceColor2 = serviceColor = custom[0]; serviceColor = custom[0];
servicePressedColor2 = servicePressedColor = custom[1]; servicePressedColor = custom[1];
serviceMessageColor = custom[0]; serviceMessageColor = custom[0];
serviceSelectedMessageColor = custom[1]; serviceSelectedMessageColor = custom[1];
} else { } else {
int serviceIndex = currentColors.indexOfKey(key_chat_serviceBackground); int serviceIndex = currentColors.indexOfKey(key_chat_serviceBackground);
if (serviceIndex >= 0) { if (serviceIndex >= 0) {
serviceColor2 = serviceColor = currentColors.valueAt(serviceIndex); serviceColor = currentColors.valueAt(serviceIndex);
} else { } else {
serviceColor = serviceMessageColor; serviceColor = serviceMessageColor;
serviceColor2 = serviceMessage2Color;
} }
int servicePressedIndex = currentColors.indexOfKey(key_chat_serviceBackgroundSelected); int servicePressedIndex = currentColors.indexOfKey(key_chat_serviceBackgroundSelected);
if (servicePressedIndex >= 0) { if (servicePressedIndex >= 0) {
servicePressedColor2 = servicePressedColor = currentColors.valueAt(servicePressedIndex); servicePressedColor = currentColors.valueAt(servicePressedIndex);
} else { } else {
servicePressedColor = serviceSelectedMessageColor; servicePressedColor = serviceSelectedMessageColor;
servicePressedColor2 = serviceSelectedMessage2Color;
} }
} }
Drawable drawable = wallpaperOverride != null ? wallpaperOverride : currentWallpaper; Drawable drawable = wallpaperOverride != null ? wallpaperOverride : currentWallpaper;
boolean drawServiceGradient = drawable instanceof MotionBackgroundDrawable && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW && LiteMode.isEnabled(LiteMode.FLAG_CHAT_BACKGROUND); boolean drawServiceGradient = (drawable instanceof MotionBackgroundDrawable || drawable instanceof BitmapDrawable) && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW && LiteMode.isEnabled(LiteMode.FLAG_CHAT_BACKGROUND);
if (drawServiceGradient) { if (drawServiceGradient) {
Bitmap newBitmap = ((MotionBackgroundDrawable) drawable).getBitmap(); Bitmap newBitmap = null;
if (drawable instanceof MotionBackgroundDrawable) {
newBitmap = ((MotionBackgroundDrawable) drawable).getBitmap();
} else if (drawable instanceof BitmapDrawable) {
newBitmap = checkBlur(drawable);
}
if (serviceBitmap != newBitmap) { if (serviceBitmap != newBitmap) {
serviceBitmap = newBitmap; serviceBitmap = newBitmap;
serviceBitmapShader = new BitmapShader(serviceBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); serviceBitmapShader = new BitmapShader(serviceBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
serviceBitmapShader.setFilterMode(BitmapShader.FILTER_MODE_LINEAR);
}
if (serviceBitmapMatrix == null) { if (serviceBitmapMatrix == null) {
serviceBitmapMatrix = new Matrix(); serviceBitmapMatrix = new Matrix();
} }
@ -9115,28 +9169,85 @@ public class Theme {
chat_actionBackgroundPaint.setColor(serviceColor); chat_actionBackgroundPaint.setColor(serviceColor);
chat_actionBackgroundSelectedPaint.setColor(servicePressedColor); chat_actionBackgroundSelectedPaint.setColor(servicePressedColor);
chat_actionBackgroundPaint2.setColor(serviceColor2);
currentColor = serviceColor; currentColor = serviceColor;
if (serviceBitmapShader != null && (currentColors.indexOfKey(key_chat_serviceBackground) < 0 || drawable instanceof MotionBackgroundDrawable)) { if (serviceBitmapShader != null && (currentColors.indexOfKey(key_chat_serviceBackground) < 0 || drawable instanceof MotionBackgroundDrawable || drawable instanceof BitmapDrawable)) {
ColorMatrix colorMatrix = new ColorMatrix(); ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(((MotionBackgroundDrawable) drawable).getIntensity() >= 0 ? 1.8f : 0.5f); if (drawable instanceof MotionBackgroundDrawable) {
float intensity = ((MotionBackgroundDrawable) drawable).getIntensity();
if (intensity >= 0) {
colorMatrix.setSaturation(1.6f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? .97f : .92f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? +.12f : -.06f);
} else {
colorMatrix.setSaturation(1.1f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? .4f : .8f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? +.08f : -.06f);
}
} else {
colorMatrix.setSaturation(1.6f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? .9f : .84f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? -.04f : +.06f);
}
chat_actionBackgroundPaint.setFilterBitmap(true);
chat_actionBackgroundPaint.setShader(serviceBitmapShader); chat_actionBackgroundPaint.setShader(serviceBitmapShader);
chat_actionBackgroundPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); chat_actionBackgroundPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
chat_actionBackgroundPaint.setAlpha(127); chat_actionBackgroundPaint.setAlpha(0xff);
chat_actionBackgroundSelectedPaint.setFilterBitmap(true);
chat_actionBackgroundSelectedPaint.setShader(serviceBitmapShader); chat_actionBackgroundSelectedPaint.setShader(serviceBitmapShader);
colorMatrix = new ColorMatrix(colorMatrix);
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.26f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, isCurrentThemeDark() ? .92f : .92f);
chat_actionBackgroundSelectedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); chat_actionBackgroundSelectedPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
chat_actionBackgroundSelectedPaint.setAlpha(200); chat_actionBackgroundSelectedPaint.setAlpha(0xff);
chat_actionBackgroundGradientDarkenPaint.setAlpha(0);
} else { } else {
chat_actionBackgroundPaint.setColorFilter(null); chat_actionBackgroundPaint.setColorFilter(null);
chat_actionBackgroundPaint.setShader(null); chat_actionBackgroundPaint.setShader(null);
chat_actionBackgroundSelectedPaint.setColorFilter(null); chat_actionBackgroundSelectedPaint.setColorFilter(null);
chat_actionBackgroundSelectedPaint.setShader(null); chat_actionBackgroundSelectedPaint.setShader(null);
chat_actionBackgroundGradientDarkenPaint.setAlpha(0x15);
} }
} }
private static WeakReference<Drawable> lastDrawableToBlur;
private static Bitmap blurredBitmap;
private static Bitmap checkBlur(Drawable d) {
if (lastDrawableToBlur != null && lastDrawableToBlur.get() == d) {
return blurredBitmap;
}
if (lastDrawableToBlur != null) {
lastDrawableToBlur.clear();
}
lastDrawableToBlur = null;
if (d == null || d.getIntrinsicWidth() == 0 || d.getIntrinsicHeight() == 0) {
return blurredBitmap = null;
}
lastDrawableToBlur = new WeakReference<>(d);
final int h = 24;
final int w = (int) ((float) d.getIntrinsicWidth() / d.getIntrinsicHeight() * h);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
d.setBounds(0, 0, w, h);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
final ColorFilter wasColorFilter = d.getColorFilter();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(1.3f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, .94f);
d.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
d.draw(new Canvas(bitmap));
d.setColorFilter(wasColorFilter);
} else {
d.draw(new Canvas(bitmap));
}
Utilities.blurBitmap(bitmap, 3, 1, bitmap.getWidth(), bitmap.getHeight(), bitmap.getRowBytes());
return blurredBitmap = bitmap;
}
public static void applyChatMessageSelectedBackgroundColor() { public static void applyChatMessageSelectedBackgroundColor() {
applyChatMessageSelectedBackgroundColor(null, wallpaper); applyChatMessageSelectedBackgroundColor(null, wallpaper);
} }
@ -9285,7 +9396,7 @@ public class Theme {
float[] hsvTemp2 = getTempHsv(2); float[] hsvTemp2 = getTempHsv(2);
Color.colorToHSV(currentTheme.accentBaseColor, hsvTemp1); Color.colorToHSV(currentTheme.accentBaseColor, hsvTemp1);
Color.colorToHSV(accent.accentColor, hsvTemp2); Color.colorToHSV(accent.accentColor, hsvTemp2);
return changeColorAccent(hsvTemp1, hsvTemp2, color, currentTheme.isDark()); return changeColorAccent(hsvTemp1, hsvTemp2, color, currentTheme.isDark(), color);
} }
return 0; return 0;
} }
@ -9567,8 +9678,6 @@ public class Theme {
int[] result = AndroidUtilities.calcDrawableColor(drawable); int[] result = AndroidUtilities.calcDrawableColor(drawable);
serviceMessageColor = serviceMessageColorBackup = result[0]; serviceMessageColor = serviceMessageColorBackup = result[0];
serviceSelectedMessageColor = serviceSelectedMessageColorBackup = result[1]; serviceSelectedMessageColor = serviceSelectedMessageColorBackup = result[1];
serviceMessage2Color = result[2];
serviceSelectedMessage2Color = result[3];
} }
} }
@ -9651,7 +9760,8 @@ public class Theme {
hasPreviousTheme, hasPreviousTheme,
isApplyingAccent, isApplyingAccent,
wallpaperMotion, wallpaperMotion,
finalWallpaperDocument finalWallpaperDocument,
false
); );
isWallpaperMotion = settings.isWallpaperMotion != null ? settings.isWallpaperMotion : isWallpaperMotion; isWallpaperMotion = settings.isWallpaperMotion != null ? settings.isWallpaperMotion : isWallpaperMotion;
isPatternWallpaper = settings.isPatternWallpaper != null ? settings.isPatternWallpaper : isPatternWallpaper; isPatternWallpaper = settings.isPatternWallpaper != null ? settings.isPatternWallpaper : isPatternWallpaper;
@ -9660,6 +9770,7 @@ public class Theme {
wallpaper = settings.wallpaper != null ? settings.wallpaper : wallpaper; wallpaper = settings.wallpaper != null ? settings.wallpaper : wallpaper;
Drawable drawable = settings.wallpaper; Drawable drawable = settings.wallpaper;
calcBackgroundColor(drawable, 1); calcBackgroundColor(drawable, 1);
applyChatServiceMessageColor();
return drawable; return drawable;
} }
@ -9668,7 +9779,8 @@ public class Theme {
ThemeInfo currentTheme, ThemeInfo currentTheme,
SparseIntArray currentColors, SparseIntArray currentColors,
String wallpaperLink, String wallpaperLink,
int prevoiusPhase int prevoiusPhase,
boolean local
) { ) {
boolean defaultTheme = currentTheme.firstAccentIsDefault && currentTheme.currentAccentId == DEFALT_THEME_ACCENT_ID; boolean defaultTheme = currentTheme.firstAccentIsDefault && currentTheme.currentAccentId == DEFALT_THEME_ACCENT_ID;
ThemeAccent accent = currentTheme.getAccent(false); ThemeAccent accent = currentTheme.getAccent(false);
@ -9680,7 +9792,7 @@ public class Theme {
: (int) (accent != null ? (accent.patternIntensity * 100) : currentTheme.patternIntensity); : (int) (accent != null ? (accent.patternIntensity * 100) : currentTheme.patternIntensity);
int wallpaperFileOffset = currentColorsNoAccent.get(key_wallpaperFileOffset, -1); int wallpaperFileOffset = currentColorsNoAccent.get(key_wallpaperFileOffset, -1);
return createBackgroundDrawable(currentTheme, overrideWallpaper, currentColors, wallpaperFile, wallpaperLink, wallpaperFileOffset, intensity, prevoiusPhase, defaultTheme, false, false, wallpaperMotion, null); return createBackgroundDrawable(currentTheme, overrideWallpaper, currentColors, wallpaperFile, wallpaperLink, wallpaperFileOffset, intensity, prevoiusPhase, defaultTheme, false, false, wallpaperMotion, null, local);
} }
public static BackgroundDrawableSettings createBackgroundDrawable( public static BackgroundDrawableSettings createBackgroundDrawable(
@ -9696,10 +9808,11 @@ public class Theme {
boolean hasPreviousTheme, boolean hasPreviousTheme,
boolean isApplyingAccent, boolean isApplyingAccent,
boolean wallpaperMotion, boolean wallpaperMotion,
TLRPC.Document wallpaperDocument TLRPC.Document wallpaperDocument,
boolean local
) { ) {
BackgroundDrawableSettings settings = new BackgroundDrawableSettings(); BackgroundDrawableSettings settings = new BackgroundDrawableSettings();
settings.wallpaper = wallpaper; settings.wallpaper = local ? null : wallpaper;
boolean overrideTheme = (!hasPreviousTheme || isApplyingAccent) && overrideWallpaper != null; boolean overrideTheme = (!hasPreviousTheme || isApplyingAccent) && overrideWallpaper != null;
if (overrideWallpaper != null) { if (overrideWallpaper != null) {
settings.isWallpaperMotion = overrideWallpaper.isMotion; settings.isWallpaperMotion = overrideWallpaper.isMotion;

View file

@ -1365,7 +1365,7 @@ public class ThemeColors {
colorKeysMap.put(key_voipgroup_overlayAlertGradientUnmuted, "voipgroup_overlayAlertGradientUnmuted"); colorKeysMap.put(key_voipgroup_overlayAlertGradientUnmuted, "voipgroup_overlayAlertGradientUnmuted");
colorKeysMap.put(key_voipgroup_overlayAlertGradientUnmuted2, "voipgroup_overlayAlertGradientUnmuted2"); colorKeysMap.put(key_voipgroup_overlayAlertGradientUnmuted2, "voipgroup_overlayAlertGradientUnmuted2");
colorKeysMap.put(key_voipgroup_overlayAlertMutedByAdmin, "voipgroup_overlayAlertMutedByAdmin"); colorKeysMap.put(key_voipgroup_overlayAlertMutedByAdmin, "voipgroup_overlayAlertMutedByAdmin");
colorKeysMap.put(key_voipgroup_overlayAlertMutedByAdmin2, "kvoipgroup_overlayAlertMutedByAdmin2"); colorKeysMap.put(key_voipgroup_overlayAlertMutedByAdmin2, "voipgroup_overlayAlertMutedByAdmin2");
colorKeysMap.put(key_voipgroup_mutedByAdminGradient, "voipgroup_mutedByAdminGradient"); colorKeysMap.put(key_voipgroup_mutedByAdminGradient, "voipgroup_mutedByAdminGradient");
colorKeysMap.put(key_voipgroup_mutedByAdminGradient2, "voipgroup_mutedByAdminGradient2"); colorKeysMap.put(key_voipgroup_mutedByAdminGradient2, "voipgroup_mutedByAdminGradient2");
colorKeysMap.put(key_voipgroup_mutedByAdminGradient3, "voipgroup_mutedByAdminGradient3"); colorKeysMap.put(key_voipgroup_mutedByAdminGradient3, "voipgroup_mutedByAdminGradient3");

View file

@ -112,6 +112,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private Runnable cancelShowMoreAnimation; private Runnable cancelShowMoreAnimation;
private ArrayList<Long> filterDialogIds; private ArrayList<Long> filterDialogIds;
private final DialogsActivity dialogsActivity; private final DialogsActivity dialogsActivity;
private final Theme.ResourcesProvider resourcesProvider;
private int currentAccount = UserConfig.selectedAccount; private int currentAccount = UserConfig.selectedAccount;
@ -163,11 +164,13 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
private final int currentAccount; private final int currentAccount;
private boolean drawChecked; private boolean drawChecked;
private boolean forceDarkTheme; private boolean forceDarkTheme;
private Theme.ResourcesProvider resourcesProvider;
public CategoryAdapterRecycler(Context context, int account, boolean drawChecked) { public CategoryAdapterRecycler(Context context, int account, boolean drawChecked, Theme.ResourcesProvider resourcesProvider) {
this.drawChecked = drawChecked; this.drawChecked = drawChecked;
mContext = context; mContext = context;
currentAccount = account; currentAccount = account;
this.resourcesProvider = resourcesProvider;
} }
public void setIndex(int value) { public void setIndex(int value) {
@ -176,7 +179,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
HintDialogCell cell = new HintDialogCell(mContext, drawChecked); HintDialogCell cell = new HintDialogCell(mContext, drawChecked, resourcesProvider);
cell.setLayoutParams(new RecyclerView.LayoutParams(AndroidUtilities.dp(80), AndroidUtilities.dp(86))); cell.setLayoutParams(new RecyclerView.LayoutParams(AndroidUtilities.dp(80), AndroidUtilities.dp(86)));
return new RecyclerListView.Holder(cell); return new RecyclerListView.Holder(cell);
} }
@ -244,9 +247,10 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
return false; return false;
} }
public DialogsSearchAdapter(Context context, DialogsActivity dialogsActivity, int messagesSearch, int type, DefaultItemAnimator itemAnimator, boolean allowGlobalSearch) { public DialogsSearchAdapter(Context context, DialogsActivity dialogsActivity, int messagesSearch, int type, DefaultItemAnimator itemAnimator, boolean allowGlobalSearch, Theme.ResourcesProvider resourcesProvider) {
this.itemAnimator = itemAnimator; this.itemAnimator = itemAnimator;
this.dialogsActivity = dialogsActivity; this.dialogsActivity = dialogsActivity;
this.resourcesProvider = resourcesProvider;
searchAdapterHelper = new SearchAdapterHelper(false) { searchAdapterHelper = new SearchAdapterHelper(false) {
@Override @Override
protected boolean filter(TLObject obj) { protected boolean filter(TLObject obj) {
@ -1418,7 +1422,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
horizontalListView.setLayoutManager(layoutManager); horizontalListView.setLayoutManager(layoutManager);
//horizontalListView.setDisallowInterceptTouchEvents(true); //horizontalListView.setDisallowInterceptTouchEvents(true);
horizontalListView.setAdapter(new CategoryAdapterRecycler(mContext, currentAccount, false)); horizontalListView.setAdapter(new CategoryAdapterRecycler(mContext, currentAccount, false, resourcesProvider));
horizontalListView.setOnItemClickListener((view1, position) -> { horizontalListView.setOnItemClickListener((view1, position) -> {
if (delegate != null) { if (delegate != null) {
delegate.didPressedOnSubDialog((Long) view1.getTag()); delegate.didPressedOnSubDialog((Long) view1.getTag());

View file

@ -0,0 +1,82 @@
package org.telegram.ui;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.style.ReplacementSpan;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.telegram.messenger.ImageReceiver;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.Components.AvatarDrawable;
public class AvatarSpan extends ReplacementSpan {
private final Paint shadowPaint;
private final ImageReceiver imageReceiver;
private final AvatarDrawable avatarDrawable;
private final int sz;
private final int currentAccount;
public AvatarSpan(View parent, int currentAccount, int sz) {
this.currentAccount = currentAccount;
this.imageReceiver = new ImageReceiver(parent);
this.avatarDrawable = new AvatarDrawable();
imageReceiver.setRoundRadius(dp(sz));
this.sz = sz;
this.shadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
shadowPaint.setShadowLayer(dp(1), 0, dp(.66f), 0x33000000);
if (parent != null && parent.isAttachedToWindow()) {
imageReceiver.onAttachedToWindow();
}
if (parent != null) {
parent.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(@NonNull View v) {
imageReceiver.onAttachedToWindow();
}
@Override
public void onViewDetachedFromWindow(@NonNull View v) {
imageReceiver.onDetachedFromWindow();
}
});
}
}
public void setChat(TLRPC.Chat chat) {
avatarDrawable.setInfo(currentAccount, chat);
imageReceiver.setForUserOrChat(chat, avatarDrawable);
}
public void setUser(TLRPC.User user) {
avatarDrawable.setInfo(currentAccount, user);
imageReceiver.setForUserOrChat(user, avatarDrawable);
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
return dp(sz);
}
private float translateX, translateY;
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
canvas.drawCircle(translateX + x + dp(sz) / 2f, translateY + (top + bottom) / 2f, dp(sz) / 2f, shadowPaint);
imageReceiver.setImageCoords(translateX + x, translateY + (top + bottom) / 2f - dp(sz) / 2f, dp(sz), dp(sz));
imageReceiver.draw(canvas);
}
public void translate(float x, float y) {
this.translateX = x;
this.translateY = y;
}
}

View file

@ -3167,7 +3167,7 @@ public class CacheControlActivity extends BaseFragment implements NotificationCe
@Override @Override
public boolean isSwipeBackEnabled(MotionEvent event) { public boolean isSwipeBackEnabled(MotionEvent event) {
if (cachedMediaLayout != null) { if (cachedMediaLayout != null && event != null) {
cachedMediaLayout.getHitRect(AndroidUtilities.rectTmp2); cachedMediaLayout.getHitRect(AndroidUtilities.rectTmp2);
if (!AndroidUtilities.rectTmp2.contains((int) event.getX(), (int) event.getY() - actionBar.getMeasuredHeight())) { if (!AndroidUtilities.rectTmp2.contains((int) event.getX(), (int) event.getY() - actionBar.getMeasuredHeight())) {
return true; return true;

View file

@ -21,7 +21,6 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
@ -122,7 +121,7 @@ public class AccountSelectCell extends FrameLayout {
public void setAccount(int account, boolean check) { public void setAccount(int account, boolean check) {
accountNumber = account; accountNumber = account;
TLRPC.User user = UserConfig.getInstance(accountNumber).getCurrentUser(); TLRPC.User user = UserConfig.getInstance(accountNumber).getCurrentUser();
avatarDrawable.setInfo(user); avatarDrawable.setInfo(account, user);
textView.setText(ContactsController.formatName(user.first_name, user.last_name)); textView.setText(ContactsController.formatName(user.first_name, user.last_name));
imageView.getImageReceiver().setCurrentAccount(account); imageView.getImageReceiver().setCurrentAccount(account);
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);

View file

@ -88,7 +88,7 @@ public class AdminedChannelCell extends FrameLayout {
public void setChannel(TLRPC.Chat channel, boolean last) { public void setChannel(TLRPC.Chat channel, boolean last) {
final String url = MessagesController.getInstance(currentAccount).linkPrefix + "/"; final String url = MessagesController.getInstance(currentAccount).linkPrefix + "/";
currentChannel = channel; currentChannel = channel;
avatarDrawable.setInfo(channel); avatarDrawable.setInfo(currentAccount, channel);
nameTextView.setText(channel.title); nameTextView.setText(channel.title);
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(url + ChatObject.getPublicUsername(channel)); SpannableStringBuilder stringBuilder = new SpannableStringBuilder(url + ChatObject.getPublicUsername(channel));
stringBuilder.setSpan(new URLSpanNoUnderline(""), url.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); stringBuilder.setSpan(new URLSpanNoUnderline(""), url.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
@ -98,7 +98,7 @@ public class AdminedChannelCell extends FrameLayout {
} }
public void update() { public void update() {
avatarDrawable.setInfo(currentChannel); avatarDrawable.setInfo(currentAccount, currentChannel);
avatarImageView.invalidate(); avatarImageView.invalidate();
} }

View file

@ -0,0 +1,872 @@
package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.dpf2;
import static org.telegram.messenger.LocaleController.getString;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.graphics.text.LineBreaker;
import android.media.Image;
import android.os.Build;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.ButtonBounce;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LoadingDrawable;
import org.telegram.ui.Components.Scroller;
import org.telegram.ui.Components.StaticLayoutEx;
import org.telegram.ui.Components.Text;
import java.util.ArrayList;
public class ChannelRecommendationsCell {
private ChatMessageCell cell;
public ChannelRecommendationsCell(ChatMessageCell cell) {
this.cell = cell;
this.scroller = new Scroller(cell.getContext());
this.closeBounce = new ButtonBounce(cell);
loading = true;
this.loadingAlpha = new AnimatedFloat(cell, 350, CubicBezierInterpolator.EASE_OUT_QUINT);
}
private int currentAccount;
private long dialogId;
private MessageObject msg;
private TLRPC.Chat currentChat;
public long chatId;
private final TextPaint serviceTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private StaticLayout serviceText;
private float serviceTextLeft, serviceTextRight;
private int serviceTextHeight;
private final Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path backgroundPath = new Path();
private float lastBackgroundPathExpandT = -1;
private int blockWidth = dp(66);
private float scrollX;
private float channelsScrollWidth;
private final ArrayList<ChannelBlock> channels = new ArrayList<>();
private final Path loadingPath = new Path();
private LoadingDrawable loadingDrawable;
private boolean loading;
private final AnimatedFloat loadingAlpha;
private Text headerText;
private final RectF backgroundBounds = new RectF();
private final RectF closeBounds = new RectF();
private final ButtonBounce closeBounce;
private final Paint closePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public void setMessageObject(MessageObject messageObject) {
this.currentAccount = messageObject.currentAccount;
this.msg = messageObject;
this.dialogId = messageObject.getDialogId();
this.currentChat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
this.chatId = -dialogId;
serviceTextPaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
serviceTextPaint.setTextSize(dp(14));
serviceTextPaint.setColor(cell.getThemedColor(Theme.key_chat_serviceText));
serviceText = new StaticLayout(getString(R.string.ChannelJoined), serviceTextPaint, msg.getMaxMessageTextWidth(), Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
serviceTextLeft = serviceText.getWidth();
serviceTextRight = 0;
for (int i = 0; i < serviceText.getLineCount(); ++i) {
serviceTextLeft = Math.min(serviceTextLeft, serviceText.getLineLeft(i));
serviceTextRight = Math.max(serviceTextRight, serviceText.getLineRight(i));
}
serviceTextHeight = serviceText.getHeight();
closePaint.setStyle(Paint.Style.STROKE);
closePaint.setStrokeCap(Paint.Cap.ROUND);
closePaint.setStrokeJoin(Paint.Join.ROUND);
closePaint.setColor(cell.getThemedColor(Theme.key_dialogEmptyImage));
cell.totalHeight = dp(4 + 3.33f + 3.33f + 4) + serviceTextHeight;
if (headerText == null) {
headerText = new Text(getString(R.string.SimilarChannels), 14, AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)).hackClipBounds();
}
for (int i = 0; i < channels.size(); ++i) {
channels.get(i).detach();
}
channels.clear();
MessagesController.ChannelRecommendations rec = MessagesController.getInstance(currentAccount).getChannelRecommendations(-dialogId);
ArrayList<TLRPC.Chat> chats = rec == null || rec.chats == null ? new ArrayList<>() : new ArrayList<>(rec.chats);
for (int i = 0; i < chats.size(); ++i) {
if (!ChatObject.isNotInChat(chats.get(i))) {
chats.remove(i);
i--;
}
}
loading = chats.isEmpty() || !UserConfig.getInstance(currentAccount).isPremium() && chats.size() == 1;
if (!loading) {
int count = chats.size();
if (!UserConfig.getInstance(currentAccount).isPremium() && rec.more > 0) {
count = Math.min(count - 1, MessagesController.getInstance(currentAccount).recommendedChannelsLimitDefault);
}
count = Math.min(count, 10);
for (int i = 0; i < count; ++i) {
channels.add(new ChannelBlock(currentAccount, cell, chats.get(i)));
}
if (count < chats.size()) {
TLRPC.Chat[] _chats = new TLRPC.Chat[3];
_chats[0] = count >= 0 && count < chats.size() ? chats.get(count) : null;
_chats[1] = count >= 0 && count + 1 < chats.size() ? chats.get(count + 1) : null;
_chats[2] = count >= 0 && count + 2 < chats.size() ? chats.get(count + 2) : null;
channels.add(new ChannelBlock(currentAccount, cell, _chats, (chats.size() + rec.more) - count));
}
}
if (isExpanded()) {
cell.totalHeight += dp(6 + 134 + 4);
backgroundPaint.setColor(cell.getThemedColor(Theme.key_chat_inBubble));
}
channelsScrollWidth = blockWidth * channels.size() + dp(9) * (channels.size() - 1);
scrollX = Utilities.clamp(scrollX, channelsScrollWidth, 0);
}
public boolean isExpanded() {
return msg.channelJoinedExpanded && channels.size() > 0;
}
public void update() {
if (msg == null) {
return;
}
setMessageObject(msg);
cell.invalidateOutbounds();
}
public void onAttachedToWindow() {
for (int i = 0; i < channels.size(); ++i) {
channels.get(i).attach();
}
}
public void onDetachedFromWindow() {
for (int i = 0; i < channels.size(); ++i) {
channels.get(i).detach();
}
}
// public void drawText(Canvas canvas) {
// if (msg == null || cell == null) return;
//
// float y = 0;
// if (serviceText != null) {
// y += dp(4 + 3.33f + 3.33f) + serviceTextHeight;
// }
//
// float expandT;
// if (cell.transitionParams.animateRecommendationsExpanded) {
// if (isExpanded()) {
// expandT = cell.transitionParams.animateChangeProgress;
// } else {
// expandT = 1f - cell.transitionParams.animateChangeProgress;
// }
// } else {
// expandT = isExpanded() ? 1f : 0f;
// }
// expandT = Utilities.clamp((expandT - .3f) / .7f, 1, 0);
// if (expandT > 0) {
// int width = (int) Math.min(cell.getWidth() - dp(18), blockWidth * 6.5f);
// backgroundBounds.set(
// (cell.getWidth() - width) / 2f,
// y + dp(4 + 6),
// (cell.getWidth() + width) / 2f,
// y + dp(4 + 134)
// );
// checkBackgroundPath(expandT);
//
// canvas.save();
// final float s = .4f + .6f * expandT;
// canvas.scale(s, s, backgroundBounds.centerX(), backgroundBounds.top - dp(6));
//
// canvas.clipPath(backgroundPath);
//
// if (headerText != null) {
// headerText.draw(canvas, backgroundBounds.left + dp(17), backgroundBounds.top + dp( 20), cell.getThemedColor(Theme.key_windowBackgroundWhiteBlackText), expandT);
// }
//
// final float loadingAlpha = this.loadingAlpha.set(loading);
//
// final float xstart = backgroundBounds.left + dp(7) - scrollX;
// final float xi = blockWidth + dp(9);
// int from = (int) Math.floor((backgroundBounds.left - width - xstart) / xi);
// int to = (int) Math.ceil((backgroundBounds.right - xstart) / xi);
//
// if (loadingAlpha < 1) {
// for (int i = Math.max(0, from); i < Math.min(to + 1, channels.size()); ++i) {
// ChannelBlock block = channels.get(i);
//
// canvas.save();
// canvas.translate(xstart + i * xi, backgroundBounds.bottom - ChannelBlock.height());
// block.drawText(canvas, blockWidth, expandT * (1f - loadingAlpha));
// canvas.restore();
// }
// }
//
// canvas.restore();
// }
// }
public void draw(Canvas canvas) {
if (msg == null || cell == null) return;
computeScroll();
float y = 0;
if (serviceText != null) {
canvas.save();
final float ox = (cell.getWidth() - serviceText.getWidth()) / 2f;
AndroidUtilities.rectTmp.set(ox + serviceTextLeft - dp(8.66f), dp(4), ox + serviceTextRight + dp(8.66f), dp(4 + 3.33f + 3.33f) + serviceTextHeight);
cell.drawServiceBackground(canvas, AndroidUtilities.rectTmp, dp(11), 1f);
canvas.translate(ox, dp(4 + 3.33f));
serviceText.draw(canvas);
canvas.restore();
y += dp(4 + 3.33f + 3.33f) + serviceTextHeight;
}
float expandT;
if (cell.transitionParams.animateRecommendationsExpanded) {
if (isExpanded()) {
expandT = cell.transitionParams.animateChangeProgress;
} else {
expandT = 1f - cell.transitionParams.animateChangeProgress;
}
} else {
expandT = isExpanded() ? 1f : 0f;
}
expandT = Utilities.clamp((expandT - .3f) / .7f, 1, 0);
if (expandT > 0) {
final int cellWidth = cell.getWidth() - dp(18);
blockWidth = (int) (cellWidth > dp(66 * 6 + 9 * 5) ? dp(66) : Math.max(cellWidth / 4.5f - dp(9), dp(66)));
channelsScrollWidth = blockWidth * channels.size() + dp(9) * (channels.size() - 1);
final int width = (int) Math.min(cellWidth, blockWidth * 6.5f);
backgroundBounds.set(
(cell.getWidth() - width) / 2f,
y + dp(4 + 6),
(cell.getWidth() + width) / 2f,
y + dp(4 + 134)
);
scrollX = Utilities.clamp(scrollX, channelsScrollWidth - (backgroundBounds.width() - dp(14)), 0);
checkBackgroundPath(expandT);
canvas.save();
final float s = .4f + .6f * expandT;
canvas.scale(s, s, backgroundBounds.centerX(), backgroundBounds.top - dp(6));
backgroundPaint.setAlpha((int) (0xFF * expandT));
backgroundPaint.setShadowLayer(dpf2(1), 0, dpf2(0.33f), ColorUtils.setAlphaComponent(Color.BLACK, (int) (27 * expandT)));
canvas.drawPath(backgroundPath, backgroundPaint);
canvas.clipPath(backgroundPath);
if (headerText != null) {
headerText.draw(canvas, backgroundBounds.left + dp(17), backgroundBounds.top + dp( 20), cell.getThemedColor(Theme.key_windowBackgroundWhiteBlackText), expandT);
}
final float loadingAlpha = this.loadingAlpha.set(loading);
final float xstart = backgroundBounds.left + dp(7) - scrollX;
final float xi = blockWidth + dp(9);
int from = (int) Math.floor((backgroundBounds.left - width - xstart) / xi);
int to = (int) Math.ceil((backgroundBounds.right - xstart) / xi);
if (loadingAlpha < 1) {
for (int i = Math.max(0, from); i < Math.min(to + 1, channels.size()); ++i) {
ChannelBlock block = channels.get(i);
canvas.save();
canvas.translate(xstart + i * xi, backgroundBounds.bottom - ChannelBlock.height());
block.draw(canvas, blockWidth, expandT * (1f - loadingAlpha));
block.drawText(canvas, blockWidth, expandT * (1f - loadingAlpha));
canvas.restore();
}
}
if (loadingAlpha > 0) {
loadingPath.rewind();
for (int i = Math.max(0, from); i < to; ++i) {
ChannelBlock.fillPath(loadingPath, blockWidth, xstart + i * xi);
}
if (loadingDrawable == null) {
loadingDrawable = new LoadingDrawable();
loadingDrawable.usePath(loadingPath);
loadingDrawable.setAppearByGradient(false);
}
final int color = cell.getThemedColor(Theme.key_windowBackgroundWhiteBlackText);
loadingDrawable.setColors(
Theme.multAlpha(color, .05f),
Theme.multAlpha(color, .15f),
Theme.multAlpha(color, .1f),
Theme.multAlpha(color, .3f)
);
loadingDrawable.setGradientScale(1.5f);
loadingDrawable.setAlpha((int) (0xFF * loadingAlpha));
canvas.save();
canvas.translate(0, backgroundBounds.bottom - ChannelBlock.height());
loadingDrawable.draw(canvas);
canvas.restore();
// cell.invalidate();
}
final float cs = closeBounce.getScale(0.02f);
final float cx = backgroundBounds.right - dp(16 + 4);
final float cy = backgroundBounds.top + dp(16 + 4);
canvas.save();
canvas.scale(cs, cs, cx, cy);
closePaint.setStrokeWidth(dp(1.33f));
canvas.drawLine(cx - dp(4), cy - dp(4), cx + dp(4), cy + dp(4), closePaint);
canvas.drawLine(cx - dp(4), cy + dp(4), cx + dp(4), cy - dp(4), closePaint);
closeBounds.set(cx - dp(12), cy - dp(12), cx + dp(12), cy + dp(12));
canvas.restore();
canvas.restore();
}
}
private void checkBackgroundPath(float t) {
if (Math.abs(t - lastBackgroundPathExpandT) < 0.001f) {
return;
}
final float r = dp(16.66f);
final float d = r * 2;
final float bottom = backgroundBounds.bottom;
backgroundPath.rewind();
AndroidUtilities.rectTmp.set(backgroundBounds.left, backgroundBounds.top, backgroundBounds.left + d, backgroundBounds.top + d);
backgroundPath.arcTo(AndroidUtilities.rectTmp, -90, -90);
AndroidUtilities.rectTmp.set(backgroundBounds.left, bottom - d, backgroundBounds.left + d, bottom);
backgroundPath.arcTo(AndroidUtilities.rectTmp, -180, -90);
AndroidUtilities.rectTmp.set(backgroundBounds.right - d, bottom - d, backgroundBounds.right, bottom);
backgroundPath.arcTo(AndroidUtilities.rectTmp, -270, -90);
AndroidUtilities.rectTmp.set(backgroundBounds.right - d, backgroundBounds.top, backgroundBounds.right, backgroundBounds.top + d);
backgroundPath.arcTo(AndroidUtilities.rectTmp, 0, -90);
backgroundPath.lineTo(backgroundBounds.centerX() + dp(8), backgroundBounds.top);
backgroundPath.lineTo(backgroundBounds.centerX(), backgroundBounds.top - dp(6));
backgroundPath.lineTo(backgroundBounds.centerX() - dp(8), backgroundBounds.top);
backgroundPath.close();
}
private static class ChannelBlock {
public static int height() { return dp(99); };
public static int avatarSize() { return dp(54); };
private final ChatMessageCell cell;
public final AvatarDrawable[] avatarDrawable;
public final ImageReceiver[] avatarImageReceiver;
private final TextPaint nameTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private final CharSequence name;
private StaticLayout nameText;
public final boolean isLock;
private final Drawable subscribersDrawable;
private final Paint subscribersStrokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint subscribersBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint subscribersBackgroundDimPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private BitmapShader subscribersBackgroundPaintShader;
private int subscribersBackgroundPaintBitmapWidth, subscribersBackgroundPaintBitmapHeight;
private Matrix subscribersBackgroundPaintMatrix;
private final Text subscribersText;
private boolean subscribersColorSetFromThumb;
private boolean subscribersColorSet;
public final ButtonBounce bounce;
public final TLRPC.Chat chat;
public ChannelBlock(int currentAccount, ChatMessageCell cell, TLRPC.Chat[] chats, int moreCount) {
this.cell = cell;
this.chat = chats[0];
this.bounce = new ButtonBounce(cell) {
@Override
public void invalidate() {
cell.invalidateOutbounds();
}
};
final int count = 3;
avatarImageReceiver = new ImageReceiver[count];
avatarDrawable = new AvatarDrawable[count];
for (int i = 0; i < count; ++i) {
avatarImageReceiver[i] = new ImageReceiver(cell);
avatarImageReceiver[i].setParentView(cell);
avatarImageReceiver[i].setRoundRadius(avatarSize());
avatarDrawable[i] = new AvatarDrawable();
if (i < chats.length && chats[i] != null) {
avatarDrawable[i].setInfo(currentAccount, chats[i]);
avatarImageReceiver[i].setForUserOrChat(chats[i], avatarDrawable[i]);
} else {
// int resId = i == 1 ? R.drawable.widget_avatar_5 : R.drawable.widget_avatar_4;
// Drawable avatar = cell.getContext().getResources().getDrawable(resId).mutate();
// avatarImageReceiver[i].setImageBitmap(avatar);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
final int color = Theme.blendOver(cell.getThemedColor(Theme.key_chat_inBubble), Theme.multAlpha(cell.getThemedColor(Theme.key_windowBackgroundWhiteGrayText), .50f));
paint.setColor(color);
avatarImageReceiver[i].setImageBitmap(new Drawable() {
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawCircle(getBounds().centerX(), getBounds().centerY(), getBounds().width() / 2f, paint);
}
@Override
public void setAlpha(int alpha) {
paint.setAlpha(Theme.multAlpha(color, alpha / 255f));
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
});
}
}
if (cell.isCellAttachedToWindow()) {
attach();
}
nameTextPaint.setTextSize(dp(11));
final boolean isPremium = UserConfig.getInstance(cell.currentAccount).isPremium();
name = LocaleController.getString(isPremium ? R.string.MoreSimilar : R.string.UnlockSimilar);
subscribersStrokePaint.setStyle(Paint.Style.STROKE);
isLock = true;
subscribersDrawable = isPremium ? null : cell.getContext().getResources().getDrawable(R.drawable.mini_switch_lock).mutate();
if (chat == null || chat.participants_count <= 1) {
subscribersText = null;
} else {
subscribersText = new Text("+" + moreCount, 9.33f, AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
}
}
private void checkNameText(int width) {
if (nameText != null && nameText.getWidth() == width)
return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
nameText = StaticLayout.Builder.obtain(name, 0, name.length(), nameTextPaint, width)
.setMaxLines(2)
.setEllipsize(TextUtils.TruncateAt.END)
.setBreakStrategy(LineBreaker.BREAK_STRATEGY_SIMPLE)
.setAlignment(Layout.Alignment.ALIGN_CENTER)
.build();
} else {
nameText = StaticLayoutEx.createStaticLayout(name, nameTextPaint, width, Layout.Alignment.ALIGN_CENTER, 1f, 0f, false, TextUtils.TruncateAt.END, width - dp(16), 2, false);
}
}
public ChannelBlock(int currentAccount, ChatMessageCell cell, TLRPC.Chat chat) {
this.cell = cell;
this.chat = chat;
this.bounce = new ButtonBounce(cell) {
@Override
public void invalidate() {
cell.invalidateOutbounds();
}
};
avatarImageReceiver = new ImageReceiver[1];
avatarImageReceiver[0] = new ImageReceiver(cell);
avatarImageReceiver[0].setParentView(cell);
avatarImageReceiver[0].setRoundRadius(avatarSize());
if (cell.isCellAttachedToWindow()) {
attach();
}
avatarDrawable = new AvatarDrawable[1];
avatarDrawable[0] = new AvatarDrawable();
avatarDrawable[0].setInfo(currentAccount, chat);
avatarImageReceiver[0].setForUserOrChat(chat, avatarDrawable[0]);
nameTextPaint.setTextSize(dp(11));
CharSequence title = chat != null ? chat.title : "";
try {
title = Emoji.replaceEmoji(title, nameTextPaint.getFontMetricsInt(), false);
} catch (Exception ignore) {}
name = title;
subscribersStrokePaint.setStyle(Paint.Style.STROKE);
isLock = false;
subscribersDrawable = cell.getContext().getResources().getDrawable(R.drawable.mini_reply_user).mutate();
if (chat == null || chat.participants_count <= 1) {
subscribersText = null;
} else {
subscribersText = new Text(chat != null ? LocaleController.formatShortNumber(chat.participants_count, null) : "", 9.33f, AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
}
}
public void drawText(Canvas canvas, int width, float alpha) {
canvas.save();
final float s = bounce.getScale(0.075f);
canvas.scale(s, s, width / 2f, height() / 2f);
checkNameText(width);
if (nameText != null) {
canvas.save();
canvas.translate((width - nameText.getWidth()) / 2f, dp(66.33f));
if (avatarImageReceiver.length <= 1) {
nameTextPaint.setColor(cell.getThemedColor(Theme.key_chat_messageTextIn));
} else {
nameTextPaint.setColor(cell.getThemedColor(Theme.key_windowBackgroundWhiteGrayText));
}
nameTextPaint.setAlpha((int) (nameTextPaint.getAlpha() * alpha));
nameText.draw(canvas);
canvas.restore();
}
if (subscribersText != null) {
subscribersText.ellipsize(width - dp(32));
final float subscribersTextWidth = dp(subscribersDrawable != null ? 17 : 8) + subscribersText.getWidth();
float left = (width - subscribersTextWidth) / 2f;
final float cy = dp(11 - 14.33f / 2f + .33f) + avatarSize();
final float sc = .625f;
if (subscribersDrawable != null) {
subscribersDrawable.setBounds(
(int) (left + (isLock ? subscribersText.getWidth() + dp(1.33f) : 0) + dp(3)),
(int) (cy - subscribersDrawable.getIntrinsicHeight() / 2f * sc),
(int) (left + (isLock ? subscribersText.getWidth() + dp(1.33f) : 0) + dp(3) + subscribersDrawable.getIntrinsicWidth() * sc),
(int) (cy + subscribersDrawable.getIntrinsicHeight() / 2f * sc)
);
subscribersDrawable.draw(canvas);
}
subscribersText.draw(canvas, left + dp(!isLock ? 12.66f : 4), cy, Color.WHITE, alpha);
}
canvas.restore();
}
private Path subscribersBackgroundPath;
public void draw(Canvas canvas, int width, float alpha) {
canvas.save();
final float s = bounce.getScale(0.075f);
canvas.scale(s, s, width / 2f, height() / 2f);
subscribersStrokePaint.setStrokeWidth(dp(2.66f));
subscribersStrokePaint.setColor(cell.getThemedColor(Theme.key_chat_inBubble));
for (int i = avatarImageReceiver.length - 1; i >= 0; --i) {
final float x = width / 2f - dp(7) * (avatarImageReceiver.length - 1) / 2f + i * dp(7);
final float y = dp(10) + avatarSize() / 2f;
if (avatarImageReceiver.length > 1) {
canvas.drawCircle(x, y, avatarSize() / 2f, subscribersStrokePaint);
}
avatarImageReceiver[i].setImageCoords(
x - avatarSize() / 2f,
y - avatarSize() / 2f,
avatarSize(),
avatarSize()
);
avatarImageReceiver[i].setAlpha(alpha);
avatarImageReceiver[i].draw(canvas);
}
if (subscribersText != null) {
subscribersText.ellipsize(width - dp(32));
final float subscribersTextWidth = dp(subscribersDrawable != null ? 17 : 8) + subscribersText.getWidth();
final float bottom = dp(10) + avatarSize() + dp(1);
AndroidUtilities.rectTmp.set((width - subscribersTextWidth) / 2f, bottom - dp(14.33f), (width + subscribersTextWidth) / 2f, bottom);
if (!subscribersColorSet && isLock) {
subscribersBackgroundPaint.setColor(Theme.blendOver(cell.getThemedColor(Theme.key_chat_inBubble), Theme.multAlpha(cell.getThemedColor(Theme.key_windowBackgroundWhiteGrayText), .85f)));
subscribersColorSet = true;
} else if (!subscribersColorSet && avatarImageReceiver[0].getStaticThumb() instanceof BitmapDrawable) {
final Bitmap bitmap = ((BitmapDrawable) avatarImageReceiver[0].getStaticThumb()).getBitmap();
try {
final int bitmapColor = bitmap.getPixel(bitmap.getWidth() / 2, bitmap.getHeight() - 2);
float[] hsl = new float[3];
ColorUtils.colorToHSL(bitmapColor, hsl);
if (hsl[1] <= .05f || hsl[1] >= .95f || hsl[2] <= .02f || hsl[2] >= .98f) {
hsl[1] = 0;
hsl[2] = Theme.isCurrentThemeDark() ? .38f : .70f;
} else {
hsl[1] = .25f;
hsl[2] = Theme.isCurrentThemeDark() ? .35f : .65f;
}
subscribersBackgroundPaint.setColor(ColorUtils.HSLToColor(hsl));
} catch (Exception e) {
FileLog.e(e);
}
subscribersColorSet = true;
} else if (!subscribersColorSet && !subscribersColorSetFromThumb) {
try {
final int color = ColorUtils.blendARGB(avatarDrawable[0].getColor(), avatarDrawable[0].getColor2(), .5f);
float[] hsl = new float[3];
ColorUtils.colorToHSL(color, hsl);
if (hsl[1] <= .05f || hsl[1] >= .95f) {
hsl[2] = Utilities.clamp(hsl[2] - .1f, .6f, .3f);
} else {
hsl[1] = Utilities.clamp(hsl[1] - .06f, .4f, 0);
hsl[2] = Utilities.clamp(hsl[2] - .08f, .5f, .2f);
}
subscribersBackgroundPaint.setColor(ColorUtils.HSLToColor(hsl));
} catch (Exception e) {
FileLog.e(e);
}
subscribersColorSetFromThumb = true;
}
if (subscribersBackgroundPaintShader != null) {
subscribersBackgroundPaintMatrix.reset();
subscribersBackgroundPaintMatrix.postScale(avatarSize() / (float) subscribersBackgroundPaintBitmapWidth, avatarSize() / (float) subscribersBackgroundPaintBitmapHeight);
subscribersBackgroundPaintMatrix.postTranslate(width / 2f - avatarSize() / 2f, AndroidUtilities.rectTmp.bottom - avatarSize());
subscribersBackgroundPaintShader.setLocalMatrix(subscribersBackgroundPaintMatrix);
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(8), dp(8), subscribersBackgroundPaint);
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(8), dp(8), subscribersBackgroundDimPaint);
} else {
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(8), dp(8), subscribersBackgroundPaint);
}
AndroidUtilities.rectTmp.inset(-dp(1) / 2f, -dp(1) / 2f);
subscribersStrokePaint.setStrokeWidth(dp(1));
canvas.drawRoundRect(AndroidUtilities.rectTmp, dp(8), dp(8), subscribersStrokePaint);
}
canvas.restore();
}
public static void fillPath(Path path, int width, float x) {
path.addCircle(x + width / 2f, dp(10) + avatarSize() / 2f, avatarSize() / 2f, Path.Direction.CW);
final float nameWidth = width * .4f;
AndroidUtilities.rectTmp.set(x + (width - nameWidth) / 2f, dp(74 - 5), x + (width + nameWidth) / 2f, dp(74 + 5));
path.addRoundRect(AndroidUtilities.rectTmp, dp(3), dp(3), Path.Direction.CW);
final float subWidth = width * .35f;
AndroidUtilities.rectTmp.set(x + (width - subWidth) / 2f, dp(87 - 4), x + (width + subWidth) / 2f, dp(87 + 4));
path.addRoundRect(AndroidUtilities.rectTmp, dp(2.5f), dp(2.5f), Path.Direction.CW);
}
public void attach() {
for (int i = 0; i < avatarImageReceiver.length; ++i) {
avatarImageReceiver[i].onAttachedToWindow();
}
}
public void detach() {
for (int i = 0; i < avatarImageReceiver.length; ++i) {
avatarImageReceiver[i].onDetachedFromWindow();
}
}
}
private boolean maybeScrolling;
private boolean scrolling;
private float lx, ly;
private VelocityTracker velocityTracker;
private final Scroller scroller;
private ChannelBlock longPressedBlock;
private Runnable longPressRunnable;
public boolean checkTouchEvent(MotionEvent ev) {
if (msg == null || cell == null) return false;
final int a = ev.getAction();
ChannelBlock block = null;
float x = backgroundBounds.left + dp(7) - scrollX;
for (int i = 0; i < channels.size(); ++i) {
ChannelBlock b = channels.get(i);
if (ev.getX() >= x && ev.getX() <= x + blockWidth && ev.getY() >= backgroundBounds.bottom - ChannelBlock.height() && ev.getY() < backgroundBounds.bottom) {
block = b;
break;
}
x += blockWidth + dp(9);
}
final boolean clickClose = closeBounds.contains(ev.getX(), ev.getY());
if (a == MotionEvent.ACTION_DOWN) {
scroller.abortAnimation();
maybeScrolling = !loading && backgroundBounds.contains(lx = ev.getX(), ly = ev.getY());
if (maybeScrolling && cell.getParent() != null) {
cell.getParent().requestDisallowInterceptTouchEvent(true);
}
scrolling = false;
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
velocityTracker = VelocityTracker.obtain();
if (block != null) {
block.bounce.setPressed(true);
}
if (clickClose) {
closeBounce.setPressed(true);
}
if (longPressRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(longPressRunnable);
longPressRunnable = null;
}
final ChannelBlock finalBlock = block;
longPressedBlock = block;
if (longPressedBlock != null) {
AndroidUtilities.runOnUIThread(longPressRunnable = () -> {
if (finalBlock == longPressedBlock) {
longPressedBlock.bounce.setPressed(false);
if (longPressedBlock.isLock) {
if (cell.getDelegate() != null) {
cell.getDelegate().didPressMoreChannelRecommendations(cell);
}
} else {
didClickChannel(longPressedBlock.chat, true);
}
}
longPressedBlock = null;
longPressRunnable = null;
scrolling = false;
maybeScrolling = false;
closeBounce.setPressed(false);
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
}, ViewConfiguration.getLongPressTimeout());
}
return maybeScrolling;
} else if (a == MotionEvent.ACTION_MOVE) {
if (velocityTracker != null) {
velocityTracker.addMovement(ev);
}
if (maybeScrolling && Math.abs(ev.getX() - lx) >= AndroidUtilities.touchSlop || scrolling) {
if (longPressRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(longPressRunnable);
longPressRunnable = null;
}
scrolling = true;
scroll(lx - ev.getX());
lx = ev.getX();
unselectBlocks();
return true;
}
} else if (a == MotionEvent.ACTION_UP || a == MotionEvent.ACTION_CANCEL) {
if (longPressRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(longPressRunnable);
longPressRunnable = null;
}
if (velocityTracker != null) {
velocityTracker.addMovement(ev);
}
final boolean wasScrolling = scrolling;
scrolling = false;
if (a == MotionEvent.ACTION_UP) {
if (!wasScrolling && block != null && block.bounce.isPressed()) {
if (block.isLock) {
if (cell.getDelegate() != null) {
cell.getDelegate().didPressMoreChannelRecommendations(cell);
}
} else {
didClickChannel(block.chat, false);
}
} else if (wasScrolling && velocityTracker != null) {
velocityTracker.computeCurrentVelocity(500);
int velocity = (int) -velocityTracker.getXVelocity();
scroller.fling((int) scrollX, 0, velocity, 0, -Integer.MAX_VALUE, Integer.MAX_VALUE, 0, 0);
} else if (closeBounce.isPressed()) {
didClickClose();
}
}
closeBounce.setPressed(false);
maybeScrolling = false;
if (velocityTracker != null) {
velocityTracker.recycle();
velocityTracker = null;
}
unselectBlocks();
return wasScrolling;
}
return false;
}
public void didClickClose() {
if (cell.getDelegate() != null) {
cell.getDelegate().didPressChannelRecommendationsClose(cell);
}
}
public void didClickChannel(TLRPC.Chat chat, boolean longPress) {
if (cell.getDelegate() != null) {
cell.getDelegate().didPressChannelRecommendation(cell, chat, longPress);
}
}
private void unselectBlocks() {
for (int i = 0; i < channels.size(); ++i) {
channels.get(i).bounce.setPressed(false);
}
}
public void computeScroll() {
if (scroller.computeScrollOffset()) {
scrollX = scroller.getCurrX();
scrollX = Utilities.clamp(scrollX, channelsScrollWidth - (backgroundBounds.width() - dp(14)), 0);
cell.invalidateOutbounds();
}
}
private void scroll(float dx) {
scrollX = Utilities.clamp(scrollX + dx, channelsScrollWidth - (backgroundBounds.width() - dp(14)), 0);
cell.invalidateOutbounds();
}
}

View file

@ -8,6 +8,8 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -23,6 +25,7 @@ import android.graphics.RectF;
import android.os.Build; import android.os.Build;
import android.text.Layout; import android.text.Layout;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.Spanned; import android.text.Spanned;
import android.text.StaticLayout; import android.text.StaticLayout;
@ -39,12 +42,15 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars; import org.telegram.messenger.BuildVars;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
import org.telegram.messenger.DocumentObject; import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.DownloadController; import org.telegram.messenger.DownloadController;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader; import org.telegram.messenger.ImageLoader;
@ -86,6 +92,8 @@ import org.telegram.ui.Components.spoilers.SpoilerEffect;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PhotoViewer; import org.telegram.ui.PhotoViewer;
import org.telegram.ui.Stories.StoriesUtilities; import org.telegram.ui.Stories.StoriesUtilities;
import org.telegram.ui.Stories.UploadingDotsSpannable;
import org.telegram.ui.Stories.recorder.HintView2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -156,6 +164,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
default void didClickImage(ChatActionCell cell) { default void didClickImage(ChatActionCell cell) {
} }
default void didClickButton(ChatActionCell cell) {
}
default void didOpenPremiumGift(ChatActionCell cell, TLRPC.TL_premiumGiftOption giftOption, boolean animateConfetti) { default void didOpenPremiumGift(ChatActionCell cell, TLRPC.TL_premiumGiftOption giftOption, boolean animateConfetti) {
} }
@ -231,6 +242,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
TextPaint textPaint; TextPaint textPaint;
private float viewTop; private float viewTop;
private float viewTranslationX;
private int backgroundHeight; private int backgroundHeight;
private boolean visiblePartSet; private boolean visiblePartSet;
@ -265,8 +277,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private int stickerSize; private int stickerSize;
private int giftRectSize; private int giftRectSize;
private StaticLayout giftPremiumTitleLayout; private StaticLayout giftPremiumTitleLayout;
private int giftPremiumSubtitleWidth;
private StaticLayout giftPremiumSubtitleLayout; private StaticLayout giftPremiumSubtitleLayout;
private StaticLayout giftPremiumButtonLayout; private StaticLayout giftPremiumButtonLayout;
private boolean buttonClickableAsImage = true;
TextPaint settingWallpaperPaint; TextPaint settingWallpaperPaint;
private StaticLayout settingWallpaperLayout; private StaticLayout settingWallpaperLayout;
private float settingWallpaperProgress; private float settingWallpaperProgress;
@ -340,7 +354,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
giftSubtitlePaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, getResources().getDisplayMetrics())); giftSubtitlePaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 15, getResources().getDisplayMetrics()));
rippleView = new View(context); rippleView = new View(context);
rippleView.setBackground(Theme.createSelectorDrawable(Theme.multAlpha(Color.WHITE, .07f), Theme.RIPPLE_MASK_ROUNDRECT_6DP, AndroidUtilities.dp(16))); rippleView.setBackground(Theme.createSelectorDrawable(Theme.multAlpha(Color.BLACK, .1f), Theme.RIPPLE_MASK_ROUNDRECT_6DP, dp(16)));
rippleView.setVisibility(GONE); rippleView.setVisibility(GONE);
addView(rippleView); addView(rippleView);
@ -420,7 +434,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
public void setMessageObject(MessageObject messageObject, boolean force) { public void setMessageObject(MessageObject messageObject, boolean force) {
if (currentMessageObject == messageObject && (textLayout == null || TextUtils.equals(textLayout.getText(), messageObject.messageText)) && (hasReplyMessage || messageObject.replyMessageObject == null) && !force && messageObject.type != MessageObject.TYPE_SUGGEST_PHOTO) { if (currentMessageObject == messageObject && (textLayout == null || TextUtils.equals(textLayout.getText(), messageObject.messageText)) && (hasReplyMessage || messageObject.replyMessageObject == null) && !force && messageObject.type != MessageObject.TYPE_SUGGEST_PHOTO && !messageObject.forceUpdate) {
return; return;
} }
if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) { if (BuildVars.DEBUG_PRIVATE_VERSION && Thread.currentThread() != ApplicationLoader.applicationHandler.getLooper().getThread()) {
@ -429,6 +443,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
accessibilityText = null; accessibilityText = null;
boolean messageIdChanged = currentMessageObject == null || currentMessageObject.stableId != messageObject.stableId; boolean messageIdChanged = currentMessageObject == null || currentMessageObject.stableId != messageObject.stableId;
currentMessageObject = messageObject; currentMessageObject = messageObject;
messageObject.forceUpdate = false;
hasReplyMessage = messageObject.replyMessageObject != null; hasReplyMessage = messageObject.replyMessageObject != null;
DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this); DownloadController.getInstance(currentAccount).removeLoadingFileObserver(this);
previousWidth = 0; previousWidth = 0;
@ -436,7 +451,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imageReceiver.clearDecorators(); imageReceiver.clearDecorators();
if (messageObject.isStoryMention()) { if (messageObject.isStoryMention()) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.media.user_id); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.messageOwner.media.user_id);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
TL_stories.StoryItem storyItem = messageObject.messageOwner.media.storyItem; TL_stories.StoryItem storyItem = messageObject.messageOwner.media.storyItem;
if (storyItem != null && storyItem.noforwards) { if (storyItem != null && storyItem.noforwards) {
imageReceiver.setForUserOrChat(user, avatarDrawable, null, true, 0, true); imageReceiver.setForUserOrChat(user, avatarDrawable, null, true, 0, true);
@ -518,7 +533,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
forceWasUnread = messageObject.wasUnread; forceWasUnread = messageObject.wasUnread;
imageReceiver.setAllowStartLottieAnimation(false); imageReceiver.setAllowStartLottieAnimation(false);
imageReceiver.setDelegate(giftStickerDelegate); imageReceiver.setDelegate(giftStickerDelegate);
imageReceiver.setImageBitmap(new RLottieDrawable(R.raw.premium_gift, messageObject.getId() + "_" + R.raw.premium_gift, AndroidUtilities.dp(160), AndroidUtilities.dp(160))); imageReceiver.setImageBitmap(new RLottieDrawable(R.raw.premium_gift, messageObject.getId() + "_" + R.raw.premium_gift, dp(160), dp(160)));
} else { } else {
TLRPC.TL_messages_stickerSet set; TLRPC.TL_messages_stickerSet set;
TLRPC.Document document = null; TLRPC.Document document = null;
@ -669,6 +684,20 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
visiblePartSet = true; visiblePartSet = true;
backgroundHeight = parentH; backgroundHeight = parentH;
viewTop = visibleTop; viewTop = visibleTop;
viewTranslationX = 0;
}
private float dimAmount;
private final Paint dimPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public void setVisiblePart(float visibleTop, float tx, int parentH, float dimAmount) {
visiblePartSet = true;
backgroundHeight = parentH;
viewTop = visibleTop;
viewTranslationX = tx;
this.dimAmount = dimAmount;
dimPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (0xFF * dimAmount)));
invalidate();
} }
@Override @Override
@ -749,7 +778,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imagePressed = true; imagePressed = true;
result = true; result = true;
} }
if (isButtonLayout(messageObject) && (giftButtonRect.contains(x, y) || backgroundRect.contains(x, y))) { if (isButtonLayout(messageObject) && giftPremiumButtonLayout != null && (giftButtonRect.contains(x, y) || buttonClickableAsImage && backgroundRect.contains(x, y))) {
rippleView.setPressed(giftButtonPressed = true); rippleView.setPressed(giftButtonPressed = true);
bounce.setPressed(true); bounce.setPressed(true);
result = true; result = true;
@ -777,7 +806,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else { } else {
ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id); ImageUpdater imageUpdater = MessagesController.getInstance(currentAccount).photoSuggestion.get(messageObject.messageOwner.local_id);
if (imageUpdater == null) { if (imageUpdater == null) {
delegate.didClickImage(this); if (buttonClickableAsImage) {
delegate.didClickImage(this);
} else {
delegate.didClickButton(this);
}
} }
} }
} }
@ -943,7 +976,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
private void createLayout(CharSequence text, int width) { private void createLayout(CharSequence text, int width) {
int maxWidth = width - AndroidUtilities.dp(30); int maxWidth = width - dp(30);
if (maxWidth < 0) { if (maxWidth < 0) {
return; return;
} }
@ -981,7 +1014,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
FileLog.e(e); FileLog.e(e);
} }
textX = (width - textWidth) / 2; textX = (width - textWidth) / 2;
textY = AndroidUtilities.dp(7); textY = dp(7);
textXLeft = (width - textLayout.getWidth()) / 2; textXLeft = (width - textLayout.getWidth()) / 2;
spoilersPool.addAll(spoilers); spoilersPool.addAll(spoilers);
@ -996,22 +1029,22 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MessageObject messageObject = currentMessageObject; MessageObject messageObject = currentMessageObject;
if (messageObject == null && customText == null) { if (messageObject == null && customText == null) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), textHeight + AndroidUtilities.dp(14)); setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), textHeight + dp(14));
return; return;
} }
if (isButtonLayout(messageObject)) { if (isButtonLayout(messageObject)) {
giftRectSize = Math.min((int) (AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() * 0.6f : AndroidUtilities.displaySize.x * 0.62f - AndroidUtilities.dp(34)), AndroidUtilities.displaySize.y - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - AndroidUtilities.dp(64)); giftRectSize = Math.min((int) (AndroidUtilities.isTablet() ? AndroidUtilities.getMinTabletSide() * 0.6f : AndroidUtilities.displaySize.x * 0.62f - dp(34)), AndroidUtilities.displaySize.y - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight - dp(64));
if (!AndroidUtilities.isTablet() && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) { if (!AndroidUtilities.isTablet() && messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
giftRectSize = (int) (giftRectSize * 1.2f); giftRectSize = (int) (giftRectSize * 1.2f);
} }
stickerSize = giftRectSize - AndroidUtilities.dp(106); stickerSize = giftRectSize - dp(106);
if (isNewStyleButtonLayout()) { if (isNewStyleButtonLayout()) {
imageReceiver.setRoundRadius(stickerSize / 2); imageReceiver.setRoundRadius(stickerSize / 2);
} else { } else {
imageReceiver.setRoundRadius(0); imageReceiver.setRoundRadius(0);
} }
} }
int width = Math.max(AndroidUtilities.dp(30), MeasureSpec.getSize(widthMeasureSpec)); int width = Math.max(dp(30), MeasureSpec.getSize(widthMeasureSpec));
if (previousWidth != width) { if (previousWidth != width) {
wasLayout = true; wasLayout = true;
previousWidth = width; previousWidth = width;
@ -1020,9 +1053,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
int additionalHeight = 0; int additionalHeight = 0;
if (messageObject != null) { if (messageObject != null) {
if (messageObject.type == MessageObject.TYPE_ACTION_PHOTO) { if (messageObject.type == MessageObject.TYPE_ACTION_PHOTO) {
additionalHeight = AndroidUtilities.roundMessageSize + AndroidUtilities.dp(10); additionalHeight = AndroidUtilities.roundMessageSize + dp(10);
} else if (isButtonLayout(messageObject)) { } else if (isButtonLayout(messageObject)) {
additionalHeight = giftRectSize + AndroidUtilities.dp(12); additionalHeight = giftRectSize + dp(12);
} }
} }
@ -1032,36 +1065,36 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
int imageSize = getImageSize(messageObject); int imageSize = getImageSize(messageObject);
float y; float y;
if (isNewStyleButtonLayout()) { if (isNewStyleButtonLayout()) {
y = textY + textHeight + AndroidUtilities.dp(4) + AndroidUtilities.dp(16) * 2 + imageSize + giftPremiumSubtitleLayout.getHeight() + AndroidUtilities.dp(4); y = textY + textHeight + dp(4) + dp(16) * 2 + imageSize + giftPremiumSubtitleLayout.getHeight() + dp(4);
} else { } else {
y = textY + textHeight + giftRectSize * 0.075f + imageSize + AndroidUtilities.dp(4) + AndroidUtilities.dp(4) + giftPremiumSubtitleLayout.getHeight(); y = textY + textHeight + giftRectSize * 0.075f + imageSize + dp(4) + dp(4) + giftPremiumSubtitleLayout.getHeight();
} }
giftPremiumAdditionalHeight = 0; giftPremiumAdditionalHeight = 0;
if (giftPremiumTitleLayout != null) { if (giftPremiumTitleLayout != null) {
y += giftPremiumTitleLayout.getHeight(); y += giftPremiumTitleLayout.getHeight();
y += AndroidUtilities.dp(isGiftChannel ? 6 : 0); y += dp(isGiftChannel ? 6 : 0);
} else { } else {
y -= AndroidUtilities.dp(12); y -= dp(12);
giftPremiumAdditionalHeight -= AndroidUtilities.dp(30); giftPremiumAdditionalHeight -= dp(30);
} }
if (giftPremiumSubtitleLayout.getLineCount() > 2) { if (giftPremiumSubtitleLayout.getLineCount() > 2) {
giftPremiumAdditionalHeight += (giftPremiumSubtitleLayout.getLineBottom(0) - giftPremiumSubtitleLayout.getLineTop(0)) * giftPremiumSubtitleLayout.getLineCount() - 2; giftPremiumAdditionalHeight += (giftPremiumSubtitleLayout.getLineBottom(0) - giftPremiumSubtitleLayout.getLineTop(0)) * giftPremiumSubtitleLayout.getLineCount() - 2;
} }
giftPremiumAdditionalHeight -= AndroidUtilities.dp(isGiftChannel ? 14 : 0); giftPremiumAdditionalHeight -= dp(isGiftChannel ? 14 : 0);
additionalHeight += giftPremiumAdditionalHeight; additionalHeight += giftPremiumAdditionalHeight;
int h = textHeight + additionalHeight + AndroidUtilities.dp(14); int h = textHeight + additionalHeight + dp(14);
if (giftPremiumButtonLayout != null) { if (giftPremiumButtonLayout != null) {
y += (h - y - (giftPremiumButtonLayout != null ? giftPremiumButtonLayout.getHeight() : 0) - AndroidUtilities.dp(8)) / 2f; y += (h - y - (giftPremiumButtonLayout != null ? giftPremiumButtonLayout.getHeight() : 0) - dp(8)) / 2f;
float rectX = (previousWidth - giftPremiumButtonWidth) / 2f; float rectX = (previousWidth - giftPremiumButtonWidth) / 2f;
giftButtonRect.set(rectX - AndroidUtilities.dp(18), y - AndroidUtilities.dp(8), rectX + giftPremiumButtonWidth + AndroidUtilities.dp(18), y + (giftPremiumButtonLayout != null ? giftPremiumButtonLayout.getHeight() : 0) + AndroidUtilities.dp(8)); giftButtonRect.set(rectX - dp(18), y - dp(8), rectX + giftPremiumButtonWidth + dp(18), y + (giftPremiumButtonLayout != null ? giftPremiumButtonLayout.getHeight() : 0) + dp(8));
} else { } else {
additionalHeight -= AndroidUtilities.dp(40); additionalHeight -= dp(40);
giftPremiumAdditionalHeight -= AndroidUtilities.dp(40); giftPremiumAdditionalHeight -= dp(40);
} }
int sizeInternal = getMeasuredWidth() << 16 + getMeasuredHeight(); int sizeInternal = getMeasuredWidth() << 16 + getMeasuredHeight();
starParticlesDrawable.rect.set(giftButtonRect); starParticlesDrawable.rect.set(giftButtonRect);
@ -1072,25 +1105,25 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
if (isNewStyleButtonLayout()) { if (isNewStyleButtonLayout()) {
exactlyHeight = textY + textHeight + AndroidUtilities.dp(4); exactlyHeight = textY + textHeight + dp(4);
backgroundRectHeight = 0; backgroundRectHeight = 0;
backgroundRectHeight += AndroidUtilities.dp(16) * 2 + imageSize; backgroundRectHeight += dp(16) * 2 + imageSize;
backgroundRectHeight += giftPremiumSubtitleLayout.getHeight(); backgroundRectHeight += giftPremiumSubtitleLayout.getHeight();
if (giftPremiumButtonLayout != null) { if (giftPremiumButtonLayout != null) {
backgroundButtonTop = exactlyHeight + backgroundRectHeight + AndroidUtilities.dp(10); backgroundButtonTop = exactlyHeight + backgroundRectHeight + dp(10);
float rectX = (previousWidth - giftPremiumButtonWidth) / 2f; float rectX = (previousWidth - giftPremiumButtonWidth) / 2f;
giftButtonRect.set(rectX - AndroidUtilities.dp(18), backgroundButtonTop, rectX + giftPremiumButtonWidth + AndroidUtilities.dp(18), backgroundButtonTop + giftPremiumButtonLayout.getHeight() + AndroidUtilities.dp(8) * 2); giftButtonRect.set(rectX - dp(18), backgroundButtonTop, rectX + giftPremiumButtonWidth + dp(18), backgroundButtonTop + giftPremiumButtonLayout.getHeight() + dp(8) * 2);
backgroundRectHeight += AndroidUtilities.dp(10) + giftButtonRect.height(); backgroundRectHeight += dp(10) + giftButtonRect.height();
} }
backgroundRectHeight += AndroidUtilities.dp(16); backgroundRectHeight += dp(16);
exactlyHeight += backgroundRectHeight; exactlyHeight += backgroundRectHeight;
exactlyHeight += AndroidUtilities.dp(6); exactlyHeight += dp(6);
} }
} }
if (messageObject != null && (isNewStyleButtonLayout())) { if (messageObject != null && (isNewStyleButtonLayout())) {
setMeasuredDimension(width, exactlyHeight); setMeasuredDimension(width, exactlyHeight);
} else { } else {
setMeasuredDimension(width, textHeight + additionalHeight + AndroidUtilities.dp(14)); setMeasuredDimension(width, textHeight + additionalHeight + dp(14));
} }
} }
@ -1101,7 +1134,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private int getImageSize(MessageObject messageObject) { private int getImageSize(MessageObject messageObject) {
int imageSize = stickerSize; int imageSize = stickerSize;
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO || isNewStyleButtonLayout()) { if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO || isNewStyleButtonLayout()) {
imageSize = AndroidUtilities.dp(78);//Math.max(, (int) (stickerSize * 0.7f)); imageSize = dp(78);//Math.max(, (int) (stickerSize * 0.7f));
} }
return imageSize; return imageSize;
} }
@ -1124,9 +1157,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (text == null) { if (text == null) {
if (messageObject.messageOwner != null && messageObject.messageOwner.media != null && messageObject.messageOwner.media.ttl_seconds != 0) { if (messageObject.messageOwner != null && messageObject.messageOwner.media != null && messageObject.messageOwner.media.ttl_seconds != 0) {
if (messageObject.messageOwner.media.photo != null) { if (messageObject.messageOwner.media.photo != null) {
text = LocaleController.getString("AttachPhotoExpired", R.string.AttachPhotoExpired); text = LocaleController.getString(R.string.AttachPhotoExpired);
} else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_documentEmpty || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && messageObject.messageOwner.media.document == null) { } else if (messageObject.messageOwner.media.document instanceof TLRPC.TL_documentEmpty || messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaDocument && messageObject.messageOwner.media.document == null) {
text = LocaleController.getString("AttachVideoExpired", R.string.AttachVideoExpired); text = LocaleController.getString(R.string.AttachVideoExpired);
} else { } else {
text = AnimatedEmojiSpan.cloneSpans(messageObject.messageText); text = AnimatedEmojiSpan.cloneSpans(messageObject.messageText);
} }
@ -1140,11 +1173,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
createLayout(text, previousWidth); createLayout(text, previousWidth);
if (messageObject != null) { if (messageObject != null) {
if (messageObject.type == MessageObject.TYPE_ACTION_PHOTO) { if (messageObject.type == MessageObject.TYPE_ACTION_PHOTO) {
imageReceiver.setImageCoords((previousWidth - AndroidUtilities.roundMessageSize) / 2f, textHeight + AndroidUtilities.dp(19), AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize); imageReceiver.setImageCoords((previousWidth - AndroidUtilities.roundMessageSize) / 2f, textHeight + dp(19), AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize);
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
createGiftPremiumChannelLayouts(); createGiftPremiumChannelLayouts();
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM) {
createGiftPremiumLayouts(LocaleController.getString(R.string.ActionGiftPremiumTitle), LocaleController.formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), LocaleController.getString(R.string.ActionGiftPremiumView), giftRectSize); createGiftPremiumLayouts(LocaleController.getString(R.string.ActionGiftPremiumTitle), LocaleController.formatString(R.string.ActionGiftPremiumSubtitle, LocaleController.formatPluralString("Months", messageObject.messageOwner.action.months)), LocaleController.getString(R.string.ActionGiftPremiumView), giftRectSize, true);
} else if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) { } else if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
TLRPC.TL_messageActionSuggestProfilePhoto actionSuggestProfilePhoto = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action; TLRPC.TL_messageActionSuggestProfilePhoto actionSuggestProfilePhoto = (TLRPC.TL_messageActionSuggestProfilePhoto) messageObject.messageOwner.action;
String description; String description;
@ -1153,24 +1186,24 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (user.id == UserConfig.getInstance(currentAccount).clientUserId) { if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId()); TLRPC.User user2 = MessagesController.getInstance(currentAccount).getUser(messageObject.getDialogId());
if (isVideo) { if (isVideo) {
description = LocaleController.formatString("ActionSuggestVideoFromYouDescription", R.string.ActionSuggestVideoFromYouDescription, user2.first_name); description = LocaleController.formatString(R.string.ActionSuggestVideoFromYouDescription, user2.first_name);
} else { } else {
description = LocaleController.formatString("ActionSuggestPhotoFromYouDescription", R.string.ActionSuggestPhotoFromYouDescription, user2.first_name); description = LocaleController.formatString(R.string.ActionSuggestPhotoFromYouDescription, user2.first_name);
} }
} else { } else {
if (isVideo) { if (isVideo) {
description = LocaleController.formatString("ActionSuggestVideoToYouDescription", R.string.ActionSuggestVideoToYouDescription, user.first_name); description = LocaleController.formatString(R.string.ActionSuggestVideoToYouDescription, user.first_name);
} else { } else {
description = LocaleController.formatString("ActionSuggestPhotoToYouDescription", R.string.ActionSuggestPhotoToYouDescription, user.first_name); description = LocaleController.formatString(R.string.ActionSuggestPhotoToYouDescription, user.first_name);
} }
} }
String action; String action;
if (actionSuggestProfilePhoto.video || (actionSuggestProfilePhoto.photo.video_sizes != null && !actionSuggestProfilePhoto.photo.video_sizes.isEmpty())) { if (actionSuggestProfilePhoto.video || (actionSuggestProfilePhoto.photo.video_sizes != null && !actionSuggestProfilePhoto.photo.video_sizes.isEmpty())) {
action = LocaleController.getString("ViewVideoAction", R.string.ViewVideoAction); action = LocaleController.getString(R.string.ViewVideoAction);
} else { } else {
action = LocaleController.getString("ViewPhotoAction", R.string.ViewPhotoAction); action = LocaleController.getString(R.string.ViewPhotoAction);
} }
createGiftPremiumLayouts(null, description, action, giftRectSize); createGiftPremiumLayouts(null, description, action, giftRectSize, true);
textLayout = null; textLayout = null;
textHeight = 0; textHeight = 0;
textY = 0; textY = 0;
@ -1178,13 +1211,18 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.isOutOwner() ? 0 : messageObject.getDialogId()); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(messageObject.isOutOwner() ? 0 : messageObject.getDialogId());
CharSequence description; CharSequence description;
String action = null; String action = null;
if (user.id == UserConfig.getInstance(currentAccount).clientUserId) { boolean actionClickableAsImage = true;
if (!messageObject.isOutOwner() && messageObject.isWallpaperForBoth() && messageObject.isCurrentWallpaper()) {
description = messageObject.messageText;
action = LocaleController.getString(R.string.RemoveWallpaperAction);
actionClickableAsImage = false;
} else if (user.id == UserConfig.getInstance(currentAccount).clientUserId) {
description = messageObject.messageText; description = messageObject.messageText;
} else { } else {
description = messageObject.messageText; description = messageObject.messageText;
action = LocaleController.getString("ViewWallpaperAction", R.string.ViewWallpaperAction); action = LocaleController.getString(R.string.ViewWallpaperAction);
} }
createGiftPremiumLayouts(null, description, action, giftRectSize); createGiftPremiumLayouts(null, description, action, giftRectSize, actionClickableAsImage);
textLayout = null; textLayout = null;
textHeight = 0; textHeight = 0;
textY = 0; textY = 0;
@ -1199,9 +1237,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else { } else {
description = AndroidUtilities.replaceTags(LocaleController.formatString("StoryMentionedTitle", R.string.StoryMentionedTitle, user.first_name)); description = AndroidUtilities.replaceTags(LocaleController.formatString("StoryMentionedTitle", R.string.StoryMentionedTitle, user.first_name));
} }
action = LocaleController.getString("StoryMentionedAction", R.string.StoryMentionedAction); action = LocaleController.getString(R.string.StoryMentionedAction);
createGiftPremiumLayouts(null, description, action, giftRectSize); createGiftPremiumLayouts(null, description, action, giftRectSize, true);
textLayout = null; textLayout = null;
textHeight = 0; textHeight = 0;
textY = 0; textY = 0;
@ -1211,9 +1249,9 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
private void createGiftPremiumChannelLayouts() { private void createGiftPremiumChannelLayouts() {
int width = giftRectSize; int width = giftRectSize;
width -= AndroidUtilities.dp(16); width -= dp(16);
giftTitlePaint.setTextSize(AndroidUtilities.dp(14)); giftTitlePaint.setTextSize(dp(14));
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(13)); giftSubtitlePaint.setTextSize(dp(13));
TLRPC.TL_messageActionGiftCode gifCodeAction = (TLRPC.TL_messageActionGiftCode) currentMessageObject.messageOwner.action; TLRPC.TL_messageActionGiftCode gifCodeAction = (TLRPC.TL_messageActionGiftCode) currentMessageObject.messageOwner.action;
int months = gifCodeAction.months; int months = gifCodeAction.months;
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-DialogObject.getPeerDialogId(gifCodeAction.boost_peer)); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-DialogObject.getPeerDialogId(gifCodeAction.boost_peer));
@ -1246,18 +1284,20 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.1f, 0.0f, false); giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.1f, 0.0f, false);
giftPremiumSubtitleWidth = width;
giftPremiumSubtitleLayout = new StaticLayout(subtitle, giftSubtitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.1f, 0.0f, false); giftPremiumSubtitleLayout = new StaticLayout(subtitle, giftSubtitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.1f, 0.0f, false);
SpannableStringBuilder buttonBuilder = SpannableStringBuilder.valueOf(btnText); SpannableStringBuilder buttonBuilder = SpannableStringBuilder.valueOf(btnText);
buttonBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, buttonBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); buttonBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, buttonBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumButtonLayout = new StaticLayout(buttonBuilder, (TextPaint) getThemedPaint(Theme.key_paint_chatActionText), width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); giftPremiumButtonLayout = new StaticLayout(buttonBuilder, (TextPaint) getThemedPaint(Theme.key_paint_chatActionText), width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
buttonClickableAsImage = true;
giftPremiumButtonWidth = measureLayoutWidth(giftPremiumButtonLayout); giftPremiumButtonWidth = measureLayoutWidth(giftPremiumButtonLayout);
} }
private void createGiftPremiumLayouts(CharSequence title, CharSequence subtitle, CharSequence button, int width) { private void createGiftPremiumLayouts(CharSequence title, CharSequence subtitle, CharSequence button, int width, boolean buttonClickableAsImage) {
width -= AndroidUtilities.dp(16); width -= dp(16);
if (title != null) { if (title != null) {
giftTitlePaint.setTextSize(AndroidUtilities.dp(16)); giftTitlePaint.setTextSize(dp(16));
SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title); SpannableStringBuilder titleBuilder = SpannableStringBuilder.valueOf(title);
titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); titleBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, titleBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); giftPremiumTitleLayout = new StaticLayout(titleBuilder, giftTitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
@ -1265,18 +1305,30 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
giftPremiumTitleLayout = null; giftPremiumTitleLayout = null;
} }
if (currentMessageObject != null && isNewStyleButtonLayout()) { if (currentMessageObject != null && isNewStyleButtonLayout()) {
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(13)); giftSubtitlePaint.setTextSize(dp(13));
} else { } else {
giftSubtitlePaint.setTextSize(AndroidUtilities.dp(15)); giftSubtitlePaint.setTextSize(dp(15));
} }
giftPremiumSubtitleLayout = new StaticLayout(subtitle, giftSubtitlePaint, width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); int subtitleWidth = giftPremiumSubtitleWidth = width;
if (currentMessageObject != null && currentMessageObject.type == MessageObject.TYPE_ACTION_WALLPAPER) {
final int recommendedWidthForTwoLines = HintView2.cutInFancyHalf(subtitle, giftSubtitlePaint);
if (recommendedWidthForTwoLines < subtitleWidth && recommendedWidthForTwoLines > subtitleWidth / 5f) {
subtitleWidth = recommendedWidthForTwoLines;
}
}
try {
subtitle = Emoji.replaceEmoji(subtitle, giftSubtitlePaint.getFontMetricsInt(), false);
} catch (Exception ignore) {}
giftPremiumSubtitleLayout = new StaticLayout(subtitle, giftSubtitlePaint, subtitleWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, dp(1.66f), false);
if (button != null) { if (button != null) {
SpannableStringBuilder buttonBuilder = SpannableStringBuilder.valueOf(button); SpannableStringBuilder buttonBuilder = SpannableStringBuilder.valueOf(button);
buttonBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, buttonBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); buttonBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)), 0, buttonBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
giftPremiumButtonLayout = new StaticLayout(buttonBuilder, (TextPaint) getThemedPaint(Theme.key_paint_chatActionText), width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); giftPremiumButtonLayout = new StaticLayout(buttonBuilder, (TextPaint) getThemedPaint(Theme.key_paint_chatActionText), width, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
this.buttonClickableAsImage = buttonClickableAsImage;
giftPremiumButtonWidth = measureLayoutWidth(giftPremiumButtonLayout); giftPremiumButtonWidth = measureLayoutWidth(giftPremiumButtonLayout);
} else { } else {
giftPremiumButtonLayout = null; giftPremiumButtonLayout = null;
this.buttonClickableAsImage = false;
giftPremiumButtonWidth = 0; giftPremiumButtonWidth = 0;
} }
} }
@ -1292,6 +1344,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
return maxWidth; return maxWidth;
} }
public boolean showingCancelButton() {
return radialProgress != null && radialProgress.getIcon() == MediaActionDrawable.ICON_CANCEL;
}
public int getCustomDate() { public int getCustomDate() {
return customDate; return customDate;
} }
@ -1301,10 +1357,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
MessageObject messageObject = currentMessageObject; MessageObject messageObject = currentMessageObject;
int imageSize = stickerSize; int imageSize = stickerSize;
if (isButtonLayout(messageObject)) { if (isButtonLayout(messageObject)) {
stickerSize = giftRectSize - AndroidUtilities.dp(106); stickerSize = giftRectSize - dp(106);
if (isNewStyleButtonLayout()) { if (isNewStyleButtonLayout()) {
imageSize = getImageSize(messageObject); imageSize = getImageSize(messageObject);
int top = textY + textHeight + AndroidUtilities.dp(4) + AndroidUtilities.dp(16); int top = textY + textHeight + dp(4) + dp(16);
float x = (previousWidth - imageSize) / 2f; float x = (previousWidth - imageSize) / 2f;
float y = top; float y = top;
if (messageObject.isStoryMention()) { if (messageObject.isStoryMention()) {
@ -1316,10 +1372,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
imageReceiver.setImageCoords((previousWidth - stickerSize) / 2f, textY + textHeight + giftRectSize * 0.075f, stickerSize, stickerSize); imageReceiver.setImageCoords((previousWidth - stickerSize) / 2f, textY + textHeight + giftRectSize * 0.075f, stickerSize, stickerSize);
} else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) { } else if (messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL) {
imageSize = (int) (stickerSize * (AndroidUtilities.isTablet() ? 1.0f : 1.2f)); imageSize = (int) (stickerSize * (AndroidUtilities.isTablet() ? 1.0f : 1.2f));
imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - AndroidUtilities.dp(22), imageSize, imageSize); imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(22), imageSize, imageSize);
} else { } else {
imageSize = (int) (stickerSize * 1f); imageSize = (int) (stickerSize * 1f);
imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - AndroidUtilities.dp(4), imageSize, imageSize); imageReceiver.setImageCoords((previousWidth - imageSize) / 2f, textY + textHeight + giftRectSize * 0.075f - dp(4), imageSize, imageSize);
} }
textPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText); textPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText);
if (textPaint != null) { if (textPaint != null) {
@ -1354,7 +1410,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (imageUpdater != null) { if (imageUpdater != null) {
radialProgress.setProgress(imageUpdater.getCurrentImageProgress(), true); radialProgress.setProgress(imageUpdater.getCurrentImageProgress(), true);
radialProgress.setCircleRadius((int) (imageReceiver.getImageWidth() * 0.5f) + 1); radialProgress.setCircleRadius((int) (imageReceiver.getImageWidth() * 0.5f) + 1);
radialProgress.setMaxIconSize(AndroidUtilities.dp(24)); radialProgress.setMaxIconSize(dp(24));
radialProgress.setColorKeys(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected); radialProgress.setColorKeys(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
if (imageUpdater.getCurrentImageProgress() == 1f) { if (imageUpdater.getCurrentImageProgress() == 1f) {
radialProgress.setIcon(MediaActionDrawable.ICON_NONE, true, true); radialProgress.setIcon(MediaActionDrawable.ICON_NONE, true, true);
@ -1366,8 +1422,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else if (messageObject.type == MessageObject.TYPE_ACTION_WALLPAPER) { } else if (messageObject.type == MessageObject.TYPE_ACTION_WALLPAPER) {
float progress = getUploadingInfoProgress(messageObject); float progress = getUploadingInfoProgress(messageObject);
radialProgress.setProgress(progress, true); radialProgress.setProgress(progress, true);
radialProgress.setCircleRadius(AndroidUtilities.dp(26)); radialProgress.setCircleRadius(dp(26));
radialProgress.setMaxIconSize(AndroidUtilities.dp(24)); radialProgress.setMaxIconSize(dp(24));
radialProgress.setColorKeys(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected); radialProgress.setColorKeys(Theme.key_chat_mediaLoaderPhoto, Theme.key_chat_mediaLoaderPhotoSelected, Theme.key_chat_mediaLoaderPhotoIcon, Theme.key_chat_mediaLoaderPhotoIconSelected);
if (progress == 1f) { if (progress == 1f) {
radialProgress.setIcon(MediaActionDrawable.ICON_NONE, true, true); radialProgress.setIcon(MediaActionDrawable.ICON_NONE, true, true);
@ -1402,18 +1458,18 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (isButtonLayout(messageObject)) { if (isButtonLayout(messageObject)) {
canvas.save(); canvas.save();
float x = (previousWidth - giftRectSize) / 2f + AndroidUtilities.dp(8); float x = (previousWidth - giftRectSize) / 2f + dp(8);
float y; float y;
if (isNewStyleButtonLayout()) { if (isNewStyleButtonLayout()) {
float top = backgroundRect != null ? backgroundRect.top : (textY + textHeight + AndroidUtilities.dp(4)); float top = backgroundRect != null ? backgroundRect.top : (textY + textHeight + dp(4));
y = top + AndroidUtilities.dp(16) * 2 + imageSize; y = top + dp(16) * 2 + imageSize;
} else { } else {
y = textY + textHeight + giftRectSize * 0.075f + (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO ? imageSize : stickerSize) + AndroidUtilities.dp(4); y = textY + textHeight + giftRectSize * 0.075f + (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO ? imageSize : stickerSize) + dp(4);
if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) { if (messageObject.type == MessageObject.TYPE_SUGGEST_PHOTO) {
y += AndroidUtilities.dp(16); y += dp(16);
} }
if (giftPremiumButtonLayout == null) { if (giftPremiumButtonLayout == null) {
y -= AndroidUtilities.dp(24); y -= dp(24);
} }
} }
@ -1421,26 +1477,40 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (giftPremiumTitleLayout != null) { if (giftPremiumTitleLayout != null) {
giftPremiumTitleLayout.draw(canvas); giftPremiumTitleLayout.draw(canvas);
y += giftPremiumTitleLayout.getHeight(); y += giftPremiumTitleLayout.getHeight();
y += AndroidUtilities.dp(messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL ? 6 : 0); y += dp(messageObject.type == MessageObject.TYPE_GIFT_PREMIUM_CHANNEL ? 6 : 0);
} else { } else {
y -= AndroidUtilities.dp(4); y -= dp(4);
} }
canvas.restore(); canvas.restore();
y += AndroidUtilities.dp(4); y += dp(4);
canvas.save(); canvas.save();
canvas.translate(x, y); canvas.translate(x, y);
if (messageObject.type == MessageObject.TYPE_ACTION_WALLPAPER) { if (messageObject.type == MessageObject.TYPE_ACTION_WALLPAPER) {
if (radialProgress.getTransitionProgress() != 1f || radialProgress.getIcon() != MediaActionDrawable.ICON_NONE) { if (radialProgress.getTransitionProgress() != 1f || radialProgress.getIcon() != MediaActionDrawable.ICON_NONE) {
if (settingWallpaperLayout == null) { if (settingWallpaperLayout == null) {
settingWallpaperPaint = new TextPaint(); settingWallpaperPaint = new TextPaint();
settingWallpaperPaint.setTextSize(AndroidUtilities.dp(13)); settingWallpaperPaint.setTextSize(dp(13));
settingWallpaperLayout = new StaticLayout("Setting new wallpaper...", settingWallpaperPaint, giftPremiumSubtitleLayout.getWidth(), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); SpannableStringBuilder cs = new SpannableStringBuilder(LocaleController.getString(R.string.ActionSettingWallpaper));
int index = cs.toString().indexOf("..."), len = 3;
if (index < 0) {
index = cs.toString().indexOf("");
len = 1;
}
if (index >= 0) {
SpannableString loading = new SpannableString("");
UploadingDotsSpannable loadingDots = new UploadingDotsSpannable();
loadingDots.fixTop = true;
loadingDots.setParent(ChatActionCell.this, false);
loading.setSpan(loadingDots, 0, loading.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
cs.replace(index, index + len, loading);
}
settingWallpaperLayout = new StaticLayout(cs, settingWallpaperPaint, giftPremiumSubtitleWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
} }
float progressLocal = getUploadingInfoProgress(messageObject); float progressLocal = getUploadingInfoProgress(messageObject);
if (settingWallpaperProgressTextLayout == null || settingWallpaperProgress != progressLocal) { if (settingWallpaperProgressTextLayout == null || settingWallpaperProgress != progressLocal) {
settingWallpaperProgress = progressLocal; settingWallpaperProgress = progressLocal;
settingWallpaperProgressTextLayout = new StaticLayout((int) (progressLocal * 100) + "%", giftSubtitlePaint, giftPremiumSubtitleLayout.getWidth(), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); settingWallpaperProgressTextLayout = new StaticLayout((int) (progressLocal * 100) + "%", giftSubtitlePaint, giftPremiumSubtitleWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
} }
settingWallpaperPaint.setColor(giftSubtitlePaint.getColor()); settingWallpaperPaint.setColor(giftSubtitlePaint.getColor());
@ -1452,7 +1522,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
float s = 0.8f + 0.2f * p; float s = 0.8f + 0.2f * p;
canvas.save(); canvas.save();
canvas.scale(s, s, giftPremiumSubtitleLayout.getWidth() / 2f, giftPremiumSubtitleLayout.getHeight() / 2f); canvas.scale(s, s, giftPremiumSubtitleWidth / 2f, giftPremiumSubtitleLayout.getHeight() / 2f);
canvas.translate((giftPremiumSubtitleWidth -giftPremiumSubtitleLayout.getWidth()) / 2f, 0);
giftPremiumSubtitleLayout.draw(canvas); giftPremiumSubtitleLayout.draw(canvas);
canvas.restore(); canvas.restore();
@ -1464,7 +1535,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
canvas.restore(); canvas.restore();
canvas.save(); canvas.save();
canvas.translate(0, settingWallpaperLayout.getHeight() + AndroidUtilities.dp(4)); canvas.translate(0, settingWallpaperLayout.getHeight() + dp(4));
canvas.scale(s, s, settingWallpaperProgressTextLayout.getWidth() / 2f, settingWallpaperProgressTextLayout.getHeight() / 2f); canvas.scale(s, s, settingWallpaperProgressTextLayout.getWidth() / 2f, settingWallpaperProgressTextLayout.getHeight() / 2f);
settingWallpaperProgressTextLayout.draw(canvas); settingWallpaperProgressTextLayout.draw(canvas);
canvas.restore(); canvas.restore();
@ -1474,30 +1545,36 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} else { } else {
settingWallpaperLayout.draw(canvas); settingWallpaperLayout.draw(canvas);
canvas.save(); canvas.save();
canvas.translate(0, settingWallpaperLayout.getHeight() + AndroidUtilities.dp(4)); canvas.translate(0, settingWallpaperLayout.getHeight() + dp(4));
settingWallpaperProgressTextLayout.draw(canvas); settingWallpaperProgressTextLayout.draw(canvas);
canvas.restore(); canvas.restore();
} }
} else { } else {
canvas.save();
canvas.translate((giftPremiumSubtitleWidth - giftPremiumSubtitleLayout.getWidth()) / 2f, 0);
giftPremiumSubtitleLayout.draw(canvas); giftPremiumSubtitleLayout.draw(canvas);
canvas.restore();
} }
} else if (giftPremiumSubtitleLayout != null) { } else if (giftPremiumSubtitleLayout != null) {
canvas.save();
canvas.translate((giftPremiumSubtitleWidth - giftPremiumSubtitleLayout.getWidth()) / 2f, 0);
giftPremiumSubtitleLayout.draw(canvas); giftPremiumSubtitleLayout.draw(canvas);
canvas.restore();
} }
canvas.restore(); canvas.restore();
if (giftPremiumTitleLayout == null) { if (giftPremiumTitleLayout == null) {
y -= AndroidUtilities.dp(8); y -= dp(8);
} }
y += giftPremiumSubtitleLayout.getHeight(); y += giftPremiumSubtitleLayout.getHeight();
int buttonH = giftPremiumButtonLayout != null ? giftPremiumButtonLayout.getHeight() : 0; int buttonH = giftPremiumButtonLayout != null ? giftPremiumButtonLayout.getHeight() : 0;
y += (getHeight() - y - buttonH - AndroidUtilities.dp(8)) / 2f; y += (getHeight() - y - buttonH - dp(8)) / 2f;
if (themeDelegate != null) { if (themeDelegate != null) {
themeDelegate.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4)); themeDelegate.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, viewTranslationX, viewTop + dp(4));
} else { } else {
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4)); Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, viewTranslationX, viewTop + dp(4));
} }
final float S = bounce.getScale(0.02f); final float S = bounce.getScale(0.02f);
@ -1505,16 +1582,18 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
canvas.scale(S, S, giftButtonRect.centerX(), giftButtonRect.centerY()); canvas.scale(S, S, giftButtonRect.centerX(), giftButtonRect.centerY());
if (giftPremiumButtonLayout != null) { if (giftPremiumButtonLayout != null) {
Paint backgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackground); Paint backgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackgroundSelected);
canvas.drawRoundRect(giftButtonRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), backgroundPaint); canvas.drawRoundRect(giftButtonRect, dp(16), dp(16), backgroundPaint);
if (hasGradientService()) { if (hasGradientService()) {
canvas.drawRoundRect(giftButtonRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint); canvas.drawRoundRect(giftButtonRect, dp(16), dp(16), getThemedPaint(Theme.key_paint_chatActionBackgroundDarken));
}
if (dimAmount > 0) {
canvas.drawRoundRect(giftButtonRect, dp(16), dp(16), dimPaint);
} }
if (getMessageObject().type != MessageObject.TYPE_SUGGEST_PHOTO && getMessageObject().type != MessageObject.TYPE_ACTION_WALLPAPER && getMessageObject().type != MessageObject.TYPE_STORY_MENTION) { if (getMessageObject().type != MessageObject.TYPE_SUGGEST_PHOTO && getMessageObject().type != MessageObject.TYPE_ACTION_WALLPAPER && getMessageObject().type != MessageObject.TYPE_STORY_MENTION) {
starsPath.rewind(); starsPath.rewind();
starsPath.addRoundRect(giftButtonRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Path.Direction.CW); starsPath.addRoundRect(giftButtonRect, dp(16), dp(16), Path.Direction.CW);
canvas.save(); canvas.save();
canvas.clipPath(starsPath); canvas.clipPath(starsPath);
@ -1539,7 +1618,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
if (progressView == null) { if (progressView == null) {
progressView = new RadialProgressView(getContext()); progressView = new RadialProgressView(getContext());
} }
int rad = AndroidUtilities.dp(16); int rad = dp(16);
canvas.save(); canvas.save();
canvas.scale(progressToProgress, progressToProgress, giftButtonRect.centerX(), giftButtonRect.centerY()); canvas.scale(progressToProgress, progressToProgress, giftButtonRect.centerX(), giftButtonRect.centerY());
progressView.setSize(rad); progressView.setSize(rad);
@ -1551,7 +1630,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
canvas.save(); canvas.save();
float s = 1f - progressToProgress; float s = 1f - progressToProgress;
canvas.scale(s, s, giftButtonRect.centerX(), giftButtonRect.centerY()); canvas.scale(s, s, giftButtonRect.centerX(), giftButtonRect.centerY());
canvas.translate(x, giftButtonRect.top + AndroidUtilities.dp(8)); canvas.translate(x, giftButtonRect.top + dp(8));
giftPremiumButtonLayout.draw(canvas); giftPremiumButtonLayout.draw(canvas);
canvas.restore(); canvas.restore();
} }
@ -1567,7 +1646,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
Theme.multAlpha(Color.WHITE, .2f), Theme.multAlpha(Color.WHITE, .2f),
Theme.multAlpha(Color.WHITE, .7f) Theme.multAlpha(Color.WHITE, .7f)
); );
loadingDrawable.strokePaint.setStrokeWidth(AndroidUtilities.dp(1)); loadingDrawable.strokePaint.setStrokeWidth(dp(1));
} }
loadingDrawable.resetDisappear(); loadingDrawable.resetDisappear();
loadingDrawable.setBounds(giftButtonRect); loadingDrawable.setBounds(giftButtonRect);
@ -1587,6 +1666,19 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
} }
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == rippleView) {
final float S = bounce.getScale(0.02f);
canvas.save();
canvas.scale(S, S, child.getX() + child.getMeasuredWidth() / 2f, child.getY() + child.getMeasuredHeight() / 2f);
final boolean r = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return r;
}
return super.drawChild(canvas, child, drawingTime);
}
public void drawBackground(Canvas canvas, boolean fromParent) { public void drawBackground(Canvas canvas, boolean fromParent) {
if (canDrawInParent) { if (canDrawInParent) {
if (hasGradientService() && !fromParent) { if (hasGradientService() && !fromParent) {
@ -1597,6 +1689,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
} }
Paint backgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackground); Paint backgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackground);
Paint darkenBackgroundPaint = getThemedPaint(Theme.key_paint_chatActionBackgroundDarken);
textPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText); textPaint = (TextPaint) getThemedPaint(Theme.key_paint_chatActionText);
if (overrideBackground >= 0) { if (overrideBackground >= 0) {
int color = getThemedColor(overrideBackground); int color = getThemedColor(overrideBackground);
@ -1605,7 +1698,7 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
overrideBackgroundPaint.setColor(color); overrideBackgroundPaint.setColor(color);
overrideTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); overrideTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
overrideTextPaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM)); overrideTextPaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
overrideTextPaint.setTextSize(AndroidUtilities.dp(Math.max(16, SharedConfig.fontSize) - 2)); overrideTextPaint.setTextSize(dp(Math.max(16, SharedConfig.fontSize) - 2));
overrideTextPaint.setColor(getThemedColor(overrideText)); overrideTextPaint.setColor(getThemedColor(overrideText));
} }
backgroundPaint = overrideBackgroundPaint; backgroundPaint = overrideBackgroundPaint;
@ -1615,8 +1708,8 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
invalidatePath = false; invalidatePath = false;
lineWidths.clear(); lineWidths.clear();
final int count = textLayout == null ? 0 : textLayout.getLineCount(); final int count = textLayout == null ? 0 : textLayout.getLineCount();
final int corner = AndroidUtilities.dp(11); final int corner = dp(11);
final int cornerIn = AndroidUtilities.dp(8); final int cornerIn = dp(8);
int prevLineWidth = 0; int prevLineWidth = 0;
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
@ -1640,12 +1733,12 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
prevLineWidth = lineWidth; prevLineWidth = lineWidth;
} }
int y = AndroidUtilities.dp(4); int y = dp(4);
int x = getMeasuredWidth() / 2; int x = getMeasuredWidth() / 2;
int previousLineBottom = 0; int previousLineBottom = 0;
final int cornerOffset = AndroidUtilities.dp(3); final int cornerOffset = dp(3);
final int cornerInSmall = AndroidUtilities.dp(6); final int cornerInSmall = dp(6);
final int cornerRest = corner - cornerOffset; final int cornerRest = corner - cornerOffset;
lineHeights.clear(); lineHeights.clear();
@ -1659,10 +1752,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
int height = lineBottom - previousLineBottom; int height = lineBottom - previousLineBottom;
if (a == 0 || lineWidth > prevLineWidth) { if (a == 0 || lineWidth > prevLineWidth) {
height += AndroidUtilities.dp(3); height += dp(3);
} }
if (a == count - 1 || lineWidth > nextLineWidth) { if (a == count - 1 || lineWidth > nextLineWidth) {
height += AndroidUtilities.dp(3); height += dp(3);
} }
previousLineBottom = lineBottom; previousLineBottom = lineBottom;
@ -1686,12 +1779,12 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
y += height; y += height;
int yOffset = y; int yOffset = y;
if (a != count - 1 && lineWidth < nextLineWidth) { if (a != count - 1 && lineWidth < nextLineWidth) {
y -= AndroidUtilities.dp(3); y -= dp(3);
height -= AndroidUtilities.dp(3); height -= dp(3);
} }
if (a != 0 && lineWidth < prevLineWidth) { if (a != 0 && lineWidth < prevLineWidth) {
y -= AndroidUtilities.dp(3); y -= dp(3);
height -= AndroidUtilities.dp(3); height -= dp(3);
} }
lineHeights.add(height); lineHeights.add(height);
@ -1744,22 +1837,35 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
backgroundHeight = parent.getMeasuredHeight(); backgroundHeight = parent.getMeasuredHeight();
} }
if (themeDelegate != null) { if (themeDelegate != null) {
themeDelegate.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4)); themeDelegate.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, viewTranslationX, viewTop + dp(4));
} else { } else {
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, 0, viewTop + AndroidUtilities.dp(4)); Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, viewTranslationX, viewTop + dp(4));
} }
int oldAlpha = -1; int oldAlpha = -1;
int oldAlpha2 = -1; int oldAlpha2 = -1;
if (fromParent && getAlpha() != 1f) { if (fromParent && (getAlpha() != 1f || isFloating())) {
oldAlpha = backgroundPaint.getAlpha(); oldAlpha = backgroundPaint.getAlpha();
oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha(); oldAlpha2 = darkenBackgroundPaint.getAlpha();
backgroundPaint.setAlpha((int) (oldAlpha * getAlpha())); backgroundPaint.setAlpha((int) (oldAlpha * getAlpha() * (isFloating() ? .75f : 1f)));
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * getAlpha())); darkenBackgroundPaint.setAlpha((int) (oldAlpha2 * getAlpha() * (isFloating() ? .75f : 1f)));
} else if (isFloating()) {
oldAlpha = backgroundPaint.getAlpha();
oldAlpha2 = darkenBackgroundPaint.getAlpha();
backgroundPaint.setAlpha((int) (oldAlpha * (isFloating() ? .75f : 1f)));
darkenBackgroundPaint.setAlpha((int) (oldAlpha2 * (isFloating() ? .75f : 1f)));
} }
canvas.drawPath(backgroundPath, backgroundPaint); canvas.drawPath(backgroundPath, backgroundPaint);
if (hasGradientService()) { if (hasGradientService()) {
canvas.drawPath(backgroundPath, Theme.chat_actionBackgroundGradientDarkenPaint); canvas.drawPath(backgroundPath, darkenBackgroundPaint);
}
if (dimAmount > 0) {
int wasAlpha = dimPaint.getAlpha();
if (fromParent) {
dimPaint.setAlpha((int) (wasAlpha * getAlpha()));
}
canvas.drawPath(backgroundPath, dimPaint);
dimPaint.setAlpha(wasAlpha);
} }
MessageObject messageObject = currentMessageObject; MessageObject messageObject = currentMessageObject;
@ -1767,26 +1873,26 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
float x = (getWidth() - giftRectSize) / 2f; float x = (getWidth() - giftRectSize) / 2f;
float y = textY + textHeight; float y = textY + textHeight;
if (isNewStyleButtonLayout()) { if (isNewStyleButtonLayout()) {
y += AndroidUtilities.dp(4); y += dp(4);
AndroidUtilities.rectTmp.set(x, y, x + giftRectSize, y + backgroundRectHeight); AndroidUtilities.rectTmp.set(x, y, x + giftRectSize, y + backgroundRectHeight);
} else { } else {
y += AndroidUtilities.dp(12); y += dp(12);
AndroidUtilities.rectTmp.set(x, y, x + giftRectSize, y + giftRectSize + giftPremiumAdditionalHeight); AndroidUtilities.rectTmp.set(x, y, x + giftRectSize, y + giftRectSize + giftPremiumAdditionalHeight);
} }
if (backgroundRect == null) { if (backgroundRect == null) {
backgroundRect = new RectF(); backgroundRect = new RectF();
} }
backgroundRect.set(AndroidUtilities.rectTmp); backgroundRect.set(AndroidUtilities.rectTmp);
canvas.drawRoundRect(backgroundRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), backgroundPaint); canvas.drawRoundRect(backgroundRect, dp(16), dp(16), backgroundPaint);
if (hasGradientService()) { if (hasGradientService()) {
canvas.drawRoundRect(backgroundRect, AndroidUtilities.dp(16), AndroidUtilities.dp(16), Theme.chat_actionBackgroundGradientDarkenPaint); canvas.drawRoundRect(backgroundRect, dp(16), dp(16), darkenBackgroundPaint);
} }
} }
if (oldAlpha >= 0) { if (oldAlpha >= 0) {
backgroundPaint.setAlpha(oldAlpha); backgroundPaint.setAlpha(oldAlpha);
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2); darkenBackgroundPaint.setAlpha(oldAlpha2);
} }
} }
@ -1925,6 +2031,10 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
} }
} }
public boolean isFloating() {
return false;
}
private ColorFilter adaptiveEmojiColorFilter; private ColorFilter adaptiveEmojiColorFilter;
private int adaptiveEmojiColor; private int adaptiveEmojiColor;
private ColorFilter getAdaptiveEmojiColorFilter(int color) { private ColorFilter getAdaptiveEmojiColorFilter(int color) {

View file

@ -8,8 +8,13 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@ -29,19 +34,58 @@ public class ChatLoadingCell extends FrameLayout {
super(context); super(context);
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
frameLayout = new FrameLayout(context); frameLayout = new FrameLayout(context) {
frameLayout.setBackground(Theme.createServiceDrawable(AndroidUtilities.dp(18), frameLayout, parent, getThemedPaint(Theme.key_paint_chatActionBackground))); private final RectF rect = new RectF();
@Override
protected void dispatchDraw(Canvas canvas) {
rect.set(0, 0, getWidth(), getHeight());
applyServiceShaderMatrix();
canvas.drawRoundRect(rect, dp(18), dp(18), getThemedPaint(Theme.key_paint_chatActionBackground));
if (hasGradientService()) {
canvas.drawRoundRect(rect, dp(18), dp(18), getThemedPaint(Theme.key_paint_chatActionBackgroundDarken));
}
super.dispatchDraw(canvas);
}
};
frameLayout.setWillNotDraw(false);
addView(frameLayout, LayoutHelper.createFrame(36, 36, Gravity.CENTER)); addView(frameLayout, LayoutHelper.createFrame(36, 36, Gravity.CENTER));
progressBar = new RadialProgressView(context, resourcesProvider); progressBar = new RadialProgressView(context, resourcesProvider);
progressBar.setSize(AndroidUtilities.dp(28)); progressBar.setSize(dp(28));
progressBar.setProgressColor(getThemedColor(Theme.key_chat_serviceText)); progressBar.setProgressColor(getThemedColor(Theme.key_chat_serviceText));
frameLayout.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER)); frameLayout.addView(progressBar, LayoutHelper.createFrame(32, 32, Gravity.CENTER));
} }
public boolean hasGradientService() {
return resourcesProvider != null ? resourcesProvider.hasGradientService() : Theme.hasGradientService();
}
private float viewTop;
private int backgroundHeight;
public void applyServiceShaderMatrix() {
applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
}
private void applyServiceShaderMatrix(int measuredWidth, int backgroundHeight, float x, float viewTop) {
if (resourcesProvider != null) {
resourcesProvider.applyServiceShaderMatrix(measuredWidth, backgroundHeight, x, viewTop);
} else {
Theme.applyServiceShaderMatrix(measuredWidth, backgroundHeight, x, viewTop);
}
}
public void setVisiblePart(float viewTop, int backgroundHeight) {
if (this.viewTop != viewTop) {
invalidate();
}
this.viewTop = viewTop;
this.backgroundHeight = backgroundHeight;
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(44), MeasureSpec.EXACTLY)); super.onMeasure(MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(44), MeasureSpec.EXACTLY));
} }
public void setProgressVisible(boolean value) { public void setProgressVisible(boolean value) {

View file

@ -15,10 +15,12 @@ import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient; import android.graphics.LinearGradient;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuffXfermode;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.Shader; import android.graphics.Shader;
@ -33,7 +35,6 @@ import android.text.Spanned;
import android.text.StaticLayout; import android.text.StaticLayout;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan; import android.text.style.ClickableSpan;
import android.text.style.ReplacementSpan; import android.text.style.ReplacementSpan;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
@ -2175,7 +2176,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
if (messageString instanceof Spannable) { if (messageString instanceof Spannable) {
Spannable messageStringSpannable = (Spannable) messageString; Spannable messageStringSpannable = (Spannable) messageString;
for (Object span : messageStringSpannable.getSpans(0, messageStringSpannable.length(), Object.class)) { 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)) { if (span instanceof ClickableSpan || span instanceof CodeHighlighting.Span || span instanceof TypefaceSpan || span instanceof CodeHighlighting.ColorSpan || span instanceof QuoteSpan || span instanceof QuoteSpan.QuoteStyleSpan || (span instanceof StyleSpan && ((StyleSpan) span).getStyle() == android.graphics.Typeface.BOLD)) {
messageStringSpannable.removeSpan(span); messageStringSpannable.removeSpan(span);
} }
} }
@ -2886,10 +2887,10 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
avatarImage.setImage(null, null, avatarDrawable, null, user, 0); avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
} else { } else {
if (useFromUserAsAvatar && message != null) { if (useFromUserAsAvatar && message != null) {
avatarDrawable.setInfo(message.getFromPeerObject()); avatarDrawable.setInfo(currentAccount, message.getFromPeerObject());
avatarImage.setForUserOrChat(message.getFromPeerObject(), avatarDrawable); avatarImage.setForUserOrChat(message.getFromPeerObject(), avatarDrawable);
} else if (user != null) { } else if (user != null) {
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
if (UserObject.isReplyUser(user)) { if (UserObject.isReplyUser(user)) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES); avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
avatarImage.setImage(null, null, avatarDrawable, null, user, 0); avatarImage.setImage(null, null, avatarDrawable, null, user, 0);
@ -2900,7 +2901,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
avatarImage.setForUserOrChat(user, avatarDrawable, null, true, VectorAvatarThumbDrawable.TYPE_SMALL, false); avatarImage.setForUserOrChat(user, avatarDrawable, null, true, VectorAvatarThumbDrawable.TYPE_SMALL, false);
} }
} else if (chat != null) { } else if (chat != null) {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
avatarImage.setForUserOrChat(chat, avatarDrawable); avatarImage.setForUserOrChat(chat, avatarDrawable);
} }
} }
@ -3387,7 +3388,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
canvas.save(); canvas.save();
canvas.translate(nameLeft + nameLayoutTranslateX, AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 13)); canvas.translate(nameLeft + nameLayoutTranslateX, AndroidUtilities.dp(useForceThreeLines || SharedConfig.useThreeLinesLayout ? 10 : 13));
SpoilerEffect.layoutDrawMaybe(nameLayout, canvas); SpoilerEffect.layoutDrawMaybe(nameLayout, canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, nameLayout, animatedEmojiStackName, -.075f, null, 0, 0, 0, 1f); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, nameLayout, animatedEmojiStackName, -.075f, null, 0, 0, 0, 1f, getAdaptiveEmojiColorFilter(0, nameLayout.getPaint().getColor()));
canvas.restore(); canvas.restore();
if (nameLayoutEllipsizeByGradient && !nameLayoutFits) { if (nameLayoutEllipsizeByGradient && !nameLayoutFits) {
canvas.save(); canvas.save();
@ -3432,7 +3433,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
canvas.translate(messageNameLeft, messageNameTop); canvas.translate(messageNameLeft, messageNameTop);
try { try {
SpoilerEffect.layoutDrawMaybe(messageNameLayout, canvas); SpoilerEffect.layoutDrawMaybe(messageNameLayout, canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, messageNameLayout, animatedEmojiStack2, -.075f, null, 0, 0, 0, 1f); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, messageNameLayout, animatedEmojiStack2, -.075f, null, 0, 0, 0, 1f, getAdaptiveEmojiColorFilter(1, messageNameLayout.getPaint().getColor()));
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
} }
@ -3466,7 +3467,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
canvas.save(); canvas.save();
SpoilerEffect.clipOutCanvas(canvas, spoilers); SpoilerEffect.clipOutCanvas(canvas, spoilers);
SpoilerEffect.layoutDrawMaybe(messageLayout, canvas); SpoilerEffect.layoutDrawMaybe(messageLayout, canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, messageLayout, animatedEmojiStack, -.075f, spoilers, 0, 0, 0, 1f); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, messageLayout, animatedEmojiStack, -.075f, spoilers, 0, 0, 0, 1f, getAdaptiveEmojiColorFilter(2, messageLayout.getPaint().getColor()));
canvas.restore(); canvas.restore();
for (int i = 0; i < spoilers.size(); i++) { for (int i = 0; i < spoilers.size(); i++) {
@ -3479,7 +3480,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
} else { } else {
SpoilerEffect.layoutDrawMaybe(messageLayout, canvas); SpoilerEffect.layoutDrawMaybe(messageLayout, canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, messageLayout, animatedEmojiStack, -.075f, null, 0, 0, 0, 1f); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, messageLayout, animatedEmojiStack, -.075f, null, 0, 0, 0, 1f, getAdaptiveEmojiColorFilter(2, messageLayout.getPaint().getColor()));
} }
messageLayout.getPaint().setAlpha(oldAlpha); messageLayout.getPaint().setAlpha(oldAlpha);
canvas.restore(); canvas.restore();
@ -3574,7 +3575,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
canvas.save(); canvas.save();
SpoilerEffect.clipOutCanvas(canvas, spoilers2); SpoilerEffect.clipOutCanvas(canvas, spoilers2);
SpoilerEffect.layoutDrawMaybe(buttonLayout, canvas); SpoilerEffect.layoutDrawMaybe(buttonLayout, canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, buttonLayout, animatedEmojiStack3, -.075f, spoilers2, 0, 0, 0, 1f); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, buttonLayout, animatedEmojiStack3, -.075f, spoilers2, 0, 0, 0, 1f, getAdaptiveEmojiColorFilter(3, buttonLayout.getPaint().getColor()));
canvas.restore(); canvas.restore();
for (int i = 0; i < spoilers2.size(); i++) { for (int i = 0; i < spoilers2.size(); i++) {
@ -3587,7 +3588,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
} else { } else {
SpoilerEffect.layoutDrawMaybe(buttonLayout, canvas); SpoilerEffect.layoutDrawMaybe(buttonLayout, canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, buttonLayout, animatedEmojiStack3, -.075f, null, 0, 0, 0, 1f); AnimatedEmojiSpan.drawAnimatedEmojis(canvas, buttonLayout, animatedEmojiStack3, -.075f, null, 0, 0, 0, 1f, getAdaptiveEmojiColorFilter(3, buttonLayout.getPaint().getColor()));
} }
canvas.restore(); canvas.restore();
} }
@ -5234,4 +5235,17 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
} }
} }
private ColorFilter[] adaptiveEmojiColorFilter;
private int[] adaptiveEmojiColor;
private ColorFilter getAdaptiveEmojiColorFilter(int n, int color) {
if (adaptiveEmojiColorFilter == null) {
adaptiveEmojiColor = new int[4];
adaptiveEmojiColorFilter = new ColorFilter[4];
}
if (color != adaptiveEmojiColor[n] || adaptiveEmojiColorFilter[n] == null) {
adaptiveEmojiColorFilter[n] = new PorterDuffColorFilter(adaptiveEmojiColor[n] = color, PorterDuff.Mode.SRC_IN);
}
return adaptiveEmojiColorFilter[n];
}
} }

View file

@ -114,7 +114,7 @@ public class DialogMeUrlCell extends BaseCell {
nameLeft = AndroidUtilities.dp(14); nameLeft = AndroidUtilities.dp(14);
} }
nameString = chat.title; nameString = chat.title;
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
avatarImage.setForUserOrChat(chat, avatarDrawable, recentMeUrl); avatarImage.setForUserOrChat(chat, avatarDrawable, recentMeUrl);
} else if (recentMeUrl instanceof TLRPC.TL_recentMeUrlUser) { } else if (recentMeUrl instanceof TLRPC.TL_recentMeUrlUser) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(recentMeUrl.user_id); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(recentMeUrl.user_id);
@ -137,7 +137,7 @@ public class DialogMeUrlCell extends BaseCell {
drawVerified = user.verified; drawVerified = user.verified;
} }
nameString = UserObject.getUserName(user); nameString = UserObject.getUserName(user);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
avatarImage.setForUserOrChat(user, avatarDrawable, recentMeUrl); avatarImage.setForUserOrChat(user, avatarDrawable, recentMeUrl);
} else if (recentMeUrl instanceof TLRPC.TL_recentMeUrlStickerSet) { } else if (recentMeUrl instanceof TLRPC.TL_recentMeUrlStickerSet) {
if (!LocaleController.isRTL) { if (!LocaleController.isRTL) {
@ -155,7 +155,7 @@ public class DialogMeUrlCell extends BaseCell {
nameLeft = AndroidUtilities.dp(14); nameLeft = AndroidUtilities.dp(14);
} }
if (recentMeUrl.chat_invite.chat != null) { if (recentMeUrl.chat_invite.chat != null) {
avatarDrawable.setInfo(recentMeUrl.chat_invite.chat); avatarDrawable.setInfo(currentAccount, recentMeUrl.chat_invite.chat);
nameString = recentMeUrl.chat_invite.chat.title; nameString = recentMeUrl.chat_invite.chat.title;
drawVerified = recentMeUrl.chat_invite.chat.verified; drawVerified = recentMeUrl.chat_invite.chat.verified;
avatarImage.setForUserOrChat(recentMeUrl.chat_invite.chat, avatarDrawable, recentMeUrl); avatarImage.setForUserOrChat(recentMeUrl.chat_invite.chat, avatarDrawable, recentMeUrl);

View file

@ -135,7 +135,7 @@ public class DrawerUserCell extends FrameLayout implements NotificationCenter.No
if (user == null) { if (user == null) {
return; return;
} }
avatarDrawable.setInfo(user); avatarDrawable.setInfo(account, user);
CharSequence text = ContactsController.formatName(user.first_name, user.last_name); CharSequence text = ContactsController.formatName(user.first_name, user.last_name);
try { try {
text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20), false); text = Emoji.replaceEmoji(text, textView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(20), false);

View file

@ -10,7 +10,6 @@ import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;

View file

@ -34,7 +34,7 @@ import org.telegram.messenger.LiteMode;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.messenger.voip.VoIPService; import org.telegram.messenger.voip.VoIPService;
@ -469,7 +469,7 @@ public class GroupCallUserCell extends FrameLayout {
if (id > 0) { if (id > 0) {
currentUser = accountInstance.getMessagesController().getUser(id); currentUser = accountInstance.getMessagesController().getUser(id);
currentChat = null; currentChat = null;
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(accountInstance.getCurrentAccount(), currentUser);
nameTextView.setText(UserObject.getUserName(currentUser)); nameTextView.setText(UserObject.getUserName(currentUser));
if (currentUser != null && currentUser.verified) { if (currentUser != null && currentUser.verified) {
@ -509,7 +509,7 @@ public class GroupCallUserCell extends FrameLayout {
} else { } else {
currentChat = accountInstance.getMessagesController().getChat(-id); currentChat = accountInstance.getMessagesController().getChat(-id);
currentUser = null; currentUser = null;
avatarDrawable.setInfo(currentChat); avatarDrawable.setInfo(accountInstance.getCurrentAccount(), currentChat);
if (currentChat != null) { if (currentChat != null) {
nameTextView.setText(currentChat.title); nameTextView.setText(currentChat.title);

View file

@ -321,7 +321,7 @@ public class GroupCreateUserCell extends FrameLayout {
return; return;
} }
} }
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(currentAccount, currentUser);
lastStatus = currentUser.status != null ? currentUser.status.expires : 0; lastStatus = currentUser.status != null ? currentUser.status.expires : 0;
if (currentName != null) { if (currentName != null) {
@ -374,7 +374,7 @@ public class GroupCreateUserCell extends FrameLayout {
} }
} }
avatarDrawable.setInfo(currentChat); avatarDrawable.setInfo(currentAccount, currentChat);
if (currentName != null) { if (currentName != null) {
lastName = null; lastName = null;

View file

@ -40,6 +40,7 @@ public class HintDialogCell extends FrameLayout {
private TextView nameTextView; private TextView nameTextView;
private AvatarDrawable avatarDrawable = new AvatarDrawable(); private AvatarDrawable avatarDrawable = new AvatarDrawable();
private RectF rect = new RectF(); private RectF rect = new RectF();
private Theme.ResourcesProvider resourcesProvider;
private int lastUnreadCount; private int lastUnreadCount;
private TLRPC.User currentUser; private TLRPC.User currentUser;
@ -53,7 +54,7 @@ public class HintDialogCell extends FrameLayout {
CheckBox2 checkBox; CheckBox2 checkBox;
private final boolean drawCheckbox; private final boolean drawCheckbox;
public HintDialogCell(Context context, boolean drawCheckbox) { public HintDialogCell(Context context, boolean drawCheckbox, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.drawCheckbox = drawCheckbox; this.drawCheckbox = drawCheckbox;
@ -69,7 +70,7 @@ public class HintDialogCell extends FrameLayout {
} }
}; };
NotificationCenter.listenEmojiLoading(nameTextView); NotificationCenter.listenEmojiLoading(nameTextView);
nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); nameTextView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); nameTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
nameTextView.setMaxLines(1); nameTextView.setMaxLines(1);
nameTextView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL); nameTextView.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
@ -77,13 +78,13 @@ public class HintDialogCell extends FrameLayout {
nameTextView.setEllipsize(TextUtils.TruncateAt.END); nameTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 6, 64, 6, 0)); addView(nameTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 6, 64, 6, 0));
counterView = new CounterView(context, null); counterView = new CounterView(context, resourcesProvider);
addView(counterView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, Gravity.TOP,0 ,4,0,0)); addView(counterView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 28, Gravity.TOP,0 ,4,0,0));
counterView.setColors(Theme.key_chats_unreadCounterText, Theme.key_chats_unreadCounter); counterView.setColors(Theme.key_chats_unreadCounterText, Theme.key_chats_unreadCounter);
counterView.setGravity(Gravity.RIGHT); counterView.setGravity(Gravity.RIGHT);
if (drawCheckbox) { if (drawCheckbox) {
checkBox = new CheckBox2(context, 21); checkBox = new CheckBox2(context, 21, resourcesProvider);
checkBox.setColor(Theme.key_dialogRoundCheckBox, Theme.key_dialogBackground, Theme.key_dialogRoundCheckBoxCheck); checkBox.setColor(Theme.key_dialogRoundCheckBox, Theme.key_dialogBackground, Theme.key_dialogRoundCheckBoxCheck);
checkBox.setDrawUnchecked(false); checkBox.setDrawUnchecked(false);
checkBox.setDrawBackgroundAsArc(4); checkBox.setDrawBackgroundAsArc(4);
@ -131,16 +132,16 @@ public class HintDialogCell extends FrameLayout {
public void update() { public void update() {
if (DialogObject.isUserDialog(dialogId)) { if (DialogObject.isUserDialog(dialogId)) {
currentUser = MessagesController.getInstance(currentAccount).getUser(dialogId); currentUser = MessagesController.getInstance(currentAccount).getUser(dialogId);
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(currentAccount, currentUser);
} else { } else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId);
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
currentUser = null; currentUser = null;
} }
} }
public void setColors(int textColorKey, int backgroundColorKey) { public void setColors(int textColorKey, int backgroundColorKey) {
nameTextView.setTextColor(Theme.getColor(textColorKey)); nameTextView.setTextColor(Theme.getColor(textColorKey, resourcesProvider));
this.backgroundColorKey = backgroundColorKey; this.backgroundColorKey = backgroundColorKey;
checkBox.setColor(Theme.key_dialogRoundCheckBox, backgroundColorKey, Theme.key_dialogRoundCheckBoxCheck); checkBox.setColor(Theme.key_dialogRoundCheckBox, backgroundColorKey, Theme.key_dialogRoundCheckBoxCheck);
} }
@ -160,7 +161,7 @@ public class HintDialogCell extends FrameLayout {
} else { } else {
nameTextView.setText(""); nameTextView.setText("");
} }
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(currentAccount, currentUser);
imageView.setForUserOrChat(currentUser, avatarDrawable); imageView.setForUserOrChat(currentUser, avatarDrawable);
} else { } else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-uid); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-uid);
@ -171,7 +172,7 @@ public class HintDialogCell extends FrameLayout {
} else { } else {
nameTextView.setText(""); nameTextView.setText("");
} }
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
currentUser = null; currentUser = null;
imageView.setForUserOrChat(chat, avatarDrawable); imageView.setForUserOrChat(chat, avatarDrawable);
} }

View file

@ -17,7 +17,6 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController; import org.telegram.messenger.ContactsController;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;

View file

@ -26,44 +26,39 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.SimpleTextView; import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Stories.StoriesUtilities;
public class ManageChatUserCell extends FrameLayout { public class ManageChatUserCell extends FrameLayout {
private BackupImageView avatarImageView; private final BackupImageView avatarImageView;
private SimpleTextView nameTextView; private final SimpleTextView nameTextView;
private SimpleTextView statusTextView; private final SimpleTextView statusTextView;
private final Theme.ResourcesProvider resourcesProvider;
private final AvatarDrawable avatarDrawable;
private ImageView optionsButton; private ImageView optionsButton;
private ImageView customImageView; private ImageView customImageView;
private Theme.ResourcesProvider resourcesProvider;
private AvatarDrawable avatarDrawable;
private Object currentObject; private Object currentObject;
private TL_stories.StoryItem storyItem;
private CharSequence currentName; private CharSequence currentName;
private CharSequence currrntStatus; private CharSequence currentStatus;
private String lastName; private String lastName;
private int lastStatus; private int lastStatus;
private TLRPC.FileLocation lastAvatar; private TLRPC.FileLocation lastAvatar;
private boolean isAdmin; private boolean isAdmin;
private boolean needDivider; private boolean needDivider;
private int statusColor; private int statusColor;
private int statusOnlineColor; private int statusOnlineColor;
private final int namePadding;
private int namePadding;
private int currentAccount = UserConfig.selectedAccount;
private int dividerColor = -1; private int dividerColor = -1;
private ManageChatUserCellDelegate delegate; private ManageChatUserCellDelegate delegate;
private final int currentAccount = UserConfig.selectedAccount;
private final StoriesUtilities.AvatarStoryParams storyAvatarParams = new StoriesUtilities.AvatarStoryParams(false);
public interface ManageChatUserCellDelegate { public interface ManageChatUserCellDelegate {
boolean onOptionsButtonCheck(ManageChatUserCell cell, boolean click); boolean onOptionsButtonCheck(ManageChatUserCell cell, boolean click);
@ -84,7 +79,24 @@ public class ManageChatUserCell extends FrameLayout {
avatarDrawable = new AvatarDrawable(); avatarDrawable = new AvatarDrawable();
avatarImageView = new BackupImageView(context); avatarImageView = new BackupImageView(context) {
@Override
protected void onDraw(Canvas canvas) {
if (storyItem != null) {
int pad = AndroidUtilities.dp(1);
storyAvatarParams.originalAvatarRect.set(pad, pad, getMeasuredWidth() - pad, getMeasuredHeight() - pad);
storyAvatarParams.drawSegments = false;
storyAvatarParams.animate = false;
storyAvatarParams.drawInside = true;
storyAvatarParams.isArchive = false;
storyAvatarParams.resourcesProvider = resourcesProvider;
storyAvatarParams.storyItem = storyItem;
StoriesUtilities.drawAvatarWithStory(storyItem.dialogId, canvas, imageReceiver, storyAvatarParams);
} else {
super.onDraw(canvas);
}
}
};
avatarImageView.setRoundRadius(AndroidUtilities.dp(23)); avatarImageView.setRoundRadius(AndroidUtilities.dp(23));
addView(avatarImageView, LayoutHelper.createFrame(46, 46, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 7 + avatarPadding, 8, LocaleController.isRTL ? 7 + avatarPadding : 0, 0)); addView(avatarImageView, LayoutHelper.createFrame(46, 46, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 0 : 7 + avatarPadding, 8, LocaleController.isRTL ? 7 + avatarPadding : 0, 0));
@ -113,6 +125,23 @@ public class ManageChatUserCell extends FrameLayout {
} }
} }
public void setStoryItem(TL_stories.StoryItem storyItem, OnClickListener listener) {
this.storyItem = storyItem;
avatarImageView.setOnClickListener(listener);
}
public TL_stories.StoryItem getStoryItem() {
return storyItem;
}
public BackupImageView getAvatarImageView() {
return avatarImageView;
}
public StoriesUtilities.AvatarStoryParams getStoryAvatarParams() {
return storyAvatarParams;
}
public void setCustomRightImage(int resId) { public void setCustomRightImage(int resId) {
customImageView = new ImageView(getContext()); customImageView = new ImageView(getContext());
customImageView.setImageResource(resId); customImageView.setImageResource(resId);
@ -130,7 +159,7 @@ public class ManageChatUserCell extends FrameLayout {
public void setData(Object object, CharSequence name, CharSequence status, boolean divider) { public void setData(Object object, CharSequence name, CharSequence status, boolean divider) {
if (object == null) { if (object == null) {
currrntStatus = null; currentStatus = null;
currentName = null; currentName = null;
currentObject = null; currentObject = null;
nameTextView.setText(""); nameTextView.setText("");
@ -138,7 +167,7 @@ public class ManageChatUserCell extends FrameLayout {
avatarImageView.setImageDrawable(null); avatarImageView.setImageDrawable(null);
return; return;
} }
currrntStatus = status; currentStatus = status;
currentName = name; currentName = name;
currentObject = object; currentObject = object;
if (optionsButton != null) { if (optionsButton != null) {
@ -229,7 +258,7 @@ public class ManageChatUserCell extends FrameLayout {
} }
} }
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(currentAccount, currentUser);
if (currentUser.status != null) { if (currentUser.status != null) {
lastStatus = currentUser.status.expires; lastStatus = currentUser.status.expires;
} else { } else {
@ -243,9 +272,9 @@ public class ManageChatUserCell extends FrameLayout {
lastName = newName == null ? UserObject.getUserName(currentUser) : newName; lastName = newName == null ? UserObject.getUserName(currentUser) : newName;
nameTextView.setText(Emoji.replaceEmoji(lastName, nameTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(15), false)); nameTextView.setText(Emoji.replaceEmoji(lastName, nameTextView.getPaint().getFontMetricsInt(), AndroidUtilities.dp(15), false));
} }
if (currrntStatus != null) { if (currentStatus != null) {
statusTextView.setTextColor(statusColor); statusTextView.setTextColor(statusColor);
statusTextView.setText(currrntStatus); statusTextView.setText(currentStatus);
} else { } else {
if (currentUser.bot) { if (currentUser.bot) {
statusTextView.setTextColor(statusColor); statusTextView.setTextColor(statusColor);
@ -293,7 +322,7 @@ public class ManageChatUserCell extends FrameLayout {
} }
} }
avatarDrawable.setInfo(currentChat); avatarDrawable.setInfo(currentAccount, currentChat);
if (currentName != null) { if (currentName != null) {
lastName = null; lastName = null;
@ -302,9 +331,9 @@ public class ManageChatUserCell extends FrameLayout {
lastName = newName == null ? currentChat.title : newName; lastName = newName == null ? currentChat.title : newName;
nameTextView.setText(lastName); nameTextView.setText(lastName);
} }
if (currrntStatus != null) { if (currentStatus != null) {
statusTextView.setTextColor(statusColor); statusTextView.setTextColor(statusColor);
statusTextView.setText(currrntStatus); statusTextView.setText(currentStatus);
} else { } else {
statusTextView.setTextColor(statusColor); statusTextView.setTextColor(statusColor);
if (currentChat.participants_count != 0) { if (currentChat.participants_count != 0) {
@ -326,7 +355,7 @@ public class ManageChatUserCell extends FrameLayout {
} else if (currentObject instanceof Integer) { } else if (currentObject instanceof Integer) {
nameTextView.setText(currentName); nameTextView.setText(currentName);
statusTextView.setTextColor(statusColor); statusTextView.setTextColor(statusColor);
statusTextView.setText(currrntStatus); statusTextView.setText(currentStatus);
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SHARES); avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_SHARES);
avatarImageView.setImage(null, "50_50", avatarDrawable); avatarImageView.setImage(null, "50_50", avatarDrawable);
} }

View file

@ -33,11 +33,11 @@ import org.telegram.ui.Components.LayoutHelper;
public class MentionCell extends LinearLayout { public class MentionCell extends LinearLayout {
private BackupImageView imageView; private final BackupImageView imageView;
private TextView nameTextView; private final TextView nameTextView;
private TextView usernameTextView; private final TextView usernameTextView;
private AvatarDrawable avatarDrawable; private final AvatarDrawable avatarDrawable;
private Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
private Drawable emojiDrawable; private Drawable emojiDrawable;

View file

@ -22,6 +22,7 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
@ -88,12 +89,25 @@ public class NotificationsCheckCell extends FrameLayout {
valueTextView.setEllipsize(TextUtils.TruncateAt.END); valueTextView.setEllipsize(TextUtils.TruncateAt.END);
addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 80 : (withImage ? 64 : padding), 38 - (withImage ? 2 : 0) + (currentHeight - 70) / 2, LocaleController.isRTL ? (withImage ? 64 : padding) : 80, 0)); addView(valueTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, LocaleController.isRTL ? 80 : (withImage ? 64 : padding), 38 - (withImage ? 2 : 0) + (currentHeight - 70) / 2, LocaleController.isRTL ? (withImage ? 64 : padding) : 80, 0));
checkBox = new Switch(context, resourcesProvider); checkBox = new Switch(context, resourcesProvider) {
@Override
protected int processColor(int color) {
return NotificationsCheckCell.this.processColor(color);
}
};
checkBox.setColors(Theme.key_switchTrack, Theme.key_switchTrackChecked, Theme.key_windowBackgroundWhite, Theme.key_windowBackgroundWhite); checkBox.setColors(Theme.key_switchTrack, Theme.key_switchTrackChecked, Theme.key_windowBackgroundWhite, Theme.key_windowBackgroundWhite);
addView(checkBox, LayoutHelper.createFrame(37, 40, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 21, 0, 21, 0)); addView(checkBox, LayoutHelper.createFrame(37, 40, (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT) | Gravity.CENTER_VERTICAL, 21, 0, 21, 0));
checkBox.setFocusable(false); checkBox.setFocusable(false);
} }
public Switch getCheckBox() {
return checkBox;
}
protected int processColor(int color) {
return color;
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (isMultiline) { if (isMultiline) {

View file

@ -10,6 +10,7 @@ package org.telegram.ui.Cells;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.Layout; import android.text.Layout;
@ -37,7 +38,6 @@ import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject; import org.telegram.messenger.UserObject;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
@ -46,9 +46,7 @@ import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.Premium.PremiumGradient; import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.NotificationsSettingsActivity; import org.telegram.ui.NotificationsSettingsActivity;
import org.telegram.ui.Stories.StoriesListPlaceProvider;
import org.telegram.ui.Stories.StoriesUtilities; import org.telegram.ui.Stories.StoriesUtilities;
import java.util.Locale; import java.util.Locale;
@ -134,6 +132,13 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
statusDrawable.setCallback(this); statusDrawable.setCallback(this);
} }
private boolean customPaints;
private TextPaint namePaint, statusPaint;
public ProfileSearchCell useCustomPaints() {
customPaints = true;
return this;
}
@Override @Override
protected boolean verifyDrawable(@NonNull Drawable who) { protected boolean verifyDrawable(@NonNull Drawable who) {
return statusDrawable == who || super.verifyDrawable(who); return statusDrawable == who || super.verifyDrawable(who);
@ -367,7 +372,19 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
nameString = LocaleController.getString("HiddenName", R.string.HiddenName); nameString = LocaleController.getString("HiddenName", R.string.HiddenName);
} }
} }
if (encryptedChat != null) { if (customPaints) {
if (namePaint == null) {
namePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
namePaint.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
}
namePaint.setTextSize(AndroidUtilities.dp(16));
if (encryptedChat != null) {
namePaint.setColor(Theme.getColor(Theme.key_chats_secretName, resourcesProvider));
} else {
namePaint.setColor(Theme.getColor(Theme.key_chats_name, resourcesProvider));
}
currentNamePaint = namePaint;
} else if (encryptedChat != null) {
currentNamePaint = Theme.dialogs_searchNameEncryptedPaint; currentNamePaint = Theme.dialogs_searchNameEncryptedPaint;
} else { } else {
currentNamePaint = Theme.dialogs_searchNamePaint; currentNamePaint = Theme.dialogs_searchNamePaint;
@ -492,6 +509,18 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
} }
nameTop = AndroidUtilities.dp(19); nameTop = AndroidUtilities.dp(19);
} }
if (customPaints) {
if (statusPaint == null) {
statusPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
}
statusPaint.setTextSize(AndroidUtilities.dp(15));
if (currentStatusPaint == Theme.dialogs_offlinePaint) {
statusPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3, resourcesProvider));
} else if (currentStatusPaint == Theme.dialogs_onlinePaint) {
statusPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText3, resourcesProvider));
}
currentStatusPaint = statusPaint;
}
if (!TextUtils.isEmpty(statusString)) { if (!TextUtils.isEmpty(statusString)) {
CharSequence statusStringFinal = TextUtils.ellipsize(statusString, currentStatusPaint, statusWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END); CharSequence statusStringFinal = TextUtils.ellipsize(statusString, currentStatusPaint, statusWidth - AndroidUtilities.dp(12), TextUtils.TruncateAt.END);
@ -581,7 +610,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
public void update(int mask) { public void update(int mask) {
TLRPC.FileLocation photo = null; TLRPC.FileLocation photo = null;
if (user != null) { if (user != null) {
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
if (UserObject.isReplyUser(user)) { if (UserObject.isReplyUser(user)) {
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES); avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
avatarImage.setImage(null, null, avatarDrawable, null, null, 0); avatarImage.setImage(null, null, avatarDrawable, null, null, 0);
@ -606,7 +635,7 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
thumb = chat.photo.strippedBitmap; thumb = chat.photo.strippedBitmap;
} }
} }
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
avatarImage.setImage(ImageLocation.getForUserOrChat(chat, ImageLocation.TYPE_SMALL), "50_50", ImageLocation.getForUserOrChat(chat, ImageLocation.TYPE_STRIPPED), "50_50", thumb, chat, 0); avatarImage.setImage(ImageLocation.getForUserOrChat(chat, ImageLocation.TYPE_SMALL), "50_50", ImageLocation.getForUserOrChat(chat, ImageLocation.TYPE_STRIPPED), "50_50", thumb, chat, 0);
} else if (contact != null) { } else if (contact != null) {
avatarDrawable.setInfo(0, contact.first_name, contact.last_name); avatarDrawable.setInfo(0, contact.first_name, contact.last_name);
@ -687,10 +716,17 @@ public class ProfileSearchCell extends BaseCell implements NotificationCenter.No
} }
if (useSeparator) { if (useSeparator) {
Paint dividerPaint = null;
if (customPaints && resourcesProvider != null) {
dividerPaint = resourcesProvider.getPaint(Theme.key_paint_divider);
}
if (dividerPaint == null) {
dividerPaint = Theme.dividerPaint;
}
if (LocaleController.isRTL) { if (LocaleController.isRTL) {
canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, Theme.dividerPaint); canvas.drawLine(0, getMeasuredHeight() - 1, getMeasuredWidth() - AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, dividerPaint);
} else { } else {
canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, Theme.dividerPaint); canvas.drawLine(AndroidUtilities.dp(AndroidUtilities.leftBaseline), getMeasuredHeight() - 1, getMeasuredWidth(), getMeasuredHeight() - 1, dividerPaint);
} }
} }

View file

@ -41,7 +41,6 @@ import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CubicBezierInterpolator; import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MessageSeenCheckDrawable; import org.telegram.ui.Components.MessageSeenCheckDrawable;
import org.telegram.ui.Components.Premium.PremiumGradient;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.ui.Components.StatusBadgeComponent; import org.telegram.ui.Components.StatusBadgeComponent;
@ -168,7 +167,7 @@ public class ReactedUserHolderView extends FrameLayout {
int colorFilter = Theme.getColor(style == STYLE_STORY ? Theme.key_windowBackgroundWhiteBlackText : Theme.key_chats_verifiedBackground, resourcesProvider); int colorFilter = Theme.getColor(style == STYLE_STORY ? Theme.key_windowBackgroundWhiteBlackText : Theme.key_chats_verifiedBackground, resourcesProvider);
statusBadgeComponent.updateDrawable(user, chat, colorFilter, false); statusBadgeComponent.updateDrawable(user, chat, colorFilter, false);
avatarDrawable.setInfo(u); avatarDrawable.setInfo(currentAccount, u);
if (user != null) { if (user != null) {
dialogId = user.id; dialogId = user.id;
titleView.setText(UserObject.getUserName(user)); titleView.setText(UserObject.getUserName(user));

View file

@ -236,7 +236,7 @@ public class SessionCell extends FrameLayout {
nameTextView.setText(session.domain); nameTextView.setText(session.domain);
String name; String name;
if (user != null) { if (user != null) {
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
name = UserObject.getFirstName(user); name = UserObject.getFirstName(user);
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);
} else { } else {

View file

@ -8,8 +8,16 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.os.SystemClock; import android.os.SystemClock;
import android.text.Layout; import android.text.Layout;
import android.text.TextUtils; import android.text.TextUtils;
@ -20,6 +28,8 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.FloatValueHolder; import androidx.dynamicanimation.animation.FloatValueHolder;
import androidx.dynamicanimation.animation.SpringAnimation; import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce; import androidx.dynamicanimation.animation.SpringForce;
@ -43,16 +53,24 @@ import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CheckBox2; import org.telegram.ui.Components.CheckBox2;
import org.telegram.ui.Components.Forum.ForumUtilities; import org.telegram.ui.Components.Forum.ForumUtilities;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable;
public class ShareDialogCell extends FrameLayout { public class ShareDialogCell extends FrameLayout {
private BackupImageView imageView; private final BackupImageView imageView;
private TextView nameTextView; private final TextView nameTextView;
private SimpleTextView topicTextView; private final SimpleTextView topicTextView;
private CheckBox2 checkBox; private final CheckBox2 checkBox;
private AvatarDrawable avatarDrawable = new AvatarDrawable(); private final AvatarDrawable avatarDrawable = new AvatarDrawable() {
@Override
public void invalidateSelf() {
super.invalidateSelf();
imageView.invalidate();
}
};
private RepostStoryDrawable repostStoryDrawable;
private TLRPC.User user; private TLRPC.User user;
private int currentType; private final int currentType;
private float onlineProgress; private float onlineProgress;
private long lastUpdateTime; private long lastUpdateTime;
@ -60,7 +78,7 @@ public class ShareDialogCell extends FrameLayout {
private boolean topicWasVisible; private boolean topicWasVisible;
private int currentAccount = UserConfig.selectedAccount; private final int currentAccount = UserConfig.selectedAccount;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
public static final int TYPE_SHARE = 0; public static final int TYPE_SHARE = 0;
@ -75,7 +93,7 @@ public class ShareDialogCell extends FrameLayout {
currentType = type; currentType = type;
imageView = new BackupImageView(context); imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(28)); imageView.setRoundRadius(dp(28));
if (type == TYPE_CREATE) { if (type == TYPE_CREATE) {
addView(imageView, LayoutHelper.createFrame(48, 48, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 7, 0, 0)); addView(imageView, LayoutHelper.createFrame(48, 48, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 7, 0, 0));
} else { } else {
@ -85,7 +103,7 @@ public class ShareDialogCell extends FrameLayout {
nameTextView = new TextView(context) { nameTextView = new TextView(context) {
@Override @Override
public void setText(CharSequence text, BufferType type) { public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(10), false); text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), dp(10), false);
super.setText(text, type); super.setText(text, type);
} }
}; };
@ -118,18 +136,24 @@ public class ShareDialogCell extends FrameLayout {
}); });
addView(checkBox, LayoutHelper.createFrame(24, 24, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 19, currentType == TYPE_CREATE ? -40 : 42, 0, 0)); addView(checkBox, LayoutHelper.createFrame(24, 24, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 19, currentType == TYPE_CREATE ? -40 : 42, 0, 0));
setBackground(Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), AndroidUtilities.dp(2), AndroidUtilities.dp(2))); setBackground(Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_listSelector, resourcesProvider), dp(2), dp(2)));
} }
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(currentType == TYPE_CREATE ? 95 : 103), MeasureSpec.EXACTLY)); super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(dp(currentType == TYPE_CREATE ? 95 : 103), MeasureSpec.EXACTLY));
} }
public void setDialog(long uid, boolean checked, CharSequence name) { public void setDialog(long uid, boolean checked, CharSequence name) {
if (DialogObject.isUserDialog(uid)) { if (uid == Long.MAX_VALUE) {
nameTextView.setText(LocaleController.getString(R.string.FwdMyStory));
if (repostStoryDrawable == null) {
repostStoryDrawable = new RepostStoryDrawable(imageView, resourcesProvider);
}
imageView.setImage(null, null, repostStoryDrawable, null);
} else if (DialogObject.isUserDialog(uid)) {
user = MessagesController.getInstance(currentAccount).getUser(uid); user = MessagesController.getInstance(currentAccount).getUser(uid);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
if (currentType != TYPE_CREATE && UserObject.isReplyUser(user)) { if (currentType != TYPE_CREATE && UserObject.isReplyUser(user)) {
nameTextView.setText(LocaleController.getString("RepliesTitle", R.string.RepliesTitle)); nameTextView.setText(LocaleController.getString("RepliesTitle", R.string.RepliesTitle));
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES); avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_REPLIES);
@ -148,7 +172,7 @@ public class ShareDialogCell extends FrameLayout {
} }
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);
} }
imageView.setRoundRadius(AndroidUtilities.dp(28)); imageView.setRoundRadius(dp(28));
} else { } else {
user = null; user = null;
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-uid); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-uid);
@ -159,9 +183,9 @@ public class ShareDialogCell extends FrameLayout {
} else { } else {
nameTextView.setText(""); nameTextView.setText("");
} }
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
imageView.setForUserOrChat(chat, avatarDrawable); imageView.setForUserOrChat(chat, avatarDrawable);
imageView.setRoundRadius(chat != null && chat.forum ? AndroidUtilities.dp(16) : AndroidUtilities.dp(28)); imageView.setRoundRadius(chat != null && chat.forum ? dp(16) : dp(28));
} }
currentDialog = uid; currentDialog = uid;
checkBox.setChecked(checked, false); checkBox.setChecked(checked, false);
@ -202,8 +226,8 @@ public class ShareDialogCell extends FrameLayout {
topicTextView.setAlpha(value); topicTextView.setAlpha(value);
nameTextView.setAlpha(1f - value); nameTextView.setAlpha(1f - value);
topicTextView.setTranslationX((1f - value) * -AndroidUtilities.dp(10)); topicTextView.setTranslationX((1f - value) * -dp(10));
nameTextView.setTranslationX(value * AndroidUtilities.dp(10)); nameTextView.setTranslationX(value * dp(10));
}) })
.addEndListener((animation, canceled, value, velocity) -> { .addEndListener((animation, canceled, value, velocity) -> {
topicTextView.setTag(R.id.spring_tag, null); topicTextView.setTag(R.id.spring_tag, null);
@ -215,11 +239,11 @@ public class ShareDialogCell extends FrameLayout {
topicTextView.setAlpha(1f); topicTextView.setAlpha(1f);
nameTextView.setAlpha(0f); nameTextView.setAlpha(0f);
topicTextView.setTranslationX(0); topicTextView.setTranslationX(0);
nameTextView.setTranslationX(AndroidUtilities.dp(10)); nameTextView.setTranslationX(dp(10));
} else { } else {
topicTextView.setAlpha(0f); topicTextView.setAlpha(0f);
nameTextView.setAlpha(1f); nameTextView.setAlpha(1f);
topicTextView.setTranslationX(-AndroidUtilities.dp(10)); topicTextView.setTranslationX(-dp(10));
nameTextView.setTranslationX(0); nameTextView.setTranslationX(0);
} }
} }
@ -242,12 +266,12 @@ public class ShareDialogCell extends FrameLayout {
boolean isOnline = !user.self && !user.bot && (user.status != null && user.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(user.id)); boolean isOnline = !user.self && !user.bot && (user.status != null && user.status.expires > ConnectionsManager.getInstance(currentAccount).getCurrentTime() || MessagesController.getInstance(currentAccount).onlinePrivacy.containsKey(user.id));
if (isOnline || onlineProgress != 0) { if (isOnline || onlineProgress != 0) {
int top = imageView.getBottom() - AndroidUtilities.dp(6); int top = imageView.getBottom() - dp(6);
int left = imageView.getRight() - AndroidUtilities.dp(10); int left = imageView.getRight() - dp(10);
Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(currentType == TYPE_CALL ? Theme.key_voipgroup_inviteMembersBackground : Theme.key_windowBackgroundWhite)); Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(currentType == TYPE_CALL ? Theme.key_voipgroup_inviteMembersBackground : Theme.key_windowBackgroundWhite));
canvas.drawCircle(left, top, AndroidUtilities.dp(7) * onlineProgress, Theme.dialogs_onlineCirclePaint); canvas.drawCircle(left, top, dp(7) * onlineProgress, Theme.dialogs_onlineCirclePaint);
Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(Theme.key_chats_onlineCircle)); Theme.dialogs_onlineCirclePaint.setColor(getThemedColor(Theme.key_chats_onlineCircle));
canvas.drawCircle(left, top, AndroidUtilities.dp(5) * onlineProgress, Theme.dialogs_onlineCirclePaint); canvas.drawCircle(left, top, dp(5) * onlineProgress, Theme.dialogs_onlineCirclePaint);
if (isOnline) { if (isOnline) {
if (onlineProgress < 1.0f) { if (onlineProgress < 1.0f) {
onlineProgress += dt / 150.0f; onlineProgress += dt / 150.0f;
@ -279,7 +303,7 @@ public class ShareDialogCell extends FrameLayout {
int cy = imageView.getTop() + imageView.getMeasuredHeight() / 2; int cy = imageView.getTop() + imageView.getMeasuredHeight() / 2;
Theme.checkboxSquare_checkPaint.setColor(getThemedColor(Theme.key_dialogRoundCheckBox)); Theme.checkboxSquare_checkPaint.setColor(getThemedColor(Theme.key_dialogRoundCheckBox));
Theme.checkboxSquare_checkPaint.setAlpha((int) (checkBox.getProgress() * 255)); Theme.checkboxSquare_checkPaint.setAlpha((int) (checkBox.getProgress() * 255));
int radius = AndroidUtilities.dp(currentType == TYPE_CREATE ? 24 : 28); int radius = dp(currentType == TYPE_CREATE ? 24 : 28);
AndroidUtilities.rectTmp.set(cx - radius, cy - radius, cx + radius, cy + radius); AndroidUtilities.rectTmp.set(cx - radius, cy - radius, cx + radius, cy + radius);
canvas.drawRoundRect(AndroidUtilities.rectTmp, imageView.getRoundRadius()[0], imageView.getRoundRadius()[0], Theme.checkboxSquare_checkPaint); canvas.drawRoundRect(AndroidUtilities.rectTmp, imageView.getRoundRadius()[0], imageView.getRoundRadius()[0], Theme.checkboxSquare_checkPaint);
super.onDraw(canvas); super.onDraw(canvas);
@ -296,4 +320,62 @@ public class ShareDialogCell extends FrameLayout {
info.setSelected(true); info.setSelected(true);
} }
} }
private static class RepostStoryDrawable extends Drawable {
private final LinearGradient gradient;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final RLottieDrawable lottieDrawable;
public RepostStoryDrawable(View view, Theme.ResourcesProvider resourcesProvider) {
gradient = new LinearGradient(0, 0, dp(56), dp(56), new int[] {
Theme.getColor(Theme.key_stories_circle1, resourcesProvider),
Theme.getColor(Theme.key_stories_circle2, resourcesProvider)
}, new float[] { 0, 1 }, Shader.TileMode.CLAMP);
paint.setShader(gradient);
lottieDrawable = new RLottieDrawable(R.raw.story_repost, "story_repost", dp(42), dp(42), true, null);
lottieDrawable.setMasterParent(view);
AndroidUtilities.runOnUIThread(lottieDrawable::start, 450);
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.save();
canvas.translate(getBounds().left, getBounds().top);
canvas.drawCircle(getBounds().width() / 2f, getBounds().height() / 2f, getBounds().width() / 2f, paint);
canvas.restore();
AndroidUtilities.rectTmp2.set(getBounds());
AndroidUtilities.rectTmp2.inset(dp(8), dp(8));
lottieDrawable.setBounds(AndroidUtilities.rectTmp2);
lottieDrawable.draw(canvas);
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getIntrinsicWidth() {
return dp(56);
}
@Override
public int getIntrinsicHeight() {
return dp(56);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
}
} }

View file

@ -47,10 +47,8 @@ import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable; import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.LoadingSpan; import org.telegram.ui.Components.LoadingSpan;
import org.telegram.ui.Components.Paint.Views.LocationView;
import org.telegram.ui.LocationActivity; import org.telegram.ui.LocationActivity;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -304,14 +302,14 @@ public class SharingLiveLocationCell extends FrameLayout {
if (DialogObject.isUserDialog(info.id)) { if (DialogObject.isUserDialog(info.id)) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(info.id); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(info.id);
if (user != null) { if (user != null) {
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name));
avatarImageView.setForUserOrChat(user, avatarDrawable); avatarImageView.setForUserOrChat(user, avatarDrawable);
} }
} else { } else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-info.id); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-info.id);
if (chat != null) { if (chat != null) {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
nameTextView.setText(chat.title); nameTextView.setText(chat.title);
avatarImageView.setForUserOrChat(chat, avatarDrawable); avatarImageView.setForUserOrChat(chat, avatarDrawable);
} }
@ -336,14 +334,14 @@ public class SharingLiveLocationCell extends FrameLayout {
if (DialogObject.isUserDialog(info.did)) { if (DialogObject.isUserDialog(info.did)) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(info.did); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(info.did);
if (user != null) { if (user != null) {
avatarDrawable.setInfo(user); avatarDrawable.setInfo(currentAccount, user);
nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name)); nameTextView.setText(ContactsController.formatName(user.first_name, user.last_name));
avatarImageView.setForUserOrChat(user, avatarDrawable); avatarImageView.setForUserOrChat(user, avatarDrawable);
} }
} else { } else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-info.did); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-info.did);
if (chat != null) { if (chat != null) {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
nameTextView.setText(chat.title); nameTextView.setText(chat.title);
avatarImageView.setForUserOrChat(chat, avatarDrawable); avatarImageView.setForUserOrChat(chat, avatarDrawable);
} }

View file

@ -1,10 +1,16 @@
package org.telegram.ui.Cells; package org.telegram.ui.Cells;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.URLSpan;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
@ -12,81 +18,105 @@ import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLoader; import org.telegram.messenger.FileLoader;
import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan; import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.CombinedDrawable;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.StatisticActivity; import org.telegram.ui.StatisticActivity;
import org.telegram.ui.Stories.StoriesUtilities;
import java.util.Date;
@SuppressLint("ViewConstructor")
public class StatisticPostInfoCell extends FrameLayout { public class StatisticPostInfoCell extends FrameLayout {
private TextView message; private final BackupImageView imageView;
private TextView views; private final SimpleTextView message;
private TextView shares; private final TextView views;
private TextView date; private final TextView shares;
private BackupImageView imageView; private final TextView date;
private AvatarDrawable avatarDrawable = new AvatarDrawable(); private final TextView likes;
private final Paint dividerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final AvatarDrawable avatarDrawable = new AvatarDrawable();
private final StoriesUtilities.AvatarStoryParams storyAvatarParams = new StoriesUtilities.AvatarStoryParams(false);
private final Theme.ResourcesProvider resourcesProvider;
private StatisticActivity.RecentPostInfo postInfo;
private final TLRPC.ChatFull chat; private final TLRPC.ChatFull chat;
private boolean needDivider;
public StatisticPostInfoCell(Context context, TLRPC.ChatFull chat) { public StatisticPostInfoCell(Context context, TLRPC.ChatFull chat, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.chat = chat; this.chat = chat;
imageView = new BackupImageView(context); this.resourcesProvider = resourcesProvider;
addView(imageView, LayoutHelper.createFrame(46, 46, Gravity.START | Gravity.CENTER_VERTICAL, 12, 0, 16, 0)); imageView = new BackupImageView(context) {
@Override
protected void onDraw(Canvas canvas) {
if (postInfo != null && postInfo.isStory()) {
int pad = AndroidUtilities.dp(1);
storyAvatarParams.originalAvatarRect.set(pad, pad, getMeasuredWidth() - pad, getMeasuredHeight() - pad);
storyAvatarParams.drawSegments = false;
storyAvatarParams.animate = false;
storyAvatarParams.drawInside = true;
storyAvatarParams.isArchive = false;
storyAvatarParams.forceState = StoriesUtilities.STATE_HAS_UNREAD;
storyAvatarParams.resourcesProvider = resourcesProvider;
StoriesUtilities.drawAvatarWithStory(0, canvas, imageReceiver, storyAvatarParams);
} else {
super.onDraw(canvas);
}
}
};
setClipChildren(false);
addView(imageView, LayoutHelper.createFrame(46, 46, (!LocaleController.isRTL ? Gravity.START : Gravity.END) | Gravity.CENTER_VERTICAL, !LocaleController.isRTL ? 12 : 16, 0, !LocaleController.isRTL ? 16 : 12, 0));
LinearLayout contentLayout = new LinearLayout(context); LinearLayout contentLayout = new LinearLayout(context);
contentLayout.setOrientation(LinearLayout.VERTICAL); contentLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout linearLayout = new LinearLayout(context); LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL); linearLayout.setOrientation(LinearLayout.HORIZONTAL);
message = new TextView(context) { message = new SimpleTextView(context) {
AnimatedEmojiSpan.EmojiGroupedSpans stack;
@Override @Override
public void setText(CharSequence text, BufferType type) { public boolean setText(CharSequence value) {
super.setText(text, type); value = Emoji.replaceEmoji(value, getPaint().getFontMetricsInt(), false);
stack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, stack, getLayout()); return super.setText(value);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
stack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, this, stack, getLayout());
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
AnimatedEmojiSpan.release(this, stack);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, getLayout(), stack, 0, null, 0, 0, 0, 1f);
} }
}; };
message.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); NotificationCenter.listenEmojiLoading(message);
message.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); message.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
message.setTextSize(16);
message.setMaxLines(1);
message.setTextColor(Color.BLACK); message.setTextColor(Color.BLACK);
message.setLines(1); message.setGravity(LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT);
message.setEllipsize(TextUtils.TruncateAt.END);
views = new TextView(context); views = new TextView(context);
views.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); views.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
views.setTextColor(Color.BLACK); views.setTextColor(Color.BLACK);
if (!LocaleController.isRTL) {
linearLayout.addView(message, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1f, Gravity.NO_GRAVITY, 0, 0, 16, 0));
linearLayout.addView(views, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
} else {
linearLayout.addView(views, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
linearLayout.addView(message, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1f, Gravity.NO_GRAVITY, 16, 0, 0, 0));
}
linearLayout.addView(message, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1f, Gravity.NO_GRAVITY, 0, 0, 16, 0)); contentLayout.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, 0, 7, 0, 0));
linearLayout.addView(views, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
contentLayout.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, 0, 8, 0, 0));
date = new TextView(context); date = new TextView(context);
date.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); date.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
@ -97,47 +127,139 @@ public class StatisticPostInfoCell extends FrameLayout {
shares = new TextView(context); shares = new TextView(context);
shares.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13); shares.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
shares.setTextColor(Color.BLACK); shares.setTextColor(Color.BLACK);
shares.setGravity(Gravity.CENTER_VERTICAL);
likes = new TextView(context);
likes.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
likes.setTextColor(Color.BLACK);
likes.setGravity(Gravity.CENTER_VERTICAL);
linearLayout = new LinearLayout(context); linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL); linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.addView(date, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1f, Gravity.NO_GRAVITY, 0, 0, 8, 0)); if (!LocaleController.isRTL) {
linearLayout.addView(shares, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT)); linearLayout.addView(date, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1f, Gravity.NO_GRAVITY, 0, 0, 8, 0));
contentLayout.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, 0, 2, 0, 8)); linearLayout.addView(likes, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL));
linearLayout.addView(shares, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 10, 0, 0, 0));
} else {
linearLayout.addView(shares, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL, 0, 0, 10, 0));
linearLayout.addView(likes, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL));
linearLayout.addView(date, LayoutHelper.createLinear(0, LayoutHelper.WRAP_CONTENT, 1f, Gravity.NO_GRAVITY, 8, 0, 0, 0));
}
addView(contentLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.NO_GRAVITY, 72, 0, 12, 0)); contentLayout.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, 0, 3, 0, 9));
addView(contentLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.NO_GRAVITY, !LocaleController.isRTL ? 72 : 18, 0, !LocaleController.isRTL ? 18 : 72, 0));
message.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); message.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
views.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); views.setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
date.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3)); date.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
shares.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3)); shares.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
likes.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
Drawable likesDrawable = ContextCompat.getDrawable(context, R.drawable.mini_stats_likes).mutate();
DrawableCompat.setTint(likesDrawable, Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
Drawable sharesDrawable = ContextCompat.getDrawable(context, R.drawable.mini_stats_shares).mutate();
DrawableCompat.setTint(sharesDrawable, Theme.getColor(Theme.key_windowBackgroundWhiteGrayText3));
CombinedDrawable likesCombinedDrawable = new CombinedDrawable(null, likesDrawable, 0, dp(1));
likesCombinedDrawable.setCustomSize(sharesDrawable.getIntrinsicWidth(), sharesDrawable.getIntrinsicHeight());
likes.setCompoundDrawablesWithIntrinsicBounds(likesCombinedDrawable, null, null, null);
likes.setCompoundDrawablePadding(dp(2));
CombinedDrawable sharesCombinedDrawable = new CombinedDrawable(null, sharesDrawable, 0, dp(1));
sharesCombinedDrawable.setCustomSize(sharesDrawable.getIntrinsicWidth(), sharesDrawable.getIntrinsicHeight());
shares.setCompoundDrawablesWithIntrinsicBounds(sharesCombinedDrawable, null, null, null);
shares.setCompoundDrawablePadding(dp(2));
setWillNotDraw(false);
} }
public void setData(StatisticActivity.RecentPostInfo postInfo) { public BackupImageView getImageView() {
return imageView;
}
public StoriesUtilities.AvatarStoryParams getStoryAvatarParams() {
return storyAvatarParams;
}
public StatisticActivity.RecentPostInfo getPostInfo() {
return postInfo;
}
public void setImageViewAction(View.OnClickListener action){
imageView.setOnClickListener(action);
}
public void setData(StatisticActivity.RecentPostInfo postInfo, boolean isLast) {
this.postInfo = postInfo;
this.needDivider = !isLast;
MessageObject messageObject = postInfo.message; MessageObject messageObject = postInfo.message;
if (messageObject.photoThumbs != null) { if (messageObject.photoThumbs != null) {
TLRPC.PhotoSize size = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize()); TLRPC.PhotoSize size = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, AndroidUtilities.getPhotoSize());
TLRPC.PhotoSize thumbSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs,50); TLRPC.PhotoSize thumbSize = FileLoader.getClosestPhotoSizeWithSize(messageObject.photoThumbs, 50);
imageView.setImage( imageView.setImage(
ImageLocation.getForObject(size, messageObject.photoThumbsObject), "50_50", ImageLocation.getForObject(size, messageObject.photoThumbsObject), "50_50",
ImageLocation.getForObject(thumbSize, messageObject.photoThumbsObject), "b1", 0, messageObject); ImageLocation.getForObject(thumbSize, messageObject.photoThumbsObject), "b1", 0, messageObject);
imageView.setRoundRadius(AndroidUtilities.dp(4)); imageView.setRoundRadius(AndroidUtilities.dp(9));
imageView.setScaleX(0.96f);
imageView.setScaleY(0.96f);
} else if (chat.chat_photo.sizes.size() > 0) { } else if (chat.chat_photo.sizes.size() > 0) {
imageView.setImage(ImageLocation.getForPhoto(chat.chat_photo.sizes.get(0), chat.chat_photo), "50_50", null, null, chat); imageView.setImage(ImageLocation.getForPhoto(chat.chat_photo.sizes.get(0), chat.chat_photo), "50_50", null, null, chat);
imageView.setRoundRadius(AndroidUtilities.dp(46) >> 1); imageView.setRoundRadius(AndroidUtilities.dp(46) >> 1);
imageView.setScaleX(0.96f);
imageView.setScaleY(0.96f);
} else {
TLRPC.Chat currentChat = MessagesController.getInstance(UserConfig.selectedAccount).getChat(chat.id);
avatarDrawable.setInfo(currentChat);
imageView.setForUserOrChat(currentChat, avatarDrawable);
imageView.setRoundRadius(AndroidUtilities.dp(46) >> 1);
imageView.setScaleX(1f);
imageView.setScaleY(1f);
}
if (messageObject.isStory()) {
imageView.setScaleX(1f);
imageView.setScaleY(1f);
imageView.setRoundRadius(AndroidUtilities.dp(46) >> 1);
} }
CharSequence text; CharSequence text;
if (messageObject.isMusic()) { if (messageObject.isMusic()) {
text = String.format("%s, %s", messageObject.getMusicTitle().trim(), messageObject.getMusicAuthor().trim()); text = String.format("%s, %s", messageObject.getMusicTitle().trim(), messageObject.getMusicAuthor().trim());
} else if (messageObject.isStory()) {
text = LocaleController.getString("Story", R.string.Story);
} else { } else {
text = messageObject.caption != null ? messageObject.caption : messageObject.messageText; text = messageObject.caption != null ? messageObject.caption : messageObject.messageText;
} }
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(text == null ? "" : text);
URLSpan[] urlSpans = stringBuilder.getSpans(0, stringBuilder.length(), URLSpan.class);
for (URLSpan urlSpan : urlSpans) {
stringBuilder.removeSpan(urlSpan);
}
message.setText(AndroidUtilities.trim(AndroidUtilities.replaceNewLines(stringBuilder), null));
views.setText(String.format(LocaleController.getPluralString("Views", postInfo.getViews()), AndroidUtilities.formatWholeNumber(postInfo.getViews(), 0)));
message.setText(AndroidUtilities.trim(AndroidUtilities.replaceNewLines(new SpannableStringBuilder(text)), null)); Date time = new Date(postInfo.getDate() * 1000L);
views.setText(String.format(LocaleController.getPluralString("Views", postInfo.counters.views), AndroidUtilities.formatCount(postInfo.counters.views))); String monthTxt = LocaleController.getInstance().formatterYear.format(time);
date.setText(LocaleController.formatDateAudio(postInfo.message.messageOwner.date, false)); String timeTxt = LocaleController.getInstance().formatterDay.format(time);
shares.setText(String.format(LocaleController.getPluralString("Shares", postInfo.counters.forwards), AndroidUtilities.formatCount(postInfo.counters.forwards))); date.setText(LocaleController.formatString("formatDateAtTime", R.string.formatDateAtTime, monthTxt, timeTxt));
shares.setText(AndroidUtilities.formatWholeNumber(postInfo.getForwards(), 0));
likes.setText(AndroidUtilities.formatWholeNumber(postInfo.getReactions(), 0));
shares.setVisibility(postInfo.getForwards() != 0 ? VISIBLE : GONE);
likes.setVisibility(postInfo.getReactions() != 0 ? VISIBLE : GONE);
invalidate();
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (needDivider) {
dividerPaint.setColor(Theme.getColor(Theme.key_divider, resourcesProvider));
int paddingDp = 72;
if (LocaleController.isRTL) {
canvas.drawRect(0, getHeight() - 1, getWidth() - dp(paddingDp), getHeight(), dividerPaint);
} else {
canvas.drawRect(dp(paddingDp), getHeight() - 1, getWidth(), getHeight(), dividerPaint);
}
}
} }
public void setData(StatisticActivity.MemberData memberData) { public void setData(StatisticActivity.MemberData memberData) {
@ -149,5 +271,12 @@ public class StatisticPostInfoCell extends FrameLayout {
views.setVisibility(View.GONE); views.setVisibility(View.GONE);
shares.setVisibility(View.GONE); shares.setVisibility(View.GONE);
likes.setVisibility(View.GONE);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
storyAvatarParams.onDetachFromWindow();
} }
} }

View file

@ -15,6 +15,7 @@ import android.graphics.Paint;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
@ -31,6 +32,7 @@ import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView; import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.Switch; import org.telegram.ui.Components.Switch;
import org.telegram.ui.FilterCreateActivity;
public class TextCell extends FrameLayout { public class TextCell extends FrameLayout {
@ -255,11 +257,26 @@ public class TextCell extends FrameLayout {
textView.setTextColor(color); textView.setTextColor(color);
} }
protected int processColor(int color) {
return color;
}
public void updateColors() {
int textKey = textView.getTag() instanceof Integer ? (int) textView.getTag() : Theme.key_windowBackgroundWhiteBlackText;
textView.setTextColor(processColor(Theme.getColor(textKey, resourcesProvider)));
if (imageView.getTag() instanceof Integer) {
imageView.setColorFilter(new PorterDuffColorFilter(processColor(Theme.getColor((int) imageView.getTag(), resourcesProvider)), PorterDuff.Mode.MULTIPLY));
}
subtitleView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText, resourcesProvider)));
valueTextView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteValueText, resourcesProvider)));
valueSpoilersTextView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteValueText, resourcesProvider)));
}
public void setColors(int icon, int text) { public void setColors(int icon, int text) {
textView.setTextColor(Theme.getColor(text, resourcesProvider)); textView.setTextColor(processColor(Theme.getColor(text, resourcesProvider)));
textView.setTag(text); textView.setTag(text);
if (icon >= 0) { if (icon >= 0) {
imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(icon, resourcesProvider), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(processColor(Theme.getColor(icon, resourcesProvider)), PorterDuff.Mode.MULTIPLY));
imageView.setTag(icon); imageView.setTag(icon);
} }
} }
@ -408,7 +425,7 @@ public class TextCell extends FrameLayout {
setTextAndValueAndIcon(text, value, false, resId, divider); setTextAndValueAndIcon(text, value, false, resId, divider);
} }
public void setTextAndValueAndIcon(String text, String value, boolean animated, int resId, boolean divider) { public void setTextAndValueAndIcon(CharSequence text, String value, boolean animated, int resId, boolean divider) {
imageLeft = 21; imageLeft = 21;
offsetFromImage = getOffsetFromImage(false); offsetFromImage = getOffsetFromImage(false);
textView.setText(text); textView.setText(text);
@ -428,6 +445,15 @@ public class TextCell extends FrameLayout {
} }
} }
public static CharSequence applyNewSpan(String str) {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(str);
spannableStringBuilder.append(" d");
FilterCreateActivity.NewSpan span = new FilterCreateActivity.NewSpan(10);
span.setColor(Theme.getColor(Theme.key_premiumGradient1));
spannableStringBuilder.setSpan(span, spannableStringBuilder.length() - 1, spannableStringBuilder.length(), 0);
return spannableStringBuilder;
}
public void setColorfulIcon(int color, int resId) { public void setColorfulIcon(int color, int resId) {
offsetFromImage = getOffsetFromImage(true); offsetFromImage = getOffsetFromImage(true);
imageView.setVisibility(VISIBLE); imageView.setVisibility(VISIBLE);

View file

@ -33,7 +33,7 @@ import org.telegram.ui.Components.LinkSpanDrawable;
public class TextDetailCell extends FrameLayout { public class TextDetailCell extends FrameLayout {
private final TextView textView; private final TextView textView;
private final LinkSpanDrawable.LinksTextView valueTextView; public final LinkSpanDrawable.LinksTextView valueTextView;
private final TextView showMoreTextView = null; private final TextView showMoreTextView = null;
private final ImageView imageView; private final ImageView imageView;
private boolean needDivider; private boolean needDivider;

View file

@ -72,8 +72,12 @@ public class ThemePreviewMessagesCell extends LinearLayout {
this(context, layout, type, 0); this(context, layout, type, 0);
} }
@SuppressLint("ClickableViewAccessibility")
public ThemePreviewMessagesCell(Context context, INavigationLayout layout, int type, long dialogId) { public ThemePreviewMessagesCell(Context context, INavigationLayout layout, int type, long dialogId) {
this(context, layout, type, dialogId, null);
}
@SuppressLint("ClickableViewAccessibility")
public ThemePreviewMessagesCell(Context context, INavigationLayout layout, int type, long dialogId, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.type = type; this.type = type;
int currentAccount = UserConfig.selectedAccount; int currentAccount = UserConfig.selectedAccount;
@ -83,7 +87,7 @@ public class ThemePreviewMessagesCell extends LinearLayout {
setOrientation(LinearLayout.VERTICAL); setOrientation(LinearLayout.VERTICAL);
setPadding(0, AndroidUtilities.dp(11), 0, AndroidUtilities.dp(11)); setPadding(0, AndroidUtilities.dp(11), 0, AndroidUtilities.dp(11));
shadowDrawable = Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow); shadowDrawable = Theme.getThemedDrawableByKey(context, R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow, resourcesProvider);
int date = (int) (System.currentTimeMillis() / 1000) - 60 * 60; int date = (int) (System.currentTimeMillis() / 1000) - 60 * 60;
@ -92,10 +96,6 @@ public class ThemePreviewMessagesCell extends LinearLayout {
if (type == TYPE_PEER_COLOR) { if (type == TYPE_PEER_COLOR) {
final boolean isChannel = dialogId < 0; final boolean isChannel = dialogId < 0;
ChatActionCell actionCell = new ChatActionCell(context);
actionCell.setCustomText(LocaleController.getString(R.string.UserColorPreviewTitle));
addView(actionCell, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 2, 0, 5));
TLRPC.Message message = new TLRPC.TL_message(); TLRPC.Message message = new TLRPC.TL_message();
message.message = LocaleController.getString(isChannel ? R.string.ChannelColorPreview : R.string.UserColorPreview); message.message = LocaleController.getString(isChannel ? R.string.ChannelColorPreview : R.string.UserColorPreview);
message.reply_to = new TLRPC.TL_messageReplyHeader(); message.reply_to = new TLRPC.TL_messageReplyHeader();
@ -277,7 +277,7 @@ public class ThemePreviewMessagesCell extends LinearLayout {
} }
for (int a = 0; a < cells.length; a++) { for (int a = 0; a < cells.length; a++) {
cells[a] = new ChatMessageCell(context) { cells[a] = new ChatMessageCell(context, false, null, resourcesProvider) {
private GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { private GestureDetector gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override @Override
public boolean onDoubleTap(MotionEvent e) { public boolean onDoubleTap(MotionEvent e) {
@ -340,12 +340,15 @@ public class ThemePreviewMessagesCell extends LinearLayout {
if (getMessageObject() != null && getMessageObject().overrideLinkColor >= 0) { if (getMessageObject() != null && getMessageObject().overrideLinkColor >= 0) {
final int colorId = getMessageObject().overrideLinkColor; final int colorId = getMessageObject().overrideLinkColor;
final int color1, color2; final int color1, color2;
if (colorId >= 14) { if (getMessageObject().overrideProfilePeerColor != null) {
color1 = getMessageObject().overrideProfilePeerColor.getAvatarColor1();
color2 = getMessageObject().overrideProfilePeerColor.getAvatarColor2();
} else if (colorId >= 14) {
MessagesController messagesController = MessagesController.getInstance(UserConfig.selectedAccount); MessagesController messagesController = MessagesController.getInstance(UserConfig.selectedAccount);
MessagesController.PeerColors peerColors = messagesController != null ? messagesController.peerColors : null; MessagesController.PeerColors peerColors = messagesController != null ? messagesController.peerColors : null;
MessagesController.PeerColor peerColor = peerColors != null ? peerColors.getColor(colorId) : null; MessagesController.PeerColor peerColor = peerColors != null ? peerColors.getColor(colorId) : null;
if (peerColor != null) { if (peerColor != null) {
final int peerColorValue = messagesController.peerColors.getColor(colorId).getColor1(); final int peerColorValue = peerColor.getColor1();
color1 = getThemedColor(Theme.keys_avatar_background[AvatarDrawable.getPeerColorIndex(peerColorValue)]); color1 = getThemedColor(Theme.keys_avatar_background[AvatarDrawable.getPeerColorIndex(peerColorValue)]);
color2 = getThemedColor(Theme.keys_avatar_background2[AvatarDrawable.getPeerColorIndex(peerColorValue)]); color2 = getThemedColor(Theme.keys_avatar_background2[AvatarDrawable.getPeerColorIndex(peerColorValue)]);
} else { } else {
@ -437,9 +440,16 @@ public class ThemePreviewMessagesCell extends LinearLayout {
} }
} }
private Drawable overrideDrawable;
public void setOverrideBackground(Drawable drawable) {
overrideDrawable = drawable;
invalidate();
}
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
Drawable newDrawable = Theme.getCachedWallpaperNonBlocking(); Drawable newDrawable = overrideDrawable != null ? overrideDrawable : Theme.getCachedWallpaperNonBlocking();
if (Theme.wallpaperLoadTask != null) { if (Theme.wallpaperLoadTask != null) {
invalidate(); invalidate();
} }

View file

@ -505,14 +505,14 @@ public class UserCell extends FrameLayout implements NotificationCenter.Notifica
((LayoutParams) nameTextView.getLayoutParams()).topMargin = AndroidUtilities.dp(19); ((LayoutParams) nameTextView.getLayoutParams()).topMargin = AndroidUtilities.dp(19);
return; return;
} }
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(currentAccount, currentUser);
if (currentUser.status != null) { if (currentUser.status != null) {
lastStatus = currentUser.status.expires; lastStatus = currentUser.status.expires;
} else { } else {
lastStatus = 0; lastStatus = 0;
} }
} else if (currentChat != null) { } else if (currentChat != null) {
avatarDrawable.setInfo(currentChat); avatarDrawable.setInfo(currentAccount, currentChat);
} else if (currentName != null) { } else if (currentName != null) {
avatarDrawable.setInfo(currentId, currentName.toString(), null); avatarDrawable.setInfo(currentId, currentName.toString(), null);
} else { } else {

View file

@ -228,14 +228,14 @@ public class UserCell2 extends FrameLayout {
lastAvatar = photo; lastAvatar = photo;
if (currentUser != null) { if (currentUser != null) {
avatarDrawable.setInfo(currentUser); avatarDrawable.setInfo(currentAccount, currentUser);
if (currentUser.status != null) { if (currentUser.status != null) {
lastStatus = currentUser.status.expires; lastStatus = currentUser.status.expires;
} else { } else {
lastStatus = 0; lastStatus = 0;
} }
} else if (currentChat != null) { } else if (currentChat != null) {
avatarDrawable.setInfo(currentChat); avatarDrawable.setInfo(currentAccount, currentChat);
} else if (currentName != null) { } else if (currentName != null) {
avatarDrawable.setInfo(currentId, currentName.toString(), null); avatarDrawable.setInfo(currentId, currentName.toString(), null);
} else { } else {

View file

@ -2090,6 +2090,9 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
} else if (view instanceof ChatActionCell) { } else if (view instanceof ChatActionCell) {
ChatActionCell cell = (ChatActionCell) view; ChatActionCell cell = (ChatActionCell) view;
cell.setVisiblePart(view.getY() + actionBar.getMeasuredHeight() - contentView.getBackgroundTranslationY(), contentView.getBackgroundSizeY()); cell.setVisiblePart(view.getY() + actionBar.getMeasuredHeight() - contentView.getBackgroundTranslationY(), contentView.getBackgroundSizeY());
if (cell.hasGradientService()) {
cell.invalidate();
}
} }
if (view.getBottom() <= chatListView.getPaddingTop()) { if (view.getBottom() <= chatListView.getPaddingTop()) {
continue; continue;

View file

@ -62,6 +62,7 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
private final static int BOTTOM_SIGNATURE_OFFSET = AndroidUtilities.dp(10); private final static int BOTTOM_SIGNATURE_OFFSET = AndroidUtilities.dp(10);
private final static int DP_12 = AndroidUtilities.dp(12); private final static int DP_12 = AndroidUtilities.dp(12);
private final static int DP_8 = AndroidUtilities.dp(8);
private final static int DP_6 = AndroidUtilities.dp(6); private final static int DP_6 = AndroidUtilities.dp(6);
private final static int DP_5 = AndroidUtilities.dp(5); private final static int DP_5 = AndroidUtilities.dp(5);
private final static int DP_2 = AndroidUtilities.dp(2); private final static int DP_2 = AndroidUtilities.dp(2);
@ -223,9 +224,15 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
private float startFromMaxH; private float startFromMaxH;
private float startFromMinH; private float startFromMinH;
private float minMaxUpdateStep; private float minMaxUpdateStep;
protected Theme.ResourcesProvider resourcesProvider;
public BaseChartView(Context context) { public BaseChartView(Context context) {
this(context, null);
}
public BaseChartView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.resourcesProvider = resourcesProvider;
init(); init();
touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
} }
@ -259,23 +266,23 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
} }
protected LegendSignatureView createLegendView() { protected LegendSignatureView createLegendView() {
return new LegendSignatureView(getContext()); return new LegendSignatureView(getContext(), resourcesProvider);
} }
public void updateColors() { public void updateColors() {
if (useAlphaSignature) { if (useAlphaSignature) {
signaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignatureAlpha)); signaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignatureAlpha, resourcesProvider));
} else { } else {
signaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignature)); signaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignature, resourcesProvider));
} }
bottomSignaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignature)); bottomSignaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignature, resourcesProvider));
linePaint.setColor(Theme.getColor(Theme.key_statisticChartHintLine)); linePaint.setColor(Theme.getColor(Theme.key_statisticChartHintLine, resourcesProvider));
selectedLinePaint.setColor(Theme.getColor(Theme.key_statisticChartActiveLine)); selectedLinePaint.setColor(Theme.getColor(Theme.key_statisticChartActiveLine, resourcesProvider));
pickerSelectorPaint.setColor(Theme.getColor(Theme.key_statisticChartActivePickerChart)); pickerSelectorPaint.setColor(Theme.getColor(Theme.key_statisticChartActivePickerChart, resourcesProvider));
unactiveBottomChartPaint.setColor(Theme.getColor(Theme.key_statisticChartInactivePickerChart)); unactiveBottomChartPaint.setColor(Theme.getColor(Theme.key_statisticChartInactivePickerChart, resourcesProvider));
selectionBackgroundPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite)); selectionBackgroundPaint.setColor(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
ripplePaint.setColor(Theme.getColor(Theme.key_statisticChartRipple)); ripplePaint.setColor(Theme.getColor(Theme.key_statisticChartRipple, resourcesProvider));
legendSignatureView.recolor(); legendSignatureView.recolor();
hintLinePaintAlpha = linePaint.getAlpha(); hintLinePaintAlpha = linePaint.getAlpha();
@ -726,13 +733,13 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
canvas.drawPath(RoundedRect(pathTmp, pickerRect.left, canvas.drawPath(RoundedRect(pathTmp, pickerRect.left,
pickerRect.top - DP_1, pickerRect.top - DP_1,
pickerRect.left + DP_12, pickerRect.left + DP_12,
pickerRect.bottom + DP_1, DP_6, DP_6, pickerRect.bottom + DP_1, DP_8, DP_8,
true, false, false, true), pickerSelectorPaint); true, false, false, true), pickerSelectorPaint);
canvas.drawPath(RoundedRect(pathTmp, pickerRect.right - DP_12, canvas.drawPath(RoundedRect(pathTmp, pickerRect.right - DP_12,
pickerRect.top - DP_1, pickerRect.right, pickerRect.top - DP_1, pickerRect.right,
pickerRect.bottom + DP_1, DP_6, DP_6, pickerRect.bottom + DP_1, DP_8, DP_8,
false, true, true, false), pickerSelectorPaint); false, true, true, false), pickerSelectorPaint);
canvas.drawRect(pickerRect.left + DP_12, canvas.drawRect(pickerRect.left + DP_12,
@ -1589,10 +1596,16 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
private RectF rectF = new RectF(); private RectF rectF = new RectF();
private Paint xRefP = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint xRefP = new Paint(Paint.ANTI_ALIAS_FLAG);
private Theme.ResourcesProvider resourcesProvider;
public SharedUiComponents() { public SharedUiComponents() {
this(null);
}
public SharedUiComponents(Theme.ResourcesProvider resourcesProvider) {
xRefP.setColor(0); xRefP.setColor(0);
xRefP.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); xRefP.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
this.resourcesProvider = resourcesProvider;
} }
int k = 0; int k = 0;
@ -1606,8 +1619,8 @@ public abstract class BaseChartView<T extends ChartData, L extends LineViewData>
canvas = new Canvas(pickerRoundBitmap); canvas = new Canvas(pickerRoundBitmap);
rectF.set(0, 0, w, h); rectF.set(0, 0, w, h);
canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite)); canvas.drawColor(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider));
canvas.drawRoundRect(rectF, AndroidUtilities.dp(4), AndroidUtilities.dp(4), xRefP); canvas.drawRoundRect(rectF, AndroidUtilities.dp(6), AndroidUtilities.dp(6), xRefP);
} }

View file

@ -14,7 +14,11 @@ import org.telegram.ui.Charts.view_data.LineViewData;
public class DoubleLinearChartView extends BaseChartView<DoubleLinearChartData, LineViewData> { public class DoubleLinearChartView extends BaseChartView<DoubleLinearChartData, LineViewData> {
public DoubleLinearChartView(Context context) { public DoubleLinearChartView(Context context) {
super(context); this(context, null);
}
public DoubleLinearChartView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, resourcesProvider);
} }
@Override @Override
@ -240,7 +244,7 @@ public class DoubleLinearChartView extends BaseChartView<DoubleLinearChartData,
int y = (int) ((getMeasuredHeight() - chartBottom) - chartHeight * ((a.values[i] - currentMinHeight) / (currentMaxHeight - currentMinHeight))); int y = (int) ((getMeasuredHeight() - chartBottom) - chartHeight * ((a.values[i] - currentMinHeight) / (currentMaxHeight - currentMinHeight)));
if (a.valuesStr != null && lines.size() > 0) { if (a.valuesStr != null && lines.size() > 0) {
if (a.valuesStr2 == null || lines.size() < 2) { if (a.valuesStr2 == null || lines.size() < 2) {
signaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignature)); signaturePaint.setColor(Theme.getColor(Theme.key_statisticChartSignature, resourcesProvider));
signaturePaint.setAlpha((int) (a.alpha * signaturePaintAlpha * transitionAlpha * additionalOutAlpha)); signaturePaint.setAlpha((int) (a.alpha * signaturePaintAlpha * transitionAlpha * additionalOutAlpha));
} else { } else {
signaturePaint.setColor(lines.get(leftIndex).lineColor); signaturePaint.setColor(lines.get(leftIndex).lineColor);
@ -259,7 +263,7 @@ public class DoubleLinearChartView extends BaseChartView<DoubleLinearChartData,
@Override @Override
public LineViewData createLineViewData(ChartData.Line line) { public LineViewData createLineViewData(ChartData.Line line) {
return new LineViewData(line); return new LineViewData(line, resourcesProvider);
} }
public int findMaxValue(int startXIndex, int endXIndex) { public int findMaxValue(int startXIndex, int endXIndex) {

View file

@ -8,6 +8,7 @@ import android.graphics.Paint;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.SegmentTree; import org.telegram.messenger.SegmentTree;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Charts.data.ChartData; import org.telegram.ui.Charts.data.ChartData;
import org.telegram.ui.Charts.data.StackBarChartData; import org.telegram.ui.Charts.data.StackBarChartData;
import org.telegram.ui.Charts.view_data.LineViewData; import org.telegram.ui.Charts.view_data.LineViewData;
@ -18,14 +19,18 @@ public class StackBarChartView extends BaseChartView<StackBarChartData, StackBar
private int[] yMaxPoints; private int[] yMaxPoints;
public StackBarChartView(Context context) { public StackBarChartView(Context context) {
super(context); this(context, null);
}
public StackBarChartView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, resourcesProvider);
superDraw = true; superDraw = true;
useAlphaSignature = true; useAlphaSignature = true;
} }
@Override @Override
public StackBarViewData createLineViewData(ChartData.Line line) { public StackBarViewData createLineViewData(ChartData.Line line) {
return new StackBarViewData(line); return new StackBarViewData(line, resourcesProvider);
} }
@Override @Override

View file

@ -37,9 +37,15 @@ public class ChartHeaderView extends FrameLayout {
SimpleDateFormat formatter = new SimpleDateFormat("d MMM yyyy"); SimpleDateFormat formatter = new SimpleDateFormat("d MMM yyyy");
int textMargin; int textMargin;
private Theme.ResourcesProvider resourcesProvider;
public ChartHeaderView(Context context) { public ChartHeaderView(Context context) {
this(context, null);
}
public ChartHeaderView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.resourcesProvider = resourcesProvider;
TextPaint textPaint = new TextPaint(); TextPaint textPaint = new TextPaint();
textPaint.setTextSize(14); textPaint.setTextSize(14);
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
@ -76,7 +82,7 @@ public class ChartHeaderView extends FrameLayout {
back.setCompoundDrawablesWithIntrinsicBounds(zoomIcon, null, null, null); back.setCompoundDrawablesWithIntrinsicBounds(zoomIcon, null, null, null);
back.setCompoundDrawablePadding(AndroidUtilities.dp(4)); back.setCompoundDrawablePadding(AndroidUtilities.dp(4));
back.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(4), AndroidUtilities.dp(8), AndroidUtilities.dp(4)); back.setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(4), AndroidUtilities.dp(8), AndroidUtilities.dp(4));
back.setBackground(Theme.getRoundRectSelectorDrawable(Theme.getColor(Theme.key_featuredStickers_removeButtonText))); back.setBackground(Theme.getRoundRectSelectorDrawable(Theme.getColor(Theme.key_featuredStickers_removeButtonText, resourcesProvider)));
datesTmp.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> { datesTmp.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
datesTmp.setPivotX(datesTmp.getMeasuredWidth() * 0.7f); datesTmp.setPivotX(datesTmp.getMeasuredWidth() * 0.7f);
@ -87,11 +93,11 @@ public class ChartHeaderView extends FrameLayout {
public void recolor() { public void recolor() {
title.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); title.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
dates.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); dates.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
datesTmp.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); datesTmp.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
back.setTextColor(Theme.getColor(Theme.key_statisticChartBackZoomColor)); back.setTextColor(Theme.getColor(Theme.key_statisticChartBackZoomColor, resourcesProvider));
zoomIcon.setColorFilter(Theme.getColor(Theme.key_statisticChartBackZoomColor), PorterDuff.Mode.SRC_IN); zoomIcon.setColorFilter(Theme.getColor(Theme.key_statisticChartBackZoomColor, resourcesProvider), PorterDuff.Mode.SRC_IN);
} }
public void setDates(long start, long end) { public void setDates(long start, long end) {
@ -105,9 +111,9 @@ public class ChartHeaderView extends FrameLayout {
} }
final String newText; final String newText;
if (end - start >= 86400000L) { if (end - start >= 86400000L) {
newText = formatter.format(new Date(start)) + "" + formatter.format(new Date(end)); newText = LocaleController.getInstance().formatterYear.format(new Date(start)) + "" + LocaleController.getInstance().formatterYear.format(new Date(end));
} else { } else {
newText = formatter.format(new Date(start)); newText = LocaleController.getInstance().formatterYear.format(new Date(start));
} }
dates.setText(newText); dates.setText(newText);

View file

@ -56,6 +56,7 @@ public class LegendSignatureView extends FrameLayout {
Drawable shadowDrawable; Drawable shadowDrawable;
Drawable backgroundDrawable; Drawable backgroundDrawable;
private Theme.ResourcesProvider resourcesProvider;
Runnable showProgressRunnable = new Runnable() { Runnable showProgressRunnable = new Runnable() {
@Override @Override
@ -72,7 +73,12 @@ public class LegendSignatureView extends FrameLayout {
}; };
public LegendSignatureView(Context context) { public LegendSignatureView(Context context) {
this(context, null);
}
public LegendSignatureView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
this.resourcesProvider = resourcesProvider;
setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8)); setPadding(AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8), AndroidUtilities.dp(8));
content = new LinearLayout(getContext()); content = new LinearLayout(getContext());
content.setOrientation(LinearLayout.VERTICAL); content.setOrientation(LinearLayout.VERTICAL);
@ -102,13 +108,13 @@ public class LegendSignatureView extends FrameLayout {
} }
public void recolor() { public void recolor() {
time.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); time.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
hourTime.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); hourTime.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
chevron.setColorFilter(Theme.getColor(Theme.key_statisticChartChevronColor)); chevron.setColorFilter(Theme.getColor(Theme.key_statisticChartChevronColor, resourcesProvider));
progressView.setProgressColor(Theme.getColor(Theme.key_statisticChartChevronColor)); progressView.setProgressColor(Theme.getColor(Theme.key_statisticChartChevronColor, resourcesProvider));
shadowDrawable = getContext().getResources().getDrawable(R.drawable.stats_tooltip).mutate(); shadowDrawable = getContext().getResources().getDrawable(R.drawable.stats_tooltip).mutate();
backgroundDrawable = Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_dialogBackground), Theme.getColor(Theme.key_listSelector), 0xff000000); backgroundDrawable = Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), Theme.getColor(Theme.key_dialogBackground, resourcesProvider), Theme.getColor(Theme.key_listSelector, resourcesProvider), 0xff000000);
CombinedDrawable drawable = new CombinedDrawable(shadowDrawable, backgroundDrawable, AndroidUtilities.dp(3), AndroidUtilities.dp(3)); CombinedDrawable drawable = new CombinedDrawable(shadowDrawable, backgroundDrawable, AndroidUtilities.dp(3), AndroidUtilities.dp(3));
drawable.setFullsize(true); drawable.setFullsize(true);
setBackground(drawable); setBackground(drawable);
@ -169,15 +175,15 @@ public class LegendSignatureView extends FrameLayout {
h.value.setText(formatWholeNumber(l.y[index])); h.value.setText(formatWholeNumber(l.y[index]));
h.signature.setText(l.name); h.signature.setText(l.name);
if (l.colorKey >= 0 && Theme.hasThemeKey(l.colorKey)) { if (l.colorKey >= 0 && Theme.hasThemeKey(l.colorKey)) {
h.value.setTextColor(Theme.getColor(l.colorKey)); h.value.setTextColor(Theme.getColor(l.colorKey, resourcesProvider));
} else { } else {
h.value.setTextColor(Theme.getCurrentTheme().isDark() ? l.colorDark : l.color); h.value.setTextColor(Theme.getCurrentTheme().isDark() ? l.colorDark : l.color);
} }
h.signature.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); h.signature.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
if (showPercentage && h.percentage != null) { if (showPercentage && h.percentage != null) {
h.percentage.setVisibility(VISIBLE); h.percentage.setVisibility(VISIBLE);
h.percentage.setTextColor(Theme.getColor(Theme.key_dialogTextBlack)); h.percentage.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
float v = lines.get(i).line.y[index] / (float) sum; float v = lines.get(i).line.y[index] / (float) sum;
if (v < 0.1f && v != 0f) { if (v < 0.1f && v != 0f) {
h.percentage.setText(String.format(Locale.ENGLISH, "%.1f%s", (100f * v), "%")); h.percentage.setText(String.format(Locale.ENGLISH, "%.1f%s", (100f * v), "%"));

View file

@ -35,7 +35,14 @@ public class LineViewData {
public float alpha = 1f; public float alpha = 1f;
private Theme.ResourcesProvider resourcesProvider;
public LineViewData(ChartData.Line line) { public LineViewData(ChartData.Line line) {
this(line, null);
}
public LineViewData(ChartData.Line line, Theme.ResourcesProvider resourcesProvider) {
this.resourcesProvider = resourcesProvider;
this.line = line; this.line = line;
paint.setStrokeWidth(AndroidUtilities.dpf2(2)); paint.setStrokeWidth(AndroidUtilities.dpf2(2));
@ -61,9 +68,9 @@ public class LineViewData {
public void updateColors() { public void updateColors() {
if (line.colorKey >= 0 && Theme.hasThemeKey(line.colorKey)) { if (line.colorKey >= 0 && Theme.hasThemeKey(line.colorKey)) {
lineColor = Theme.getColor(line.colorKey); lineColor = Theme.getColor(line.colorKey, resourcesProvider);
} else { } else {
int color = Theme.getColor(Theme.key_windowBackgroundWhite); int color = Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider);
boolean darkBackground = ColorUtils.calculateLuminance(color) < 0.5f; boolean darkBackground = ColorUtils.calculateLuminance(color) < 0.5f;
lineColor = darkBackground ? line.colorDark : line.color; lineColor = darkBackground ? line.colorDark : line.color;
} }

View file

@ -13,13 +13,20 @@ public class StackBarViewData extends LineViewData {
public final Paint unselectedPaint = new Paint(); public final Paint unselectedPaint = new Paint();
public int blendColor = 0; public int blendColor = 0;
private Theme.ResourcesProvider resourcesProvider;
public void updateColors() { public void updateColors() {
super.updateColors(); super.updateColors();
blendColor = ColorUtils.blendARGB(Theme.getColor(Theme.key_windowBackgroundWhite),lineColor,0.3f); blendColor = ColorUtils.blendARGB(Theme.getColor(Theme.key_windowBackgroundWhite, resourcesProvider),lineColor,0.3f);
} }
public StackBarViewData(ChartData.Line line) { public StackBarViewData(ChartData.Line line) {
this(line, null);
}
public StackBarViewData(ChartData.Line line, Theme.ResourcesProvider resourcesProvider) {
super(line); super(line);
this.resourcesProvider = resourcesProvider;
paint.setStrokeWidth(AndroidUtilities.dpf2(1)); paint.setStrokeWidth(AndroidUtilities.dpf2(1));
paint.setStyle(Paint.Style.STROKE); paint.setStyle(Paint.Style.STROKE);
unselectedPaint.setStyle(Paint.Style.STROKE); unselectedPaint.setStyle(Paint.Style.STROKE);

File diff suppressed because it is too large Load diff

View file

@ -138,6 +138,9 @@ public class ChatBackgroundDrawable extends Drawable {
public static Drawable createThumb(TLRPC.WallPaper wallPaper) { public static Drawable createThumb(TLRPC.WallPaper wallPaper) {
Drawable thumb = null; Drawable thumb = null;
if (wallPaper.thumbDrawable != null) {
return wallPaper.thumbDrawable;
}
if (wallPaper.stripedThumb != null) { if (wallPaper.stripedThumb != null) {
return new BitmapDrawable(wallPaper.stripedThumb); return new BitmapDrawable(wallPaper.stripedThumb);
} }
@ -171,7 +174,7 @@ public class ChatBackgroundDrawable extends Drawable {
} }
} }
} }
return thumb; return wallPaper.thumbDrawable = thumb;
} }
private static Drawable bitmapDrawableOf(Drawable drawable) { private static Drawable bitmapDrawableOf(Drawable drawable) {
@ -205,6 +208,13 @@ public class ChatBackgroundDrawable extends Drawable {
} }
} }
public float getDimAmount() {
if (motionBackgroundDrawable == null) {
return dimAmount;
}
return 0;
}
@Override @Override
public void setAlpha(int alpha) { public void setAlpha(int alpha) {
if (this.alpha != alpha) { if (this.alpha != alpha) {
@ -255,16 +265,18 @@ public class ChatBackgroundDrawable extends Drawable {
} }
} }
public Drawable getDrawable() { public Drawable getDrawable(boolean prioritizeThumb) {
if (motionBackgroundDrawable != null) { if (motionBackgroundDrawable != null) {
return motionBackgroundDrawable; return motionBackgroundDrawable;
} }
if (imageReceiver.getStaticThumb() != null) { if (prioritizeThumb && imageReceiver.getStaticThumb() != null) {
return imageReceiver.getStaticThumb(); return imageReceiver.getStaticThumb();
} else if (imageReceiver.getThumb() != null) { } else if (imageReceiver.getThumb() != null) {
return imageReceiver.getThumb(); return imageReceiver.getThumb();
} else { } else if (imageReceiver.getDrawable() != null) {
return imageReceiver.getDrawable(); return imageReceiver.getDrawable();
} else {
return imageReceiver.getStaticThumb();
} }
} }

View file

@ -75,6 +75,7 @@ import org.telegram.ui.Cells.TextDetailCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell; import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.TextSettingsCell; import org.telegram.ui.Cells.TextSettingsCell;
import org.telegram.ui.Components.AlertsCreator; import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AvatarDrawable; import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView; import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.BulletinFactory; import org.telegram.ui.Components.BulletinFactory;
@ -86,6 +87,8 @@ import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable; import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RadialProgressView; import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.Reactions.ChatCustomReactionsEditActivity;
import org.telegram.ui.Components.Reactions.ReactionsUtils;
import org.telegram.ui.Components.SizeNotifierFrameLayout; import org.telegram.ui.Components.SizeNotifierFrameLayout;
import org.telegram.ui.Components.UndoView; import org.telegram.ui.Components.UndoView;
@ -177,6 +180,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
private final static int done_button = 1; private final static int done_button = 1;
private boolean hasUploadedPhoto; private boolean hasUploadedPhoto;
private final List<AnimatedEmojiDrawable> preloadedReactions = new ArrayList<>();
private PhotoViewer.PhotoViewerProvider provider = new PhotoViewer.EmptyPhotoViewerProvider() { private PhotoViewer.PhotoViewerProvider provider = new PhotoViewer.EmptyPhotoViewerProvider() {
@ -397,6 +401,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
ReactionsUtils.stopPreloadReactions(preloadedReactions);
if (nameTextView != null) { if (nameTextView != null) {
nameTextView.onPause(); nameTextView.onPause();
} }
@ -883,7 +888,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
} }
if (ChatObject.isChannelAndNotMegaGroup(currentChat) && ChatObject.canChangeChatInfo(currentChat)) { if (ChatObject.isChannelAndNotMegaGroup(currentChat) && ChatObject.canChangeChatInfo(currentChat)) {
colorCell = new PeerColorActivity.ChangeNameColorCell(true, context, getResourceProvider()); colorCell = new PeerColorActivity.ChangeNameColorCell(currentAccount, true, context, getResourceProvider());
colorCell.setBackgroundDrawable(Theme.getSelectorDrawable(true)); colorCell.setBackgroundDrawable(Theme.getSelectorDrawable(true));
typeEditContainer.addView(colorCell, LayoutHelper.createLinear(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); typeEditContainer.addView(colorCell, LayoutHelper.createLinear(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
colorCell.setOnClickListener(v -> { colorCell.setOnClickListener(v -> {
@ -1029,11 +1034,15 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
reactionsCell = new TextCell(context); reactionsCell = new TextCell(context);
reactionsCell.setBackground(Theme.getSelectorDrawable(false)); reactionsCell.setBackground(Theme.getSelectorDrawable(false));
reactionsCell.setOnClickListener(v -> { reactionsCell.setOnClickListener(v -> {
Bundle args = new Bundle(); if (ChatObject.isChannelAndNotMegaGroup(currentChat)) {
args.putLong(ChatReactionsEditActivity.KEY_CHAT_ID, chatId); presentFragment(new ChatCustomReactionsEditActivity(chatId, info));
ChatReactionsEditActivity reactionsEditActivity = new ChatReactionsEditActivity(args); } else {
reactionsEditActivity.setInfo(info); Bundle args = new Bundle();
presentFragment(reactionsEditActivity); args.putLong(ChatReactionsEditActivity.KEY_CHAT_ID, chatId);
ChatReactionsEditActivity reactionsEditActivity = new ChatReactionsEditActivity(args);
reactionsEditActivity.setInfo(info);
presentFragment(reactionsEditActivity);
}
}); });
adminCell = new TextCell(context); adminCell = new TextCell(context);
@ -1632,8 +1641,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
getParentLayout().removeFragmentFromStack(i); getParentLayout().removeFragmentFromStack(i);
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putLong("chat_id",chatId); bundle.putLong("chat_id",chatId);
TopicsFragment topicsFragment = new TopicsFragment(bundle); getParentLayout().addFragmentToStack(TopicsFragment.getTopicsOrChat(this, bundle), i);
getParentLayout().addFragmentToStack(topicsFragment, i);
} }
} }
} }
@ -1737,6 +1745,8 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
} }
historyHidden = !ChatObject.isChannel(currentChat) || info.hidden_prehistory; historyHidden = !ChatObject.isChannel(currentChat) || info.hidden_prehistory;
availableReactions = info.available_reactions; availableReactions = info.available_reactions;
preloadedReactions.clear();
preloadedReactions.addAll(ReactionsUtils.startPreloadReactions(currentChat, info));
} }
} }
@ -1995,6 +2005,7 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
} }
private void updateReactionsCell(boolean animated) { private void updateReactionsCell(boolean animated) {
boolean isChannelAndNotMegaGroup = ChatObject.isChannelAndNotMegaGroup(currentChat);
String finalString; String finalString;
if (availableReactions == null || availableReactions instanceof TLRPC.TL_chatReactionsNone) { if (availableReactions == null || availableReactions instanceof TLRPC.TL_chatReactionsNone) {
finalString = LocaleController.getString("ReactionsOff", R.string.ReactionsOff); finalString = LocaleController.getString("ReactionsOff", R.string.ReactionsOff);
@ -2009,17 +2020,25 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
if (reaction != null && !reaction.inactive) { if (reaction != null && !reaction.inactive) {
count++; count++;
} }
} else if (someReaction instanceof TLRPC.TL_reactionCustomEmoji) {
count++;
} }
} }
int reacts = Math.min(getMediaDataController().getEnabledReactionsList().size(), count); if (isChannelAndNotMegaGroup) {
finalString = reacts == 0 ? LocaleController.getString("ReactionsOff", R.string.ReactionsOff) : finalString = count == 0 ? LocaleController.getString("ReactionsOff", R.string.ReactionsOff) : String.valueOf(count);
LocaleController.formatString("ReactionsCount", R.string.ReactionsCount, reacts, getMediaDataController().getEnabledReactionsList().size()); } else {
int reacts = Math.min(getMediaDataController().getEnabledReactionsList().size(), count);
finalString = reacts == 0 ? LocaleController.getString("ReactionsOff", R.string.ReactionsOff) :
LocaleController.formatString("ReactionsCount", R.string.ReactionsCount, reacts, getMediaDataController().getEnabledReactionsList().size());
}
} else { } else {
finalString = LocaleController.getString("ReactionsAll", R.string.ReactionsAll); finalString = LocaleController.getString("ReactionsAll", R.string.ReactionsAll);
} }
if (isChannelAndNotMegaGroup) {
reactionsCell.setTextAndValueAndIcon(TextCell.applyNewSpan(LocaleController.getString("Reactions", R.string.Reactions)), finalString, animated, R.drawable.msg_reactions2, true);
reactionsCell.setTextAndValueAndIcon(LocaleController.getString("Reactions", R.string.Reactions), finalString, animated, R.drawable.msg_reactions2, true); } else {
reactionsCell.setTextAndValueAndIcon(LocaleController.getString("Reactions", R.string.Reactions), finalString, animated, R.drawable.msg_reactions2, true);
}
} }
@Override @Override
@ -2126,6 +2145,12 @@ public class ChatEditActivity extends BaseFragment implements ImageUpdater.Image
themeDescriptions.add(new ThemeDescription(reactionsCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText)); themeDescriptions.add(new ThemeDescription(reactionsCell, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(reactionsCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon)); themeDescriptions.add(new ThemeDescription(reactionsCell, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
if (statsAndBoosts != null) {
themeDescriptions.add(new ThemeDescription(statsAndBoosts, ThemeDescription.FLAG_SELECTOR, null, null, null, null, Theme.key_listSelector));
themeDescriptions.add(new ThemeDescription(statsAndBoosts, ThemeDescription.FLAG_TEXTCOLOR, new Class[]{TextCell.class}, new String[]{"textView"}, null, null, null, Theme.key_windowBackgroundWhiteBlackText));
themeDescriptions.add(new ThemeDescription(statsAndBoosts, 0, new Class[]{TextCell.class}, new String[]{"imageView"}, null, null, null, Theme.key_windowBackgroundWhiteGrayIcon));
}
return themeDescriptions; return themeDescriptions;
} }
} }

View file

@ -541,7 +541,7 @@ public class ChatLinkActivity extends BaseFragment implements NotificationCenter
frameLayout2.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 11, (LocaleController.isRTL ? 76 : 21), 0)); frameLayout2.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 11, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout2.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 9)); frameLayout2.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 9));
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(currentAccount, chat);
imageView.setForUserOrChat(chat, avatarDrawable); imageView.setForUserOrChat(chat, avatarDrawable);
builder.setPositiveButton(LocaleController.getString("DiscussionLinkGroup", R.string.DiscussionLinkGroup), (dialogInterface, i) -> { builder.setPositiveButton(LocaleController.getString("DiscussionLinkGroup", R.string.DiscussionLinkGroup), (dialogInterface, i) -> {
if (chatFull.hidden_prehistory) { if (chatFull.hidden_prehistory) {

View file

@ -5,7 +5,6 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint; import android.graphics.Paint;
import android.graphics.Path; import android.graphics.Path;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
@ -14,13 +13,10 @@ import android.graphics.RectF;
import android.text.Layout; import android.text.Layout;
import android.text.StaticLayout; import android.text.StaticLayout;
import android.text.TextPaint; import android.text.TextPaint;
import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AccountInstance; import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.DialogObject; import org.telegram.messenger.DialogObject;
@ -130,7 +126,7 @@ public class ChatPullingDownDrawable implements NotificationCenter.NotificationC
MessagesController.getInstance(currentAccount).getChat(dialog.id); MessagesController.getInstance(currentAccount).getChat(dialog.id);
} }
AvatarDrawable avatarDrawable = new AvatarDrawable(); AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setInfo(nextChat); avatarDrawable.setInfo(currentAccount, nextChat);
imageReceiver.setImage(ImageLocation.getForChat(nextChat, ImageLocation.TYPE_SMALL), "50_50", avatarDrawable, null, UserConfig.getInstance(0).getCurrentUser(), 0); imageReceiver.setImage(ImageLocation.getForChat(nextChat, ImageLocation.TYPE_SMALL), "50_50", avatarDrawable, null, UserConfig.getInstance(0).getCurrentUser(), 0);
MessagesController.getInstance(currentAccount).ensureMessagesLoaded(dialog.id, 0, null); MessagesController.getInstance(currentAccount).ensureMessagesLoaded(dialog.id, 0, null);
counterDrawable.setCount(dialog.unread_count, false); counterDrawable.setCount(dialog.unread_count, false);

View file

@ -8,6 +8,8 @@
package org.telegram.ui; package org.telegram.ui;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.app.TimePickerDialog; import android.app.TimePickerDialog;
@ -1322,6 +1324,14 @@ public class ChatRightsEditActivity extends BaseFragment {
} }
}, err -> { }, err -> {
setLoading(false); setLoading(false);
if (err != null && "USER_PRIVACY_RESTRICTED".equals(err.text)) {
LimitReachedBottomSheet restrictedUsersBottomSheet = new LimitReachedBottomSheet(ChatRightsEditActivity.this, getParentActivity(), LimitReachedBottomSheet.TYPE_ADD_MEMBERS_RESTRICTED, currentAccount, getResourceProvider());
ArrayList<TLRPC.User> arrayList = new ArrayList<>();
arrayList.add(currentUser);
restrictedUsersBottomSheet.setRestrictedUsers(currentChat, arrayList);
restrictedUsersBottomSheet.show();
return false;
}
return true; return true;
}); });
} else if (currentType == TYPE_BANNED) { } else if (currentType == TYPE_BANNED) {
@ -1400,19 +1410,26 @@ public class ChatRightsEditActivity extends BaseFragment {
private ValueAnimator doneDrawableAnimator; private ValueAnimator doneDrawableAnimator;
public void setLoading(boolean enable) { public void setLoading(boolean newLoading) {
if (doneDrawableAnimator != null) { if (doneDrawableAnimator != null) {
doneDrawableAnimator.cancel(); doneDrawableAnimator.cancel();
} }
loading = !enable; loading = newLoading;
actionBar.getBackButton().setEnabled(!enable); actionBar.getBackButton().setEnabled(!loading);
if (doneDrawable != null) { if (doneDrawable != null) {
doneDrawableAnimator = ValueAnimator.ofFloat(doneDrawable.getProgress(), enable ? 1f : 0f); doneDrawableAnimator = ValueAnimator.ofFloat(doneDrawable.getProgress(), loading ? 1f : 0f);
doneDrawableAnimator.addUpdateListener(a -> { doneDrawableAnimator.addUpdateListener(a -> {
doneDrawable.setProgress((float) a.getAnimatedValue()); doneDrawable.setProgress((float) a.getAnimatedValue());
doneDrawable.invalidateSelf(); doneDrawable.invalidateSelf();
}); });
doneDrawableAnimator.setDuration((long) (150 * Math.abs(doneDrawable.getProgress() - (enable ? 1 : 0)))); doneDrawableAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
doneDrawable.setProgress(loading ? 1 : 0);
doneDrawable.invalidateSelf();
}
});
doneDrawableAnimator.setDuration((long) (150 * Math.abs(doneDrawable.getProgress() - (loading ? 1 : 0))));
doneDrawableAnimator.start(); doneDrawableAnimator.start();
} }
} }

View file

@ -1380,11 +1380,11 @@ public class AlertsCreator {
imageView.setImage(null, null, avatarDrawable, user); imageView.setImage(null, null, avatarDrawable, user);
} else { } else {
avatarDrawable.setScaleSize(1f); avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(account, user);
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);
} }
} else { } else {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(account, chat);
imageView.setForUserOrChat(chat, avatarDrawable); imageView.setForUserOrChat(chat, avatarDrawable);
} }
@ -1461,7 +1461,7 @@ public class AlertsCreator {
imageView.setImage(null, null, avatarDrawable, user); imageView.setImage(null, null, avatarDrawable, user);
} else { } else {
avatarDrawable.setScaleSize(1f); avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(fragment.getCurrentAccount(), user);
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);
} }
} }
@ -1582,7 +1582,7 @@ public class AlertsCreator {
imageView.setImage(null, null, avatarDrawable, user); imageView.setImage(null, null, avatarDrawable, user);
} else { } else {
avatarDrawable.setScaleSize(1f); avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(fragment.getCurrentAccount(), user);
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);
} }
} }
@ -1757,11 +1757,11 @@ public class AlertsCreator {
imageView.setImage(null, null, avatarDrawable, user); imageView.setImage(null, null, avatarDrawable, user);
} else { } else {
avatarDrawable.setScaleSize(1f); avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(fragment.getCurrentAccount(), user);
imageView.setForUserOrChat(user, avatarDrawable); imageView.setForUserOrChat(user, avatarDrawable);
} }
} else { } else {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(fragment.getCurrentAccount(), chat);
imageView.setForUserOrChat(chat, avatarDrawable); imageView.setForUserOrChat(chat, avatarDrawable);
} }
@ -2046,7 +2046,7 @@ public class AlertsCreator {
AvatarDrawable avatarDrawable = new AvatarDrawable(); AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setTextSize(AndroidUtilities.dp(12)); avatarDrawable.setTextSize(AndroidUtilities.dp(12));
avatarDrawable.setScaleSize(1f); avatarDrawable.setScaleSize(1f);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(fragment.getCurrentAccount(), user);
BackupImageView imageView = new BackupImageView(context); BackupImageView imageView = new BackupImageView(context);
imageView.setRoundRadius(AndroidUtilities.dp(20)); imageView.setRoundRadius(AndroidUtilities.dp(20));
@ -2386,7 +2386,7 @@ public class AlertsCreator {
buttonTextView.setText(LocaleController.getString("IUnderstand", R.string.IUnderstand)); buttonTextView.setText(LocaleController.getString("IUnderstand", R.string.IUnderstand));
buttonTextView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText)); buttonTextView.setTextColor(Theme.getColor(Theme.key_featuredStickers_buttonText));
buttonTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed))); buttonTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), Theme.getColor(Theme.key_featuredStickers_addButton), Theme.getColor(Theme.key_featuredStickers_addButtonPressed)));
linearLayout.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, 0, 16, 12, 16, 8)); linearLayout.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, 0, 16, 12, 16, 8));
@ -2489,9 +2489,9 @@ public class AlertsCreator {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
BaseFragment lastFragment = LaunchActivity.getLastFragment(); BaseFragment lastFragment = LaunchActivity.getLastFragment();
if (lastFragment != null && lastFragment.getParentActivity() != null) { if (lastFragment != null && lastFragment.getParentActivity() != null) {
LimitReachedBottomSheet restricterdUsersBottomSheet = new LimitReachedBottomSheet(lastFragment, lastFragment.getParentActivity(), LimitReachedBottomSheet.TYPE_ADD_MEMBERS_RESTRICTED, currentAccount, null); LimitReachedBottomSheet restrictedUsersBottomSheet = new LimitReachedBottomSheet(lastFragment, lastFragment.getParentActivity(), LimitReachedBottomSheet.TYPE_ADD_MEMBERS_RESTRICTED, currentAccount, null);
restricterdUsersBottomSheet.setRestrictedUsers(currentChat, finalArrayList); restrictedUsersBottomSheet.setRestrictedUsers(currentChat, finalArrayList);
restricterdUsersBottomSheet.show(); restrictedUsersBottomSheet.show();
} }
}, 200); }, 200);
} }
@ -3208,7 +3208,7 @@ public class AlertsCreator {
buttonTextView.setTextColor(datePickerColors.buttonTextColor); buttonTextView.setTextColor(datePickerColors.buttonTextColor);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor)); buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
buttonTextView.setText(LocaleController.getString("SetTimeLimit", R.string.SetTimeLimit)); buttonTextView.setText(LocaleController.getString("SetTimeLimit", R.string.SetTimeLimit));
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16)); container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
buttonTextView.setOnClickListener(v -> { buttonTextView.setOnClickListener(v -> {
@ -3396,7 +3396,7 @@ public class AlertsCreator {
buttonTextView.setTextColor(datePickerColors.buttonTextColor); buttonTextView.setTextColor(datePickerColors.buttonTextColor);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor)); buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
buttonTextView.setText(LocaleController.getString("SetEmojiStatusUntilButton", R.string.SetEmojiStatusUntilButton)); buttonTextView.setText(LocaleController.getString("SetEmojiStatusUntilButton", R.string.SetEmojiStatusUntilButton));
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16)); container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
buttonTextView.setOnClickListener(v -> { buttonTextView.setOnClickListener(v -> {
@ -3541,7 +3541,7 @@ public class AlertsCreator {
buttonTextView.setTextColor(datePickerColors.buttonTextColor); buttonTextView.setTextColor(datePickerColors.buttonTextColor);
buttonTextView.setTextSize(AndroidUtilities.dp(14)); buttonTextView.setTextSize(AndroidUtilities.dp(14));
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor)); buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16)); container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
buttonTextView.setText(LocaleController.getString("DisableAutoDeleteTimer", R.string.DisableAutoDeleteTimer)); buttonTextView.setText(LocaleController.getString("DisableAutoDeleteTimer", R.string.DisableAutoDeleteTimer));
@ -3685,7 +3685,7 @@ public class AlertsCreator {
buttonTextView.setTextColor(datePickerColors.buttonTextColor); buttonTextView.setTextColor(datePickerColors.buttonTextColor);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor)); buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
buttonTextView.setText(LocaleController.getString("AutoDeleteConfirm", R.string.AutoDeleteConfirm)); buttonTextView.setText(LocaleController.getString("AutoDeleteConfirm", R.string.AutoDeleteConfirm));
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16)); container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
@ -3855,7 +3855,7 @@ public class AlertsCreator {
buttonTextView.setTextColor(datePickerColors.buttonTextColor); buttonTextView.setTextColor(datePickerColors.buttonTextColor);
buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14); buttonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); buttonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor)); buttonTextView.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(8), datePickerColors.buttonBackgroundColor, datePickerColors.buttonBackgroundPressedColor));
buttonTextView.setText(LocaleController.getString("AutoDeleteConfirm", R.string.AutoDeleteConfirm)); buttonTextView.setText(LocaleController.getString("AutoDeleteConfirm", R.string.AutoDeleteConfirm));
container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16)); container.addView(buttonTextView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM, 16, 15, 16, 16));
buttonTextView.setOnClickListener(v -> { buttonTextView.setOnClickListener(v -> {

View file

@ -70,6 +70,7 @@ public class AnimatedEmojiDrawable extends Drawable {
public static final int CACHE_TYPE_ALERT_PREVIEW_STATIC = 13; public static final int CACHE_TYPE_ALERT_PREVIEW_STATIC = 13;
public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW = 14; public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW = 14;
public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 = 15; public static final int CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW2 = 15;
public static final int CACHE_TYPE_ALERT_PREVIEW_STATIC_WITH_THUMB = 16;
public int rawDrawIndex; public int rawDrawIndex;
@ -520,7 +521,7 @@ public class AnimatedEmojiDrawable extends Drawable {
} }
imageReceiver.setVideoThumbIsSame(true); imageReceiver.setVideoThumbIsSame(true);
boolean onlyStaticPreview = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW && cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP || cacheType == CACHE_TYPE_KEYBOARD && !liteModeKeyboard || cacheType == CACHE_TYPE_ALERT_PREVIEW && !liteModeReactions; boolean onlyStaticPreview = SharedConfig.getDevicePerformanceClass() == SharedConfig.PERFORMANCE_CLASS_LOW && cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP || cacheType == CACHE_TYPE_KEYBOARD && !liteModeKeyboard || cacheType == CACHE_TYPE_ALERT_PREVIEW && !liteModeReactions;
if (cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC) { if (cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC || cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC_WITH_THUMB) {
onlyStaticPreview = true; onlyStaticPreview = true;
} }
String filter = sizedp + "_" + sizedp; String filter = sizedp + "_" + sizedp;
@ -572,12 +573,16 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.setImage(null, null, mediaLocation, mediaFilter, null, null, thumbDrawable, document.size, null, document, 1); imageReceiver.setImage(null, null, mediaLocation, mediaFilter, null, null, thumbDrawable, document.size, null, document, 1);
} else { } else {
if (onlyStaticPreview || (!liteModeKeyboard && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW)) { if (onlyStaticPreview || (!liteModeKeyboard && cacheType != CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW)) {
ImageLocation thumbLocation = null;
if (cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC_WITH_THUMB) {
thumbLocation = ImageLocation.getForDocument(thumb, document);
}
if ("video/webm".equals(document.mime_type)) { if ("video/webm".equals(document.mime_type)) {
imageReceiver.setImage(null, null, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1); imageReceiver.setImage(null, null, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, thumbLocation, null, thumbDrawable, document.size, null, document, 1);
} else if (MessageObject.isAnimatedStickerDocument(document, true)) { } else if (MessageObject.isAnimatedStickerDocument(document, true)) {
imageReceiver.setImage(mediaLocation, mediaFilter + "_firstframe", null, null, thumbDrawable, document.size, null, document, 1); imageReceiver.setImage(mediaLocation, mediaFilter + "_firstframe", thumbLocation, null, thumbDrawable, document.size, null, document, 1);
} else { } else {
imageReceiver.setImage(ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1); imageReceiver.setImage(ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, thumbLocation, null, thumbDrawable, document.size, null, document, 1);
} }
} else { } else {
imageReceiver.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1); imageReceiver.setImage(mediaLocation, mediaFilter, ImageLocation.getForDocument(thumb, document), sizedp + "_" + sizedp, null, null, thumbDrawable, document.size, null, document, 1);
@ -586,7 +591,7 @@ public class AnimatedEmojiDrawable extends Drawable {
updateAutoRepeat(imageReceiver); updateAutoRepeat(imageReceiver);
if (cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC || cacheType == CACHE_TYPE_ALERT_PREVIEW || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_LARGE) { if (cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC || cacheType == CACHE_TYPE_ALERT_PREVIEW_STATIC_WITH_THUMB || cacheType == CACHE_TYPE_ALERT_PREVIEW || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_LARGE) {
imageReceiver.setLayerNum(7); imageReceiver.setLayerNum(7);
} }
if (cacheType == CACHE_TYPE_ALERT_EMOJI_STATUS) { if (cacheType == CACHE_TYPE_ALERT_EMOJI_STATUS) {
@ -1059,7 +1064,7 @@ public class AnimatedEmojiDrawable extends Drawable {
changeProgress.set(1, true); changeProgress.set(1, true);
} }
public boolean set(long documentId, int cacheType, boolean animated) { public boolean set(long documentId, int cacheType, boolean animated) {
if (drawables[0] instanceof AnimatedEmojiDrawable && ((AnimatedEmojiDrawable) drawables[0]).getDocumentId() == documentId) { if (drawables[0] instanceof AnimatedEmojiDrawable && ((AnimatedEmojiDrawable) drawables[0]).getDocumentId() == documentId) {
return false; return false;
} }

View file

@ -1,5 +1,8 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
@ -32,10 +35,12 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
public class AnimatedEmojiSpan extends ReplacementSpan { public class AnimatedEmojiSpan extends ReplacementSpan {
private static boolean lockPositionChanging;
public long documentId; public long documentId;
public TLRPC.Document document; public TLRPC.Document document;
private float scale; private float scale;
private float extraScale = 1f;
public boolean standard; public boolean standard;
public boolean full = false; public boolean full = false;
public boolean top = false; public boolean top = false;
@ -52,6 +57,80 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
float lastDrawnCy; float lastDrawnCy;
private boolean recordPositions = true; private boolean recordPositions = true;
public boolean fromEmojiKeyboard; public boolean fromEmojiKeyboard;
private boolean isAdded;
private boolean isRemoved;
private Runnable removedAction;
private boolean animateChanges;
private ValueAnimator moveAnimator;
private ValueAnimator scaleAnimator;
/**
* To correctly move emoji to a new line, we need to return the final size in {@link #getSize}.
* However, this approach causes flickering. So fix this using {@link #lockPositionChanging} flag.
*/
public void setAdded() {
isAdded = true;
extraScale = 0f;
lockPositionChanging = true;
}
public void setAnimateChanges() {
this.animateChanges = true;
}
public void setRemoved(Runnable action) {
removedAction = action;
isRemoved = true;
extraScale = 1f;
}
public float getExtraScale() {
if (isAdded) {
isAdded = false;
extraScale = 0f;
scaleAnimator = ValueAnimator.ofFloat(extraScale, 1f);
scaleAnimator.addUpdateListener(animator -> {
extraScale = (float) animator.getAnimatedValue();
scale = AndroidUtilities.lerp(.2f, 1f, extraScale);
lockPositionChanging = false;
});
scaleAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
scaleAnimator = null;
}
});
scaleAnimator.setDuration(130);
scaleAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
scaleAnimator.start();
} else if (isRemoved) {
isRemoved = false;
extraScale = 1f;
if (scaleAnimator != null) {
scaleAnimator.removeAllListeners();
scaleAnimator.cancel();
}
scaleAnimator = ValueAnimator.ofFloat(extraScale, 0f);
scaleAnimator.addUpdateListener(animator -> {
extraScale = (float) animator.getAnimatedValue();
scale = AndroidUtilities.lerp(0f, 1f, extraScale);
});
scaleAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
scaleAnimator = null;
if (removedAction != null) {
removedAction.run();
removedAction = null;
}
}
});
scaleAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
scaleAnimator.setDuration(130);
scaleAnimator.start();
}
return extraScale;
}
public AnimatedEmojiSpan(@NonNull TLRPC.Document document, Paint.FontMetricsInt fontMetrics) { public AnimatedEmojiSpan(@NonNull TLRPC.Document document, Paint.FontMetricsInt fontMetrics) {
this(document.id, 1.2f, fontMetrics); this(document.id, 1.2f, fontMetrics);
@ -146,19 +225,19 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
if (fm != null) { if (fm != null) {
if (!full) { if (!full) {
fm.ascent = (int) (fontMetrics.ascent); fm.ascent = (int) (fontMetrics.ascent);
fm.descent = (int) (fontMetrics.descent); fm.descent = (int) (fontMetrics.descent);
fm.top = (int) (fontMetrics.top); fm.top = (int) (fontMetrics.top);
fm.bottom = (int) (fontMetrics.bottom); fm.bottom = (int) (fontMetrics.bottom);
} else { } else {
float height = Math.abs(fontMetrics.bottom) + Math.abs(fontMetrics.top); float height = Math.abs(fontMetrics.bottom) + Math.abs(fontMetrics.top);
fm.ascent = (int) Math.ceil(fontMetrics.top / height * measuredSize); fm.ascent = (int) Math.ceil(fontMetrics.top / height * measuredSize);
fm.descent = (int) Math.ceil(fontMetrics.bottom / height * measuredSize); fm.descent = (int) Math.ceil(fontMetrics.bottom / height * measuredSize);
fm.top = (int) Math.ceil(fontMetrics.top / height * measuredSize); fm.top = (int) Math.ceil(fontMetrics.top / height * measuredSize);
fm.bottom = (int) Math.ceil(fontMetrics.bottom / height * measuredSize); fm.bottom = (int) Math.ceil(fontMetrics.bottom / height * measuredSize);
} }
} }
} }
@ -167,12 +246,41 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
fm.ascent += diff; fm.ascent += diff;
fm.descent -= diff; fm.descent -= diff;
} }
return measuredSize - 1; return Math.max(0, measuredSize - 1);
} }
private int asizeDp; private boolean isAnimating() {
public void addSize(int asizeDp) { return moveAnimator != null || scaleAnimator != null;
// this.asizeDp = asizeDp; }
private boolean animateChanges(float cx, float cy) {
if (moveAnimator != null) {
return true;
}
if (!animateChanges) {
return false;
}
animateChanges = false;
final float fromCx = lastDrawnCx;
final float fromCy = lastDrawnCy;
final float toCx = cx;
final float toCy = cy;
moveAnimator = ValueAnimator.ofFloat(0f, 1f);
moveAnimator.addUpdateListener(animator -> {
float percent = (float) animator.getAnimatedValue();
lastDrawnCy = AndroidUtilities.lerp(fromCy, toCy, percent);
lastDrawnCx = AndroidUtilities.lerp(fromCx, toCx, percent);
});
moveAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
moveAnimator = null;
}
});
moveAnimator.setDuration(140);
moveAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
moveAnimator.start();
return true;
} }
@Override @Override
@ -181,6 +289,12 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
spanDrawn = true; spanDrawn = true;
float cx = x + measuredSize / 2f; float cx = x + measuredSize / 2f;
float cy = top + (bottom - top) / 2f; float cy = top + (bottom - top) / 2f;
if ((cy != lastDrawnCy && lastDrawnCy != 0 || cx != lastDrawnCx && lastDrawnCx != 0) && animateChanges(cx, cy)) {
return;
}
if (lockPositionChanging) {
return;
}
if (cx != lastDrawnCx || cy != lastDrawnCy) { if (cx != lastDrawnCx || cy != lastDrawnCy) {
lastDrawnCx = cx; lastDrawnCx = cx;
lastDrawnCy = cy; lastDrawnCy = cy;
@ -300,7 +414,18 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
if (drawable.getImageReceiver() != null) { if (drawable.getImageReceiver() != null) {
drawable.setColorFilter(colorFilter == null ? Theme.chat_animatedEmojiTextColorFilter : colorFilter); drawable.setColorFilter(colorFilter == null ? Theme.chat_animatedEmojiTextColorFilter : colorFilter);
drawable.setTime(time); drawable.setTime(time);
drawable.draw(canvas, drawableBounds, alpha * this.alpha); float scale = span.getExtraScale();
if (scale != 1f) {
canvas.save();
canvas.scale(scale, scale, drawableBounds.centerX(), drawableBounds.centerY());
drawable.draw(canvas, drawableBounds, alpha * this.alpha);
canvas.restore();
} else {
drawable.draw(canvas, drawableBounds, alpha * this.alpha);
}
if (span.isAnimating()) {
invalidate();
}
} }
} }
@ -337,15 +462,15 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
return update(cacheType, view, invalidateParent, prev, clone, layouts); return update(cacheType, view, invalidateParent, prev, clone, layouts);
} }
public static EmojiGroupedSpans update(int cacheType, View view, EmojiGroupedSpans prev, Layout ...layouts) { public static EmojiGroupedSpans update(int cacheType, View view, EmojiGroupedSpans prev, Layout... layouts) {
return update(cacheType, view, false, prev, layouts); return update(cacheType, view, false, prev, layouts);
} }
public static EmojiGroupedSpans update(int cacheType, View view, boolean invalidateParent, EmojiGroupedSpans prev, Layout ...layouts) { public static EmojiGroupedSpans update(int cacheType, View view, boolean invalidateParent, EmojiGroupedSpans prev, Layout... layouts) {
return update(cacheType, view, invalidateParent, prev, false, layouts); return update(cacheType, view, invalidateParent, prev, false, layouts);
} }
public static EmojiGroupedSpans update(int cacheType, View view, boolean invalidateParent, EmojiGroupedSpans prev, boolean clone, Layout ...layouts) { public static EmojiGroupedSpans update(int cacheType, View view, boolean invalidateParent, EmojiGroupedSpans prev, boolean clone, Layout... layouts) {
if (layouts == null || layouts.length <= 0) { if (layouts == null || layouts.length <= 0) {
if (prev != null) { if (prev != null) {
prev.holders.clear(); prev.holders.clear();
@ -645,14 +770,6 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
} }
} }
public void incrementFrames(int inc) {
for (int i = 0; i < holders.size(); i++) {
if (holders.get(i).drawable != null && holders.get(i).drawable.getImageReceiver() != null) {
holders.get(i).drawable.getImageReceiver().incrementFrames(inc);
}
}
}
public void recordPositions(boolean record) { public void recordPositions(boolean record) {
for (int i = 0; i < holders.size(); i++) { for (int i = 0; i < holders.size(); i++) {
holders.get(i).span.recordPositions = record; holders.get(i).span.recordPositions = record;
@ -706,7 +823,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
private final ArrayList<AnimatedEmojiHolder> backgroundHolders = new ArrayList<>(); private final ArrayList<AnimatedEmojiHolder> backgroundHolders = new ArrayList<>();
@Override @Override
public void drawInBackground(Canvas canvas) { public void drawInBackground(Canvas canvas) {
for (int i = 0; i < backgroundHolders.size(); i++) { for (int i = 0; i < backgroundHolders.size(); i++) {
AnimatedEmojiHolder holder = backgroundHolders.get(i); AnimatedEmojiHolder holder = backgroundHolders.get(i);
if (holder != null && holder.backgroundDrawHolder[threadIndex] != null) { if (holder != null && holder.backgroundDrawHolder[threadIndex] != null) {
@ -826,6 +943,8 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
animatedEmojiSpan = new AnimatedEmojiSpan(span.documentId, span.scale, span.fontMetrics); animatedEmojiSpan = new AnimatedEmojiSpan(span.documentId, span.scale, span.fontMetrics);
} }
animatedEmojiSpan.fromEmojiKeyboard = span.fromEmojiKeyboard; animatedEmojiSpan.fromEmojiKeyboard = span.fromEmojiKeyboard;
animatedEmojiSpan.isAdded = span.isAdded;
animatedEmojiSpan.isRemoved = span.isRemoved;
return animatedEmojiSpan; return animatedEmojiSpan;
} }
@ -854,7 +973,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
if (spans[i] instanceof AnimatedEmojiSpan) { if (spans[i] instanceof AnimatedEmojiSpan) {
int start = spanned.getSpanStart(spans[i]); int start = spanned.getSpanStart(spans[i]);
int end = spanned.getSpanEnd(spans[i]); int end = spanned.getSpanEnd(spans[i]);
AnimatedEmojiSpan oldSpan = (AnimatedEmojiSpan) spans[i]; AnimatedEmojiSpan oldSpan = (AnimatedEmojiSpan) spans[i];
newText.removeSpan(oldSpan); newText.removeSpan(oldSpan);
@ -876,6 +995,7 @@ public class AnimatedEmojiSpan extends ReplacementSpan {
} }
AnimatedEmojiSpan.EmojiGroupedSpans stack; AnimatedEmojiSpan.EmojiGroupedSpans stack;
@Override @Override
public void setText(CharSequence text, TextView.BufferType type) { public void setText(CharSequence text, TextView.BufferType type) {
super.setText(text, type); super.setText(text, type);

View file

@ -62,7 +62,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
private static native void stopDecoder(long ptr); private static native void stopDecoder(long ptr);
private static native int getVideoFrame(long ptr, Bitmap bitmap, int[] params, int stride, boolean preview, float startTimeSeconds, float endTimeSeconds); private static native int getVideoFrame(long ptr, Bitmap bitmap, int[] params, int stride, boolean preview, float startTimeSeconds, float endTimeSeconds, boolean loop);
private static native void seekToMs(long ptr, long ms, boolean precise); private static native void seekToMs(long ptr, long ms, boolean precise);
@ -431,7 +431,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
if (backgroundBitmap != null) { if (backgroundBitmap != null) {
lastFrameDecodeTime = System.currentTimeMillis(); lastFrameDecodeTime = System.currentTimeMillis();
if (getVideoFrame(nativePtr, backgroundBitmap, metaData, backgroundBitmap.getRowBytes(), false, startTime, endTime) == 0) { if (getVideoFrame(nativePtr, backgroundBitmap, metaData, backgroundBitmap.getRowBytes(), false, startTime, endTime, true) == 0) {
AndroidUtilities.runOnUIThread(uiRunnableNoFrame); AndroidUtilities.runOnUIThread(uiRunnableNoFrame);
return; return;
} }
@ -547,7 +547,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
if (precise) { if (precise) {
result = getFrameAtTime(nativePtr, ms, backgroundBitmap, metaData, backgroundBitmap.getRowBytes()); result = getFrameAtTime(nativePtr, ms, backgroundBitmap, metaData, backgroundBitmap.getRowBytes());
} else { } else {
result = getVideoFrame(nativePtr, backgroundBitmap, metaData, backgroundBitmap.getRowBytes(), true, 0, 0); result = getVideoFrame(nativePtr, backgroundBitmap, metaData, backgroundBitmap.getRowBytes(), true, 0, 0, true);
} }
return result != 0 ? backgroundBitmap : null; return result != 0 ? backgroundBitmap : null;
} }
@ -765,6 +765,10 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
return nextRenderingBitmapTime != 0 ? nextRenderingBitmapTime : renderingBitmapTime; return nextRenderingBitmapTime != 0 ? nextRenderingBitmapTime : renderingBitmapTime;
} }
public int getProgressMs() {
return metaData[3];
}
public int getDurationMs() { public int getDurationMs() {
return metaData[4]; return metaData[4];
} }
@ -1083,7 +1087,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
return isRecycled || decoderTryCount >= 15; return isRecycled || decoderTryCount >= 15;
} }
public Bitmap getNextFrame() { public Bitmap getNextFrame(boolean loop) {
if (nativePtr == 0) { if (nativePtr == 0) {
return backgroundBitmap; return backgroundBitmap;
} }
@ -1094,7 +1098,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
backgroundBitmap = Bitmap.createBitmap((int) (metaData[0] * scaleFactor), (int) (metaData[1] * scaleFactor), Bitmap.Config.ARGB_8888); backgroundBitmap = Bitmap.createBitmap((int) (metaData[0] * scaleFactor), (int) (metaData[1] * scaleFactor), Bitmap.Config.ARGB_8888);
} }
} }
getVideoFrame(nativePtr, backgroundBitmap, metaData, backgroundBitmap.getRowBytes(), false, startTime, endTime); getVideoFrame(nativePtr, backgroundBitmap, metaData, backgroundBitmap.getRowBytes(), false, startTime, endTime, loop);
return backgroundBitmap; return backgroundBitmap;
} }
@ -1140,7 +1144,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
if (generatingCacheBitmap == null) { if (generatingCacheBitmap == null) {
generatingCacheBitmap = Bitmap.createBitmap(metaData[0], metaData[1], Bitmap.Config.ARGB_8888); generatingCacheBitmap = Bitmap.createBitmap(metaData[0], metaData[1], Bitmap.Config.ARGB_8888);
} }
getVideoFrame(cacheGenerateNativePtr, generatingCacheBitmap, metaData, generatingCacheBitmap.getRowBytes(), false, startTime, endTime); getVideoFrame(cacheGenerateNativePtr, generatingCacheBitmap, metaData, generatingCacheBitmap.getRowBytes(), false, startTime, endTime, true);
if (cacheGenerateTimestamp != 0 && (metaData[3] == 0 || cacheGenerateTimestamp > metaData[3])) { if (cacheGenerateTimestamp != 0 && (metaData[3] == 0 || cacheGenerateTimestamp > metaData[3])) {
return 0; return 0;
} }
@ -1175,7 +1179,7 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
if (nativePtr == 0) { if (nativePtr == 0) {
return bitmap; return bitmap;
} }
getVideoFrame(nativePtr, generatingCacheBitmap, metaData, generatingCacheBitmap.getRowBytes(), false, startTime, endTime); getVideoFrame(nativePtr, generatingCacheBitmap, metaData, generatingCacheBitmap.getRowBytes(), false, startTime, endTime, true);
destroyDecoder(nativePtr); destroyDecoder(nativePtr);
bitmap.eraseColor(Color.TRANSPARENT); bitmap.eraseColor(Color.TRANSPARENT);
canvas.save(); canvas.save();
@ -1192,11 +1196,11 @@ public class AnimatedFileDrawable extends BitmapDrawable implements Animatable,
return; return;
} }
for (int i = 0; i < incFrame; ++i) { for (int i = 0; i < incFrame; ++i) {
getNextFrame(); getNextFrame(true);
} }
Bitmap bitmap = getBackgroundBitmap(); Bitmap bitmap = getBackgroundBitmap();
if (bitmap == null) { if (bitmap == null) {
bitmap = getNextFrame(); bitmap = getNextFrame(true);
} }
AndroidUtilities.rectTmp2.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); AndroidUtilities.rectTmp2.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
canvas.drawBitmap(getBackgroundBitmap(), AndroidUtilities.rectTmp2, getBounds(), getPaint()); canvas.drawBitmap(getBackgroundBitmap(), AndroidUtilities.rectTmp2, getBounds(), getPaint());

View file

@ -115,6 +115,8 @@ public class AnimatedFloat {
this.firstSet = false; this.firstSet = false;
} }
// get() is not recommended to use (unless minimize System.currentTimeMillis() calls)
@Deprecated
public float get() { public float get() {
return value; return value;
} }

View file

@ -26,7 +26,7 @@ public class AutoDeletePopupWrapper {
private final ActionBarMenuSubItem disableItem; private final ActionBarMenuSubItem disableItem;
Callback callback; Callback callback;
long lastDismissTime; long lastDismissTime;
TextView textView; public TextView textView;
public AutoDeletePopupWrapper(Context context, PopupSwipeBackLayout swipeBackLayout, Callback callback, boolean createBackground, int type, Theme.ResourcesProvider resourcesProvider) { public AutoDeletePopupWrapper(Context context, PopupSwipeBackLayout swipeBackLayout, Callback callback, boolean createBackground, int type, Theme.ResourcesProvider resourcesProvider) {
windowLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(context, createBackground ? R.drawable.popup_fixed_alert : 0, resourcesProvider); windowLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(context, createBackground ? R.drawable.popup_fixed_alert : 0, resourcesProvider);
@ -115,14 +115,14 @@ public class AutoDeletePopupWrapper {
} }
} }
public void allowExtenededHint() { public void allowExtendedHint(int linkColor) {
if (textView == null) { if (textView == null) {
return; return;
} }
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
spannableStringBuilder.append(LocaleController.getString("AutoDeletePopupDescription", R.string.AutoDeletePopupDescription)); spannableStringBuilder.append(LocaleController.getString("AutoDeletePopupDescription", R.string.AutoDeletePopupDescription));
spannableStringBuilder.append("\n\n"); spannableStringBuilder.append("\n\n");
spannableStringBuilder.append(AndroidUtilities.replaceSingleTag(LocaleController.getString("AutoDeletePopupDescription2", R.string.AutoDeletePopupDescription2), () -> { spannableStringBuilder.append(AndroidUtilities.replaceSingleLink(LocaleController.getString(R.string.AutoDeletePopupDescription2), linkColor, () -> {
callback.showGlobalAutoDeleteScreen(); callback.showGlobalAutoDeleteScreen();
})); }));
textView.setText(spannableStringBuilder); textView.setText(spannableStringBuilder);

View file

@ -8,6 +8,8 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
@ -24,9 +26,9 @@ import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.Emoji; import org.telegram.messenger.Emoji;
import org.telegram.messenger.FileLog; import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
@ -66,12 +68,14 @@ public class AvatarDrawable extends Drawable {
private int gradientColor21, gradientColor22; private int gradientColor21, gradientColor22;
private LinearGradient gradient2; private LinearGradient gradient2;
private boolean drawAvatarBackground = true; private boolean drawAvatarBackground = true;
private boolean rotate45Background = false;
public static final int AVATAR_TYPE_NORMAL = 0; public static final int AVATAR_TYPE_NORMAL = 0;
public static final int AVATAR_TYPE_SAVED = 1; public static final int AVATAR_TYPE_SAVED = 1;
public static final int AVATAR_TYPE_ARCHIVED = 2; public static final int AVATAR_TYPE_ARCHIVED = 2;
public static final int AVATAR_TYPE_SHARES = 3; public static final int AVATAR_TYPE_SHARES = 3;
public static final int AVATAR_TYPE_REPLIES = 12; public static final int AVATAR_TYPE_REPLIES = 12;
public static final int AVATAR_TYPE_STORY = 20;
public static final int AVATAR_TYPE_FILTER_CONTACTS = 4; public static final int AVATAR_TYPE_FILTER_CONTACTS = 4;
public static final int AVATAR_TYPE_FILTER_NON_CONTACTS = 5; public static final int AVATAR_TYPE_FILTER_NON_CONTACTS = 5;
@ -102,7 +106,7 @@ public class AvatarDrawable extends Drawable {
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
namePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); namePaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
namePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); namePaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
namePaint.setTextSize(AndroidUtilities.dp(18)); namePaint.setTextSize(dp(18));
} }
public AvatarDrawable(TLRPC.User user) { public AvatarDrawable(TLRPC.User user) {
@ -190,8 +194,12 @@ public class AvatarDrawable extends Drawable {
} }
public void setInfo(TLRPC.User user) { public void setInfo(TLRPC.User user) {
setInfo(UserConfig.selectedAccount, user);
}
public void setInfo(int currentAccount, TLRPC.User user) {
if (user != null) { if (user != null) {
setInfo(user.id, user.first_name, user.last_name, null, (user.flags2 & 128) != 0 ? user.color : null); setInfo(user.id, user.first_name, user.last_name, null, user != null && user.color != null ? UserObject.getColorId(user) : null, UserObject.getPeerColorForAvatar(currentAccount, user));
drawDeleted = UserObject.isDeleted(user); drawDeleted = UserObject.isDeleted(user);
} }
} }
@ -206,12 +214,23 @@ public class AvatarDrawable extends Drawable {
} }
} }
public void setInfo(int currentAccount, TLObject object) {
if (object instanceof TLRPC.User) {
setInfo(currentAccount, (TLRPC.User) object);
} else if (object instanceof TLRPC.Chat) {
setInfo(currentAccount, (TLRPC.Chat) object);
} else if (object instanceof TLRPC.ChatInvite) {
setInfo(currentAccount, (TLRPC.ChatInvite) object);
}
}
public void setScaleSize(float value) { public void setScaleSize(float value) {
scaleSize = value; scaleSize = value;
} }
public void setAvatarType(int value) { public void setAvatarType(int value) {
avatarType = value; avatarType = value;
rotate45Background = false;
if (avatarType == AVATAR_TYPE_REGISTER) { if (avatarType == AVATAR_TYPE_REGISTER) {
hasGradient = false; hasGradient = false;
color = color2 = Theme.getColor(Theme.key_chats_actionBackground); color = color2 = Theme.getColor(Theme.key_chats_actionBackground);
@ -222,6 +241,11 @@ public class AvatarDrawable extends Drawable {
hasGradient = true; hasGradient = true;
color = getThemedColor(Theme.key_avatar_backgroundSaved); color = getThemedColor(Theme.key_avatar_backgroundSaved);
color2 = getThemedColor(Theme.key_avatar_background2Saved); color2 = getThemedColor(Theme.key_avatar_background2Saved);
} else if (avatarType == AVATAR_TYPE_STORY) {
rotate45Background = true;
hasGradient = true;
color = getThemedColor(Theme.key_stories_circle1);
color2 = getThemedColor(Theme.key_stories_circle2);
} else if (avatarType == AVATAR_TYPE_SHARES) { } else if (avatarType == AVATAR_TYPE_SHARES) {
hasGradient = true; hasGradient = true;
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]); color = getThemedColor(Theme.keys_avatar_background[getColorIndex(5)]);
@ -263,7 +287,7 @@ public class AvatarDrawable extends Drawable {
color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]); color = getThemedColor(Theme.keys_avatar_background[getColorIndex(4)]);
color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(4)]); color2 = getThemedColor(Theme.keys_avatar_background2[getColorIndex(4)]);
} }
needApplyColorAccent = avatarType != AVATAR_TYPE_ARCHIVED && avatarType != AVATAR_TYPE_SAVED && avatarType != AVATAR_TYPE_REPLIES && avatarType != AVATAR_TYPE_OTHER_CHATS; needApplyColorAccent = avatarType != AVATAR_TYPE_ARCHIVED && avatarType != AVATAR_TYPE_SAVED && avatarType != AVATAR_TYPE_STORY && avatarType != AVATAR_TYPE_REPLIES && avatarType != AVATAR_TYPE_OTHER_CHATS;
} }
public void setArchivedAvatarHiddenProgress(float progress) { public void setArchivedAvatarHiddenProgress(float progress) {
@ -275,13 +299,20 @@ public class AvatarDrawable extends Drawable {
} }
public void setInfo(TLRPC.Chat chat) { public void setInfo(TLRPC.Chat chat) {
setInfo(UserConfig.selectedAccount, chat);
}
public void setInfo(int currentAccount, TLRPC.Chat chat) {
if (chat != null) { if (chat != null) {
setInfo(chat.id, chat.title, null, null, (chat.flags2 & 64) != 0 ? chat.color : null); setInfo(chat.id, chat.title, null, null, chat != null && chat.color != null ? ChatObject.getColorId(chat) : null, ChatObject.getPeerColorForAvatar(currentAccount, chat));
} }
} }
public void setInfo(TLRPC.ChatInvite chat) { public void setInfo(TLRPC.ChatInvite chat) {
setInfo(UserConfig.selectedAccount, chat);
}
public void setInfo(int currentAccount, TLRPC.ChatInvite chat) {
if (chat != null) { if (chat != null) {
setInfo(0, chat.title, null, null, chat.chat != null && (chat.chat.flags2 & 64) != 0 ? chat.chat.color : null); setInfo(0, chat.title, null, null, chat.chat != null && chat.chat.color != null ? ChatObject.getColorId(chat.chat) : null, ChatObject.getPeerColorForAvatar(currentAccount, chat.chat));
} }
} }
@ -303,7 +334,7 @@ public class AvatarDrawable extends Drawable {
} }
public void setInfo(long id, String firstName, String lastName) { public void setInfo(long id, String firstName, String lastName) {
setInfo(id, firstName, lastName, null, null); setInfo(id, firstName, lastName, null, null, null);
} }
public int getColor() { public int getColor() {
@ -323,13 +354,16 @@ public class AvatarDrawable extends Drawable {
} }
public void setInfo(long id, String firstName, String lastName, String custom) { public void setInfo(long id, String firstName, String lastName, String custom) {
setInfo(id, firstName, lastName, custom, null); setInfo(id, firstName, lastName, custom, null, null);
} }
public void setInfo(long id, String firstName, String lastName, String custom, Integer customColor) { public void setInfo(long id, String firstName, String lastName, String custom, Integer customColor, MessagesController.PeerColor profileColor) {
hasGradient = true; hasGradient = true;
invalidateTextLayout = true; invalidateTextLayout = true;
if (customColor != null) { if (profileColor != null) {
color = profileColor.getAvatarColor1();
color2 = profileColor.getAvatarColor2();
} else if (customColor != null) {
if (customColor >= 14) { if (customColor >= 14) {
MessagesController messagesController = MessagesController.getInstance(UserConfig.selectedAccount); MessagesController messagesController = MessagesController.getInstance(UserConfig.selectedAccount);
if (messagesController != null && messagesController.peerColors != null && messagesController.peerColors.getColor(customColor) != null) { if (messagesController != null && messagesController.peerColors != null && messagesController.peerColors.getColor(customColor) != null) {
@ -419,12 +453,19 @@ public class AvatarDrawable extends Drawable {
canvas.translate(bounds.left, bounds.top); canvas.translate(bounds.left, bounds.top);
if (drawAvatarBackground) { if (drawAvatarBackground) {
if (rotate45Background) {
canvas.save();
canvas.rotate(-45, size / 2.0f, size / 2.0f);
}
if (roundRadius > 0) { if (roundRadius > 0) {
AndroidUtilities.rectTmp.set(0, 0, size, size); AndroidUtilities.rectTmp.set(0, 0, size, size);
canvas.drawRoundRect(AndroidUtilities.rectTmp, roundRadius, roundRadius, Theme.avatar_backgroundPaint); canvas.drawRoundRect(AndroidUtilities.rectTmp, roundRadius, roundRadius, Theme.avatar_backgroundPaint);
} else { } else {
canvas.drawCircle(size / 2.0f, size / 2.0f, size / 2.0f, Theme.avatar_backgroundPaint); canvas.drawCircle(size / 2.0f, size / 2.0f, size / 2.0f, Theme.avatar_backgroundPaint);
} }
if (rotate45Background) {
canvas.restore();
}
} }
if (avatarType == AVATAR_TYPE_ARCHIVED) { if (avatarType == AVATAR_TYPE_ARCHIVED) {
@ -488,6 +529,8 @@ public class AvatarDrawable extends Drawable {
drawable = Theme.avatarDrawables[15]; drawable = Theme.avatarDrawables[15];
} else if (avatarType == AVATAR_TYPE_UNCLAIMED) { } else if (avatarType == AVATAR_TYPE_UNCLAIMED) {
drawable = Theme.avatarDrawables[16]; drawable = Theme.avatarDrawables[16];
} else if (avatarType == AVATAR_TYPE_STORY) {
drawable = Theme.avatarDrawables[17];
} else { } else {
drawable = Theme.avatarDrawables[9]; drawable = Theme.avatarDrawables[9];
} }
@ -508,8 +551,8 @@ public class AvatarDrawable extends Drawable {
} else if (drawDeleted && Theme.avatarDrawables[1] != null) { } else if (drawDeleted && Theme.avatarDrawables[1] != null) {
int w = Theme.avatarDrawables[1].getIntrinsicWidth(); int w = Theme.avatarDrawables[1].getIntrinsicWidth();
int h = Theme.avatarDrawables[1].getIntrinsicHeight(); int h = Theme.avatarDrawables[1].getIntrinsicHeight();
if (w > size - AndroidUtilities.dp(6) || h > size - AndroidUtilities.dp(6)) { if (w > size - dp(6) || h > size - dp(6)) {
float scale = size / (float) AndroidUtilities.dp(50); float scale = size / (float) dp(50);
w *= scale; w *= scale;
h *= scale; h *= scale;
} }
@ -522,10 +565,10 @@ public class AvatarDrawable extends Drawable {
invalidateTextLayout = false; invalidateTextLayout = false;
if (stringBuilder.length() > 0) { if (stringBuilder.length() > 0) {
CharSequence text = stringBuilder.toString().toUpperCase(); CharSequence text = stringBuilder.toString().toUpperCase();
text = Emoji.replaceEmoji(text, namePaint.getFontMetricsInt(), AndroidUtilities.dp(16), true); text = Emoji.replaceEmoji(text, namePaint.getFontMetricsInt(), dp(16), true);
if (textLayout == null || !TextUtils.equals(text, textLayout.getText())) { if (textLayout == null || !TextUtils.equals(text, textLayout.getText())) {
try { try {
textLayout = new StaticLayout(text, namePaint, AndroidUtilities.dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); textLayout = new StaticLayout(text, namePaint, dp(100), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
if (textLayout.getLineCount() > 0) { if (textLayout.getLineCount() > 0) {
textLeft = textLayout.getLineLeft(0); textLeft = textLayout.getLineLeft(0);
textWidth = textLayout.getLineWidth(0); textWidth = textLayout.getLineWidth(0);
@ -540,7 +583,7 @@ public class AvatarDrawable extends Drawable {
} }
} }
if (textLayout != null) { if (textLayout != null) {
float scale = size / (float) AndroidUtilities.dp(50); float scale = size / (float) dp(50);
canvas.scale(scale, scale, size / 2f, size / 2f) ; canvas.scale(scale, scale, size / 2f, size / 2f) ;
canvas.translate((size - textWidth) / 2 - textLeft, (size - textHeight) / 2); canvas.translate((size - textWidth) / 2 - textLeft, (size - textHeight) / 2);

View file

@ -305,10 +305,10 @@ public class AvatarsDrawable {
long id = MessageObject.getPeerId(participant.peer); long id = MessageObject.getPeerId(participant.peer);
if (DialogObject.isUserDialog(id)) { if (DialogObject.isUserDialog(id)) {
currentUser = MessagesController.getInstance(account).getUser(id); currentUser = MessagesController.getInstance(account).getUser(id);
animatingStates[index].avatarDrawable.setInfo(currentUser); animatingStates[index].avatarDrawable.setInfo(account, currentUser);
} else { } else {
currentChat = MessagesController.getInstance(account).getChat(-id); currentChat = MessagesController.getInstance(account).getChat(-id);
animatingStates[index].avatarDrawable.setInfo(currentChat); animatingStates[index].avatarDrawable.setInfo(account, currentChat);
} }
if (currentStyle == 4) { if (currentStyle == 4) {
if (id == AccountInstance.getInstance(account).getUserConfig().getClientUserId()) { if (id == AccountInstance.getInstance(account).getUserConfig().getClientUserId()) {
@ -332,14 +332,14 @@ public class AvatarsDrawable {
} else { } else {
animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_NORMAL); animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_NORMAL);
animatingStates[index].avatarDrawable.setScaleSize(1f); animatingStates[index].avatarDrawable.setScaleSize(1f);
animatingStates[index].avatarDrawable.setInfo(currentUser); animatingStates[index].avatarDrawable.setInfo(account, currentUser);
} }
animatingStates[index].id = currentUser.id; animatingStates[index].id = currentUser.id;
} else { } else {
currentChat = (TLRPC.Chat) object; currentChat = (TLRPC.Chat) object;
animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_NORMAL); animatingStates[index].avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_NORMAL);
animatingStates[index].avatarDrawable.setScaleSize(1f); animatingStates[index].avatarDrawable.setScaleSize(1f);
animatingStates[index].avatarDrawable.setInfo(currentChat); animatingStates[index].avatarDrawable.setInfo(account, currentChat);
animatingStates[index].id = -currentChat.id; animatingStates[index].id = -currentChat.id;
} }
if (currentUser != null) { if (currentUser != null) {

View file

@ -105,7 +105,7 @@ public class BackButtonMenu {
Drawable thumb = avatarDrawable; Drawable thumb = avatarDrawable;
boolean addDivider = false; boolean addDivider = false;
if (chat != null) { if (chat != null) {
avatarDrawable.setInfo(chat); avatarDrawable.setInfo(thisFragment.getCurrentAccount(), chat);
if (chat.photo != null && chat.photo.strippedBitmap != null) { if (chat.photo != null && chat.photo.strippedBitmap != null) {
thumb = chat.photo.strippedBitmap; thumb = chat.photo.strippedBitmap;
} }
@ -126,11 +126,11 @@ public class BackButtonMenu {
imageView.setImageDrawable(avatarDrawable); imageView.setImageDrawable(avatarDrawable);
} else if (UserObject.isDeleted(user)) { } else if (UserObject.isDeleted(user)) {
name = LocaleController.getString("HiddenName", R.string.HiddenName); name = LocaleController.getString("HiddenName", R.string.HiddenName);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(thisFragment.getCurrentAccount(), user);
imageView.setImage(ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), "50_50", avatarDrawable, user); imageView.setImage(ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), "50_50", avatarDrawable, user);
} else { } else {
name = UserObject.getUserName(user); name = UserObject.getUserName(user);
avatarDrawable.setInfo(user); avatarDrawable.setInfo(thisFragment.getCurrentAccount(), user);
imageView.setImage(ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), "50_50", thumb, user); imageView.setImage(ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), "50_50", thumb, user);
} }
titleView.setText(name); titleView.setText(name);

View file

@ -42,6 +42,7 @@ public class BackupImageView extends View {
public BackupImageView(Context context) { public BackupImageView(Context context) {
super(context); super(context);
imageReceiver = createImageReciever(); imageReceiver = createImageReciever();
imageReceiver.setCrossfadeByScale(0);
imageReceiver.setAllowLoadingOnAttachedOnly(true); imageReceiver.setAllowLoadingOnAttachedOnly(true);
imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> { imageReceiver.setDelegate((imageReceiver1, set, thumb, memCache) -> {
if (set && !thumb) { if (set && !thumb) {
@ -183,6 +184,11 @@ public class BackupImageView extends View {
onNewImageSet(); onNewImageSet();
} }
public void setImage(ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, Drawable thumb, String ext, long size, int cacheType, Object parentObject) {
imageReceiver.setImage(imageLocation, imageFilter, thumbLocation, thumbFilter, thumb, size, ext, parentObject, cacheType);
onNewImageSet();
}
public void setImage(ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, String ext, long size, int cacheType, Object parentObject) { public void setImage(ImageLocation imageLocation, String imageFilter, ImageLocation thumbLocation, String thumbFilter, String ext, long size, int cacheType, Object parentObject) {
imageReceiver.setImage(imageLocation, imageFilter, thumbLocation, thumbFilter, null, size, ext, parentObject, cacheType); imageReceiver.setImage(imageLocation, imageFilter, thumbLocation, thumbFilter, null, size, ext, parentObject, cacheType);
onNewImageSet(); onNewImageSet();

View file

@ -178,6 +178,10 @@ public class BlobDrawable {
private final static float animationSpeed = 1f - ANIMATION_SPEED_WAVE_HUGE; private final static float animationSpeed = 1f - ANIMATION_SPEED_WAVE_HUGE;
private final static float animationSpeedTiny = 1f - ANIMATION_SPEED_WAVE_SMALL; private final static float animationSpeedTiny = 1f - ANIMATION_SPEED_WAVE_SMALL;
public void setValue(float value) {
amplitude = value;
}
public void setValue(float value, boolean isBig) { public void setValue(float value, boolean isBig) {
animateToAmplitude = value; animateToAmplitude = value;
if (!LiteMode.isEnabled(liteFlag)) { if (!LiteMode.isEnabled(liteFlag)) {

View file

@ -696,6 +696,8 @@ public class BlurringShader {
public static final int BLUR_TYPE_MENU_BACKGROUND = 5; public static final int BLUR_TYPE_MENU_BACKGROUND = 5;
public static final int BLUR_TYPE_SHADOW = 6; public static final int BLUR_TYPE_SHADOW = 6;
public static final int BLUR_TYPE_EMOJI_VIEW = 7; public static final int BLUR_TYPE_EMOJI_VIEW = 7;
public static final int BLUR_TYPE_REPLY_BACKGROUND = 8;
public static final int BLUR_TYPE_REPLY_TEXT_XFER = 9;
private final BlurManager manager; private final BlurManager manager;
private final View view; private final View view;
@ -728,10 +730,9 @@ public class BlurringShader {
} else if (type == BLUR_TYPE_CAPTION_XFER) { } else if (type == BLUR_TYPE_CAPTION_XFER) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
oldPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); oldPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.8f); AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.4f);
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.45f); AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.3f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, 2.5f); // AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, 1.4f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.8f);
} else if (type == BLUR_TYPE_CAPTION) { } else if (type == BLUR_TYPE_CAPTION) {
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.35f); AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.35f);
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.7f); AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.7f);
@ -747,7 +748,16 @@ public class BlurringShader {
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, 0.35f); AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, 0.35f);
} else if (type == BLUR_TYPE_EMOJI_VIEW) { } else if (type == BLUR_TYPE_EMOJI_VIEW) {
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.5f); AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.5f);
AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, .85f); AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, .95f);
} else if (type == BLUR_TYPE_REPLY_BACKGROUND) {
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, -.15f);
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.47f);
} else if (type == BLUR_TYPE_REPLY_TEXT_XFER) {
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
oldPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
AndroidUtilities.adjustBrightnessColorMatrix(colorMatrix, +.4f);
AndroidUtilities.adjustSaturationColorMatrix(colorMatrix, +.45f);
// AndroidUtilities.multiplyBrightnessColorMatrix(colorMatrix, 1.4f);
} }
paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
oldPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); oldPaint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));

View file

@ -46,6 +46,7 @@ public class BottomPagerTabs extends View {
final AnimatedFloat nonscrollingT = new AnimatedFloat(BottomPagerTabs.this, 0, 200, CubicBezierInterpolator.EASE_OUT_QUINT); final AnimatedFloat nonscrollingT = new AnimatedFloat(BottomPagerTabs.this, 0, 200, CubicBezierInterpolator.EASE_OUT_QUINT);
public int customEndFrameMid; public int customEndFrameMid;
public int customEndFrameEnd; public int customEndFrameEnd;
public boolean customFrameInvert;
public Tab(int i, int resId, CharSequence text) { public Tab(int i, int resId, CharSequence text) {
this.i = i; this.i = i;
@ -68,6 +69,9 @@ public class BottomPagerTabs extends View {
private boolean active; private boolean active;
public void setActive(boolean active, boolean animated) { public void setActive(boolean active, boolean animated) {
if (customFrameInvert) {
active = !active;
}
if (this.active == active) { if (this.active == active) {
return; return;
} }

View file

@ -202,6 +202,11 @@ public class Bulletin {
return this; return this;
} }
public Bulletin setTag(int tag) {
this.tag = tag;
return this;
}
public Bulletin show() { public Bulletin show() {
return show(false); return show(false);
} }
@ -1897,9 +1902,4 @@ public class Bulletin {
} }
} }
} }
public Bulletin setTag(int tag) {
this.tag = tag;
return this;
}
} }

View file

@ -219,6 +219,26 @@ public final class BulletinFactory {
return create(layout, text.length() < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG); return create(layout, text.length() < 20 ? Bulletin.DURATION_SHORT : Bulletin.DURATION_LONG);
} }
public Bulletin createSimpleBulletin(int iconRawId, CharSequence text, int maxLines, int duration) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
layout.setAnimation(iconRawId, 36, 36);
if (text != null) {
String string = text.toString();
SpannableStringBuilder ssb = text instanceof SpannableStringBuilder ? (SpannableStringBuilder) text : new SpannableStringBuilder(text);
for (int index = string.indexOf('\n'), l = 0; index >= 0 && index < text.length(); l++, index = string.indexOf('\n', index + 1)) {
if (l >= maxLines) {
ssb.replace(index, index + 1, " ");
}
}
text = ssb;
}
layout.textView.setText(text);
layout.textView.setSingleLine(false);
layout.textView.setMaxLines(maxLines);
return create(layout, duration);
}
public Bulletin createSimpleBulletin(int iconRawId, CharSequence text, CharSequence subtext) { public Bulletin createSimpleBulletin(int iconRawId, CharSequence text, CharSequence subtext) {
final Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(getContext(), resourcesProvider); final Bulletin.TwoLineLottieLayout layout = new Bulletin.TwoLineLottieLayout(getContext(), resourcesProvider);
layout.setAnimation(iconRawId, 36, 36); layout.setAnimation(iconRawId, 36, 36);
@ -497,6 +517,20 @@ public final class BulletinFactory {
return create(layout, Bulletin.DURATION_LONG); return create(layout, Bulletin.DURATION_LONG);
} }
public Bulletin createStaticEmojiBulletin(TLRPC.Document document, CharSequence text) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
if (MessageObject.isTextColorEmoji(document)) {
layout.imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_undo_infoColor), PorterDuff.Mode.SRC_IN));
}
layout.setAnimation(document, 36, 36);
layout.imageView.stopAnimation();
layout.textView.setText(text);
layout.textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
layout.textView.setSingleLine(false);
layout.textView.setMaxLines(3);
return create(layout, Bulletin.DURATION_LONG);
}
public Bulletin createEmojiBulletin(TLRPC.Document document, CharSequence text, CharSequence button, Runnable onButtonClick) { public Bulletin createEmojiBulletin(TLRPC.Document document, CharSequence text, CharSequence button, Runnable onButtonClick) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider); final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
if (MessageObject.isTextColorEmoji(document)) { if (MessageObject.isTextColorEmoji(document)) {

View file

@ -94,7 +94,7 @@ public class ButtonBounce {
return isPressed; return isPressed;
} }
private void invalidate() { public void invalidate() {
if (view != null) { if (view != null) {
view.invalidate(); view.invalidate();
} }

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