update to 10.6.4 (4365)

This commit is contained in:
dkaraush 2024-02-06 20:34:03 +04:00
parent 928146c3da
commit 5dd649197b
182 changed files with 7043 additions and 1797 deletions

View file

@ -2390,7 +2390,7 @@ void ConnectionsManager::processRequestQueue(uint32_t connectionTypes, uint32_t
} }
} }
if (request->retryCount >= retryMax) { if (request->retryCount >= retryMax) {
if (LOGS_ENABLED) DEBUG_E("timed out %s", typeInfo.name()); if (LOGS_ENABLED) DEBUG_E("timed out %s, message_id = 0x%" PRIx64, typeInfo.name(), request->messageId);
auto error = new TL_error(); auto error = new TL_error();
error->code = -123; error->code = -123;
error->text = "RETRY_LIMIT"; error->text = "RETRY_LIMIT";

View file

@ -49,7 +49,7 @@ chat_inReplyNameText=-14643754
chats_onlineCircle=-13192972 chats_onlineCircle=-13192972
chat_outAudioSelectedProgress=-7484939 chat_outAudioSelectedProgress=-7484939
chat_inInstant=-14707230 chat_inInstant=-14707230
avatar_backgroundSaved=-10438409 avatar_backgroundSaved=-9847303
chats_sentReadCheck=-15754010 chats_sentReadCheck=-15754010
chats_nameMessageArchived=-7237231 chats_nameMessageArchived=-7237231
chat_outSentCheckSelected=-14968350 chat_outSentCheckSelected=-14968350

View file

@ -9,6 +9,9 @@ windowBackgroundWhiteBlueIcon=-528890628
chat_goDownButtonCounterBackground=-11425042 chat_goDownButtonCounterBackground=-11425042
actionBarActionModeDefault=-14273984 actionBarActionModeDefault=-14273984
actionBarActionModeDefaultTop=-14536643 actionBarActionModeDefaultTop=-14536643
actionBarActionModeReaction=318767103
actionBarActionModeReactionText=-1
actionBarActionModeReactionDot=-13287865
statisticChartHintLine=452984831 statisticChartHintLine=452984831
chats_menuPhone=-1816080163 chats_menuPhone=-1816080163
chat_outViews=-7357217 chat_outViews=-7357217
@ -425,7 +428,7 @@ chats_attachMessage=-8548712
chat_topPanelBackground=-14602949 chat_topPanelBackground=-14602949
chat_outSentClock=-8213557 chat_outSentClock=-8213557
dialogBackgroundGray=-14932431 dialogBackgroundGray=-14932431
chat_searchPanelText=-8796932 chat_searchPanelText=-1
chat_inContactIcon=-1 chat_inContactIcon=-1
code_comment=-2130706433 code_comment=-2130706433
chat_outCodeBackground=857487708 chat_outCodeBackground=857487708

View file

@ -8,6 +8,9 @@ chat_inSentClockSelected=-7490861
chat_goDownButtonCounterBackground=-11425042 chat_goDownButtonCounterBackground=-11425042
actionBarActionModeDefault=-14211289 actionBarActionModeDefault=-14211289
actionBarActionModeDefaultTop=-14277082 actionBarActionModeDefaultTop=-14277082
actionBarActionModeReaction=318767103
actionBarActionModeReactionText=-1
actionBarActionModeReactionDot=-13287865
statisticChartHintLine=452984831 statisticChartHintLine=452984831
chats_menuPhone=-1815557944 chats_menuPhone=-1815557944
chat_outViews=-7357217 chat_outViews=-7357217
@ -450,7 +453,7 @@ chats_attachMessage=-8224126
chat_topPanelBackground=-15066597 chat_topPanelBackground=-15066597
chat_outSentClock=-6698513 chat_outSentClock=-6698513
dialogBackgroundGray=-14013910 dialogBackgroundGray=-14013910
chat_searchPanelText=-10767620 chat_searchPanelText=-1
chat_inContactIcon=-1 chat_inContactIcon=-1
code_comment=-2130706433 code_comment=-2130706433
chat_outCodeBackground=859062986 chat_outCodeBackground=859062986

View file

@ -990,7 +990,7 @@ public class ChatListItemAnimator extends DefaultItemAnimator {
return true; return true;
} }
void animateChangeImpl(final ChangeInfo changeInfo) { public void animateChangeImpl(final ChangeInfo changeInfo) {
final RecyclerView.ViewHolder holder = changeInfo.oldHolder; final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView; final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder; final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;

View file

@ -468,7 +468,7 @@ public class DefaultItemAnimator extends SimpleItemAnimator {
return true; return true;
} }
void animateChangeImpl(final ChangeInfo changeInfo) { public void animateChangeImpl(final ChangeInfo changeInfo) {
final RecyclerView.ViewHolder holder = changeInfo.oldHolder; final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView; final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder; final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;

View file

@ -25,7 +25,6 @@ public class SQLitePreparedStatement {
private long startTime; private long startTime;
private String query; private String query;
//private static HashMap<SQLitePreparedStatement, String> hashMap;
public long getStatementHandle() { public long getStatementHandle() {
return sqliteStatementHandle; return sqliteStatementHandle;
@ -112,9 +111,6 @@ public class SQLitePreparedStatement {
} }
} }
try { try {
/*if (BuildVars.DEBUG_PRIVATE_VERSION) {
hashMap.remove(this);
}*/
isFinalized = true; isFinalized = true;
finalize(sqliteStatementHandle); finalize(sqliteStatementHandle);
} catch (SQLiteException e) { } catch (SQLiteException e) {

View file

@ -73,6 +73,7 @@ import android.text.style.ClickableSpan;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.StateSet; import android.util.StateSet;
import android.util.TypedValue; import android.util.TypedValue;
@ -155,6 +156,7 @@ import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.PickerBottomLayout; import org.telegram.ui.Components.PickerBottomLayout;
import org.telegram.ui.Components.PipRoundVideoView; import org.telegram.ui.Components.PipRoundVideoView;
import org.telegram.ui.Components.PipVideoOverlay; import org.telegram.ui.Components.PipVideoOverlay;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ShareAlert; import org.telegram.ui.Components.ShareAlert;
import org.telegram.ui.Components.TypefaceSpan; import org.telegram.ui.Components.TypefaceSpan;
@ -314,6 +316,7 @@ public class AndroidUtilities {
}; };
public static final String STICKERS_PLACEHOLDER_PACK_NAME = "tg_placeholders_android"; public static final String STICKERS_PLACEHOLDER_PACK_NAME = "tg_placeholders_android";
public static final String STICKERS_PLACEHOLDER_PACK_NAME_2 = "tg_superplaceholders_android_2";
private static boolean containsUnsupportedCharacters(String text) { private static boolean containsUnsupportedCharacters(String text) {
if (text.contains("\u202C")) { if (text.contains("\u202C")) {
@ -4441,6 +4444,7 @@ public class AndroidUtilities {
} }
public static void makeAccessibilityAnnouncement(CharSequence what) { public static void makeAccessibilityAnnouncement(CharSequence what) {
if (TextUtils.isEmpty(what)) return;
AccessibilityManager am = (AccessibilityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACCESSIBILITY_SERVICE); AccessibilityManager am = (AccessibilityManager) ApplicationLoader.applicationContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
if (am.isEnabled()) { if (am.isEnabled()) {
AccessibilityEvent ev = AccessibilityEvent.obtain(); AccessibilityEvent ev = AccessibilityEvent.obtain();

View file

@ -429,11 +429,6 @@ public class ApplicationLoader extends Application {
return false; return false;
} }
public static boolean useLessData() {
ensureCurrentNetworkGet();
return BuildVars.DEBUG_PRIVATE_VERSION && (SharedConfig.forceLessData || isConnectionSlow());
}
public static boolean isConnectionSlow() { public static boolean isConnectionSlow() {
try { try {
ensureCurrentNetworkGet(false); ensureCurrentNetworkGet(false);

View file

@ -23,7 +23,7 @@ public class ChatMessagesMetadataController {
} }
public void checkMessages(ChatActivity.ChatActivityAdapter chatAdapter, int maxAdapterPosition, int minAdapterPosition, long currentTime) { public void checkMessages(ChatActivity.ChatActivityAdapter chatAdapter, int maxAdapterPosition, int minAdapterPosition, long currentTime) {
ArrayList<MessageObject> messages = chatActivity.messages; ArrayList<MessageObject> messages = chatAdapter.getMessages();
if (!chatActivity.isInScheduleMode() && maxAdapterPosition >= 0 && minAdapterPosition >= 0) { if (!chatActivity.isInScheduleMode() && maxAdapterPosition >= 0 && minAdapterPosition >= 0) {
int from = minAdapterPosition - chatAdapter.messagesStartRow - 10; int from = minAdapterPosition - chatAdapter.messagesStartRow - 10;
int to = maxAdapterPosition - chatAdapter.messagesStartRow + 10; int to = maxAdapterPosition - chatAdapter.messagesStartRow + 10;

View file

@ -1409,10 +1409,22 @@ public class DatabaseMigrationHelper {
version = 138; version = 138;
} }
if (version == 138) { if (version == 138 || version == 139 || version == 140 || version == 141) {
database.executeFast("CREATE TABLE IF NOT EXISTS saved_reaction_tags (data BLOB);").stepThis().dispose(); database.executeFast("DROP TABLE IF EXISTS tag_message_id;").stepThis().dispose();
database.executeFast("PRAGMA user_version = 139").stepThis().dispose(); database.executeFast("CREATE TABLE tag_message_id(mid INTEGER, topic_id INTEGER, tag INTEGER, text TEXT);").stepThis().dispose();
version = 139; database.executeFast("CREATE INDEX IF NOT EXISTS tag_idx_tag_message_id ON tag_message_id(tag);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_text_idx_tag_message_id ON tag_message_id(tag, text);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_topic_idx_tag_message_id ON tag_message_id(topic_id, tag);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_topic_text_idx_tag_message_id ON tag_message_id(topic_id, tag, text);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 142").stepThis().dispose();
version = 142;
}
if (version == 142) {
database.executeFast("DROP TABLE IF EXISTS saved_reaction_tags;").stepThis().dispose();
database.executeFast("CREATE TABLE saved_reaction_tags (topic_id INTEGER PRIMARY KEY, data BLOB);").stepThis().dispose();
database.executeFast("PRAGMA user_version = 143").stepThis().dispose();
version = 143;
} }
return version; return version;

View file

@ -53,7 +53,7 @@ public class DocumentObject {
TLRPC.PhotoSize photoSize = sizes.get(a); TLRPC.PhotoSize photoSize = sizes.get(a);
if (photoSize instanceof TLRPC.TL_photoPathSize) { if (photoSize instanceof TLRPC.TL_photoPathSize) {
photoPathSize = (TLRPC.TL_photoPathSize) photoSize; photoPathSize = (TLRPC.TL_photoPathSize) photoSize;
} else { } else if (photoSize instanceof TLRPC.TL_photoSize) {
w = photoSize.w; w = photoSize.w;
h = photoSize.h; h = photoSize.h;
} }

View file

@ -2441,7 +2441,7 @@ public class FileLoadOperation {
} }
}, null, null, flags, datacenterId, connectionType, isLast); }, null, null, flags, datacenterId, connectionType, isLast);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("debug_loading: " + cacheFileFinal.getName() + " dc=" + datacenterId + " send reqId " + requestInfo.requestToken + " offset=" + requestInfo.offset + " conType=" + connectionType + " priority="); FileLog.d("debug_loading: " + cacheFileFinal.getName() + " dc=" + datacenterId + " send reqId " + requestInfo.requestToken + " offset=" + requestInfo.offset + " conType=" + connectionType + " priority=" + priority);
} }
requestsCount++; requestsCount++;
} }

View file

@ -984,7 +984,7 @@ public class FileLoader extends BaseController {
loaderQueue.checkLoadingOperations(operation.isStory && priority >= PRIORITY_HIGH); loaderQueue.checkLoadingOperations(operation.isStory && priority >= PRIORITY_HIGH);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("create load operation fileName=" + finalFileName + " documentName=" + getDocumentFileName(document) + " size=" + AndroidUtilities.formatFileSize(operation.totalBytesCount) + " position in queue " + operation.getPositionInQueue() + " account=" + currentAccount); FileLog.d("create load operation fileName=" + finalFileName + " documentName=" + getDocumentFileName(document) + " size=" + AndroidUtilities.formatFileSize(operation.totalBytesCount) + " position in queue " + operation.getPositionInQueue() + " account=" + currentAccount + " cacheType=" + cacheType);
} }
return operation; return operation;
} }

View file

@ -75,7 +75,7 @@ public class FileLog {
private static Gson gson; private static Gson gson;
private static HashSet<String> excludeRequests; private static HashSet<String> excludeRequests;
public static void dumpResponseAndRequest(TLObject request, TLObject response, TLRPC.TL_error error, long requestMsgId, long startRequestTimeInMillis, int requestToken) { public static void dumpResponseAndRequest(int account, TLObject request, TLObject response, TLRPC.TL_error error, long requestMsgId, long startRequestTimeInMillis, int requestToken) {
if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || request == null) { if (!BuildVars.DEBUG_PRIVATE_VERSION || !BuildVars.LOGS_ENABLED || request == null) {
return; return;
} }
@ -97,7 +97,7 @@ public class FileLog {
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
FileLog.getInstance().logQueue.postRunnable(() -> { FileLog.getInstance().logQueue.postRunnable(() -> {
try { try {
String metadata = "requestMsgId=" + requestMsgId + " requestingTime=" + (System.currentTimeMillis() - startRequestTimeInMillis) + " request_token=" + requestToken; String metadata = "requestMsgId=" + requestMsgId + " requestingTime=" + (System.currentTimeMillis() - startRequestTimeInMillis) + " request_token=" + requestToken + " account=" + account;
FileLog.getInstance().tlStreamWriter.write(getInstance().dateFormat.format(time) + " " + metadata); FileLog.getInstance().tlStreamWriter.write(getInstance().dateFormat.format(time) + " " + metadata);
FileLog.getInstance().tlStreamWriter.write("\n"); FileLog.getInstance().tlStreamWriter.write("\n");
FileLog.getInstance().tlStreamWriter.write(req); FileLog.getInstance().tlStreamWriter.write(req);

View file

@ -1,6 +1,7 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log;
import org.telegram.tgnet.RequestDelegate; import org.telegram.tgnet.RequestDelegate;
import org.telegram.tgnet.TLObject; import org.telegram.tgnet.TLObject;

View file

@ -1722,6 +1722,31 @@ public class LocaleController {
return "LOC_ERR"; return "LOC_ERR";
} }
public static String formatPmSeenDate(long date) {
try {
date *= 1000;
Calendar rightNow = Calendar.getInstance();
int day = rightNow.get(Calendar.DAY_OF_YEAR);
int year = rightNow.get(Calendar.YEAR);
rightNow.setTimeInMillis(date);
int dateDay = rightNow.get(Calendar.DAY_OF_YEAR);
int dateYear = rightNow.get(Calendar.YEAR);
if (dateDay == day && year == dateYear) {
return LocaleController.formatString(R.string.PmReadTodayAt, getInstance().formatterDay.format(new Date(date)));
} else if (dateDay + 1 == day && year == dateYear) {
return LocaleController.formatString(R.string.PmReadYesterdayAt, getInstance().formatterDay.format(new Date(date)));
} else if (Math.abs(System.currentTimeMillis() - date) < 31536000000L) {
return LocaleController.formatString(R.string.PmReadDateTimeAt, getInstance().formatterDayMonth.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
} else {
return LocaleController.formatString(R.string.PmReadDateTimeAt, getInstance().formatterYear.format(new Date(date)), getInstance().formatterDay.format(new Date(date)));
}
} catch (Exception e) {
FileLog.e(e);
}
return "LOC_ERR";
}
public static String formatShortDate(long date) { public static String formatShortDate(long date) {
try { try {
date *= 1000; date *= 1000;

View file

@ -54,7 +54,6 @@ import android.provider.OpenableColumns;
import android.telephony.PhoneStateListener; import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
@ -84,6 +83,7 @@ import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.EmbedBottomSheet; import org.telegram.ui.Components.EmbedBottomSheet;
import org.telegram.ui.Components.PhotoFilterView; import org.telegram.ui.Components.PhotoFilterView;
import org.telegram.ui.Components.PipRoundVideoView; import org.telegram.ui.Components.PipRoundVideoView;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.VideoPlayer; import org.telegram.ui.Components.VideoPlayer;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PhotoViewer; import org.telegram.ui.PhotoViewer;
@ -2397,10 +2397,10 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
//TODO topics //TODO topics
if (!playlistEndReached[0]) { if (!playlistEndReached[0]) {
loadingPlaylist = true; loadingPlaylist = true;
AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playingMessageObject.getDialogId(), 50, playlistMaxId[0], 0, MediaDataController.MEDIA_MUSIC, 0, 1, playlistClassGuid, 0); AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playingMessageObject.getDialogId(), 50, playlistMaxId[0], 0, MediaDataController.MEDIA_MUSIC, 0, 1, playlistClassGuid, 0, null, null);
} else if (playlistMergeDialogId != 0 && !playlistEndReached[1]) { } else if (playlistMergeDialogId != 0 && !playlistEndReached[1]) {
loadingPlaylist = true; loadingPlaylist = true;
AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playlistMergeDialogId, 50, playlistMaxId[0], 0, MediaDataController.MEDIA_MUSIC, 0, 1, playlistClassGuid, 0); AccountInstance.getInstance(playingMessageObject.currentAccount).getMediaDataController().loadMedia(playlistMergeDialogId, 50, playlistMaxId[0], 0, MediaDataController.MEDIA_MUSIC, 0, 1, playlistClassGuid, 0, null, null);
} }
} }
@ -5572,6 +5572,7 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
final String query; final String query;
final FiltersView.MediaFilterData filter; final FiltersView.MediaFilterData filter;
final long dialogId; final long dialogId;
public long topicId;
final long minDate; final long minDate;
final long maxDate; final long maxDate;
public int totalCount; public int totalCount;
@ -5579,6 +5580,8 @@ public class MediaController implements AudioManager.OnAudioFocusChangeListener,
public int nextSearchRate; public int nextSearchRate;
public int folderId; public int folderId;
public ReactionsLayoutInBubble.VisibleReaction reaction;
public PlaylistGlobalSearchParams(String query, long dialogId, long minDate, long maxDate, FiltersView.MediaFilterData filter) { public PlaylistGlobalSearchParams(String query, long dialogId, long minDate, long maxDate, FiltersView.MediaFilterData filter) {
this.filter = filter; this.filter = filter;
this.query = query; this.query = query;

View file

@ -60,10 +60,12 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.EmojiThemes; import org.telegram.ui.ActionBar.EmojiThemes;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
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.Bulletin; import org.telegram.ui.Components.Bulletin;
import org.telegram.ui.Components.ChatThemeBottomSheet; import org.telegram.ui.Components.ChatThemeBottomSheet;
import org.telegram.ui.Components.QuoteSpan; import org.telegram.ui.Components.QuoteSpan;
@ -566,7 +568,7 @@ public class MediaDataController extends BaseController {
boolean forceReload = false; boolean forceReload = false;
if (bots != null) { if (bots != null) {
if (!cache) { if (!cache) {
getMessagesStorage().putUsersAndChats(bots.users, null, true, false); getMessagesStorage().putUsersAndChats(bots.users, null, true, true);
} }
getMessagesController().putUsers(bots.users, cache); getMessagesController().putUsers(bots.users, cache);
AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.attachMenuBotsDidLoad)); AndroidUtilities.runOnUIThread(() -> NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.attachMenuBotsDidLoad));
@ -1199,6 +1201,31 @@ public class MediaDataController extends BaseController {
return null; return null;
} }
public void setPlaceholderImage(BackupImageView imageView, String setName, String emoji, String filter) {
TLRPC.InputStickerSet inputStickerSet = new TLRPC.TL_inputStickerSetShortName();
inputStickerSet.short_name = setName;
MediaDataController.getInstance(currentAccount).getStickerSet(inputStickerSet, 0, false, set -> {
if (set == null) return;
TLRPC.Document document = null;
for (int i = 0; i < set.packs.size(); ++i) {
if (!set.packs.get(i).documents.isEmpty() && TextUtils.equals(set.packs.get(i).emoticon, emoji)) {
long documentId = set.packs.get(i).documents.get(0);
for (int j = 0; j < set.documents.size(); ++j) {
if (set.documents.get(j).id == documentId) {
document = set.documents.get(j);
break;
}
}
break;
}
}
if (document != null) {
Drawable thumbDrawable = DocumentObject.getSvgThumb(document, Theme.key_windowBackgroundWhiteGrayIcon, 0.2f, 1f, null);
imageView.setImage(ImageLocation.getForDocument(document), filter, thumbDrawable, 0, document);
}
});
}
public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly) { public TLRPC.TL_messages_stickerSet getStickerSet(TLRPC.InputStickerSet inputStickerSet, boolean cacheOnly) {
return getStickerSet(inputStickerSet, null, cacheOnly, null); return getStickerSet(inputStickerSet, null, cacheOnly, null);
} }
@ -3344,15 +3371,108 @@ public class MediaDataController extends BaseController {
private int lastGuid; private int lastGuid;
private TLRPC.User lastSearchUser; private TLRPC.User lastSearchUser;
private TLRPC.Chat lastSearchChat; private TLRPC.Chat lastSearchChat;
private int messagesLocalSearchCount;
private int[] messagesSearchCount = new int[]{0, 0}; private int[] messagesSearchCount = new int[]{0, 0};
private boolean[] messagesSearchEndReached = new boolean[]{false, false}; private boolean[] messagesSearchEndReached = new boolean[]{false, false};
private ArrayList<MessageObject> searchResultMessages = new ArrayList<>(); public ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
private SparseArray<MessageObject>[] searchResultMessagesMap = new SparseArray[]{new SparseArray<>(), new SparseArray<>()}; public ArrayList<MessageObject> searchServerResultMessages = new ArrayList<>();
public ArrayList<MessageObject> searchLocalResultMessages = new ArrayList<>();
private SparseArray<MessageObject>[] searchServerResultMessagesMap = new SparseArray[]{new SparseArray<>(), new SparseArray<>()};
private ArrayList<MessageObject> deletedFromResultMessages = new ArrayList<>();
private String lastSearchQuery; private String lastSearchQuery;
private int lastReturnedNum; private int lastReturnedNum;
private boolean loadingMoreSearchMessages; private boolean loadingMoreSearchMessages;
private boolean loadingSearchLocal;
private boolean loadedPredirectedSearchLocal;
private int getMask() { public void removeMessageFromResults(int id) {
for (int i = 0; i < searchResultMessages.size(); ++i) {
MessageObject m = searchResultMessages.get(i);
if (id == m.getId()) {
deletedFromResultMessages.add(searchResultMessages.remove(i));
i--;
}
}
for (int i = 0; i < searchServerResultMessages.size(); ++i) {
MessageObject m = searchServerResultMessages.get(i);
if (id == m.getId()) {
searchServerResultMessages.remove(i);
i--;
}
}
for (int i = 0; i < searchLocalResultMessages.size(); ++i) {
MessageObject m = searchLocalResultMessages.get(i);
if (id == m.getId()) {
searchLocalResultMessages.remove(i);
i--;
}
}
}
public boolean processDeletedMessage(int id, long[] topic_id) {
boolean updated = false;
MessageObject messageObject = null;
for (int i = 0; i < deletedFromResultMessages.size(); ++i) {
if (deletedFromResultMessages.get(i).getId() == id) {
messageObject = deletedFromResultMessages.get(i);
break;
}
}
if (messageObject != null && messageObject.getDialogId() == getUserConfig().getClientUserId()) {
updated = getMessagesController().processDeletedReactionTags(messageObject.messageOwner);
topic_id[0] = MessageObject.getSavedDialogId(getUserConfig().getClientUserId(), messageObject.messageOwner);
}
deletedFromResultMessages.remove(messageObject);
return updated;
}
private void updateSearchResults() {
ArrayList<MessageObject> previousSearchResultMessages = new ArrayList<>(searchResultMessages);
searchResultMessages.clear();
HashSet<Integer> messageIds = new HashSet<>();
for (int i = 0; i < searchServerResultMessages.size(); ++i) {
MessageObject m = searchServerResultMessages.get(i);
if ((!m.hasValidGroupId() || m.isPrimaryGroupMessage) && !messageIds.contains(m.getId())) {
MessageObject prev = null;
for (int j = 0; j < previousSearchResultMessages.size(); ++j) {
if (previousSearchResultMessages.get(j).getId() == m.getId()) {
prev = previousSearchResultMessages.get(j);
break;
}
}
if (prev != null) {
m.copyStableParams(prev);
m.mediaExists = prev.mediaExists;
m.attachPathExists = prev.attachPathExists;
}
m.isSavedFiltered = true;
searchResultMessages.add(m);
messageIds.add(m.getId());
}
}
for (int i = 0; i < searchLocalResultMessages.size(); ++i) {
MessageObject m = searchLocalResultMessages.get(i);
if (!messageIds.contains(m.getId())) {
MessageObject prev = null;
for (int j = 0; j < previousSearchResultMessages.size(); ++j) {
if (previousSearchResultMessages.get(j).getId() == m.getId()) {
prev = previousSearchResultMessages.get(j);
break;
}
}
if (prev != null) {
m.copyStableParams(prev);
m.mediaExists = prev.mediaExists;
m.attachPathExists = prev.attachPathExists;
}
m.isSavedFiltered = true;
searchResultMessages.add(m);
messageIds.add(m.getId());
}
}
}
public int getMask() {
int mask = 0; int mask = 0;
if (lastReturnedNum < searchResultMessages.size() - 1 || !messagesSearchEndReached[0] || !messagesSearchEndReached[1]) { if (lastReturnedNum < searchResultMessages.size() - 1 || !messagesSearchEndReached[0] || !messagesSearchEndReached[1]) {
mask |= 1; mask |= 1;
@ -3369,10 +3489,12 @@ public class MediaDataController extends BaseController {
public void clearFoundMessageObjects() { public void clearFoundMessageObjects() {
searchResultMessages.clear(); searchResultMessages.clear();
searchServerResultMessages.clear();
searchLocalResultMessages.clear();
} }
public boolean isMessageFound(int messageId, boolean mergeDialog) { public boolean isMessageFound(int messageId, boolean mergeDialog) {
return searchResultMessagesMap[mergeDialog ? 1 : 0].indexOfKey(messageId) >= 0; return searchServerResultMessagesMap[mergeDialog ? 1 : 0].indexOfKey(messageId) >= 0;
} }
public void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, long replyMessageId, TLRPC.User user, TLRPC.Chat chat, ReactionsLayoutInBubble.VisibleReaction reaction) { public void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, long replyMessageId, TLRPC.User user, TLRPC.Chat chat, ReactionsLayoutInBubble.VisibleReaction reaction) {
@ -3385,29 +3507,52 @@ public class MediaDataController extends BaseController {
} }
lastReturnedNum = index; lastReturnedNum = index;
MessageObject messageObject = searchResultMessages.get(lastReturnedNum); MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1], true); getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, getSearchCount(), true);
}
public int getSearchPosition() {
return lastReturnedNum;
}
public int getSearchCount() {
if (searchServerResultMessages.isEmpty()) {
return Math.max(Math.max(messagesSearchCount[0] + messagesSearchCount[1], messagesLocalSearchCount), searchServerResultMessages.size());
}
return Math.max(messagesSearchCount[0] + messagesSearchCount[1], searchServerResultMessages.size());
}
public void setSearchedPosition(int index) {
if (index < 0 || index >= searchResultMessages.size()) {
return;
}
lastReturnedNum = index;
} }
public boolean searchEndReached() { public boolean searchEndReached() {
return messagesSearchEndReached[0] && lastMergeDialogId == 0 && messagesSearchEndReached[1]; return messagesSearchEndReached[0] && lastMergeDialogId == 0 && messagesSearchEndReached[1] || (loadingSearchLocal || loadedPredirectedSearchLocal);
} }
public void loadMoreSearchMessages() { public void loadMoreSearchMessages(boolean fromList) {
if (loadingMoreSearchMessages || messagesSearchEndReached[0] && lastMergeDialogId == 0 && messagesSearchEndReached[1]) { if (loadingMoreSearchMessages || reqId != 0 || messagesSearchEndReached[0] && lastMergeDialogId == 0 && messagesSearchEndReached[1]) {
return; return;
} }
int temp = searchResultMessages.size(); int temp = lastReturnedNum;
lastReturnedNum = searchResultMessages.size(); lastReturnedNum = searchResultMessages.size();
loadingMoreSearchMessages = true;
searchMessagesInChat(null, lastDialogId, lastMergeDialogId, lastGuid, 1, lastReplyMessageId, false, lastSearchUser, lastSearchChat, false, lastReaction); searchMessagesInChat(null, lastDialogId, lastMergeDialogId, lastGuid, 1, lastReplyMessageId, false, lastSearchUser, lastSearchChat, false, lastReaction);
lastReturnedNum = temp; lastReturnedNum = temp;
loadingMoreSearchMessages = true;
} }
private void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, long replyMessageId, boolean internal, TLRPC.User user, TLRPC.Chat chat, boolean jumpToMessage, ReactionsLayoutInBubble.VisibleReaction reaction) { public boolean isSearchLoading() {
return reqId != 0;
}
public void searchMessagesInChat(String query, long dialogId, long mergeDialogId, int guid, int direction, long replyMessageId, boolean internal, TLRPC.User user, TLRPC.Chat chat, boolean jumpToMessage, ReactionsLayoutInBubble.VisibleReaction reaction) {
int max_id = 0; int max_id = 0;
long queryWithDialog = dialogId; long queryWithDialog = dialogId;
boolean firstQuery = !internal; boolean firstQuery = !internal;
if (reqId != 0) { if (reqId != 0) {
loadingMoreSearchMessages = false;
getConnectionsManager().cancelRequest(reqId, true); getConnectionsManager().cancelRequest(reqId, true);
reqId = 0; reqId = 0;
} }
@ -3417,17 +3562,20 @@ public class MediaDataController extends BaseController {
} }
if (query == null) { if (query == null) {
if (searchResultMessages.isEmpty()) { if (searchResultMessages.isEmpty()) {
loadingMoreSearchMessages = false;
return; return;
} }
if (direction == 1) { if (direction == 1) {
lastReturnedNum++; lastReturnedNum++;
if (lastReturnedNum < searchResultMessages.size()) { if (lastReturnedNum < searchResultMessages.size()) {
MessageObject messageObject = searchResultMessages.get(lastReturnedNum); MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1], jumpToMessage); getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, getSearchCount(), jumpToMessage);
loadingMoreSearchMessages = false;
return; return;
} else { } else {
if (messagesSearchEndReached[0] && mergeDialogId == 0 && messagesSearchEndReached[1]) { if (messagesSearchEndReached[0] && mergeDialogId == 0 && messagesSearchEndReached[1]) {
lastReturnedNum--; lastReturnedNum--;
loadingMoreSearchMessages = false;
return; return;
} }
firstQuery = false; firstQuery = false;
@ -3454,17 +3602,20 @@ public class MediaDataController extends BaseController {
lastReturnedNum = searchResultMessages.size() - 1; lastReturnedNum = searchResultMessages.size() - 1;
} }
MessageObject messageObject = searchResultMessages.get(lastReturnedNum); MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1], jumpToMessage); getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, getSearchCount(), jumpToMessage);
loadingMoreSearchMessages = false;
return; return;
} else { } else {
loadingMoreSearchMessages = false;
return; return;
} }
} else if (firstQuery) { } else if (firstQuery) {
messagesSearchEndReached[0] = messagesSearchEndReached[1] = false; messagesSearchEndReached[0] = messagesSearchEndReached[1] = false;
messagesSearchCount[0] = messagesSearchCount[1] = 0; messagesSearchCount[0] = messagesSearchCount[1] = 0;
searchResultMessages.clear(); searchResultMessages.clear();
searchResultMessagesMap[0].clear(); searchLocalResultMessages.clear();
searchResultMessagesMap[1].clear(); searchServerResultMessagesMap[0].clear();
searchServerResultMessagesMap[1].clear();
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsLoading, guid); getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsLoading, guid);
} }
if (messagesSearchEndReached[0] && !messagesSearchEndReached[1] && mergeDialogId != 0) { if (messagesSearchEndReached[0] && !messagesSearchEndReached[1] && mergeDialogId != 0) {
@ -3527,6 +3678,7 @@ public class MediaDataController extends BaseController {
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.peer = getMessagesController().getInputPeer(queryWithDialog); req.peer = getMessagesController().getInputPeer(queryWithDialog);
if (req.peer == null) { if (req.peer == null) {
loadingMoreSearchMessages = false;
return; return;
} }
lastGuid = guid; lastGuid = guid;
@ -3545,6 +3697,33 @@ public class MediaDataController extends BaseController {
req.from_id = MessagesController.getInputPeer(chat); req.from_id = MessagesController.getInputPeer(chat);
req.flags |= 1; req.flags |= 1;
} }
loadingSearchLocal = false;
loadedPredirectedSearchLocal = false;
int currentReqId = ++lastReqId;
final boolean isSaved = dialogId == getUserConfig().getClientUserId();
if (isSaved && reaction != null && firstQuery) {
lastReturnedNum = 0;
searchServerResultMessages.clear();
searchServerResultMessagesMap[0].clear();
searchServerResultMessagesMap[1].clear();
final int predictedCount = getMessagesController().getSavedTagCount(lastReplyMessageId, reaction);
messagesLocalSearchCount = TextUtils.isEmpty(req.q) ? predictedCount : 0;
loadingSearchLocal = true;
loadedPredirectedSearchLocal = false;
getMessagesStorage().searchSavedByTag(reaction.toTLReaction(), lastReplyMessageId, query, 300, searchLocalResultMessages == null ? 0 : searchLocalResultMessages.size(), (messages, users, chats, emojis) -> {
if (currentReqId == lastReqId) {
loadedPredirectedSearchLocal = messages.size() == predictedCount;
loadingSearchLocal = false;
getMessagesController().putUsers(users, true);
getMessagesController().putChats(chats, true);
AnimatedEmojiDrawable.getDocumentFetcher(currentAccount).processDocuments(emojis);
searchLocalResultMessages = messages;
updateSearchResults();
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), dialogId, lastReturnedNum, getSearchCount(), true);
}
}, true);
}
if (lastReplyMessageId != 0) { if (lastReplyMessageId != 0) {
if (queryWithDialog == getUserConfig().getClientUserId()) { if (queryWithDialog == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(lastReplyMessageId); req.saved_peer_id = getMessagesController().getInputPeer(lastReplyMessageId);
@ -3559,7 +3738,6 @@ public class MediaDataController extends BaseController {
req.flags |= 8; req.flags |= 8;
} }
req.filter = new TLRPC.TL_inputMessagesFilterEmpty(); req.filter = new TLRPC.TL_inputMessagesFilterEmpty();
int currentReqId = ++lastReqId;
lastSearchQuery = query; lastSearchQuery = query;
long queryWithDialogFinal = queryWithDialog; long queryWithDialogFinal = queryWithDialog;
String finalQuery = query; String finalQuery = query;
@ -3568,10 +3746,13 @@ public class MediaDataController extends BaseController {
if (error == null) { if (error == null) {
TLRPC.messages_Messages res = (TLRPC.messages_Messages) response; TLRPC.messages_Messages res = (TLRPC.messages_Messages) response;
int N = Math.min(res.messages.size(), 20); int N = Math.min(res.messages.size(), req.limit - 1);
for (int a = 0; a < N; a++) { for (int a = 0; a < N; a++) {
TLRPC.Message message = res.messages.get(a); TLRPC.Message message = res.messages.get(a);
MessageObject messageObject = new MessageObject(currentAccount, message, false, false); MessageObject messageObject = new MessageObject(currentAccount, message, null, null, null, null, null, true, true, 0, false, false, isSaved);
if (messageObject.hasValidGroupId()) {
messageObject.isPrimaryGroupMessage = true;
}
messageObject.setQuery(finalQuery); messageObject.setQuery(finalQuery);
messageObjects.add(messageObject); messageObjects.add(messageObject);
} }
@ -3594,38 +3775,47 @@ public class MediaDataController extends BaseController {
getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true); getMessagesStorage().putUsersAndChats(res.users, res.chats, true, true);
getMessagesController().putUsers(res.users, false); getMessagesController().putUsers(res.users, false);
getMessagesController().putChats(res.chats, false); getMessagesController().putChats(res.chats, false);
if (req.offset_id == 0 && queryWithDialogFinal == dialogId) { Runnable done = () -> {
lastReturnedNum = 0; if (req.offset_id == 0 && queryWithDialogFinal == dialogId) {
searchResultMessages.clear(); lastReturnedNum = 0;
searchResultMessagesMap[0].clear(); searchServerResultMessages.clear();
searchResultMessagesMap[1].clear(); searchServerResultMessagesMap[0].clear();
messagesSearchCount[0] = 0; searchServerResultMessagesMap[1].clear();
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsLoading, guid); messagesSearchCount[0] = 0;
} getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsLoading, guid);
boolean added = false;
int N = Math.min(res.messages.size(), 20);
for (int a = 0; a < N; a++) {
TLRPC.Message message = res.messages.get(a);
added = true;
MessageObject messageObject = messageObjects.get(a);
searchResultMessages.add(messageObject);
searchResultMessagesMap[queryWithDialogFinal == dialogId ? 0 : 1].put(messageObject.getId(), messageObject);
}
messagesSearchEndReached[queryWithDialogFinal == dialogId ? 0 : 1] = res.messages.size() < req.limit;
messagesSearchCount[queryWithDialogFinal == dialogId ? 0 : 1] = res instanceof TLRPC.TL_messages_messagesSlice || res instanceof TLRPC.TL_messages_channelMessages ? res.count : res.messages.size();
if (searchResultMessages.isEmpty()) {
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0, 0, 0, jumpToMessage);
} else {
if (added) {
if (lastReturnedNum >= searchResultMessages.size()) {
lastReturnedNum = searchResultMessages.size() - 1;
}
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, messagesSearchCount[0] + messagesSearchCount[1], jumpToMessage);
} }
} boolean added = false;
if (queryWithDialogFinal == dialogId && messagesSearchEndReached[0] && mergeDialogId != 0 && !messagesSearchEndReached[1]) { int N = Math.min(res.messages.size(), req.limit - 1);
searchMessagesInChat(lastSearchQuery, dialogId, mergeDialogId, guid, 0, replyMessageId, true, user, chat, jumpToMessage, lastReaction); for (int a = 0; a < N; a++) {
added = true;
MessageObject messageObject = messageObjects.get(a);
searchServerResultMessages.add(messageObject);
searchServerResultMessagesMap[queryWithDialogFinal == dialogId ? 0 : 1].put(messageObject.getId(), messageObject);
}
updateSearchResults();
messagesSearchEndReached[queryWithDialogFinal == dialogId ? 0 : 1] = res.messages.size() < req.limit;
messagesSearchCount[queryWithDialogFinal == dialogId ? 0 : 1] = res instanceof TLRPC.TL_messages_messagesSlice || res instanceof TLRPC.TL_messages_channelMessages ? res.count : res.messages.size();
if (searchServerResultMessages.isEmpty()) {
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), (long) 0, 0, 0, jumpToMessage);
} else {
if (added) {
if (lastReturnedNum >= searchResultMessages.size()) {
lastReturnedNum = searchResultMessages.size() - 1;
}
MessageObject messageObject = searchResultMessages.get(lastReturnedNum);
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, messageObject.getId(), getMask(), messageObject.getDialogId(), lastReturnedNum, getSearchCount(), jumpToMessage);
} else if (isSaved) {
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), dialogId, lastReturnedNum, getSearchCount(), false);
}
}
if (queryWithDialogFinal == dialogId && messagesSearchEndReached[0] && mergeDialogId != 0 && !messagesSearchEndReached[1]) {
searchMessagesInChat(lastSearchQuery, dialogId, mergeDialogId, guid, 0, replyMessageId, true, user, chat, jumpToMessage, lastReaction);
}
};
if (isSaved) {
loadReplyMessagesForMessages(messageObjects, dialogId, false, lastReplyMessageId, done, guid);
} else {
done.run();
} }
} }
} }
@ -3633,6 +3823,22 @@ public class MediaDataController extends BaseController {
}, ConnectionsManager.RequestFlagFailOnServerErrors); }, ConnectionsManager.RequestFlagFailOnServerErrors);
} }
public void portSavedSearchResults(int guid, ReactionsLayoutInBubble.VisibleReaction reaction, String query, ArrayList<MessageObject> local, ArrayList<MessageObject> loaded, int num, int count, boolean reached) {
lastReaction = reaction;
lastSearchQuery = query;
messagesSearchEndReached[0] = reached;
messagesSearchEndReached[1] = true;
searchServerResultMessages.clear();
searchServerResultMessages.addAll(loaded);
searchLocalResultMessages.clear();
searchLocalResultMessages.addAll(local);
updateSearchResults();
messagesSearchCount[0] = count;
messagesSearchCount[1] = 0;
lastReturnedNum = num;
getNotificationCenter().postNotificationName(NotificationCenter.chatSearchResultsAvailable, guid, 0, getMask(), getUserConfig().getClientUserId(), lastReturnedNum, getSearchCount(), true);
}
public String getLastSearchQuery() { public String getLastSearchQuery() {
return lastSearchQuery; return lastSearchQuery;
} }
@ -3651,14 +3857,14 @@ public class MediaDataController extends BaseController {
public final static int MEDIA_STORIES = 8; public final static int MEDIA_STORIES = 8;
public void loadMedia(long dialogId, int count, int max_id, int min_id, int type, long topicId, int fromCache, int classGuid, int requestIndex) { public void loadMedia(long dialogId, int count, int max_id, int min_id, int type, long topicId, int fromCache, int classGuid, int requestIndex, ReactionsLayoutInBubble.VisibleReaction tag, String query) {
boolean isChannel = DialogObject.isChatDialog(dialogId) && ChatObject.isChannel(-dialogId, currentAccount); boolean isChannel = DialogObject.isChatDialog(dialogId) && ChatObject.isChannel(-dialogId, currentAccount);
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("load media did " + dialogId + " count = " + count + " max_id " + max_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid); FileLog.d("load media did " + dialogId + " count = " + count + " max_id " + max_id + " type = " + type + " cache = " + fromCache + " classGuid = " + classGuid);
} }
if (fromCache != 0 || DialogObject.isEncryptedDialog(dialogId)) { if (fromCache != 0 && TextUtils.isEmpty(query) || DialogObject.isEncryptedDialog(dialogId)) {
loadMediaDatabase(dialogId, count, max_id, min_id, type, topicId, classGuid, isChannel, fromCache, requestIndex); loadMediaDatabase(dialogId, count, max_id, min_id, type, topicId, tag, classGuid, isChannel, fromCache, requestIndex);
} else { } else {
TLRPC.TL_messages_search req = new TLRPC.TL_messages_search(); TLRPC.TL_messages_search req = new TLRPC.TL_messages_search();
req.limit = count; req.limit = count;
@ -3668,6 +3874,10 @@ public class MediaDataController extends BaseController {
} else { } else {
req.offset_id = max_id; req.offset_id = max_id;
} }
if (tag != null) {
req.flags |= 8;
req.saved_reaction.add(tag.toTLReaction());
}
if (type == MEDIA_PHOTOVIDEO) { if (type == MEDIA_PHOTOVIDEO) {
req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo(); req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo();
@ -3686,7 +3896,11 @@ public class MediaDataController extends BaseController {
} else if (type == MEDIA_GIF) { } else if (type == MEDIA_GIF) {
req.filter = new TLRPC.TL_inputMessagesFilterGif(); req.filter = new TLRPC.TL_inputMessagesFilterGif();
} }
req.q = ""; if (!TextUtils.isEmpty(query)) {
req.q = query;
} else {
req.q = "";
}
req.peer = getMessagesController().getInputPeer(dialogId); req.peer = getMessagesController().getInputPeer(dialogId);
if (topicId != 0) { if (topicId != 0) {
if (dialogId == getUserConfig().getClientUserId()) { if (dialogId == getUserConfig().getClientUserId()) {
@ -3834,7 +4048,7 @@ public class MediaDataController extends BaseController {
}); });
getConnectionsManager().bindRequestToGuid(reqId, classGuid); getConnectionsManager().bindRequestToGuid(reqId, classGuid);
} }
if (!missing) { if (!missing || getConnectionsManager().getConnectionState() != ConnectionsManager.ConnectionStateConnected) {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.mediaCountsDidLoad, dialogId, topicId, countsFinal)); AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.mediaCountsDidLoad, dialogId, topicId, countsFinal));
} }
} }
@ -3864,7 +4078,7 @@ public class MediaDataController extends BaseController {
} }
if (topicId != 0) { if (topicId != 0) {
if (dialogId == getUserConfig().getClientUserId()) { if (dialogId == getUserConfig().getClientUserId()) {
req.saved_peer_id = getMessagesController().getInputPeer(dialogId); req.saved_peer_id = getMessagesController().getInputPeer(topicId);
req.flags |= 4; req.flags |= 4;
} else { } else {
req.top_msg_id = (int) topicId; req.top_msg_id = (int) topicId;
@ -3967,7 +4181,7 @@ public class MediaDataController extends BaseController {
if (fromCache == 2) { if (fromCache == 2) {
return; return;
} }
loadMedia(dialogId, count, max_id, min_id, type, topicId, 0, classGuid, requestIndex); loadMedia(dialogId, count, max_id, min_id, type, topicId, 0, classGuid, requestIndex, null, null);
} else { } else {
if (fromCache == 0) { if (fromCache == 0) {
ImageLoader.saveMessagesThumbs(res.messages); ImageLoader.saveMessagesThumbs(res.messages);
@ -4093,11 +4307,12 @@ public class MediaDataController extends BaseController {
}); });
} }
private void loadMediaDatabase(long uid, int count, int max_id, int min_id, int type, long topicId, int classGuid, boolean isChannel, int fromCache, int requestIndex) { private void loadMediaDatabase(long uid, int count, int max_id, int min_id, int type, long topicId, ReactionsLayoutInBubble.VisibleReaction tag, int classGuid, boolean isChannel, int fromCache, int requestIndex) {
Runnable runnable = new Runnable() { Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
boolean topReached = false; boolean topReached = false;
final long selfId = getUserConfig().getClientUserId();
TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages(); TLRPC.TL_messages_messages res = new TLRPC.TL_messages_messages();
try { try {
ArrayList<Long> usersToLoad = new ArrayList<>(); ArrayList<Long> usersToLoad = new ArrayList<>();
@ -4151,6 +4366,20 @@ public class MediaDataController extends BaseController {
cursor.dispose(); cursor.dispose();
} }
String beforeWhere = "";
String afterWhere = "";
if (tag != null) {
long taghash = 0;
if (!TextUtils.isEmpty(tag.emojicon)) {
taghash = tag.emojicon.hashCode();
} else {
taghash = tag.documentId;
}
beforeWhere = "INNER JOIN tag_message_id t ON m.mid = t.mid";
afterWhere = "t.tag = " + taghash + " AND";
}
int holeMessageId = 0; int holeMessageId = 0;
if (max_id != 0) { if (max_id != 0) {
int startHole = 0; int startHole = 0;
@ -4167,17 +4396,17 @@ public class MediaDataController extends BaseController {
if (topicId != 0) { if (topicId != 0) {
if (holeMessageId > 1) { if (holeMessageId > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_topics WHERE uid = %d AND topic_id = %d AND mid > 0 AND mid < %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, topicId, max_id, holeMessageId, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_topics m %s WHERE %s m.uid = %d AND m.topic_id = %d AND m.mid > 0 AND m.mid < %d AND m.mid >= %d AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, topicId, max_id, holeMessageId, type, countToLoad));
isEnd = false; isEnd = false;
} else { } else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_topics WHERE uid = %d AND topic_id = %d AND mid > 0 AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, topicId, max_id, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_topics m %s WHERE %s m.uid = %d AND m.topic_id = %d AND m.mid > 0 AND m.mid < %d AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, topicId, max_id, type, countToLoad));
} }
} else { } else {
if (holeMessageId > 1) { if (holeMessageId > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid < %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, holeMessageId, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_v4 m %s WHERE %s m.uid = %d AND m.mid > 0 AND m.mid < %d AND m.mid >= %d AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, max_id, holeMessageId, type, countToLoad));
isEnd = false; isEnd = false;
} else { } else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid < %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, max_id, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_v4 m %s WHERE %s m.uid = %d AND m.mid > 0 AND m.mid < %d AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, max_id, type, countToLoad));
} }
} }
} else if (min_id != 0) { } else if (min_id != 0) {
@ -4195,17 +4424,17 @@ public class MediaDataController extends BaseController {
reverseMessages = true; reverseMessages = true;
if (topicId != 0) { if (topicId != 0) {
if (startHole > 1) { if (startHole > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_topics WHERE uid = %d AND topic_id = %d AND mid > 0 AND mid >= %d AND mid <= %d AND type = %d ORDER BY date ASC, mid ASC LIMIT %d", uid, topicId, min_id, startHole, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_topics m %s WHERE %s m.uid = %d AND m.topic_id = %d AND m.mid > 0 AND m.mid >= %d AND m.mid <= %d AND m.type = %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", beforeWhere, afterWhere, uid, topicId, min_id, startHole, type, countToLoad));
} else { } else {
isEnd = true; isEnd = true;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_topics WHERE uid = %d AND topic_id = %d AND mid > 0 AND mid >= %d AND type = %d ORDER BY date ASC, mid ASC LIMIT %d", uid, topicId, min_id, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_topics m %s WHERE %s m.uid = %d AND m.topic_id = %d AND m.mid > 0 AND m.mid >= %d AND m.type = %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", beforeWhere, afterWhere, uid, topicId, min_id, type, countToLoad));
} }
} else { } else {
if (startHole > 1) { if (startHole > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid >= %d AND mid <= %d AND type = %d ORDER BY date ASC, mid ASC LIMIT %d", uid, min_id, startHole, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_v4 m %s WHERE %s m.uid = %d AND m.mid > 0 AND m.mid >= %d AND m.mid <= %d AND m.type = %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", beforeWhere, afterWhere, uid, min_id, startHole, type, countToLoad));
} else { } else {
isEnd = true; isEnd = true;
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND mid >= %d AND type = %d ORDER BY date ASC, mid ASC LIMIT %d", uid, min_id, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_v4 m %s WHERE %s m.uid = %d AND m.mid > 0 AND m.mid >= %d AND m.type = %d ORDER BY m.date ASC, m.mid ASC LIMIT %d", beforeWhere, afterWhere, uid, min_id, type, countToLoad));
} }
} }
} else { } else {
@ -4220,15 +4449,15 @@ public class MediaDataController extends BaseController {
cursor.dispose(); cursor.dispose();
if (topicId != 0) { if (topicId != 0) {
if (holeMessageId > 1) { if (holeMessageId > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_topics WHERE uid = %d AND topic_id = %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, topicId, holeMessageId, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_topics m %s WHERE %s m.uid = %d AND m.topic_id = %d AND m.mid >= %d AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, topicId, holeMessageId, type, countToLoad));
} else { } else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_topics WHERE uid = %d AND topic_id = %d AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, topicId, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_topics m %s WHERE %s m.uid = %d AND m.topic_id = %d AND m.mid > 0 AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, topicId, type, countToLoad));
} }
} else { } else {
if (holeMessageId > 1) { if (holeMessageId > 1) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid >= %d AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, holeMessageId, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_v4 m %s WHERE %s m.uid = %d AND m.mid >= %d AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, holeMessageId, type, countToLoad));
} else { } else {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data, mid FROM media_v4 WHERE uid = %d AND mid > 0 AND type = %d ORDER BY date DESC, mid DESC LIMIT %d", uid, type, countToLoad)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT m.data, m.mid FROM media_v4 m %s WHERE %s m.uid = %d AND m.mid > 0 AND m.type = %d ORDER BY m.date DESC, m.mid DESC LIMIT %d", beforeWhere, afterWhere, uid, type, countToLoad));
} }
} }
} }
@ -4254,17 +4483,21 @@ public class MediaDataController extends BaseController {
} }
HashSet<Long> groupsToLoad = tag != null ? new HashSet<>() : null;
while (cursor.next()) { while (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0); NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) { if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, getUserConfig().clientUserId); message.readAttachPath(data, selfId);
data.reuse(); data.reuse();
message.id = cursor.intValue(1); message.id = cursor.intValue(1);
message.dialog_id = uid; message.dialog_id = uid;
if (DialogObject.isEncryptedDialog(uid)) { if (DialogObject.isEncryptedDialog(uid)) {
message.random_id = cursor.longValue(2); message.random_id = cursor.longValue(2);
} }
if (message.grouped_id != 0 && groupsToLoad != null) {
groupsToLoad.add(message.grouped_id);
}
if (reverseMessages) { if (reverseMessages) {
res.messages.add(0, message); res.messages.add(0, message);
} else { } else {
@ -4276,6 +4509,38 @@ public class MediaDataController extends BaseController {
} }
cursor.dispose(); cursor.dispose();
if (tag != null && !groupsToLoad.isEmpty()) {
for (long grouped_id : groupsToLoad) {
int index = -1;
for (int i = 0; i < res.messages.size(); ++i) {
if (res.messages.get(i).grouped_id == grouped_id) {
index = i;
break;
}
}
if (index < 0) continue;
cursor = database.queryFinalized("SELECT data, mid FROM messages_v2 WHERE uid = ? AND group_id = ? ORDER BY mid DESC", uid, grouped_id);
ArrayList<TLRPC.Message> groupMessages = new ArrayList<>();
while (cursor.next()) {
int id = cursor.intValue(1);
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data == null) continue;
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, selfId);
data.reuse();
message.id = id;
message.dialog_id = uid;
groupMessages.add(message);
MessagesStorage.addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad, null);
}
if (reverseMessages)
Collections.reverse(groupMessages);
res.messages.remove(index);
res.messages.addAll(index, groupMessages);
cursor.dispose();
}
}
if (!usersToLoad.isEmpty()) { if (!usersToLoad.isEmpty()) {
getMessagesStorage().getUsersInternal(TextUtils.join(",", usersToLoad), res.users); getMessagesStorage().getUsersInternal(TextUtils.join(",", usersToLoad), res.users);
} }
@ -7566,8 +7831,12 @@ public class MediaDataController extends BaseController {
} }
private HashMap<String, Boolean> currentFetchingEmoji = new HashMap<>(); private HashMap<String, Boolean> currentFetchingEmoji = new HashMap<>();
private HashSet<String> fetchedEmoji = new HashSet<>();
public void fetchNewEmojiKeywords(String[] langCodes) { public void fetchNewEmojiKeywords(String[] langCodes) {
fetchNewEmojiKeywords(langCodes, false);
}
public void fetchNewEmojiKeywords(String[] langCodes, boolean doNotFetchTwice) {
if (langCodes == null) { if (langCodes == null) {
return; return;
} }
@ -7576,7 +7845,7 @@ public class MediaDataController extends BaseController {
if (TextUtils.isEmpty(langCode)) { if (TextUtils.isEmpty(langCode)) {
return; return;
} }
if (currentFetchingEmoji.get(langCode) != null) { if (currentFetchingEmoji.get(langCode) != null || doNotFetchTwice && fetchedEmoji.contains(langCode)) {
return; return;
} }
currentFetchingEmoji.put(langCode, true); currentFetchingEmoji.put(langCode, true);
@ -7596,7 +7865,11 @@ public class MediaDataController extends BaseController {
FileLog.e(e); FileLog.e(e);
} }
if (!BuildVars.DEBUG_VERSION && Math.abs(System.currentTimeMillis() - date) < 60 * 60 * 1000) { if (!BuildVars.DEBUG_VERSION && Math.abs(System.currentTimeMillis() - date) < 60 * 60 * 1000) {
AndroidUtilities.runOnUIThread(() -> currentFetchingEmoji.remove(langCode)); AndroidUtilities.runOnUIThread(() -> {
currentFetchingEmoji.remove(langCode);
fetchedEmoji.add(langCode);
getNotificationCenter().postNotificationName(NotificationCenter.emojiKeywordsLoaded);
});
return; return;
} }
TLObject request; TLObject request;
@ -7625,7 +7898,9 @@ public class MediaDataController extends BaseController {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
currentFetchingEmoji.remove(langCode); currentFetchingEmoji.remove(langCode);
fetchedEmoji.add(langCode);
fetchNewEmojiKeywords(new String[]{langCode}); fetchNewEmojiKeywords(new String[]{langCode});
getNotificationCenter().postNotificationName(NotificationCenter.emojiKeywordsLoaded);
}); });
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -7633,9 +7908,16 @@ public class MediaDataController extends BaseController {
}); });
} else { } else {
putEmojiKeywords(langCode, res); putEmojiKeywords(langCode, res);
AndroidUtilities.runOnUIThread(() -> {
getNotificationCenter().postNotificationName(NotificationCenter.emojiKeywordsLoaded);
});
} }
} else { } else {
AndroidUtilities.runOnUIThread(() -> currentFetchingEmoji.remove(langCode)); AndroidUtilities.runOnUIThread(() -> {
currentFetchingEmoji.remove(langCode);
fetchedEmoji.add(langCode);
getNotificationCenter().postNotificationName(NotificationCenter.emojiKeywordsLoaded);
});
} }
}); });
}); });
@ -7752,6 +8034,44 @@ public class MediaDataController extends BaseController {
}); });
} }
public void getEmojiNames(String[] langCodes, String emoji, Utilities.Callback<ArrayList<String>> whenDone) {
if (whenDone == null || emoji == null) return;
getMessagesStorage().getStorageQueue().postRunnable(() -> {
SQLiteCursor cursor = null;
try {
Object[] args = new Object[1 + langCodes.length];
args[0] = emoji;
String langQuery = "1 = 1";
for (int i = 0; i < langCodes.length; ++i) {
if (i == 0) langQuery = "lang = ?";
else langQuery = langQuery + " OR lang = ?";
cursor = getMessagesStorage().getDatabase().queryFinalized("SELECT alias FROM emoji_keywords_info_v2 WHERE lang = ?", langCodes[i]);
if (cursor.next()) {
langCodes[i] = cursor.stringValue(0);
}
cursor.dispose();
args[1 + i] = langCodes[i];
}
cursor = getMessagesStorage().getDatabase().executeFast("SELECT keyword FROM emoji_keywords_v2 WHERE emoji = ? AND (" + langQuery + ")").query(args);
ArrayList<String> names = new ArrayList<>();
while (cursor.next()) {
String name = cursor.stringValue(0);
names.add(name);
}
AndroidUtilities.runOnUIThread(() -> {
whenDone.run(names);
});
} catch (Exception e) {
FileLog.e(e);
} finally {
if (cursor != null) {
cursor.dispose();
cursor = null;
}
}
});
}
public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, boolean allowAnimated) { public void getEmojiSuggestions(String[] langCodes, String keyword, boolean fullMatch, KeywordResultCallback callback, boolean allowAnimated) {
getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, false, false, null); getEmojiSuggestions(langCodes, keyword, fullMatch, callback, null, allowAnimated, false, false, null);
} }
@ -8502,7 +8822,7 @@ public class MediaDataController extends BaseController {
saveReactionsToPref(savedReactionsPref, reactions.hash, reactions.reactions); saveReactionsToPref(savedReactionsPref, reactions.hash, reactions.reactions);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate); getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate, 0L);
} }
if (response instanceof TLRPC.TL_messages_reactionsNotModified) { if (response instanceof TLRPC.TL_messages_reactionsNotModified) {

View file

@ -34,6 +34,7 @@ import android.text.style.URLSpan;
import android.text.util.Linkify; import android.text.util.Linkify;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import android.util.SparseIntArray;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
@ -167,6 +168,7 @@ public class MessageObject {
public long eventId; public long eventId;
public int contentType; public int contentType;
public String dateKey; public String dateKey;
public int dateKeyInt;
public String monthKey; public String monthKey;
public boolean deleted; public boolean deleted;
public boolean deletedByThanos; public boolean deletedByThanos;
@ -315,6 +317,7 @@ public class MessageObject {
public boolean forceAvatar; public boolean forceAvatar;
public Drawable customAvatarDrawable; public Drawable customAvatarDrawable;
public boolean isSaved; public boolean isSaved;
public boolean isSavedFiltered;
private byte[] randomWaveform; private byte[] randomWaveform;
public boolean drawServiceWithDefaultTypeface; public boolean drawServiceWithDefaultTypeface;
@ -567,6 +570,10 @@ public class MessageObject {
return !(replyMessageObject != null && replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty) && messageOwner.reply_to != null && messageOwner.reply_to.story_id != 0 && (messageOwner.flags & TLRPC.MESSAGE_FLAG_REPLY) != 0; return !(replyMessageObject != null && replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty) && messageOwner.reply_to != null && messageOwner.reply_to.story_id != 0 && (messageOwner.flags & TLRPC.MESSAGE_FLAG_REPLY) != 0;
} }
public boolean isUnsupported() {
return getMedia(messageOwner) instanceof TLRPC.TL_messageMediaUnsupported;
}
public boolean isExpiredStory() { public boolean isExpiredStory() {
return (type == MessageObject.TYPE_STORY || type == MessageObject.TYPE_STORY_MENTION) && messageOwner.media.storyItem instanceof TL_stories.TL_storyItemDeleted; return (type == MessageObject.TYPE_STORY || type == MessageObject.TYPE_STORY_MENTION) && messageOwner.media.storyItem instanceof TL_stories.TL_storyItemDeleted;
} }
@ -926,9 +933,21 @@ public class MessageObject {
public ArrayList<MessageObject> messages = new ArrayList<>(); public ArrayList<MessageObject> messages = new ArrayList<>();
public ArrayList<GroupedMessagePosition> posArray = new ArrayList<>(); public ArrayList<GroupedMessagePosition> posArray = new ArrayList<>();
public HashMap<MessageObject, GroupedMessagePosition> positions = new HashMap<>(); public HashMap<MessageObject, GroupedMessagePosition> positions = new HashMap<>();
public LongSparseArray<GroupedMessagePosition> positionsArray = new LongSparseArray<>();
public MessageObject captionMessage; public MessageObject captionMessage;
public boolean isDocuments; public boolean isDocuments;
public GroupedMessagePosition getPosition(MessageObject msg) {
if (msg == null) {
return null;
}
GroupedMessagePosition pos = positions.get(msg);
if (pos == null) {
pos = positionsArray.get(msg.getId());
}
return pos;
}
private int maxSizeWidth = 800; private int maxSizeWidth = 800;
public final TransitionParams transitionParams = new TransitionParams(); public final TransitionParams transitionParams = new TransitionParams();
@ -967,6 +986,7 @@ public class MessageObject {
public void calculate() { public void calculate() {
posArray.clear(); posArray.clear();
positions.clear(); positions.clear();
positionsArray.clear();
captionMessage = null; captionMessage = null;
maxSizeWidth = 800; maxSizeWidth = 800;
@ -996,6 +1016,7 @@ public class MessageObject {
for (int a = (reversed ? count - 1 : 0); (reversed ? a >= 0 : a < count);) { for (int a = (reversed ? count - 1 : 0); (reversed ? a >= 0 : a < count);) {
MessageObject messageObject = messages.get(a); MessageObject messageObject = messages.get(a);
if (a == (reversed ? count - 1 : 0)) { if (a == (reversed ? count - 1 : 0)) {
messageObject.isOutOwnerCached = null;
isOut = messageObject.isOutOwner(); isOut = messageObject.isOutOwner();
needShare = !isOut && ( needShare = !isOut && (
messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.saved_from_peer != null || messageObject.messageOwner.fwd_from != null && messageObject.messageOwner.fwd_from.saved_from_peer != null ||
@ -1026,6 +1047,7 @@ public class MessageObject {
} }
positions.put(messageObject, position); positions.put(messageObject, position);
positionsArray.put(messageObject.getId(), position);
posArray.add(position); posArray.add(position);
if (messageObject.caption != null) { if (messageObject.caption != null) {
@ -1048,19 +1070,21 @@ public class MessageObject {
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
GroupedMessagePosition pos = posArray.get(a); GroupedMessagePosition pos = posArray.get(a);
pos.flags = POSITION_FLAG_LEFT | POSITION_FLAG_RIGHT; pos.flags = POSITION_FLAG_LEFT | POSITION_FLAG_RIGHT;
if (!reversed && a == 0 || reversed && a == count - 1) { if (a == 0) {
pos.flags |= POSITION_FLAG_TOP; pos.flags |= POSITION_FLAG_TOP;
pos.last = false; pos.last = false;
} else if (reversed && a == 0 || !reversed && a == count - 1) { } else if (a == count - 1) {
pos.flags |= POSITION_FLAG_BOTTOM; pos.flags |= POSITION_FLAG_BOTTOM;
pos.last = true; pos.last = true;
} else {
pos.last = false;
} }
pos.edge = true; pos.edge = true;
pos.aspectRatio = 1.0f; pos.aspectRatio = 1.0f;
pos.minX = 0; pos.minX = 0;
pos.maxX = 0; pos.maxX = 0;
pos.minY = (byte) (reversed ? count - 1 - a : a); pos.minY = (byte) a;
pos.maxY = (byte) (reversed ? count - 1 - a : a); pos.maxY = (byte) a;
pos.spanSize = 1000; pos.spanSize = 1000;
pos.pw = maxSizeWidth; pos.pw = maxSizeWidth;
pos.ph = 100; pos.ph = 100;
@ -1366,7 +1390,7 @@ public class MessageObject {
} }
public MessageObject findPrimaryMessageObject() { public MessageObject findPrimaryMessageObject() {
return findMessageWithFlags(MessageObject.POSITION_FLAG_TOP | MessageObject.POSITION_FLAG_LEFT); return findMessageWithFlags(reversed ? MessageObject.POSITION_FLAG_BOTTOM | MessageObject.POSITION_FLAG_RIGHT : MessageObject.POSITION_FLAG_TOP | MessageObject.POSITION_FLAG_LEFT);
} }
public MessageObject findCaptionMessageObject() { public MessageObject findCaptionMessageObject() {
@ -1535,7 +1559,7 @@ public class MessageObject {
this.isRepostPreview = isRepostPreview; this.isRepostPreview = isRepostPreview;
this.isRepostVideoPreview = isRepostVideoPreview; this.isRepostVideoPreview = isRepostVideoPreview;
this.isSaved = isSavedMessages; this.isSaved = isSavedMessages || getDialogId(message) == UserConfig.getInstance(accountNum).getClientUserId();
currentAccount = accountNum; currentAccount = accountNum;
messageOwner = message; messageOwner = message;
@ -1565,6 +1589,7 @@ public class MessageObject {
int dateYear = rightNow.get(Calendar.YEAR); int dateYear = rightNow.get(Calendar.YEAR);
int dateMonth = rightNow.get(Calendar.MONTH); int dateMonth = rightNow.get(Calendar.MONTH);
dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay); dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay);
dateKeyInt = dateYear + 10000 * dateMonth + 10000 * 100 * dateDay;
monthKey = String.format("%d_%02d", dateYear, dateMonth); monthKey = String.format("%d_%02d", dateYear, dateMonth);
createMessageSendInfo(); createMessageSendInfo();
@ -1809,6 +1834,7 @@ public class MessageObject {
int dateYear = rightNow.get(Calendar.YEAR); int dateYear = rightNow.get(Calendar.YEAR);
int dateMonth = rightNow.get(Calendar.MONTH); int dateMonth = rightNow.get(Calendar.MONTH);
dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay); dateKey = String.format("%d_%02d_%02d", dateYear, dateMonth, dateDay);
dateKeyInt = dateYear + 1000 * dateMonth + 1000 * 100 * dateDay;
monthKey = String.format("%d_%02d", dateYear, dateMonth); monthKey = String.format("%d_%02d", dateYear, dateMonth);
TLRPC.Peer peer_id = new TLRPC.TL_peerChannel(); TLRPC.Peer peer_id = new TLRPC.TL_peerChannel();
@ -2611,19 +2637,31 @@ public class MessageObject {
messageText = replaceWithLink(LocaleController.getString("EventLogSendMessages", R.string.EventLogSendMessages), "un1", fromUser); messageText = replaceWithLink(LocaleController.getString("EventLogSendMessages", R.string.EventLogSendMessages), "un1", fromUser);
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeAvailableReactions) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeAvailableReactions) {
TLRPC.TL_channelAdminLogEventActionChangeAvailableReactions eventActionChangeAvailableReactions = (TLRPC.TL_channelAdminLogEventActionChangeAvailableReactions) event.action; TLRPC.TL_channelAdminLogEventActionChangeAvailableReactions eventActionChangeAvailableReactions = (TLRPC.TL_channelAdminLogEventActionChangeAvailableReactions) event.action;
boolean customReactionsChanged = eventActionChangeAvailableReactions.prev_value instanceof TLRPC.TL_chatReactionsSome
CharSequence oldReactions = getStringFrom(eventActionChangeAvailableReactions.prev_value); && eventActionChangeAvailableReactions.new_value instanceof TLRPC.TL_chatReactionsSome;
CharSequence newReactions = getStringFrom(eventActionChangeAvailableReactions.new_value); CharSequence newReactions = getStringFrom(eventActionChangeAvailableReactions.new_value);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(replaceWithLink(LocaleController.formatString("ActionReactionsChanged", R.string.ActionReactionsChanged, "**old**", "**new**"), "un1", fromUser)); String newStr = "**new**";
int i = spannableStringBuilder.toString().indexOf("**old**"); String oldStr = "**old**";
if (i > 0) { if (customReactionsChanged) {
spannableStringBuilder.replace(i, i + "**old**".length(), oldReactions); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(replaceWithLink(LocaleController.formatString("ActionReactionsChangedList", R.string.ActionReactionsChangedList, newStr), "un1", fromUser));
int i = spannableStringBuilder.toString().indexOf(newStr);
if (i > 0) {
spannableStringBuilder.replace(i, i + newStr.length(), newReactions);
}
messageText = spannableStringBuilder;
} else {
CharSequence oldReactions = getStringFrom(eventActionChangeAvailableReactions.prev_value);
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(replaceWithLink(LocaleController.formatString("ActionReactionsChanged", R.string.ActionReactionsChanged, oldStr, newStr), "un1", fromUser));
int i = spannableStringBuilder.toString().indexOf(oldStr);
if (i > 0) {
spannableStringBuilder.replace(i, i + oldStr.length(), oldReactions);
}
i = spannableStringBuilder.toString().indexOf(newStr);
if (i > 0) {
spannableStringBuilder.replace(i, i + newStr.length(), newReactions);
}
messageText = spannableStringBuilder;
} }
i = spannableStringBuilder.toString().indexOf("**new**");
if (i > 0) {
spannableStringBuilder.replace(i, i + "**new**".length(), newReactions);
}
messageText = spannableStringBuilder;
} else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeUsernames) { } else if (event.action instanceof TLRPC.TL_channelAdminLogEventActionChangeUsernames) {
TLRPC.TL_channelAdminLogEventActionChangeUsernames log = (TLRPC.TL_channelAdminLogEventActionChangeUsernames) event.action; TLRPC.TL_channelAdminLogEventActionChangeUsernames log = (TLRPC.TL_channelAdminLogEventActionChangeUsernames) event.action;
@ -3030,10 +3068,12 @@ public class MessageObject {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder();
for (int i = 0; i < reactionsSome.reactions.size(); i++) { for (int i = 0; i < reactionsSome.reactions.size(); i++) {
if (i != 0) { if (i != 0) {
spannableStringBuilder.append(", "); spannableStringBuilder.append(" ");
} }
spannableStringBuilder.append(ReactionsUtils.reactionToCharSequence(reactionsSome.reactions.get(i))); CharSequence reaction = ReactionsUtils.reactionToCharSequence(reactionsSome.reactions.get(i));
spannableStringBuilder.append(Emoji.replaceEmoji(reaction, null, false));
} }
return spannableStringBuilder;
} }
return LocaleController.getString("NoReactions", R.string.NoReactions); return LocaleController.getString("NoReactions", R.string.NoReactions);
} }
@ -3334,6 +3374,18 @@ public class MessageObject {
return messageOwner.reactions != null && !messageOwner.reactions.results.isEmpty(); return messageOwner.reactions != null && !messageOwner.reactions.results.isEmpty();
} }
public boolean hasReaction(ReactionsLayoutInBubble.VisibleReaction reaction) {
if (!hasReactions() || reaction == null) return false;
for (int i = 0; i < messageOwner.reactions.results.size(); ++i) {
TLRPC.ReactionCount rc = messageOwner.reactions.results.get(i);
if (reaction.isSame(rc.reaction)) {
return true;
}
}
return false;
}
public static void updatePollResults(TLRPC.TL_messageMediaPoll media, TLRPC.PollResults results) { public static void updatePollResults(TLRPC.TL_messageMediaPoll media, TLRPC.PollResults results) {
if (media == null || results == null) { if (media == null || results == null) {
return; return;
@ -4554,7 +4606,7 @@ public class MessageObject {
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaInvoice) { } else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaInvoice) {
messageText = getMedia(messageOwner).description; messageText = getMedia(messageOwner).description;
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaUnsupported) { } else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaUnsupported) {
messageText = LocaleController.getString(ApplicationLoader.applicationLoaderInstance.isStandalone() ? R.string.UnsupportedMediaStandalone : R.string.UnsupportedMedia); messageText = LocaleController.getString(R.string.UnsupportedMedia2);
} else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument) { } else if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaDocument) {
if (isSticker() || isAnimatedStickerDocument(getDocument(), true)) { if (isSticker() || isAnimatedStickerDocument(getDocument(), true)) {
String sch = getStickerChar(); String sch = getStickerChar();
@ -4666,7 +4718,7 @@ public class MessageObject {
} else if (media instanceof TLRPC.TL_messageMediaInvoice) { } else if (media instanceof TLRPC.TL_messageMediaInvoice) {
return media.description; return media.description;
} else if (media instanceof TLRPC.TL_messageMediaUnsupported) { } else if (media instanceof TLRPC.TL_messageMediaUnsupported) {
return LocaleController.getString(ApplicationLoader.applicationLoaderInstance.isStandalone() ? R.string.UnsupportedMediaStandalone : R.string.UnsupportedMedia); return LocaleController.getString(R.string.UnsupportedMedia2);
} else if (media instanceof TLRPC.TL_messageMediaDocument) { } else if (media instanceof TLRPC.TL_messageMediaDocument) {
if (isStickerDocument(media.document) || isAnimatedStickerDocument(media.document, true)) { if (isStickerDocument(media.document) || isAnimatedStickerDocument(media.document, true)) {
String sch = getStickerChar(); String sch = getStickerChar();
@ -5770,6 +5822,8 @@ public class MessageObject {
return result; return result;
} }
// only set in searching with tags
public boolean isPrimaryGroupMessage;
public boolean hasValidGroupId() { public boolean hasValidGroupId() {
return getGroupId() != 0 && (photoThumbs != null && !photoThumbs.isEmpty() || isMusic() || isDocument()); return getGroupId() != 0 && (photoThumbs != null && !photoThumbs.isEmpty() || isMusic() || isDocument());
} }
@ -5823,7 +5877,7 @@ public class MessageObject {
if (text == null) { if (text == null) {
return false; return false;
} }
if (isRestrictedMessage) { if (isRestrictedMessage || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaUnsupported) {
ArrayList<TLRPC.MessageEntity> entities = new ArrayList<>(); ArrayList<TLRPC.MessageEntity> entities = new ArrayList<>();
TLRPC.TL_messageEntityItalic entityItalic = new TLRPC.TL_messageEntityItalic(); TLRPC.TL_messageEntityItalic entityItalic = new TLRPC.TL_messageEntityItalic();
entityItalic.offset = 0; entityItalic.offset = 0;
@ -6282,8 +6336,8 @@ public class MessageObject {
if (needDrawAvatarInternal() && !isOutOwner() && !messageOwner.isThreadMessage) { if (needDrawAvatarInternal() && !isOutOwner() && !messageOwner.isThreadMessage) {
maxWidth -= dp(52); maxWidth -= dp(52);
} }
if (needDrawShareButton() && !isOutOwner()) { if (needDrawShareButton() && (isSaved || !isOutOwner())) {
maxWidth -= dp(10); maxWidth -= dp(isSaved && isOutOwner() ? 40 : 10);
} }
if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) { if (getMedia(messageOwner) instanceof TLRPC.TL_messageMediaGame) {
maxWidth -= dp(10); maxWidth -= dp(10);
@ -6328,17 +6382,18 @@ public class MessageObject {
} }
boolean useManualParse = !hasEntities && ( boolean useManualParse = !hasEntities && (
eventId != 0 || eventId != 0 ||
messageOwner instanceof TLRPC.TL_message_old || messageOwner instanceof TLRPC.TL_message_old ||
messageOwner instanceof TLRPC.TL_message_old2 || messageOwner instanceof TLRPC.TL_message_old2 ||
messageOwner instanceof TLRPC.TL_message_old3 || messageOwner instanceof TLRPC.TL_message_old3 ||
messageOwner instanceof TLRPC.TL_message_old4 || messageOwner instanceof TLRPC.TL_message_old4 ||
messageOwner instanceof TLRPC.TL_messageForwarded_old || messageOwner instanceof TLRPC.TL_messageForwarded_old ||
messageOwner instanceof TLRPC.TL_messageForwarded_old2 || messageOwner instanceof TLRPC.TL_messageForwarded_old2 ||
messageOwner instanceof TLRPC.TL_message_secret || messageOwner instanceof TLRPC.TL_message_secret ||
getMedia(messageOwner) instanceof TLRPC.TL_messageMediaInvoice || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaInvoice ||
isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT || isOut() && messageOwner.send_state != MESSAGE_SEND_STATE_SENT ||
messageOwner.id < 0 || getMedia(messageOwner) instanceof TLRPC.TL_messageMediaUnsupported); messageOwner.id < 0
);
if (useManualParse) { if (useManualParse) {
addLinks(isOutOwner(), messageText, true, true); addLinks(isOutOwner(), messageText, true, true);
@ -7239,7 +7294,7 @@ public class MessageObject {
return isOutOwnerCached; return isOutOwnerCached;
} }
long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId(); long selfUserId = UserConfig.getInstance(currentAccount).getClientUserId();
if (isSaved && messageOwner.fwd_from != null) { if ((isSaved || getDialogId() == selfUserId) && messageOwner.fwd_from != null) {
return isOutOwnerCached = messageOwner.fwd_from.from_id != null && messageOwner.fwd_from.from_id.user_id == selfUserId || messageOwner.fwd_from.saved_out; return isOutOwnerCached = messageOwner.fwd_from.from_id != null && messageOwner.fwd_from.from_id.user_id == selfUserId || messageOwner.fwd_from.saved_out;
} }
TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(null, null, messageOwner.peer_id.channel_id) : null; TLRPC.Chat chat = messageOwner.peer_id != null && messageOwner.peer_id.channel_id != 0 ? getChat(null, null, messageOwner.peer_id.channel_id) : null;
@ -7261,7 +7316,7 @@ public class MessageObject {
return true; return true;
} }
if (isSaved) { if (isSaved) {
return getSavedDialogId() < 0 || getSavedDialogId() == UserObject.ANONYMOUS; return true;
} }
if (forceAvatar || customAvatarDrawable != null) { if (forceAvatar || customAvatarDrawable != null) {
return true; return true;
@ -7274,7 +7329,7 @@ public class MessageObject {
return true; return true;
} }
if (isSaved) { if (isSaved) {
return getSavedDialogId() < 0 || getSavedDialogId() == UserObject.ANONYMOUS; return true;
} }
if (forceAvatar || customAvatarDrawable != null) { if (forceAvatar || customAvatarDrawable != null) {
return true; return true;
@ -8777,6 +8832,9 @@ public class MessageObject {
} }
public boolean needDrawForwarded() { public boolean needDrawForwarded() {
if (type == MessageObject.TYPE_STORY && !isExpiredStory()) {
return true;
}
if (isSaved) { if (isSaved) {
if (messageOwner == null || messageOwner.fwd_from == null) return false; if (messageOwner == null || messageOwner.fwd_from == null) return false;
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId(); final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
@ -8788,9 +8846,6 @@ public class MessageObject {
if (fromId == 0) return savedId != UserObject.ANONYMOUS; if (fromId == 0) return savedId != UserObject.ANONYMOUS;
return savedId != fromId && fromId != selfId; return savedId != fromId && fromId != selfId;
} }
if (type == MessageObject.TYPE_STORY && !isExpiredStory()) {
return true;
}
return (messageOwner.flags & TLRPC.MESSAGE_FLAG_FWD) != 0 && messageOwner.fwd_from != null && !messageOwner.fwd_from.imported && (messageOwner.fwd_from.saved_from_peer == null || !(messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChannel) || messageOwner.fwd_from.saved_from_peer.channel_id != messageOwner.fwd_from.from_id.channel_id) && UserConfig.getInstance(currentAccount).getClientUserId() != getDialogId(); return (messageOwner.flags & TLRPC.MESSAGE_FLAG_FWD) != 0 && messageOwner.fwd_from != null && !messageOwner.fwd_from.imported && (messageOwner.fwd_from.saved_from_peer == null || !(messageOwner.fwd_from.from_id instanceof TLRPC.TL_peerChannel) || messageOwner.fwd_from.saved_from_peer.channel_id != messageOwner.fwd_from.from_id.channel_id) && UserConfig.getInstance(currentAccount).getClientUserId() != getDialogId();
} }
@ -9341,7 +9396,7 @@ public class MessageObject {
} else { } else {
text = messageText; text = messageText;
} }
CharSequence charSequence = AndroidUtilities.replaceCharSequence("\n", text, " "); CharSequence charSequence = AndroidUtilities.replaceMultipleCharSequence("\n", text, " ");
if (inQuote && messageOwner != null && messageOwner.reply_to != null && messageOwner.reply_to.quote_text != null) { if (inQuote && messageOwner != null && messageOwner.reply_to != null && messageOwner.reply_to.quote_text != null) {
SpannableStringBuilder quoteText = new SpannableStringBuilder(messageOwner.reply_to.quote_text); SpannableStringBuilder quoteText = new SpannableStringBuilder(messageOwner.reply_to.quote_text);
addEntitiesToText(quoteText, messageOwner.reply_to.quote_entities, isOutOwner(), false, false, false); addEntitiesToText(quoteText, messageOwner.reply_to.quote_entities, isOutOwner(), false, false, false);
@ -9354,13 +9409,13 @@ public class MessageObject {
String str = charSequence.toString(); String str = charSequence.toString();
int lastIndex = str.length(); int lastIndex = str.length();
int startHighlightedIndex = str.toLowerCase().indexOf(foundWords.get(0)); int startHighlightedIndex = str.toLowerCase().indexOf(foundWords.get(0));
int maxSymbols = 200; int maxSymbols = 120;
if (startHighlightedIndex < 0) { if (startHighlightedIndex < 0) {
startHighlightedIndex = 0; startHighlightedIndex = 0;
} }
if (lastIndex > maxSymbols) { if (lastIndex > maxSymbols) {
int newStart = Math.max(0, startHighlightedIndex - maxSymbols / 2); int newStart = Math.max(0, startHighlightedIndex - (int) (maxSymbols * .1f));
charSequence = charSequence.subSequence(newStart, Math.min(lastIndex, startHighlightedIndex - newStart + startHighlightedIndex + maxSymbols / 2)); charSequence = charSequence.subSequence(newStart, Math.min(lastIndex, startHighlightedIndex - newStart + startHighlightedIndex + (int) (maxSymbols * .9f)));
} }
messageTrimmedToHighlight = charSequence; messageTrimmedToHighlight = charSequence;
} }
@ -9462,9 +9517,6 @@ public class MessageObject {
if (newReaction.count <= 0) { if (newReaction.count <= 0) {
messageOwner.reactions.results.remove(newReaction); messageOwner.reactions.results.remove(newReaction);
} }
if (messageOwner.reactions.reactions_as_tags) {
MessagesController.getInstance(currentAccount).updateSavedReactionTags(visibleReaction, false);
}
} }
if (messageOwner.reactions.can_see_list) { if (messageOwner.reactions.can_see_list) {
for (int i = 0; i < messageOwner.reactions.recent_reactions.size(); i++) { for (int i = 0; i < messageOwner.reactions.recent_reactions.size(); i++) {
@ -9491,9 +9543,6 @@ public class MessageObject {
if (choosenReaction.count <= 0) { if (choosenReaction.count <= 0) {
messageOwner.reactions.results.remove(choosenReaction); messageOwner.reactions.results.remove(choosenReaction);
} }
if (messageOwner.reactions.reactions_as_tags) {
MessagesController.getInstance(currentAccount).updateSavedReactionTags(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(choosenReaction.reaction), false);
}
choosenReactions.remove(choosenReaction); choosenReactions.remove(choosenReaction);
if (messageOwner.reactions.can_see_list) { if (messageOwner.reactions.can_see_list) {
@ -9514,9 +9563,6 @@ public class MessageObject {
newReaction.chosen = true; newReaction.chosen = true;
newReaction.count++; newReaction.count++;
newReaction.chosen_order = maxChoosenOrder + 1; newReaction.chosen_order = maxChoosenOrder + 1;
if (messageOwner.reactions.reactions_as_tags) {
MessagesController.getInstance(currentAccount).updateSavedReactionTags(visibleReaction, true);
}
if (messageOwner.reactions.can_see_list || (messageOwner.dialog_id > 0 && maxReactionsCount > 1)) { if (messageOwner.reactions.can_see_list || (messageOwner.dialog_id > 0 && maxReactionsCount > 1)) {
TLRPC.TL_messagePeerReaction action = new TLRPC.TL_messagePeerReaction(); TLRPC.TL_messagePeerReaction action = new TLRPC.TL_messagePeerReaction();
@ -9791,13 +9837,14 @@ public class MessageObject {
webpage != null && (webpage.photo != null || isVideoDocument(webpage.document)) && webpage != null && (webpage.photo != null || isVideoDocument(webpage.document)) &&
!(webpage != null && TextUtils.isEmpty(webpage.description) && TextUtils.isEmpty(webpage.title)) && !(webpage != null && TextUtils.isEmpty(webpage.description) && TextUtils.isEmpty(webpage.title)) &&
!(isSponsored() && sponsoredWebPage == null && sponsoredChannelPost == 0) && // drawInstantViewType = 1 !(isSponsored() && sponsoredWebPage == null && sponsoredChannelPost == 0) && // drawInstantViewType = 1
!"telegram_megagroup".equals(webpageType) && // drawInstantViewType = 2 !"telegram_megagroup".equals(webpageType) && // drawInstantViewType = 2
!"telegram_background".equals(webpageType) && // drawInstantViewType = 6 !"telegram_background".equals(webpageType) && // drawInstantViewType = 6
!"telegram_voicechat".equals(webpageType) && // drawInstantViewType = 9 !"telegram_voicechat".equals(webpageType) && // drawInstantViewType = 9
!"telegram_livestream".equals(webpageType) && // drawInstantViewType = 11 !"telegram_livestream".equals(webpageType) && // drawInstantViewType = 11
!"telegram_user".equals(webpageType) && // drawInstantViewType = 13 !"telegram_user".equals(webpageType) && // drawInstantViewType = 13
!"telegram_story".equals(webpageType) && // drawInstantViewType = 17 !"telegram_story".equals(webpageType) && // drawInstantViewType = 17
!"telegram_channel_boost".equals(webpageType) // drawInstantViewType = 18 !"telegram_channel_boost".equals(webpageType) && // drawInstantViewType = 18
!"telegram_chat".equals(webpageType)
; ;
} }
@ -9805,11 +9852,14 @@ public class MessageObject {
final boolean hasLinkPreview = !isRestrictedMessage && MessageObject.getMedia(messageOwner) instanceof TLRPC.TL_messageMediaWebPage && MessageObject.getMedia(messageOwner).webpage instanceof TLRPC.TL_webPage; final boolean hasLinkPreview = !isRestrictedMessage && MessageObject.getMedia(messageOwner) instanceof TLRPC.TL_messageMediaWebPage && MessageObject.getMedia(messageOwner).webpage instanceof TLRPC.TL_webPage;
final TLRPC.WebPage webpage = hasLinkPreview ? MessageObject.getMedia(messageOwner).webpage : null; final TLRPC.WebPage webpage = hasLinkPreview ? MessageObject.getMedia(messageOwner).webpage : null;
final String webpageType = webpage != null ? webpage.type : null; final String webpageType = webpage != null ? webpage.type : null;
return !(webpage != null && TextUtils.isEmpty(webpage.description) && TextUtils.isEmpty(webpage.title)) && ("app".equals(webpageType) || "profile".equals(webpageType) || return !(webpage != null && TextUtils.isEmpty(webpage.description) && TextUtils.isEmpty(webpage.title)) && (
"app".equals(webpageType) || "profile".equals(webpageType) ||
"article".equals(webpageType) || "telegram_bot".equals(webpageType) || "article".equals(webpageType) || "telegram_bot".equals(webpageType) ||
"telegram_user".equals(webpageType) || "telegram_channel".equals(webpageType) || "telegram_user".equals(webpageType) || "telegram_channel".equals(webpageType) ||
"telegram_megagroup".equals(webpageType) || "telegram_voicechat".equals(webpageType) || "telegram_megagroup".equals(webpageType) || "telegram_voicechat".equals(webpageType) ||
"telegram_livestream".equals(webpageType) || "telegram_channel_boost".equals(webpageType)); "telegram_livestream".equals(webpageType) || "telegram_channel_boost".equals(webpageType) ||
"telegram_chat".equals(webpageType)
);
} }

View file

@ -584,6 +584,9 @@ public class MessagesController extends BaseController implements NotificationCe
public int savedDialogsPinnedLimitDefault; public int savedDialogsPinnedLimitDefault;
public int savedDialogsPinnedLimitPremium; public int savedDialogsPinnedLimitPremium;
public boolean savedViewAsChats;
public boolean storyQualityFull;
public int uploadMaxFileParts; public int uploadMaxFileParts;
public int uploadMaxFilePartsPremium; public int uploadMaxFilePartsPremium;
@ -1472,6 +1475,8 @@ public class MessagesController extends BaseController implements NotificationCe
boostsChannelLevelMax = mainPreferences.getInt("boostsChannelLevelMax", 100); boostsChannelLevelMax = mainPreferences.getInt("boostsChannelLevelMax", 100);
savedDialogsPinnedLimitDefault = mainPreferences.getInt("savedDialogsPinnedLimitDefault", 4); savedDialogsPinnedLimitDefault = mainPreferences.getInt("savedDialogsPinnedLimitDefault", 4);
savedDialogsPinnedLimitPremium = mainPreferences.getInt("savedDialogsPinnedLimitPremium", 6); savedDialogsPinnedLimitPremium = mainPreferences.getInt("savedDialogsPinnedLimitPremium", 6);
storyQualityFull = mainPreferences.getBoolean("storyQualityFull", true);
savedViewAsChats = mainPreferences.getBoolean("savedViewAsChats", false);
scheduleTranscriptionUpdate(); scheduleTranscriptionUpdate();
BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID); BuildVars.GOOGLE_AUTH_CLIENT_ID = mainPreferences.getString("googleAuthClientId", BuildVars.GOOGLE_AUTH_CLIENT_ID);
if (mainPreferences.contains("dcDomainName2")) { if (mainPreferences.contains("dcDomainName2")) {
@ -4919,6 +4924,9 @@ public class MessagesController extends BaseController implements NotificationCe
} else if (id == NotificationCenter.currentUserPremiumStatusChanged) { } else if (id == NotificationCenter.currentUserPremiumStatusChanged) {
loadAppConfig(false); loadAppConfig(false);
getContactsController().reloadContactsStatusesMaybe(true); getContactsController().reloadContactsStatusesMaybe(true);
if (storyQualityFull && !getUserConfig().isPremium() || getUserConfig().isPremium()) {
getNotificationCenter().postNotificationName(NotificationCenter.storyQualityUpdate);
}
} }
} }
@ -7906,6 +7914,9 @@ public class MessagesController extends BaseController implements NotificationCe
protected void deleteDialog(long did, int first, int onlyHistory, int max_id, boolean revoke, TLRPC.InputPeer peer, long taskId) { protected void deleteDialog(long did, int first, int onlyHistory, int max_id, boolean revoke, TLRPC.InputPeer peer, long taskId) {
if (onlyHistory == 2) { if (onlyHistory == 2) {
if (did == getUserConfig().getClientUserId()) {
getSavedMessagesController().deleteAllDialogs();
}
getMessagesStorage().deleteDialog(did, onlyHistory); getMessagesStorage().deleteDialog(did, onlyHistory);
return; return;
} }
@ -7930,6 +7941,9 @@ public class MessagesController extends BaseController implements NotificationCe
if (first == 1 && max_id == 0) { if (first == 1 && max_id == 0) {
TLRPC.InputPeer peerFinal = peer; TLRPC.InputPeer peerFinal = peer;
getMessagesStorage().getDialogMaxMessageId(did, (param) -> { getMessagesStorage().getDialogMaxMessageId(did, (param) -> {
if (did == getUserConfig().getClientUserId()) {
getSavedMessagesController().deleteAllDialogs();
}
deleteDialog(did, 2, onlyHistory, Math.max(0, param), revoke, peerFinal, taskId); deleteDialog(did, 2, onlyHistory, Math.max(0, param), revoke, peerFinal, taskId);
checkIfFolderEmpty(1); checkIfFolderEmpty(1);
}); });
@ -7945,6 +7959,9 @@ public class MessagesController extends BaseController implements NotificationCe
FileLog.d("delete dialog with id " + did); FileLog.d("delete dialog with id " + did);
} }
boolean isPromoDialog = false; boolean isPromoDialog = false;
if (did == getUserConfig().getClientUserId()) {
getSavedMessagesController().deleteAllDialogs();
}
getMessagesStorage().deleteDialog(did, onlyHistory); getMessagesStorage().deleteDialog(did, onlyHistory);
TLRPC.Dialog dialog = dialogs_dict.get(did); TLRPC.Dialog dialog = dialogs_dict.get(did);
if (onlyHistory == 0 || onlyHistory == 3) { if (onlyHistory == 0 || onlyHistory == 3) {
@ -17284,6 +17301,8 @@ public class MessagesController extends BaseController implements NotificationCe
getMediaDataController().loadRecentAndTopReactions(true); getMediaDataController().loadRecentAndTopReactions(true);
} else if (baseUpdate instanceof TLRPC.TL_updateRecentReactions) { } else if (baseUpdate instanceof TLRPC.TL_updateRecentReactions) {
getMediaDataController().loadSavedReactions(true); getMediaDataController().loadSavedReactions(true);
} else if (baseUpdate instanceof TLRPC.TL_updateSavedReactionTags) {
getSavedReactionTags(0, true);
} else if (baseUpdate instanceof TLRPC.TL_updateFavedStickers) { } else if (baseUpdate instanceof TLRPC.TL_updateFavedStickers) {
getMediaDataController().loadRecents(MediaDataController.TYPE_FAVE, false, false, true); getMediaDataController().loadRecents(MediaDataController.TYPE_FAVE, false, false, true);
} else if (baseUpdate instanceof TLRPC.TL_updateContactsReset) { } else if (baseUpdate instanceof TLRPC.TL_updateContactsReset) {
@ -19960,24 +19979,56 @@ public class MessagesController extends BaseController implements NotificationCe
return rec; return rec;
} }
private boolean loadedReactionTags; private HashSet<Long> loadingReactionTags;
private TLRPC.TL_messages_savedReactionsTags reactionTags; private LongSparseArray<TLRPC.TL_messages_savedReactionsTags> reactionTags;
public void updateSavedReactionTags(ReactionsLayoutInBubble.VisibleReaction reaction, boolean add) {
if (reactionTags != null) { public boolean processDeletedReactionTags(TLRPC.Message message) {
if (message == null || DialogObject.getPeerDialogId(message.peer_id) != getUserConfig().getClientUserId() || message.reactions == null || !message.reactions.reactions_as_tags || message.reactions.results == null) {
return false;
}
long topic_id = MessageObject.getSavedDialogId(getUserConfig().getClientUserId(), message);
boolean changed = false;
for (int i = 0; i < message.reactions.results.size(); ++i) {
if (updateSavedReactionTags(topic_id, ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(message.reactions.results.get(i).reaction), false, false)) {
changed = true;
}
}
return changed;
}
public boolean updateSavedReactionTags(long topic_id, ReactionsLayoutInBubble.VisibleReaction reaction, boolean add, boolean update) {
if (reactionTags == null) {
return false;
}
boolean gchanged = false;
for (int a = 0; a < 2; ++a) {
long topicId = a == 0 ? 0 : topic_id;
if (a == 1 && topicId == 0) continue;
TLRPC.TL_messages_savedReactionsTags tags = reactionTags.get(topicId);
if (tags == null) {
if (topicId != 0) {
reactionTags.put(topicId, tags = new TLRPC.TL_messages_savedReactionsTags());
} else {
continue;
}
}
boolean changed = false; boolean changed = false;
boolean found = false; boolean found = false;
for (int i = 0; i < reactionTags.tags.size(); ++i) { for (int i = 0; i < tags.tags.size(); ++i) {
TLRPC.TL_savedReactionTag tag = reactionTags.tags.get(i); TLRPC.TL_savedReactionTag tag = tags.tags.get(i);
if (reaction.isSame(tag.reaction)) { if (reaction.isSame(tag.reaction)) {
found = true; found = true;
int wasCount = tag.count; int wasCount = tag.count;
tag.count = Math.max(0, tag.count + (add ? +1 : -1)); tag.count = Math.max(0, tag.count + (add ? +1 : -1));
if (tag.count <= 0) { if (tag.count <= 0) {
reactionTags.tags.remove(i); tags.tags.remove(i);
i--; i--;
changed = true; changed = true;
gchanged = true;
} else if (tag.count != wasCount) { } else if (tag.count != wasCount) {
changed = true; changed = true;
gchanged = true;
} }
} }
} }
@ -19985,43 +20036,205 @@ public class MessagesController extends BaseController implements NotificationCe
TLRPC.TL_savedReactionTag tag = new TLRPC.TL_savedReactionTag(); TLRPC.TL_savedReactionTag tag = new TLRPC.TL_savedReactionTag();
tag.reaction = reaction.toTLReaction(); tag.reaction = reaction.toTLReaction();
tag.count = 1; tag.count = 1;
reactionTags.tags.add(tag); tags.tags.add(tag);
changed = true; changed = true;
gchanged = true;
} }
if (changed) { if (update && changed) {
Collections.sort(reactionTags.tags, (a, b) -> b.count - a.count); updateSavedReactionTags(topicId);
long hash = 0;
for (int i = 0; i < reactionTags.tags.size(); ++i) {
TLRPC.TL_savedReactionTag tag = reactionTags.tags.get(i);
if (tag.count <= 0) continue;
if (tag.reaction instanceof TLRPC.TL_reactionEmoji) {
String md5 = Utilities.MD5(((TLRPC.TL_reactionEmoji) tag.reaction).emoticon);
hash = MediaDataController.calcHash(hash, Long.parseLong(md5.substring(0, 16), 16));
} else if (tag.reaction instanceof TLRPC.TL_reactionCustomEmoji) {
hash = MediaDataController.calcHash(hash, ((TLRPC.TL_reactionCustomEmoji) tag.reaction).document_id);
}
if ((tag.flags & 1) != 0 && tag.title != null) {
hash = MediaDataController.calcHash(hash, Long.parseLong(Utilities.MD5(tag.title).substring(0, 16), 16));
}
hash = MediaDataController.calcHash(hash, tag.count);
}
reactionTags.hash = hash;
saveSavedReactionsTags(reactionTags);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate);
} }
} }
return gchanged;
}
public void updateSavedReactionTags(HashSet<Long> topic_ids) {
updateSavedReactionTags(0);
for (long topic_id : topic_ids) {
updateSavedReactionTags(topic_id);
}
} }
public TLRPC.TL_messages_savedReactionsTags getSavedReactionTags() {
if (loadedReactionTags) { public void updateSavedReactionTags(long topic_id) {
return reactionTags; if (reactionTags == null) return;
TLRPC.TL_messages_savedReactionsTags tags = reactionTags.get(topic_id);
if (tags == null) {
if (topic_id != 0) {
reactionTags.put(topic_id, tags = new TLRPC.TL_messages_savedReactionsTags());
} else {
return;
}
} }
loadedReactionTags = true; Collections.sort(tags.tags, (a, b) -> {
if (a.count == b.count) {
return Long.compareUnsigned(getTagLongId(b.reaction), getTagLongId(a.reaction));
}
return b.count - a.count;
});
long hash = 0;
for (int i = 0; i < tags.tags.size(); ++i) {
TLRPC.TL_savedReactionTag tag = tags.tags.get(i);
if (tag.count <= 0) continue;
if (tag.reaction instanceof TLRPC.TL_reactionEmoji) {
String md5 = Utilities.MD5(((TLRPC.TL_reactionEmoji) tag.reaction).emoticon);
hash = MediaDataController.calcHash(hash, Long.parseUnsignedLong(md5.substring(0, 16), 16));
} else if (tag.reaction instanceof TLRPC.TL_reactionCustomEmoji) {
hash = MediaDataController.calcHash(hash, ((TLRPC.TL_reactionCustomEmoji) tag.reaction).document_id);
}
if (topic_id == 0 && (tag.flags & 1) != 0 && tag.title != null) {
hash = MediaDataController.calcHash(hash, Long.parseUnsignedLong(Utilities.MD5(tag.title).substring(0, 16), 16));
}
hash = MediaDataController.calcHash(hash, tag.count);
}
tags.hash = hash;
saveSavedReactionsTags(topic_id, tags);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate, topic_id);
}
public String getSavedTagName(ReactionsLayoutInBubble.VisibleReaction reaction) {
if (reactionTags == null) {
return null;
}
TLRPC.TL_messages_savedReactionsTags tags = reactionTags.get(0);
if (tags == null) return null;
for (int i = 0; i < tags.tags.size(); ++i) {
if (reaction.isSame(tags.tags.get(i).reaction)) {
return tags.tags.get(i).title;
}
}
return null;
}
public int getSavedTagCount(long topic_id, ReactionsLayoutInBubble.VisibleReaction reaction) {
if (reactionTags == null) {
return 0;
}
TLRPC.TL_messages_savedReactionsTags tags = reactionTags.get(topic_id);
if (tags == null) return 0;
for (int i = 0; i < tags.tags.size(); ++i) {
if (reaction.isSame(tags.tags.get(i).reaction)) {
return tags.tags.get(i).count;
}
}
return 0;
}
public String getSavedTagName(TLRPC.Reaction reaction) {
if (reactionTags == null) {
return null;
}
TLRPC.TL_messages_savedReactionsTags tags = reactionTags.get(0);
if (tags == null) return null;
for (int i = 0; i < tags.tags.size(); ++i) {
if (ReactionsLayoutInBubble.reactionsEqual(reaction, tags.tags.get(i).reaction)) {
return tags.tags.get(i).title;
}
}
return null;
}
public void renameSavedReactionTag(ReactionsLayoutInBubble.VisibleReaction reaction, String name) {
if (reactionTags == null) {
return;
}
TLRPC.TL_messages_savedReactionsTags tags = reactionTags.get(0);
if (tags == null) {
reactionTags.put(0, tags = new TLRPC.TL_messages_savedReactionsTags());
}
boolean found = false;
boolean changed = false;
for (int i = 0; i < tags.tags.size(); ++i) {
TLRPC.TL_savedReactionTag tag = tags.tags.get(i);
if (reaction.isSame(tag.reaction)) {
found = true;
if (TextUtils.isEmpty(name)) {
changed = tag.title != null;
tag.flags &=~ 1;
tag.title = null;
} else {
changed = !TextUtils.equals(tag.title, name);
tag.flags |= 1;
tag.title = name;
}
break;
}
}
if (!found) {
TLRPC.TL_savedReactionTag tag = new TLRPC.TL_savedReactionTag();
tag.reaction = reaction.toTLReaction();
if (!TextUtils.isEmpty(name)) {
tag.title = name;
}
tag.count = 1;
tags.tags.add(tag);
changed = true;
}
if (changed) {
TLRPC.TL_messages_updateSavedReactionTag req = new TLRPC.TL_messages_updateSavedReactionTag();
req.reaction = reaction.toTLReaction();
if (!TextUtils.isEmpty(name)) {
req.flags |= 1;
req.title = name;
}
getConnectionsManager().sendRequest(req, null);
Collections.sort(tags.tags, (a, b) -> {
if (a.count == b.count) {
return Long.compareUnsigned(getTagLongId(b.reaction), getTagLongId(a.reaction));
}
return b.count - a.count;
});
long hash = 0;
for (int i = 0; i < tags.tags.size(); ++i) {
TLRPC.TL_savedReactionTag tag = tags.tags.get(i);
if (tag.count <= 0) continue;
if (tag.reaction instanceof TLRPC.TL_reactionEmoji) {
String md5 = Utilities.MD5(((TLRPC.TL_reactionEmoji) tag.reaction).emoticon);
hash = MediaDataController.calcHash(hash, Long.parseUnsignedLong(md5.substring(0, 16), 16));
} else if (tag.reaction instanceof TLRPC.TL_reactionCustomEmoji) {
hash = MediaDataController.calcHash(hash, ((TLRPC.TL_reactionCustomEmoji) tag.reaction).document_id);
}
if ((tag.flags & 1) != 0 && tag.title != null) {
hash = MediaDataController.calcHash(hash, Long.parseUnsignedLong(Utilities.MD5(tag.title).substring(0, 16), 16));
}
hash = MediaDataController.calcHash(hash, tag.count);
}
tags.hash = hash;
saveSavedReactionsTags(0, tags);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate, 0L);
}
}
private long getTagLongId(TLRPC.Reaction reaction) {
if (reaction == null) return 0;
if (reaction.tag_long_id != 0) return reaction.tag_long_id;
if (reaction instanceof TLRPC.TL_reactionEmoji) {
String md5 = Utilities.MD5(((TLRPC.TL_reactionEmoji) reaction).emoticon);
return reaction.tag_long_id = Long.parseUnsignedLong(md5.substring(0, 16), 16);
} else if (reaction instanceof TLRPC.TL_reactionCustomEmoji) {
return reaction.tag_long_id = ((TLRPC.TL_reactionCustomEmoji) reaction).document_id;
}
return 0;
}
public TLRPC.TL_messages_savedReactionsTags getSavedReactionTags(long topic_id) {
return getSavedReactionTags(topic_id, false);
}
public TLRPC.TL_messages_savedReactionsTags getSavedReactionTags(long topic_id, boolean force) {
if (loadingReactionTags != null && loadingReactionTags.contains(topic_id) && !force) {
if (reactionTags == null) return null;
return reactionTags.get(topic_id);
}
if (loadingReactionTags == null) {
loadingReactionTags = new HashSet<>();
}
loadingReactionTags.add(topic_id);
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
TLRPC.messages_SavedReactionTags result = null; TLRPC.messages_SavedReactionTags result = null;
SQLiteDatabase database = getMessagesStorage().getDatabase(); SQLiteDatabase database = getMessagesStorage().getDatabase();
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
try { try {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT data FROM saved_reaction_tags")); cursor = database.queryFinalized("SELECT data FROM saved_reaction_tags WHERE topic_id = ?", topic_id);
if (cursor.next()) { if (cursor.next()) {
NativeByteBuffer data = cursor.byteBufferValue(0); NativeByteBuffer data = cursor.byteBufferValue(0);
if (data != null) { if (data != null) {
@ -20039,20 +20252,31 @@ public class MessagesController extends BaseController implements NotificationCe
final TLRPC.messages_SavedReactionTags finalResult = result; final TLRPC.messages_SavedReactionTags finalResult = result;
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (reactionTags == null) reactionTags = new LongSparseArray<>();
if (finalResult instanceof TLRPC.TL_messages_savedReactionsTags) { if (finalResult instanceof TLRPC.TL_messages_savedReactionsTags) {
reactionTags = (TLRPC.TL_messages_savedReactionsTags) finalResult; reactionTags.put(topic_id, (TLRPC.TL_messages_savedReactionsTags) finalResult);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate); getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate, topic_id);
} }
TLRPC.TL_messages_getSavedReactionTags req = new TLRPC.TL_messages_getSavedReactionTags(); TLRPC.TL_messages_getSavedReactionTags req = new TLRPC.TL_messages_getSavedReactionTags();
if (finalResult instanceof TLRPC.TL_messages_savedReactionsTags) { if (finalResult instanceof TLRPC.TL_messages_savedReactionsTags) {
req.hash = finalResult.hash; req.hash = finalResult.hash;
} }
if (topic_id != 0) {
req.flags |= 1;
req.peer = getInputPeer(topic_id);
}
getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> { getConnectionsManager().sendRequest(req, (res, err) -> AndroidUtilities.runOnUIThread(() -> {
if (res instanceof TLRPC.TL_messages_savedReactionsTags) { if (res instanceof TLRPC.TL_messages_savedReactionsTags) {
reactionTags = (TLRPC.TL_messages_savedReactionsTags) res; TLRPC.TL_messages_savedReactionsTags tags = (TLRPC.TL_messages_savedReactionsTags) res;
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate); reactionTags.put(topic_id, tags);
saveSavedReactionsTags(reactionTags); getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate, topic_id);
saveSavedReactionsTags(topic_id, tags);
} else if (res instanceof TLRPC.TL_messages_savedReactionsTagsNotModified && finalResult == null && req.hash == 0) {
TLRPC.TL_messages_savedReactionsTags emptyTags = new TLRPC.TL_messages_savedReactionsTags();
reactionTags.put(topic_id, emptyTags);
getNotificationCenter().postNotificationName(NotificationCenter.savedReactionTagsUpdate, topic_id);
saveSavedReactionsTags(topic_id, emptyTags);
} }
})); }));
}); });
@ -20060,17 +20284,18 @@ public class MessagesController extends BaseController implements NotificationCe
return null; return null;
} }
private void saveSavedReactionsTags(TLRPC.TL_messages_savedReactionsTags res) { private void saveSavedReactionsTags(long topic_id, TLRPC.TL_messages_savedReactionsTags res) {
getMessagesStorage().getStorageQueue().postRunnable(() -> { getMessagesStorage().getStorageQueue().postRunnable(() -> {
SQLiteDatabase database2 = getMessagesStorage().getDatabase(); SQLiteDatabase database2 = getMessagesStorage().getDatabase();
SQLitePreparedStatement state = null; SQLitePreparedStatement state = null;
try { try {
database2.executeFast("DELETE FROM saved_reaction_tags WHERE 1").stepThis().dispose(); database2.executeFast("DELETE FROM saved_reaction_tags WHERE topic_id = " + topic_id).stepThis().dispose();
state = database2.executeFast("REPLACE INTO saved_reaction_tags VALUES(?)"); state = database2.executeFast("REPLACE INTO saved_reaction_tags VALUES(?, ?)");
state.requery(); state.requery();
NativeByteBuffer buffer = new NativeByteBuffer(res.getObjectSize()); NativeByteBuffer buffer = new NativeByteBuffer(res.getObjectSize());
res.serializeToStream(buffer); res.serializeToStream(buffer);
state.bindByteBuffer(1, buffer); state.bindLong(1, topic_id);
state.bindByteBuffer(2, buffer);
state.step(); state.step();
} catch (Exception e) { } catch (Exception e) {
FileLog.e(e); FileLog.e(e);
@ -20116,6 +20341,27 @@ public class MessagesController extends BaseController implements NotificationCe
} }
} }
public void setStoryQuality(boolean full) {
if (storyQualityFull != full) {
mainPreferences.edit().putBoolean("storyQualityFull", storyQualityFull = full).apply();
getNotificationCenter().postNotificationName(NotificationCenter.storyQualityUpdate);
}
}
public void setSavedViewAs(boolean chats) {
if (savedViewAsChats != chats) {
mainPreferences.edit().putBoolean("savedViewAsChats", savedViewAsChats = chats).apply();
}
}
public boolean isStoryQualityFullOnAccount() {
return getUserConfig().isPremium() && storyQualityFull;
}
public static boolean isStoryQualityFull() {
return MessagesController.getInstance(UserConfig.selectedAccount).isStoryQualityFullOnAccount();
}
private LongSparseArray<Boolean> cachedIsUserPremiumBlocked = new LongSparseArray<>(); private LongSparseArray<Boolean> cachedIsUserPremiumBlocked = new LongSparseArray<>();
private HashSet<Long> loadingIsUserPremiumBlocked = new HashSet<>(); private HashSet<Long> loadingIsUserPremiumBlocked = new HashSet<>();
public boolean isUserPremiumBlocked(long userId) { public boolean isUserPremiumBlocked(long userId) {

View file

@ -43,6 +43,7 @@ import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Adapters.DialogsSearchAdapter; import org.telegram.ui.Adapters.DialogsSearchAdapter;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.DialogsActivity; import org.telegram.ui.DialogsActivity;
import org.telegram.ui.EditWidgetActivity; import org.telegram.ui.EditWidgetActivity;
@ -104,7 +105,7 @@ public class MessagesStorage extends BaseController {
} }
} }
public final static int LAST_DB_VERSION = 139; public final static int LAST_DB_VERSION = 143;
private boolean databaseMigrationInProgress; private boolean databaseMigrationInProgress;
public boolean showClearDatabaseAlert; public boolean showClearDatabaseAlert;
private LongSparseIntArray dialogIsForum = new LongSparseIntArray(); private LongSparseIntArray dialogIsForum = new LongSparseIntArray();
@ -704,7 +705,13 @@ public class MessagesStorage extends BaseController {
database.executeFast("CREATE TABLE unconfirmed_auth (data BLOB);").stepThis().dispose(); database.executeFast("CREATE TABLE unconfirmed_auth (data BLOB);").stepThis().dispose();
database.executeFast("CREATE TABLE saved_reaction_tags (data BLOB);").stepThis().dispose(); database.executeFast("CREATE TABLE saved_reaction_tags (topic_id INTEGER PRIMARY KEY, data BLOB);").stepThis().dispose();
database.executeFast("CREATE TABLE tag_message_id(mid INTEGER, topic_id INTEGER, tag INTEGER, text TEXT);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_idx_tag_message_id ON tag_message_id(tag);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_text_idx_tag_message_id ON tag_message_id(tag, text COLLATE NOCASE);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_topic_idx_tag_message_id ON tag_message_id(topic_id, tag);").stepThis().dispose();
database.executeFast("CREATE INDEX IF NOT EXISTS tag_topic_text_idx_tag_message_id ON tag_message_id(topic_id, tag, text COLLATE NOCASE);").stepThis().dispose();
database.executeFast("PRAGMA user_version = " + MessagesStorage.LAST_DB_VERSION).stepThis().dispose(); database.executeFast("PRAGMA user_version = " + MessagesStorage.LAST_DB_VERSION).stepThis().dispose();
@ -1933,13 +1940,26 @@ public class MessagesStorage extends BaseController {
} }
cursor.dispose(); cursor.dispose();
cursor = null; cursor = null;
if (!mids.isEmpty()) { cursor = database.queryFinalized("SELECT mid, data FROM messages_v2 WHERE uid = ?", selfId);
database.executeFast("DELETE FROM messages_v2 WHERE uid = " + selfId + " AND mid IN ("+TextUtils.join(",", mids)+")").stepThis().dispose(); while (cursor.next()) {
database.executeFast("DELETE FROM messages_topics WHERE uid = " + selfId + " AND topic_id = " + did).stepThis().dispose(); final int mid = cursor.intValue(0);
database.executeFast("DELETE FROM media_v4 WHERE uid = " + selfId + " AND mid IN ("+TextUtils.join(",", mids)+")").stepThis().dispose(); if (mids.contains(mid)) continue;
NativeByteBuffer buffer = cursor.byteBufferValue(1);
TLRPC.Message message = TLRPC.Message.TLdeserialize(buffer, buffer.readInt32(false), false);
if (MessageObject.getSavedDialogId(selfId, message) == did) {
mids.add(mid);
}
buffer.reuse();
} }
cursor.dispose();
cursor = null;
if (!mids.isEmpty()) { if (!mids.isEmpty()) {
AndroidUtilities.runOnUIThread(() -> getNotificationCenter().postNotificationName(NotificationCenter.messagesDeleted, mids, 0L, false)); markMessagesAsDeletedInternal(selfId, mids, true, false);
updateDialogsWithDeletedMessages(selfId, -selfId, mids, null, false);
AndroidUtilities.runOnUIThread(() -> {
getMessagesController().markDialogMessageAsDeleted(selfId, mids);
getNotificationCenter().postNotificationName(NotificationCenter.messagesDeleted, mids, 0L, false);
});
} }
} catch (Exception e) { } catch (Exception e) {
checkSQLException(e); checkSQLException(e);
@ -2525,6 +2545,7 @@ public class MessagesStorage extends BaseController {
forumUnreadCount.put(dialogId, 1); forumUnreadCount.put(dialogId, 1);
} }
} }
cursor.dispose();
cursor = database.queryFinalized("SELECT did, folder_id, unread_count, unread_count_i FROM dialogs WHERE unread_count > 0 OR flags > 0 UNION ALL " + cursor = database.queryFinalized("SELECT did, folder_id, unread_count, unread_count_i FROM dialogs WHERE unread_count > 0 OR flags > 0 UNION ALL " +
"SELECT did, folder_id, unread_count, unread_count_i FROM dialogs WHERE unread_count_i > 0"); "SELECT did, folder_id, unread_count, unread_count_i FROM dialogs WHERE unread_count_i > 0");
while (cursor.next()) { while (cursor.next()) {
@ -4063,6 +4084,9 @@ public class MessagesStorage extends BaseController {
cursor2 = null; cursor2 = null;
database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did + " AND mid != " + last_mid_i + " AND mid != " + last_mid).stepThis().dispose(); database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did + " AND mid != " + last_mid_i + " AND mid != " + last_mid).stepThis().dispose();
if (did == getUserConfig().getClientUserId()) {
database.executeFast("DELETE FROM messages_topics WHERE uid = " + did + " AND mid != " + last_mid_i + " AND mid != " + last_mid).stepThis().dispose();
}
database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM messages_holes WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard_topics WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM bot_keyboard_topics WHERE uid = " + did).stepThis().dispose();
@ -4089,6 +4113,9 @@ public class MessagesStorage extends BaseController {
database.executeFast("UPDATE dialogs SET unread_count = 0, unread_count_i = 0 WHERE did = " + did).stepThis().dispose(); database.executeFast("UPDATE dialogs SET unread_count = 0, unread_count_i = 0 WHERE did = " + did).stepThis().dispose();
database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM messages_v2 WHERE uid = " + did).stepThis().dispose();
if (did == getUserConfig().getClientUserId()) {
database.executeFast("DELETE FROM messages_topics WHERE uid = " + did).stepThis().dispose();
}
database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM bot_keyboard WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM bot_keyboard_topics WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM bot_keyboard_topics WHERE uid = " + did).stepThis().dispose();
database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose(); database.executeFast("DELETE FROM media_counts_v2 WHERE uid = " + did).stepThis().dispose();
@ -4559,10 +4586,138 @@ public class MessagesStorage extends BaseController {
}); });
} }
public void searchSavedByTag(TLRPC.Reaction tag, long topic_id, String query, int limit, int offset, Utilities.Callback4<ArrayList<MessageObject>, ArrayList<TLRPC.User>, ArrayList<TLRPC.Chat>, ArrayList<TLRPC.Document>> done, boolean includeGroups) {
if (done == null) {
return;
}
storageQueue.postRunnable(() -> {
SQLitePreparedStatement state = null;
SQLiteCursor cursor = null;
SQLiteCursor cursor_groups = null;
try {
final long selfId = getUserConfig().getClientUserId();
state = database.executeFast("SELECT m.data, m.replydata, m.group_id FROM messages_v2 m INNER JOIN tag_message_id t ON m.mid = t.mid WHERE m.uid = ? AND t.tag = ?" + (!TextUtils.isEmpty(query) ? " AND t.text LIKE '%' || ? || '%'" : "") + (topic_id != 0 ? " AND topic_id = ? " : "") + " ORDER BY m.mid DESC LIMIT ? OFFSET ?");
ArrayList<TLRPC.User> users = new ArrayList<>();
// ArrayList<TLRPC.User> encUsers = new ArrayList<>();
ArrayList<TLRPC.Chat> chats = new ArrayList<>();
ArrayList<Long> animatedEmojiToLoad = new ArrayList<>();
ArrayList<Long> usersToLoad = new ArrayList<>();
ArrayList<Long> chatsToLoad = new ArrayList<>();
ArrayList<TLRPC.Document> animatedEmoji = new ArrayList<>();
// LongSparseArray<SparseArray<ArrayList<TLRPC.Message>>> replyMessageOwners = new LongSparseArray<>();
// LongSparseArray<ArrayList<Integer>> dialogReplyMessagesIds = new LongSparseArray<>();
int pointer = 1;
state.bindLong(pointer++, selfId);
long hash = 0;
if (tag instanceof TLRPC.TL_reactionEmoji) {
hash = ((TLRPC.TL_reactionEmoji) tag).emoticon.hashCode();
} else if (tag instanceof TLRPC.TL_reactionCustomEmoji) {
hash = ((TLRPC.TL_reactionCustomEmoji) tag).document_id;
}
state.bindLong(pointer++, hash);
if (!TextUtils.isEmpty(query)) {
String q = LocaleController.getInstance().getTranslitString(query);
if (q == null) q = "";
state.bindString(pointer++, q);
}
if (topic_id != 0) {
state.bindLong(pointer++, topic_id);
}
state.bindInteger(pointer++, limit);
state.bindInteger(pointer++, offset);
cursor = state.query(new Object[] {});
state = null;
ArrayList<MessageObject> messageObjects = new ArrayList<>();
while (cursor.next()) {
long group_id = cursor.longValue(2);
if (group_id != 0 && includeGroups) {
cursor_groups = database.queryFinalized("SELECT data, replydata, group_id FROM messages_v2 WHERE uid = ? AND group_id = ? ORDER BY mid DESC", selfId, group_id);
ArrayList<MessageObject> groupmessages = new ArrayList<>();
while (cursor_groups.next()) {
NativeByteBuffer data = cursor_groups.byteBufferValue(0);
TLRPC.Message groupmessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
groupmessage.readAttachPath(data, selfId);
data.reuse();
addUsersAndChatsFromMessage(groupmessage, usersToLoad, chatsToLoad, animatedEmojiToLoad);
MessageObject messageObject = new MessageObject(currentAccount, groupmessage, null, null, null, null, null, true, true, 0, false, false, true);
if (groupmessage.reactions != null) {
messageObject.isPrimaryGroupMessage = true;
}
groupmessages.add(messageObject);
}
cursor_groups.dispose();
messageObjects.addAll(groupmessages);
} else {
NativeByteBuffer data = cursor.byteBufferValue(0);
if (data == null) continue;
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
if (message != null) {
message.readAttachPath(data, selfId);
data.reuse();
addUsersAndChatsFromMessage(message, usersToLoad, chatsToLoad, animatedEmojiToLoad);
if (message.reply_to != null && (message.reply_to.reply_to_msg_id != 0 || message.reply_to.reply_to_random_id != 0)) {
if (!cursor.isNull(1)) {
data = cursor.byteBufferValue(1);
if (data != null) {
message.replyMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.replyMessage.readAttachPath(data, selfId);
data.reuse();
if (message.replyMessage != null) {
addUsersAndChatsFromMessage(message.replyMessage, usersToLoad, chatsToLoad, animatedEmojiToLoad);
}
}
}
}
MessageObject messageObject = new MessageObject(currentAccount, message, null, null, null, null, null, true, true, 0, false, false, true);
messageObjects.add(messageObject);
}
}
}
cursor.dispose();
// loadReplyMessages(replyMessageOwners, dialogReplyMessagesIds, usersToLoad, chatsToLoad, false);
if (!usersToLoad.isEmpty()) {
getUsersInternal(TextUtils.join(",", usersToLoad), users);
}
if (!chatsToLoad.isEmpty()) {
getChatsInternal(TextUtils.join(",", chatsToLoad), chats);
}
if (!animatedEmojiToLoad.isEmpty()) {
getAnimatedEmoji(TextUtils.join(",", animatedEmojiToLoad), animatedEmoji);
}
AndroidUtilities.runOnUIThread(() -> {
done.run(messageObjects, users, chats, animatedEmoji);
});
} catch (Exception e) {
FileLog.e(e);
} finally {
if (state != null) {
state.dispose();
}
if (cursor != null) {
cursor.dispose();
}
if (cursor_groups != null) {
cursor_groups.dispose();
}
}
});
}
public void updateMessageReactions(long dialogId, int msgId, TLRPC.TL_messageReactions reactions) { public void updateMessageReactions(long dialogId, int msgId, TLRPC.TL_messageReactions reactions) {
storageQueue.postRunnable(() -> { storageQueue.postRunnable(() -> {
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
try { try {
final long selfId = getUserConfig().getClientUserId();
TLRPC.TL_messageReactions pastReactions = null;
long topicId = 0;
database.beginTransaction(); database.beginTransaction();
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
if (i == 0) { if (i == 0) {
@ -4577,6 +4732,10 @@ public class MessagesStorage extends BaseController {
if (message != null) { if (message != null) {
message.readAttachPath(data, getUserConfig().clientUserId); message.readAttachPath(data, getUserConfig().clientUserId);
data.reuse(); data.reuse();
if (pastReactions == null) {
pastReactions = message.reactions;
topicId = MessageObject.getSavedDialogId(selfId, message);
}
MessageObject.updateReactions(message, reactions); MessageObject.updateReactions(message, reactions);
SQLitePreparedStatement state; SQLitePreparedStatement state;
if (i == 0) { if (i == 0) {
@ -4594,6 +4753,12 @@ public class MessagesStorage extends BaseController {
state.step(); state.step();
data2.reuse(); data2.reuse();
state.dispose(); state.dispose();
if (selfId == dialogId) {
database.executeFast(String.format(Locale.US, "DELETE FROM tag_message_id WHERE mid = %d", message.id)).stepThis().dispose();
SQLitePreparedStatement state_tag_message = database.executeFast("REPLACE INTO tag_message_id VALUES(?, ?, ?, ?)");
bindMessageTags(state_tag_message, message);
state_tag_message.dispose();
}
} else { } else {
data.reuse(); data.reuse();
} }
@ -4603,6 +4768,9 @@ public class MessagesStorage extends BaseController {
cursor = null; cursor = null;
} }
database.commitTransaction(); database.commitTransaction();
if (dialogId == selfId && pastReactions != null) {
onReactionsUpdate(topicId, pastReactions, reactions);
}
} catch (Exception e) { } catch (Exception e) {
checkSQLException(e); checkSQLException(e);
} finally { } finally {
@ -4616,6 +4784,145 @@ public class MessagesStorage extends BaseController {
}); });
} }
private class SavedReactionsUpdate {
long topic_id;
TLRPC.TL_messageReactions old;
TLRPC.TL_messageReactions last;
public SavedReactionsUpdate(long selfId, TLRPC.Message oldMessage, TLRPC.Message newMessage) {
topic_id = MessageObject.getSavedDialogId(selfId, newMessage);
old = oldMessage.reactions;
last = newMessage.reactions;
}
}
private void onReactionsUpdate(ArrayList<SavedReactionsUpdate> reactionUpdates) {
if (reactionUpdates == null || reactionUpdates.isEmpty()) return;
AndroidUtilities.runOnUIThread(() -> {
boolean updated = false;
HashSet<Long> topicIds = new HashSet<>();
LongSparseArray<ReactionsLayoutInBubble.VisibleReaction> oldTags = new LongSparseArray<>();
LongSparseArray<ReactionsLayoutInBubble.VisibleReaction> newTags = new LongSparseArray<>();
for (int i = 0; i < reactionUpdates.size(); ++i) {
SavedReactionsUpdate pair = reactionUpdates.get(i);
TLRPC.TL_messageReactions a = pair.old;
TLRPC.TL_messageReactions b = pair.last;
oldTags.clear();
newTags.clear();
if (a != null && a.results != null && a.reactions_as_tags) {
for (int j = 0; j < a.results.size(); ++j) {
ReactionsLayoutInBubble.VisibleReaction reaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(a.results.get(j).reaction);
if (reaction != null) {
oldTags.put(reaction.hash, reaction);
}
}
}
if (b != null && b.results != null && b.reactions_as_tags) {
for (int j = 0; j < b.results.size(); ++j) {
ReactionsLayoutInBubble.VisibleReaction reaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(b.results.get(j).reaction);
if (reaction != null) {
newTags.put(reaction.hash, reaction);
}
}
}
// delete reactions
for (int j = 0; j < oldTags.size(); ++j) {
long hash = oldTags.keyAt(j);
ReactionsLayoutInBubble.VisibleReaction reaction = oldTags.valueAt(j);
if (!newTags.containsKey(hash)) {
if (getMessagesController().updateSavedReactionTags(pair.topic_id, reaction, false, false)) {
updated = true;
topicIds.add(pair.topic_id);
}
}
}
// add new reactions
for (int j = 0; j < newTags.size(); ++j) {
long hash = newTags.keyAt(j);
ReactionsLayoutInBubble.VisibleReaction reaction = newTags.valueAt(j);
if (!oldTags.containsKey(hash)) {
if (getMessagesController().updateSavedReactionTags(pair.topic_id, reaction, true, false)) {
updated = true;
topicIds.add(pair.topic_id);
}
}
}
}
if (updated && !topicIds.isEmpty()) {
getMessagesController().updateSavedReactionTags(topicIds);
}
});
}
private void onReactionsUpdate(long topic_id, TLRPC.TL_messageReactions a, TLRPC.TL_messageReactions b) {
if (a == null || a.results == null || a != null && a.results != null && a.results.isEmpty() && b != null && b.results.isEmpty()) {
return;
}
AndroidUtilities.runOnUIThread(() -> {
LongSparseArray<ReactionsLayoutInBubble.VisibleReaction> oldTags = new LongSparseArray<>();
LongSparseArray<ReactionsLayoutInBubble.VisibleReaction> newTags = new LongSparseArray<>();
if (a != null && a.results != null && a.reactions_as_tags) {
for (int i = 0; i < a.results.size(); ++i) {
ReactionsLayoutInBubble.VisibleReaction reaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(a.results.get(i).reaction);
oldTags.put(reaction.hash, reaction);
}
}
if (b != null && b.results != null && b.reactions_as_tags) {
for (int i = 0; i < b.results.size(); ++i) {
ReactionsLayoutInBubble.VisibleReaction reaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(b.results.get(i).reaction);
newTags.put(reaction.hash, reaction);
}
}
boolean updated = false;
// delete reactions
for (int i = 0; i < oldTags.size(); ++i) {
long hash = oldTags.keyAt(i);
ReactionsLayoutInBubble.VisibleReaction reaction = oldTags.valueAt(i);
if (!newTags.containsKey(hash)) {
updated = getMessagesController().updateSavedReactionTags(topic_id, reaction, false, false) || updated;
}
}
// add new reactions
for (int i = 0; i < newTags.size(); ++i) {
long hash = newTags.keyAt(i);
ReactionsLayoutInBubble.VisibleReaction reaction = newTags.valueAt(i);
if (!oldTags.containsKey(hash)) {
updated = getMessagesController().updateSavedReactionTags(topic_id, reaction, true, false) || updated;
}
}
if (updated) {
if (topic_id != 0) {
getMessagesController().updateSavedReactionTags(0);
}
getMessagesController().updateSavedReactionTags(topic_id);
}
});
}
private void bindMessageTags(SQLitePreparedStatement state, TLRPC.Message message) throws SQLiteException {
long selfId = getUserConfig().getClientUserId();
if (message.reactions != null && message.reactions.reactions_as_tags && message.reactions.results != null && !message.reactions.results.isEmpty()) {
final String text = LocaleController.getInstance().getTranslitString(message.message == null ? "" : message.message);
for (TLRPC.ReactionCount result : message.reactions.results) {
if (result.reaction instanceof TLRPC.TL_reactionEmoji || result.reaction instanceof TLRPC.TL_reactionCustomEmoji) {
state.requery();
state.bindLong(1, message.id);
state.bindLong(2, MessageObject.getSavedDialogId(selfId, message));
long hash = 0;
if (result.reaction instanceof TLRPC.TL_reactionEmoji) {
hash = ((TLRPC.TL_reactionEmoji) result.reaction).emoticon.hashCode();
} else if (result.reaction instanceof TLRPC.TL_reactionCustomEmoji) {
hash = ((TLRPC.TL_reactionCustomEmoji) result.reaction).document_id;
}
state.bindLong(3, hash);
state.bindString(4, text == null ? "" : text);
state.step();
}
}
}
}
public void updateMessageVoiceTranscriptionOpen(long dialogId, int msgId, TLRPC.Message saveFromMessage) { public void updateMessageVoiceTranscriptionOpen(long dialogId, int msgId, TLRPC.Message saveFromMessage) {
storageQueue.postRunnable(() -> { storageQueue.postRunnable(() -> {
SQLitePreparedStatement state = null; SQLitePreparedStatement state = null;
@ -10517,6 +10824,7 @@ public class MessagesStorage extends BaseController {
boolean databaseInTransaction = false; boolean databaseInTransaction = false;
SQLitePreparedStatement state_messages = null; SQLitePreparedStatement state_messages = null;
SQLitePreparedStatement state_messages_topic = null; SQLitePreparedStatement state_messages_topic = null;
SQLitePreparedStatement state_messages_tags = null;
SQLitePreparedStatement state_randoms = null; SQLitePreparedStatement state_randoms = null;
SQLitePreparedStatement state_download = null; SQLitePreparedStatement state_download = null;
SQLitePreparedStatement state_webpage = null; SQLitePreparedStatement state_webpage = null;
@ -10532,6 +10840,7 @@ public class MessagesStorage extends BaseController {
try { try {
final boolean scheduled = mode == ChatActivity.MODE_SCHEDULED; final boolean scheduled = mode == ChatActivity.MODE_SCHEDULED;
final boolean saved = mode == ChatActivity.MODE_SAVED; final boolean saved = mode == ChatActivity.MODE_SAVED;
final long selfId = getUserConfig().getClientUserId();
if (scheduled) { if (scheduled) {
if (withTransaction) { if (withTransaction) {
database.beginTransaction(); database.beginTransaction();
@ -10914,6 +11223,8 @@ public class MessagesStorage extends BaseController {
mediaTypesChange.put(mid, type); mediaTypesChange.put(mid, type);
} }
} }
cursor.dispose();
cursor = null;
SparseIntArray mediaTypes = dialogMediaTypes.get(topicKey.dialogId); SparseIntArray mediaTypes = dialogMediaTypes.get(topicKey.dialogId);
@ -10971,6 +11282,7 @@ public class MessagesStorage extends BaseController {
if (!messageIdsMap.isEmpty()) { if (!messageIdsMap.isEmpty()) {
for (int b = 0, N2 = messageIdsMap.size(); b < N2; b++) { for (int b = 0, N2 = messageIdsMap.size(); b < N2; b++) {
long dialogId = messageIdsMap.keyAt(b); long dialogId = messageIdsMap.keyAt(b);
if (dialogId == selfId) continue;
StringBuilder messageIds = messageIdsMap.valueAt(b); StringBuilder messageIds = messageIdsMap.valueAt(b);
ArrayList<Integer> messagesIdsMap = dialogMessagesIdsMap.get(dialogId); ArrayList<Integer> messagesIdsMap = dialogMessagesIdsMap.get(dialogId);
ArrayList<Integer> mentionsIdsMap = dialogMentionsIdsMap.get(dialogId); ArrayList<Integer> mentionsIdsMap = dialogMentionsIdsMap.get(dialogId);
@ -11085,7 +11397,6 @@ public class MessagesStorage extends BaseController {
createNewTopics.add(message); createNewTopics.add(message);
} }
final long selfId = getUserConfig().getClientUserId();
if (updateDialog) { if (updateDialog) {
TLRPC.Message lastMessage = messagesMap.get(message.dialog_id); TLRPC.Message lastMessage = messagesMap.get(message.dialog_id);
if (lastMessage == null || message.date > lastMessage.date || lastMessage.id > 0 && message.id > lastMessage.id || lastMessage.id < 0 && message.id < lastMessage.id) { if (lastMessage == null || message.date > lastMessage.date || lastMessage.id > 0 && message.id > lastMessage.id || lastMessage.id < 0 && message.id < lastMessage.id) {
@ -11113,6 +11424,9 @@ public class MessagesStorage extends BaseController {
} }
statement = state_messages_topic; statement = state_messages_topic;
if (selfId == dialogId && MessageObject.getSavedDialogId(selfId, message) != 0) { if (selfId == dialogId && MessageObject.getSavedDialogId(selfId, message) != 0) {
if (message.id < 0 && MessageObject.getSavedDialogId(selfId, message) != selfId) {
continue;
}
if (changedSavedMessages == null) { if (changedSavedMessages == null) {
changedSavedMessages = new ArrayList<>(); changedSavedMessages = new ArrayList<>();
} }
@ -11200,6 +11514,16 @@ public class MessagesStorage extends BaseController {
if (storyData != null) { if (storyData != null) {
storyData.reuse(); storyData.reuse();
} }
if (dialogId == selfId) {
database.executeFast(String.format(Locale.US, "DELETE FROM tag_message_id WHERE mid = %d", message.id)).stepThis().dispose();
if (state_messages_tags == null) {
state_messages_tags = database.executeFast("REPLACE INTO tag_message_id VALUES(?, ?, ?, ?)");
}
state_messages_tags.requery();
bindMessageTags(state_messages_tags, message);
state_messages_tags.step();
}
} }
if (message.random_id != 0) { if (message.random_id != 0) {
@ -11341,6 +11665,14 @@ public class MessagesStorage extends BaseController {
state_media.dispose(); state_media.dispose();
state_media = null; state_media = null;
} }
if (state_media_topics != null) {
state_media_topics.dispose();
state_media_topics = null;
}
if (state_messages_tags != null) {
state_messages_tags.dispose();
state_messages_tags = null;
}
if (state_tasks != null) { if (state_tasks != null) {
state_tasks.dispose(); state_tasks.dispose();
getMessagesController().didAddedNewTask(minDeleteTime, 0, null); getMessagesController().didAddedNewTask(minDeleteTime, 0, null);
@ -11425,7 +11757,7 @@ public class MessagesStorage extends BaseController {
dids.add(key); dids.add(key);
if (exists) { if (exists) {
if (message == null || (DialogObject.isEncryptedDialog(key) ? message.date > dialog_date : message.id >= last_mid) || message.send_state != 0 && ((message.flags & TLRPC.MESSAGE_FLAG_EDITED) == 0 || message.id >= last_mid)) { if (message == null || (DialogObject.isEncryptedDialog(key) ? message.date > dialog_date : message.id >= last_mid) || message.send_state != 0 && (message.flags & TLRPC.MESSAGE_FLAG_EDITED) == 0) {
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);
@ -11700,6 +12032,12 @@ public class MessagesStorage extends BaseController {
if (state_webpage != null) { if (state_webpage != null) {
state_webpage.dispose(); state_webpage.dispose();
} }
if (state_media_topics != null) {
state_media_topics.dispose();
}
if (state_messages_tags != null) {
state_messages_tags.dispose();
}
if (state_media != null) { if (state_media != null) {
state_media.dispose(); state_media.dispose();
} }
@ -12383,6 +12721,9 @@ public class MessagesStorage extends BaseController {
SQLiteCursor cursor = null; SQLiteCursor cursor = null;
SQLitePreparedStatement state = null; SQLitePreparedStatement state = null;
try { try {
if (getUserConfig().getClientUserId() == dialogId) {
database.executeFast(String.format(Locale.US, "DELETE FROM tag_message_id WHERE mid IN(%s)", TextUtils.join(",", messages))).stepThis().dispose();
}
ArrayList<Long> dialogsIds = new ArrayList<>(); ArrayList<Long> dialogsIds = new ArrayList<>();
if (scheduled) { if (scheduled) {
String ids = TextUtils.join(",", messages); String ids = TextUtils.join(",", messages);
@ -12408,6 +12749,8 @@ public class MessagesStorage extends BaseController {
broadcastScheduledMessagesChange(dialogsToUpdate.get(a)); broadcastScheduledMessagesChange(dialogsToUpdate.get(a));
} }
} else { } else {
long currentUser = getUserConfig().getClientUserId();
ArrayList<Integer> unknownMessages = new ArrayList<>(messages); ArrayList<Integer> unknownMessages = new ArrayList<>(messages);
ArrayList<Integer> unknownMessagesInTopics = new ArrayList<>(messages); ArrayList<Integer> unknownMessagesInTopics = new ArrayList<>(messages);
LongSparseArray<Integer[]> dialogsToUpdate = new LongSparseArray<>(); LongSparseArray<Integer[]> dialogsToUpdate = new LongSparseArray<>();
@ -12419,8 +12762,8 @@ public class MessagesStorage extends BaseController {
ArrayList<String> namesToDelete = new ArrayList<>(); ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>(); ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
ArrayList<TopicsController.TopicUpdate> topicUpdatesInUi = null; ArrayList<TopicsController.TopicUpdate> topicUpdatesInUi = null;
ArrayList<TLRPC.Message> deletedMessages = currentUser == dialogId || dialogId == 0 ? new ArrayList<>() : null;
long currentUser = getUserConfig().getClientUserId();
if (dialogId != 0) { if (dialogId != 0) {
cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data, read_state, out, mention, mid FROM messages_v2 WHERE mid IN(%s) AND uid = %d", ids, dialogId)); cursor = database.queryFinalized(String.format(Locale.US, "SELECT uid, data, read_state, out, mention, mid FROM messages_v2 WHERE mid IN(%s) AND uid = %d", ids, dialogId));
} else { } else {
@ -12461,6 +12804,9 @@ public class MessagesStorage extends BaseController {
if (data != null) { if (data != null) {
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
message.readAttachPath(data, currentUser); message.readAttachPath(data, currentUser);
if (deletedMessages != null) {
deletedMessages.add(message);
}
data.reuse(); data.reuse();
if (DialogObject.isEncryptedDialog(did) || deleteFiles) { if (DialogObject.isEncryptedDialog(did) || deleteFiles) {
addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false); addFilesToDelete(message, filesToDelete, idsToDelete, namesToDelete, false);
@ -12830,6 +13176,36 @@ public class MessagesStorage extends BaseController {
database.executeFast(String.format(Locale.US, "UPDATE media_counts_v2 SET old = 1 WHERE uid = %d", dialogId)).stepThis().dispose(); database.executeFast(String.format(Locale.US, "UPDATE media_counts_v2 SET old = 1 WHERE uid = %d", dialogId)).stepThis().dispose();
} }
} }
if (deletedMessages != null && !deletedMessages.isEmpty()) {
AndroidUtilities.runOnUIThread(() -> {
boolean changed = false;
HashSet<Long> topicIds = new HashSet<>();
for (TLRPC.Message msg : deletedMessages) {
if (getMessagesController().processDeletedReactionTags(msg)) {
topicIds.add(MessageObject.getSavedDialogId(currentUser, msg));
changed = true;
}
}
if (changed) {
getMessagesController().updateSavedReactionTags(topicIds);
}
});
} else if (deletedMessages != null && deletedMessages.isEmpty()) {
AndroidUtilities.runOnUIThread(() -> {
HashSet<Long> topicIds = new HashSet<>();
boolean changed = false;
long[] topic_id = new long[1];
for (int i = 0; i < messages.size(); ++i) {
if (getMediaDataController().processDeletedMessage(messages.get(i), topic_id)) {
topicIds.add(topic_id[0]);
changed = true;
}
}
if (changed) {
getMessagesController().updateSavedReactionTags(topicIds);
}
});
}
if (!unknownMessagesInTopics.isEmpty()) { if (!unknownMessagesInTopics.isEmpty()) {
if (dialogId == 0) { if (dialogId == 0) {
database.executeFast("UPDATE media_counts_topics SET old = 1 WHERE 1").stepThis().dispose(); database.executeFast("UPDATE media_counts_topics SET old = 1 WHERE 1").stepThis().dispose();
@ -13832,6 +14208,7 @@ public class MessagesStorage extends BaseController {
SQLitePreparedStatement state_messages_topics = null; SQLitePreparedStatement state_messages_topics = null;
SQLitePreparedStatement state_media = null; SQLitePreparedStatement state_media = null;
SQLitePreparedStatement state_media_topics = null; SQLitePreparedStatement state_media_topics = null;
SQLitePreparedStatement state_messages_tags = null;
SQLitePreparedStatement state_polls = null; SQLitePreparedStatement state_polls = null;
SQLitePreparedStatement state_webpage = null; SQLitePreparedStatement state_webpage = null;
SQLitePreparedStatement state_tasks = null; SQLitePreparedStatement state_tasks = null;
@ -13900,6 +14277,7 @@ public class MessagesStorage extends BaseController {
closeHolesInMedia(dialogId, minId, maxId, -1, threadMessageId); closeHolesInMedia(dialogId, minId, maxId, -1, threadMessageId);
} }
int count = messages.messages.size(); int count = messages.messages.size();
final long selfId = getUserConfig().getClientUserId();
//load_type == 0 ? backward loading //load_type == 0 ? backward loading
//load_type == 1 ? forward loading //load_type == 1 ? forward loading
@ -13910,6 +14288,7 @@ public class MessagesStorage extends BaseController {
ArrayList<String> namesToDelete = new ArrayList<>(); ArrayList<String> namesToDelete = new ArrayList<>();
ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>(); ArrayList<Pair<Long, Integer>> idsToDelete = new ArrayList<>();
ArrayList<TLRPC.Message> changedSavedMessages = null; ArrayList<TLRPC.Message> changedSavedMessages = null;
ArrayList<SavedReactionsUpdate> reactionUpdates = dialogId == selfId ? new ArrayList<>() : null;
Integer lastMessageId = null; Integer lastMessageId = null;
Long lastMessageGroupId = null; Long lastMessageGroupId = null;
@ -13923,7 +14302,16 @@ public class MessagesStorage extends BaseController {
int minDeleteTime = Integer.MAX_VALUE; int minDeleteTime = Integer.MAX_VALUE;
HashMap<TopicKey, TLRPC.Message> botKeyboards = null; HashMap<TopicKey, TLRPC.Message> botKeyboards = null;
long channelId = 0; long channelId = 0;
final long selfId = getUserConfig().getClientUserId(); final boolean self = selfId == dialogId;
if (self) {
ArrayList<Integer> ids = new ArrayList<>();
for (int a = 0; a < count; a++) {
TLRPC.Message message = messages.messages.get(a);
ids.add(message.id);
}
database.executeFast("DELETE FROM tag_message_id WHERE mid IN (" + TextUtils.join(",", ids) + ")").stepThis().dispose();
state_messages_tags = database.executeFast("REPLACE INTO tag_message_id VALUES(?, ?, ?, ?)");
}
for (int a = 0; a < count; a++) { for (int a = 0; a < count; a++) {
TLRPC.Message message = messages.messages.get(a); TLRPC.Message message = messages.messages.get(a);
if (lastMessageId == null && message != null || lastMessageId != null && lastMessageId < message.id) { if (lastMessageId == null && message != null || lastMessageId != null && lastMessageId < message.id) {
@ -13944,6 +14332,9 @@ public class MessagesStorage extends BaseController {
TLRPC.Message oldMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false); TLRPC.Message oldMessage = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
oldMessage.readAttachPath(data, getUserConfig().clientUserId); oldMessage.readAttachPath(data, getUserConfig().clientUserId);
data.reuse(); data.reuse();
if (reactionUpdates != null) {
reactionUpdates.add(new SavedReactionsUpdate(selfId, oldMessage, message));
}
int send_state = cursor.intValue(5); int send_state = cursor.intValue(5);
if (send_state != 3) { if (send_state != 3) {
if (MessageObject.getFileName(oldMessage).equals(MessageObject.getFileName(message))) { if (MessageObject.getFileName(oldMessage).equals(MessageObject.getFileName(message))) {
@ -14150,6 +14541,10 @@ public class MessagesStorage extends BaseController {
} }
currentState.step(); currentState.step();
if (i == 0 && state_messages_tags != null) {
bindMessageTags(state_messages_tags, message);
}
if (repliesData != null) { if (repliesData != null) {
repliesData.reuse(); repliesData.reuse();
} }
@ -14248,6 +14643,10 @@ public class MessagesStorage extends BaseController {
state_messages = null; state_messages = null;
state_messages_topics.dispose(); state_messages_topics.dispose();
state_messages_topics = null; state_messages_topics = null;
if (state_messages_tags != null) {
state_messages_tags.dispose();
state_messages_tags = null;
}
state_media.dispose(); state_media.dispose();
state_media = null; state_media = null;
if (state_webpage != null) { if (state_webpage != null) {
@ -14302,6 +14701,7 @@ public class MessagesStorage extends BaseController {
} }
}); });
} }
onReactionsUpdate(reactionUpdates);
} }
} catch (Exception e) { } catch (Exception e) {
checkSQLException(e); checkSQLException(e);
@ -14312,6 +14712,9 @@ public class MessagesStorage extends BaseController {
if (state_messages_topics != null) { if (state_messages_topics != null) {
state_messages_topics.dispose(); state_messages_topics.dispose();
} }
if (state_messages_tags != null) {
state_messages_tags.dispose();
}
if (state_messages != null) { if (state_messages != null) {
state_messages.dispose(); state_messages.dispose();
} }

View file

@ -9,6 +9,7 @@
package org.telegram.messenger; package org.telegram.messenger;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.view.View; import android.view.View;
@ -228,6 +229,9 @@ public class NotificationCenter {
public static final int savedMessagesDialogsUpdate = totalEvents++; public static final int savedMessagesDialogsUpdate = totalEvents++;
public static final int savedReactionTagsUpdate = totalEvents++; public static final int savedReactionTagsUpdate = totalEvents++;
public static final int userIsPremiumBlockedUpadted = totalEvents++; public static final int userIsPremiumBlockedUpadted = totalEvents++;
public static final int savedMessagesForwarded = totalEvents++;
public static final int emojiKeywordsLoaded = totalEvents++;
public static final int storyQualityUpdate = totalEvents++;
//global //global
public static final int pushMessagesUpdated = totalEvents++; public static final int pushMessagesUpdated = totalEvents++;
@ -507,7 +511,7 @@ public class NotificationCenter {
} }
public void postNotificationName(int id, Object... args) { public void postNotificationName(int id, Object... args) {
boolean allowDuringAnimation = id == startAllHeavyOperations || id == stopAllHeavyOperations || id == didReplacedPhotoInMemCache || id == closeChats || id == invalidateMotionBackground; boolean allowDuringAnimation = id == startAllHeavyOperations || id == stopAllHeavyOperations || id == didReplacedPhotoInMemCache || id == closeChats || id == invalidateMotionBackground || id == needCheckSystemBarColors;
ArrayList<Integer> expiredIndices = null; ArrayList<Integer> expiredIndices = null;
if (!allowDuringAnimation && allowedNotifications.size() > 0) { if (!allowDuringAnimation && allowedNotifications.size() > 0) {
int size = allowedNotifications.size(); int size = allowedNotifications.size();

View file

@ -2,29 +2,23 @@ package org.telegram.messenger;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.Util;
import org.telegram.SQLite.SQLiteCursor; import org.telegram.SQLite.SQLiteCursor;
import org.telegram.SQLite.SQLiteDatabase; import org.telegram.SQLite.SQLiteDatabase;
import org.telegram.SQLite.SQLiteException;
import org.telegram.SQLite.SQLitePreparedStatement; import org.telegram.SQLite.SQLitePreparedStatement;
import org.telegram.tgnet.ConnectionsManager; import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.NativeByteBuffer; import org.telegram.tgnet.NativeByteBuffer;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.Cells.TextCell;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import java.math.BigInteger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects; import java.util.Objects;
@ -98,6 +92,9 @@ public class SavedMessagesController {
allDialogs.addAll(dialogs); allDialogs.addAll(dialogs);
if (notify) { if (notify) {
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.savedMessagesDialogsUpdate); NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.savedMessagesDialogsUpdate);
if (!hasDialogs() && MessagesController.getInstance(currentAccount).savedViewAsChats) {
MessagesController.getInstance(currentAccount).setSavedViewAs(false);
}
} }
} }
@ -111,6 +108,15 @@ public class SavedMessagesController {
return cachedDialogs.size(); return cachedDialogs.size();
} }
public boolean hasDialogs() {
if (getAllCount() <= 0) return false;
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
if (allDialogs.size() == 1 && allDialogs.get(0).dialogId == selfId) {
return false;
}
return true;
}
public int getLoadedCount() { public int getLoadedCount() {
return loadedDialogs.size(); return loadedDialogs.size();
} }
@ -191,20 +197,21 @@ public class SavedMessagesController {
return false; return false;
} }
public void preloadDialogs() { public void preloadDialogs(boolean cache) {
if (!dialogsLoaded) { if (!dialogsLoaded) {
loadDialogs(); loadDialogs(cache);
} }
} }
public void loadDialogs() { public void loadDialogs(boolean onlyCache) {
loadingCacheOnly = onlyCache;
if (dialogsLoading || dialogsEndReached || loadingCache) { if (dialogsLoading || dialogsEndReached || loadingCache) {
return; return;
} }
if (!loadedCache) { if (!loadedCache) {
loadCache(this::loadDialogs); loadCache(() -> loadDialogs(false));
return; return;
} } else if (onlyCache) return;
dialogsLoading = true; dialogsLoading = true;
TLRPC.TL_messages_getSavedDialogs req = new TLRPC.TL_messages_getSavedDialogs(); TLRPC.TL_messages_getSavedDialogs req = new TLRPC.TL_messages_getSavedDialogs();
@ -365,10 +372,18 @@ public class SavedMessagesController {
found = true; found = true;
if (d.top_message_id < message.id || message.id < 0 && message.date > d.getDate()) { if (d.top_message_id < message.id || message.id < 0 && message.date > d.getDate()) {
changed = true; changed = true;
if (d.top_message_id < message.id) {
int count = 0;
for (int k = 0; k < inputMessages.size(); ++k) {
if (inputMessages.get(k).id > d.top_message_id) {
count++;
}
}
d.messagesCount += count;
}
d.message = new MessageObject(currentAccount, message, false, false); d.message = new MessageObject(currentAccount, message, false, false);
d.top_message_id = d.message.getId(); d.top_message_id = d.message.getId();
} }
dialogsCountToCheck.add(d.dialogId);
break; break;
} }
} }
@ -387,10 +402,18 @@ public class SavedMessagesController {
found = true; found = true;
if (d.top_message_id < message.id || message.id < 0 && message.date > d.getDate()) { if (d.top_message_id < message.id || message.id < 0 && message.date > d.getDate()) {
changed = true; changed = true;
if (d.top_message_id < message.id) {
int count = 0;
for (int k = 0; k < inputMessages.size(); ++k) {
if (inputMessages.get(k).id > d.top_message_id) {
count++;
}
}
d.messagesCount += count;
}
d.message = new MessageObject(currentAccount, message, false, false); d.message = new MessageObject(currentAccount, message, false, false);
d.top_message_id = d.message.getId(); d.top_message_id = d.message.getId();
} }
dialogsCountToCheck.add(d.dialogId);
break; break;
} }
} }
@ -403,9 +426,6 @@ public class SavedMessagesController {
changed = true; changed = true;
} }
} }
if (!dialogsCountToCheck.isEmpty()) {
updateDialogsCount(dialogsCountToCheck);
}
return changed; return changed;
} }
@ -432,6 +452,7 @@ public class SavedMessagesController {
if (d.dialogId == dialogId) { if (d.dialogId == dialogId) {
if (d.messagesCount != messagesCount) { if (d.messagesCount != messagesCount) {
d.messagesCount = messagesCount; d.messagesCount = messagesCount;
d.messagesCountLoaded = true;
return true; return true;
} }
break; break;
@ -519,7 +540,7 @@ public class SavedMessagesController {
dialogsCount = 0; dialogsCount = 0;
dialogsEndReached = false; dialogsEndReached = false;
update(); update();
loadDialogs(); loadDialogs(false);
} }
public void deleteDialog(long did) { public void deleteDialog(long did) {
@ -534,6 +555,14 @@ public class SavedMessagesController {
update(); update();
} }
public void deleteAllDialogs() {
dialogsCount = 0;
allDialogs.clear();
loadedDialogs.clear();
cachedDialogs.clear();
update();
}
private int removeDialog(long did) { private int removeDialog(long did) {
int acount = 0; int acount = 0;
for (int i = 0; i < allDialogs.size(); ++i) { for (int i = 0; i < allDialogs.size(); ++i) {
@ -565,7 +594,7 @@ public class SavedMessagesController {
saveCacheSchedule(); saveCacheSchedule();
} }
public boolean updatePinned(ArrayList<Long> dialogIds, boolean pin) { public boolean updatePinned(ArrayList<Long> dialogIds, boolean pin, boolean toServer) {
ArrayList<Long> currentOrder = getCurrentPinnedOrder(allDialogs); ArrayList<Long> currentOrder = getCurrentPinnedOrder(allDialogs);
ArrayList<Long> newOrder = new ArrayList<>(currentOrder); ArrayList<Long> newOrder = new ArrayList<>(currentOrder);
for (int i = dialogIds.size() - 1; i >= 0; --i) { for (int i = dialogIds.size() - 1; i >= 0; --i) {
@ -585,9 +614,16 @@ public class SavedMessagesController {
return false; return false;
} }
if (!sameOrder(currentOrder, newOrder)) { if (!sameOrder(currentOrder, newOrder)) {
updatePinnedOrderToServer(newOrder); if (toServer) {
updatePinnedOrderToServer(newOrder);
return true;
} else {
final boolean updateLoaded = updatePinnedOrder(loadedDialogs, newOrder);
final boolean updateCached = updatePinnedOrder(cachedDialogs, newOrder);
return updateLoaded || updateCached;
}
} }
return true; return false;
} }
public boolean updatePinnedOrder(ArrayList<Long> newOrder) { public boolean updatePinnedOrder(ArrayList<Long> newOrder) {
@ -636,18 +672,9 @@ public class SavedMessagesController {
TLRPC.TL_updateSavedDialogPinned upd = (TLRPC.TL_updateSavedDialogPinned) update; TLRPC.TL_updateSavedDialogPinned upd = (TLRPC.TL_updateSavedDialogPinned) update;
if (!(upd.peer instanceof TLRPC.TL_dialogPeer)) return false; if (!(upd.peer instanceof TLRPC.TL_dialogPeer)) return false;
long dialogId = DialogObject.getPeerDialogId(((TLRPC.TL_dialogPeer) upd.peer).peer); long dialogId = DialogObject.getPeerDialogId(((TLRPC.TL_dialogPeer) upd.peer).peer);
boolean changed = false; ArrayList<Long> ids = new ArrayList<>();
ArrayList<SavedDialog>[] arraysToCheck = new ArrayList[] { loadedDialogs, cachedDialogs }; ids.add(dialogId);
for (int a = 0; a < arraysToCheck.length; ++a) { return updatePinned(ids, upd.pinned, false);
for (int i = 0; i < arraysToCheck[a].size(); ++i) {
SavedDialog d = arraysToCheck[a].get(i);
if (d.dialogId == dialogId && d.pinned != upd.pinned) {
d.pinned = upd.pinned;
changed = true;
}
}
}
return changed;
} else if (update instanceof TLRPC.TL_updatePinnedSavedDialogs) { } else if (update instanceof TLRPC.TL_updatePinnedSavedDialogs) {
TLRPC.TL_updatePinnedSavedDialogs upd = (TLRPC.TL_updatePinnedSavedDialogs) update; TLRPC.TL_updatePinnedSavedDialogs upd = (TLRPC.TL_updatePinnedSavedDialogs) update;
ArrayList<Long> newOrder = new ArrayList<>(upd.order.size()); ArrayList<Long> newOrder = new ArrayList<>(upd.order.size());
@ -731,49 +758,8 @@ public class SavedMessagesController {
return true; return true;
} }
private void updateDialogsCount(HashSet<Long> dialogIds) {
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
MessagesStorage messagesStorage = MessagesStorage.getInstance(currentAccount);
messagesStorage.getStorageQueue().postRunnable(() -> {
SQLiteDatabase db = messagesStorage.getDatabase();
LongSparseArray<Integer> countResult = new LongSparseArray<>();
SQLiteCursor cursor = null;
try {
for (long did : dialogIds) {
cursor = db.queryFinalized("SELECT COUNT(*) FROM messages_topics WHERE uid = ? AND topic_id = ?", selfId, did);
if (cursor.next()) {
countResult.put(did, cursor.intValue(0));
}
cursor.dispose();
}
} catch (Exception e) {
FileLog.e(e);
} finally {
if (cursor != null) {
cursor.dispose();
cursor = null;
}
}
AndroidUtilities.runOnUIThread(() -> {
boolean changed = false;
for (int i = 0; i < countResult.size(); ++i) {
long did = countResult.keyAt(i);
int count = countResult.valueAt(i);
SavedDialog d = findSavedDialog(did);
if (d != null && d.messagesCount != count) {
d.messagesCount = count;
changed = true;
}
}
if (changed) {
update();
}
});
});
}
private boolean loadingCache, loadedCache; private boolean loadingCache, loadedCache;
private boolean loadingCacheOnly;
private void loadCache(Runnable whenDone) { private void loadCache(Runnable whenDone) {
if (loadingCache) { if (loadingCache) {
return; return;
@ -802,6 +788,8 @@ public class SavedMessagesController {
d.localDate = cursor.intValue(1); d.localDate = cursor.intValue(1);
d.top_message_id = cursor.intValue(2); d.top_message_id = cursor.intValue(2);
d.pinnedOrder = cursor.intValue(3); d.pinnedOrder = cursor.intValue(3);
final int flags = cursor.intValue(4);
d.messagesCountLoaded = (flags & 1) != 0;
d.pinned = d.pinnedOrder != 999; d.pinned = d.pinnedOrder != 999;
d.messagesCount = cursor.intValue(7); d.messagesCount = cursor.intValue(7);
if (d.dialogId < 0) { if (d.dialogId < 0) {
@ -855,7 +843,7 @@ public class SavedMessagesController {
cachedDialogs.addAll(dialogs); cachedDialogs.addAll(dialogs);
updateAllDialogs(true); updateAllDialogs(true);
if (whenDone != null) { if (whenDone != null && !loadingCacheOnly) {
whenDone.run(); whenDone.run();
} }
}); });
@ -974,7 +962,7 @@ public class SavedMessagesController {
state.bindInteger(2, d.getDate()); state.bindInteger(2, d.getDate());
state.bindInteger(3, d.top_message_id); state.bindInteger(3, d.top_message_id);
state.bindInteger(4, d.pinned ? i : 999); state.bindInteger(4, d.pinned ? i : 999);
state.bindInteger(5, 0); state.bindInteger(5, d.messagesCountLoaded ? 1 : 0);
state.bindInteger(6, 0); state.bindInteger(6, 0);
state.bindInteger(7, 0); state.bindInteger(7, 0);
state.bindInteger(8, d.messagesCount); state.bindInteger(8, d.messagesCount);
@ -1022,6 +1010,8 @@ public class SavedMessagesController {
public MessageObject message; public MessageObject message;
public int messagesCount; public int messagesCount;
public boolean messagesCountLoaded;
// used only in cache // used only in cache
private int localDate; private int localDate;
@ -1032,7 +1022,7 @@ public class SavedMessagesController {
if (message == null || message.messageOwner == null) { if (message == null || message.messageOwner == null) {
return localDate; return localDate;
} }
if ((message.messageOwner.flags & TLRPC.MESSAGE_FLAG_EDITED) != 0) { if ((message.messageOwner.flags & TLRPC.MESSAGE_FLAG_EDITED) != 0 && !message.messageOwner.edit_hide) {
return message.messageOwner.edit_date; return message.messageOwner.edit_date;
} }
return message.messageOwner.date; return message.messageOwner.date;
@ -1080,23 +1070,28 @@ public class SavedMessagesController {
lastFragment.presentFragment(new ChatActivity(args)); lastFragment.presentFragment(new ChatActivity(args));
} }
public void checkSavedDialogCount(long dialogId) {
SavedDialog d = findSavedDialog(dialogId);
if (d != null && !d.messagesCountLoaded) {
hasSavedMessages(dialogId, null);
}
}
private final LongSparseArray<ArrayList<Utilities.Callback<Boolean>>> checkMessagesCallbacks = new LongSparseArray<>(); private final LongSparseArray<ArrayList<Utilities.Callback<Boolean>>> checkMessagesCallbacks = new LongSparseArray<>();
public void hasSavedMessages(long did, Utilities.Callback<Boolean> whenDone) { public void hasSavedMessages(long did, Utilities.Callback<Boolean> whenDone) {
if (whenDone == null) return;
final SavedDialog savedDialog = findSavedDialog(did); final SavedDialog savedDialog = findSavedDialog(did);
if (savedDialog != null && savedDialog.messagesCount > 0) { if (savedDialog != null && savedDialog.messagesCount > 0 && savedDialog.messagesCountLoaded) {
whenDone.run(true); if (whenDone != null) whenDone.run(true);
return; return;
} }
ArrayList<Utilities.Callback<Boolean>> existingCallbacks = checkMessagesCallbacks.get(did); ArrayList<Utilities.Callback<Boolean>> existingCallbacks = checkMessagesCallbacks.get(did);
if (existingCallbacks != null) { if (existingCallbacks != null) {
existingCallbacks.add(whenDone); if (whenDone != null) existingCallbacks.add(whenDone);
return; return;
} }
existingCallbacks = new ArrayList<>(); existingCallbacks = new ArrayList<>();
existingCallbacks.add(whenDone); if (whenDone != null) existingCallbacks.add(whenDone);
checkMessagesCallbacks.put(did, existingCallbacks); checkMessagesCallbacks.put(did, existingCallbacks);
TLRPC.TL_messages_getSavedHistory req = new TLRPC.TL_messages_getSavedHistory(); TLRPC.TL_messages_getSavedHistory req = new TLRPC.TL_messages_getSavedHistory();
@ -1124,9 +1119,12 @@ public class SavedMessagesController {
if (!r.messages.isEmpty()) { if (!r.messages.isEmpty()) {
SavedDialog dialog = SavedDialog.fromMessage(currentAccount, r.messages.get(0)); SavedDialog dialog = SavedDialog.fromMessage(currentAccount, r.messages.get(0));
dialog.messagesCount = count; dialog.messagesCount = count;
dialog.messagesCountLoaded = true;
cachedDialogs.add(dialog); cachedDialogs.add(dialog);
update(); update();
} }
} else {
update();
} }
} }

View file

@ -2189,6 +2189,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
a1--; a1--;
} }
} }
getNotificationCenter().postNotificationNameOnUIThread(NotificationCenter.savedMessagesForwarded, newMessagesByIds);
Integer value = getMessagesController().dialogs_read_outbox_max.get(peer); Integer value = getMessagesController().dialogs_read_outbox_max.get(peer);
if (value == null) { if (value == null) {
value = getMessagesStorage().getDialogReadMax(true, peer); value = getMessagesStorage().getDialogReadMax(true, peer);
@ -2958,7 +2959,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
return voteSendTime.get(pollId, 0L); return voteSendTime.get(pollId, 0L);
} }
public void sendReaction(MessageObject messageObject, ArrayList<ReactionsLayoutInBubble.VisibleReaction> visibleReactions, ReactionsLayoutInBubble.VisibleReaction addedReaction, boolean big, boolean addToRecent, ChatActivity parentFragment, Runnable callback) { public void sendReaction(MessageObject messageObject, ArrayList<ReactionsLayoutInBubble.VisibleReaction> visibleReactions, ReactionsLayoutInBubble.VisibleReaction addedReaction, boolean big, boolean addToRecent, BaseFragment parentFragment, Runnable callback) {
if (messageObject == null || parentFragment == null) { if (messageObject == null || parentFragment == null) {
return; return;
} }
@ -4092,6 +4093,7 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
inputWebPage.url = mediaWebPage.webpage.url; inputWebPage.url = mediaWebPage.webpage.url;
inputWebPage.force_large_media = mediaWebPage.force_large_media; inputWebPage.force_large_media = mediaWebPage.force_large_media;
inputWebPage.force_small_media = mediaWebPage.force_small_media; inputWebPage.force_small_media = mediaWebPage.force_small_media;
inputWebPage.optional = true;
reqSend.media = inputWebPage; reqSend.media = inputWebPage;
if (replyToStoryItem != null) { if (replyToStoryItem != null) {
reqSend.reply_to = createReplyInput(replyToStoryItem); reqSend.reply_to = createReplyInput(replyToStoryItem);
@ -5102,10 +5104,12 @@ public class SendMessagesHelper extends BaseController implements NotificationCe
} }
} }
putToDelayedMessages(location, message); putToDelayedMessages(location, message);
if (message.obj.videoEditedInfo != null && message.obj.videoEditedInfo.needConvert()) { if (message.obj.videoEditedInfo == null || !message.obj.videoEditedInfo.notReadyYet) {
getFileLoader().uploadFile(location, true, false, document.size, ConnectionsManager.FileTypeVideo, false); if (message.obj.videoEditedInfo != null && message.obj.videoEditedInfo.needConvert()) {
} else { getFileLoader().uploadFile(location, true, false, document.size, ConnectionsManager.FileTypeVideo, false);
getFileLoader().uploadFile(location, true, false, ConnectionsManager.FileTypeVideo); } else {
getFileLoader().uploadFile(location, true, false, ConnectionsManager.FileTypeVideo);
}
} }
putToUploadingMessages(message.obj); putToUploadingMessages(message.obj);
} }

View file

@ -238,7 +238,6 @@ public class SharedConfig {
public static int keepMedia = CacheByChatsController.KEEP_MEDIA_ONE_MONTH; //deprecated public static int keepMedia = CacheByChatsController.KEEP_MEDIA_ONE_MONTH; //deprecated
public static int lastKeepMediaCheckTime; public static int lastKeepMediaCheckTime;
public static int lastLogsCheckTime; public static int lastLogsCheckTime;
public static int searchMessagesAsListHintShows;
public static int textSelectionHintShows; public static int textSelectionHintShows;
public static int scheduledOrNoSoundHintShows; public static int scheduledOrNoSoundHintShows;
public static long scheduledOrNoSoundHintSeenAt; public static long scheduledOrNoSoundHintSeenAt;
@ -310,7 +309,6 @@ public class SharedConfig {
public static int messageSeenHintCount; public static int messageSeenHintCount;
public static int emojiInteractionsHintCount; public static int emojiInteractionsHintCount;
public static int dayNightThemeSwitchHintCount; public static int dayNightThemeSwitchHintCount;
public static boolean forceLessData;
public static int callEncryptionHintDisplayedCount; public static int callEncryptionHintDisplayedCount;
public static TLRPC.TL_help_appUpdate pendingAppUpdate; public static TLRPC.TL_help_appUpdate pendingAppUpdate;
@ -616,7 +614,6 @@ public class SharedConfig {
debugWebView = preferences.getBoolean("debugWebView", false); debugWebView = preferences.getBoolean("debugWebView", false);
lastKeepMediaCheckTime = preferences.getInt("lastKeepMediaCheckTime", 0); lastKeepMediaCheckTime = preferences.getInt("lastKeepMediaCheckTime", 0);
lastLogsCheckTime = preferences.getInt("lastLogsCheckTime", 0); lastLogsCheckTime = preferences.getInt("lastLogsCheckTime", 0);
searchMessagesAsListHintShows = preferences.getInt("searchMessagesAsListHintShows", 0);
searchMessagesAsListUsed = preferences.getBoolean("searchMessagesAsListUsed", false); searchMessagesAsListUsed = preferences.getBoolean("searchMessagesAsListUsed", false);
stickersReorderingHintUsed = preferences.getBoolean("stickersReorderingHintUsed", false); stickersReorderingHintUsed = preferences.getBoolean("stickersReorderingHintUsed", false);
storyReactionsLongPressHint = preferences.getBoolean("storyReactionsLongPressHint", false); storyReactionsLongPressHint = preferences.getBoolean("storyReactionsLongPressHint", false);
@ -649,7 +646,6 @@ public class SharedConfig {
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); multipleReactionsPromoShowed = preferences.getBoolean("multipleReactionsPromoShowed", false);
forceLessData = preferences.getBoolean("forceLessData", false);
callEncryptionHintDisplayedCount = preferences.getInt("callEncryptionHintDisplayedCount", 0); callEncryptionHintDisplayedCount = preferences.getInt("callEncryptionHintDisplayedCount", 0);
loadDebugConfig(preferences); loadDebugConfig(preferences);
@ -1003,13 +999,6 @@ public class SharedConfig {
editor.apply(); editor.apply();
} }
public static void increaseSearchAsListHintShows() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("searchMessagesAsListHintShows", ++searchMessagesAsListHintShows);
editor.apply();
}
public static void setKeepMedia(int value) { public static void setKeepMedia(int value) {
keepMedia = value; keepMedia = value;
SharedPreferences preferences = MessagesController.getGlobalMainSettings(); SharedPreferences preferences = MessagesController.getGlobalMainSettings();
@ -1545,11 +1534,6 @@ public class SharedConfig {
preferences.edit().putInt("emojiInteractionsHintCount", emojiInteractionsHintCount).apply(); preferences.edit().putInt("emojiInteractionsHintCount", emojiInteractionsHintCount).apply();
} }
public static void setForceLessData(boolean value) {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
preferences.edit().putBoolean("forceLessData", forceLessData = value).apply();
}
public static void updateDayNightThemeSwitchHintCount(int count) { public static void updateDayNightThemeSwitchHintCount(int count) {
dayNightThemeSwitchHintCount = count; dayNightThemeSwitchHintCount = count;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE); SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("mainconfig", Activity.MODE_PRIVATE);

View file

@ -1001,7 +1001,7 @@ public class TopicsController extends BaseController {
} }
} }
public void loadTopic(long chatId, int topicId, Runnable runnable) { public void loadTopic(long chatId, long topicId, Runnable runnable) {
getMessagesStorage().loadTopics(-chatId, topics -> { getMessagesStorage().loadTopics(-chatId, topics -> {
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
@ -1015,7 +1015,7 @@ public class TopicsController extends BaseController {
} else { } else {
ArrayList<TLRPC.TL_forumTopic> topicToReload = new ArrayList<>(); ArrayList<TLRPC.TL_forumTopic> topicToReload = new ArrayList<>();
TLRPC.TL_forumTopic topic = new TLRPC.TL_forumTopic(); TLRPC.TL_forumTopic topic = new TLRPC.TL_forumTopic();
topic.id = topicId; topic.id = (int) topicId;
reloadTopics(chatId, topicToReload, runnable); reloadTopics(chatId, topicToReload, runnable);
} }
}); });

View file

@ -499,6 +499,16 @@ public class Utilities {
return Math.max(Math.min(value, maxValue), minValue); return Math.max(Math.min(value, maxValue), minValue);
} }
public static double clamp(double value, double maxValue, double minValue) {
if (Double.isNaN(value)) {
return minValue;
}
if (Double.isInfinite(value)) {
return maxValue;
}
return Math.max(Math.min(value, maxValue), minValue);
}
public static String generateRandomString() { public static String generateRandomString() {
return generateRandomString(16); return generateRandomString(16);
} }

View file

@ -11,11 +11,10 @@ package org.telegram.messenger;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat; import androidx.core.app.NotificationManagerCompat;
import com.google.android.exoplayer2.util.Log;
public class VideoEncodingService extends Service implements NotificationCenter.NotificationCenterDelegate { public class VideoEncodingService extends Service implements NotificationCenter.NotificationCenterDelegate {
private NotificationCompat.Builder builder; private NotificationCompat.Builder builder;
@ -89,11 +88,7 @@ public class VideoEncodingService extends Service implements NotificationCenter.
Boolean enc = (Boolean) args[3]; Boolean enc = (Boolean) args[3];
int currentProgress = (int) (progress * 100); int currentProgress = (int) (progress * 100);
builder.setProgress(100, currentProgress, currentProgress == 0); builder.setProgress(100, currentProgress, currentProgress == 0);
try { updateNotification();
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build());
} catch (Throwable e) {
FileLog.e(e);
}
} }
} else if (id == NotificationCenter.fileUploaded || id == NotificationCenter.fileUploadFailed) { } else if (id == NotificationCenter.fileUploaded || id == NotificationCenter.fileUploadFailed) {
String fileName = (String) args[0]; String fileName = (String) args[0];
@ -110,12 +105,27 @@ public class VideoEncodingService extends Service implements NotificationCenter.
} }
} }
private void updateNotification() {
try {
MediaController.VideoConvertMessage message = MediaController.getInstance().getCurrentForegroundConverMessage();
if (message == null) {
return;
}
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build());
} catch (Throwable e) {
FileLog.e(e);
}
}
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
if (isRunning()) { if (isRunning()) {
return Service.START_NOT_STICKY; return Service.START_NOT_STICKY;
} }
instance = this;
MediaController.VideoConvertMessage videoConvertMessage = MediaController.getInstance().getCurrentForegroundConverMessage(); MediaController.VideoConvertMessage videoConvertMessage = MediaController.getInstance().getCurrentForegroundConverMessage();
if (videoConvertMessage == null) {
return Service.START_NOT_STICKY;
}
instance = this;
if (builder == null) { if (builder == null) {
NotificationsController.checkOtherNotificationsChannel(); NotificationsController.checkOtherNotificationsChannel();
builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext, NotificationsController.OTHER_NOTIFICATIONS_CHANNEL); builder = new NotificationCompat.Builder(ApplicationLoader.applicationContext, NotificationsController.OTHER_NOTIFICATIONS_CHANNEL);
@ -124,7 +134,6 @@ public class VideoEncodingService extends Service implements NotificationCenter.
builder.setChannelId(NotificationsController.OTHER_NOTIFICATIONS_CHANNEL); builder.setChannelId(NotificationsController.OTHER_NOTIFICATIONS_CHANNEL);
builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName)); builder.setContentTitle(LocaleController.getString("AppName", R.string.AppName));
} }
setCurrentMessage(videoConvertMessage); setCurrentMessage(videoConvertMessage);
try { try {
startForeground(4, builder.build()); startForeground(4, builder.build());
@ -132,7 +141,7 @@ public class VideoEncodingService extends Service implements NotificationCenter.
//ignore ForegroundServiceStartNotAllowedException //ignore ForegroundServiceStartNotAllowedException
FileLog.e(e); FileLog.e(e);
} }
AndroidUtilities.runOnUIThread(() -> NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build())); AndroidUtilities.runOnUIThread(this::updateNotification);
return Service.START_NOT_STICKY; return Service.START_NOT_STICKY;
} }
@ -169,7 +178,7 @@ public class VideoEncodingService extends Service implements NotificationCenter.
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileUploadFailed); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileUploadFailed);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileUploaded); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.fileUploaded);
if (isRunning()) { if (isRunning()) {
NotificationManagerCompat.from(ApplicationLoader.applicationContext).notify(4, builder.build()); updateNotification();
} }
} }

View file

@ -86,7 +86,7 @@ public class VideoPlayerHolderBase {
long startTime; long startTime;
public void preparePlayer(Uri uri, boolean audioDisabled) { public void preparePlayer(Uri uri, boolean audioDisabled, float speed) {
this.audioDisabled = audioDisabled; this.audioDisabled = audioDisabled;
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.contentUri = uri; this.contentUri = uri;
@ -99,13 +99,14 @@ public class VideoPlayerHolderBase {
return; return;
} }
ensurePlayerCreated(audioDisabled); ensurePlayerCreated(audioDisabled);
videoPlayer.setPlaybackSpeed(speed);
videoPlayer.preparePlayer(uri, "other", FileLoader.PRIORITY_LOW); videoPlayer.preparePlayer(uri, "other", FileLoader.PRIORITY_LOW);
videoPlayer.setPlayWhenReady(false); videoPlayer.setPlayWhenReady(false);
videoPlayer.setWorkerQueue(dispatchQueue); videoPlayer.setWorkerQueue(dispatchQueue);
}); });
} }
public void start(boolean paused, Uri uri, long position, boolean audioDisabled) { public void start(boolean paused, Uri uri, long position, boolean audioDisabled, float speed) {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
this.audioDisabled = audioDisabled; this.audioDisabled = audioDisabled;
this.paused = paused; this.paused = paused;
@ -118,6 +119,7 @@ public class VideoPlayerHolderBase {
} }
if (videoPlayer == null) { if (videoPlayer == null) {
ensurePlayerCreated(audioDisabled); ensurePlayerCreated(audioDisabled);
videoPlayer.setPlaybackSpeed(speed);
videoPlayer.preparePlayer(uri, "other"); videoPlayer.preparePlayer(uri, "other");
videoPlayer.setWorkerQueue(dispatchQueue); videoPlayer.setWorkerQueue(dispatchQueue);
if (!paused) { if (!paused) {
@ -280,6 +282,17 @@ public class VideoPlayerHolderBase {
} }
} }
public void setSpeed(float speed) {
if (released) {
return;
}
dispatchQueue.postRunnable(() -> {
if (videoPlayer != null) {
videoPlayer.setPlaybackSpeed(speed);
}
});
}
public void play() { public void play() {
if (released) { if (released) {
return; return;
@ -304,6 +317,31 @@ public class VideoPlayerHolderBase {
}); });
} }
public void play(float speed) {
if (released) {
return;
}
if (!paused) {
return;
}
paused = false;
dispatchQueue.postRunnable(() -> {
if (videoPlayer != null) {
if (surfaceView != null) {
videoPlayer.setSurfaceView(surfaceView);
} else {
videoPlayer.setTextureView(textureView);
}
if (pendingSeekTo > 0) {
videoPlayer.seekTo(pendingSeekTo);
pendingSeekTo = 0;
}
videoPlayer.setPlaybackSpeed(speed);
videoPlayer.setPlayWhenReady(true);
}
});
}
public void setAudioEnabled(boolean enabled, boolean prepared) { public void setAudioEnabled(boolean enabled, boolean prepared) {
boolean disabled = !enabled; boolean disabled = !enabled;
if (audioDisabled == disabled) { if (audioDisabled == disabled) {
@ -430,16 +468,6 @@ public class VideoPlayerHolderBase {
return contentUri; return contentUri;
} }
public void setPlaybackSpeed(float currentVideoSpeed) {
dispatchQueue.postRunnable(() -> {
if (videoPlayer == null) {
return;
}
videoPlayer.setPlaybackSpeed(currentVideoSpeed);
});
}
private Runnable onSeekUpdate; private Runnable onSeekUpdate;
public void setOnSeekUpdate(Runnable onSeekUpdate) { public void setOnSeekUpdate(Runnable onSeekUpdate) {
this.onSeekUpdate = onSeekUpdate; this.onSeekUpdate = onSeekUpdate;

View file

@ -379,7 +379,7 @@ public class ConnectionsManager extends BaseController {
if (BuildVars.LOGS_ENABLED) { if (BuildVars.LOGS_ENABLED) {
FileLog.d("java received " + resp + " error = " + error + " messageId = " + requestMsgId); FileLog.d("java received " + resp + " error = " + error + " messageId = " + requestMsgId);
} }
FileLog.dumpResponseAndRequest(object, resp, error, requestMsgId, finalStartRequestTime, requestToken); FileLog.dumpResponseAndRequest(currentAccount, object, resp, error, requestMsgId, finalStartRequestTime, requestToken);
final TLObject finalResponse = resp; final TLObject finalResponse = resp;
final TLRPC.TL_error finalError = error; final TLRPC.TL_error finalError = error;
Utilities.stageQueue.postRunnable(() -> { Utilities.stageQueue.postRunnable(() -> {

View file

@ -23,6 +23,7 @@ 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;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.SvgHelper; import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.tgnet.tl.TL_stories; import org.telegram.tgnet.tl.TL_stories;
@ -76,7 +77,7 @@ public class TLRPC {
public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800; public static final int MESSAGE_FLAG_HAS_BOT_ID = 0x00000800;
public static final int MESSAGE_FLAG_EDITED = 0x00008000; public static final int MESSAGE_FLAG_EDITED = 0x00008000;
public static final int LAYER = 172; public static final int LAYER = 173;
public static class TL_stats_megagroupStats extends TLObject { public static class TL_stats_megagroupStats extends TLObject {
public static final int constructor = 0xef7ff916; public static final int constructor = 0xef7ff916;
@ -28863,6 +28864,8 @@ public class TLRPC {
public String title; public String title;
public int count; public int count;
public long hash; // custom
public static TL_savedReactionTag TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { public static TL_savedReactionTag TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
if (TL_savedReactionTag.constructor != constructor) { if (TL_savedReactionTag.constructor != constructor) {
if (exception) { if (exception) {
@ -55720,6 +55723,8 @@ public class TLRPC {
public static abstract class Reaction extends TLObject { public static abstract class Reaction extends TLObject {
public long tag_long_id; // custom
public static Reaction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) { public static Reaction TLdeserialize(AbstractSerializedData stream, int constructor, boolean exception) {
Reaction result = null; Reaction result = null;
switch (constructor) { switch (constructor) {
@ -60820,7 +60825,7 @@ public class TLRPC {
stream.writeInt32(constructor); stream.writeInt32(constructor);
stream.writeInt32(flags); stream.writeInt32(flags);
peer.serializeToStream(stream); peer.serializeToStream(stream);
if ((flags & 2) != 0) { if ((flags & 4) != 0) {
saved_peer_id.serializeToStream(stream); saved_peer_id.serializeToStream(stream);
} }
if ((flags & 1) != 0) { if ((flags & 1) != 0) {
@ -64959,9 +64964,8 @@ public class TLRPC {
return result; return result;
} }
public Boolean documentExists;
public Document getDocument() { public Document getDocument() {
if (alt_document != null && ApplicationLoader.useLessData()) { if (alt_document != null && !MessagesController.isStoryQualityFull()) {
return alt_document; return alt_document;
} }
return document; return document;
@ -75061,8 +75065,10 @@ public class TLRPC {
} }
public static class TL_messages_getSavedReactionTags extends TLObject { public static class TL_messages_getSavedReactionTags extends TLObject {
public static final int constructor = 0x761ddacf; public static final int constructor = 0x3637e05b;
public int flags;
public InputPeer peer;
public long hash; public long hash;
@Override @Override
@ -75073,6 +75079,10 @@ public class TLRPC {
@Override @Override
public void serializeToStream(AbstractSerializedData stream) { public void serializeToStream(AbstractSerializedData stream) {
stream.writeInt32(constructor); stream.writeInt32(constructor);
stream.writeInt32(flags);
if ((flags & 1) != 0) {
peer.serializeToStream(stream);
}
stream.writeInt64(hash); stream.writeInt64(hash);
} }
} }

View file

@ -24,6 +24,7 @@ import android.graphics.Paint;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.text.SpannableString; import android.text.SpannableString;
@ -147,8 +148,6 @@ public class ActionBar extends FrameLayout {
private View.OnTouchListener interceptTouchEventListener; private View.OnTouchListener interceptTouchEventListener;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
private PorterDuff.Mode colorFilterMode = PorterDuff.Mode.MULTIPLY;
SizeNotifierFrameLayout contentView; SizeNotifierFrameLayout contentView;
boolean blurredBackground; boolean blurredBackground;
public Paint blurScrimPaint = new Paint(); public Paint blurScrimPaint = new Paint();
@ -173,10 +172,6 @@ public class ActionBar extends FrameLayout {
}); });
} }
public void setColorFilterMode(PorterDuff.Mode colorFilterMode) {
this.colorFilterMode = colorFilterMode;
}
public INavigationLayout.BackButtonState getBackButtonState() { public INavigationLayout.BackButtonState getBackButtonState() {
if (backButtonDrawable instanceof INavigationLayout.IBackButtonDrawable) { if (backButtonDrawable instanceof INavigationLayout.IBackButtonDrawable) {
return ((INavigationLayout.IBackButtonDrawable) backButtonDrawable).getBackButtonState(); return ((INavigationLayout.IBackButtonDrawable) backButtonDrawable).getBackButtonState();
@ -191,9 +186,6 @@ public class ActionBar extends FrameLayout {
backButtonImageView = new ImageView(getContext()); backButtonImageView = new ImageView(getContext());
backButtonImageView.setScaleType(ImageView.ScaleType.CENTER); backButtonImageView.setScaleType(ImageView.ScaleType.CENTER);
backButtonImageView.setBackgroundDrawable(Theme.createSelectorDrawable(itemsBackgroundColor)); backButtonImageView.setBackgroundDrawable(Theme.createSelectorDrawable(itemsBackgroundColor));
if (itemsColor != 0) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, colorFilterMode));
}
backButtonImageView.setPadding(dp(1), 0, 0, 0); backButtonImageView.setPadding(dp(1), 0, 0, 0);
addView(backButtonImageView, LayoutHelper.createFrame(54, 54, Gravity.LEFT | Gravity.TOP)); addView(backButtonImageView, LayoutHelper.createFrame(54, 54, Gravity.LEFT | Gravity.TOP));
@ -228,6 +220,8 @@ public class ActionBar extends FrameLayout {
MenuDrawable menuDrawable = (MenuDrawable) drawable; MenuDrawable menuDrawable = (MenuDrawable) drawable;
menuDrawable.setBackColor(actionBarColor); menuDrawable.setBackColor(actionBarColor);
menuDrawable.setIconColor(itemsColor); menuDrawable.setIconColor(itemsColor);
} else if (drawable instanceof BitmapDrawable) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, PorterDuff.Mode.SRC_IN));
} }
} }
@ -359,6 +353,7 @@ public class ActionBar extends FrameLayout {
} }
backButtonImageView.setVisibility(resource == 0 ? GONE : VISIBLE); backButtonImageView.setVisibility(resource == 0 ? GONE : VISIBLE);
backButtonImageView.setImageResource(resource); backButtonImageView.setImageResource(resource);
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, PorterDuff.Mode.SRC_IN));
} }
private void createSubtitleTextView() { private void createSubtitleTextView() {
@ -1599,18 +1594,21 @@ public class ActionBar extends FrameLayout {
Drawable drawable = backButtonImageView.getDrawable(); Drawable drawable = backButtonImageView.getDrawable();
if (drawable instanceof BackDrawable) { if (drawable instanceof BackDrawable) {
((BackDrawable) drawable).setRotatedColor(color); ((BackDrawable) drawable).setRotatedColor(color);
} else if (drawable instanceof BitmapDrawable) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
} else { } else {
itemsColor = color; itemsColor = color;
if (backButtonImageView != null) { if (backButtonImageView != null) {
if (itemsColor != 0) { if (itemsColor != 0) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(itemsColor, colorFilterMode));
Drawable drawable = backButtonImageView.getDrawable(); Drawable drawable = backButtonImageView.getDrawable();
if (drawable instanceof BackDrawable) { if (drawable instanceof BackDrawable) {
((BackDrawable) drawable).setColor(color); ((BackDrawable) drawable).setColor(color);
} else if (drawable instanceof MenuDrawable) { } else if (drawable instanceof MenuDrawable) {
((MenuDrawable) drawable).setIconColor(color); ((MenuDrawable) drawable).setIconColor(color);
} else if (drawable instanceof BitmapDrawable) {
backButtonImageView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN));
} }
} }
} }

View file

@ -64,6 +64,7 @@ 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.LaunchActivity;
import org.telegram.ui.LogoutActivity;
import org.telegram.ui.Stories.StoryViewer; import org.telegram.ui.Stories.StoryViewer;
import java.util.ArrayList; import java.util.ArrayList;
@ -1627,6 +1628,12 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
fragmentsStack.add(position, fragment); fragmentsStack.add(position, fragment);
onFragmentStackChanged("addFragmentToStack"); onFragmentStackChanged("addFragmentToStack");
} }
if (!useAlphaAnimations) {
setVisibility(VISIBLE);
if (backgroundView != null) {
backgroundView.setVisibility(VISIBLE);
}
}
return true; return true;
} }
@ -2035,6 +2042,11 @@ public class ActionBarLayout extends FrameLayout implements INavigationLayout, F
removeFragmentFromStackInternal(fragmentsStack.get(a), false); removeFragmentFromStackInternal(fragmentsStack.get(a), false);
a--; a--;
} }
if (backgroundView != null) {
backgroundView.animate().alpha(0.0f).setDuration(180).withEndAction(() -> {
backgroundView.setVisibility(View.GONE);
}).start();
}
} }
@Keep @Keep

View file

@ -508,6 +508,13 @@ public class ActionBarMenu extends LinearLayout {
return null; return null;
} }
public void setItemVisibility(int id, int visibility) {
View item = getItem(id);
if (item != null) {
item.setVisibility(visibility);
}
}
@Override @Override
public void setEnabled(boolean enabled) { public void setEnabled(boolean enabled) {
super.setEnabled(enabled); super.setEnabled(enabled);

View file

@ -32,6 +32,7 @@ import android.transition.TransitionManager;
import android.transition.TransitionSet; import android.transition.TransitionSet;
import android.transition.TransitionValues; import android.transition.TransitionValues;
import android.transition.Visibility; import android.transition.Visibility;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.Gravity; import android.view.Gravity;
@ -990,7 +991,7 @@ public class ActionBarMenuItem extends FrameLayout {
boolean visible = !currentSearchFilters.isEmpty(); boolean visible = !currentSearchFilters.isEmpty();
ArrayList<FiltersView.MediaFilterData> localFilters = new ArrayList<>(currentSearchFilters); ArrayList<FiltersView.MediaFilterData> localFilters = new ArrayList<>(currentSearchFilters);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && searchContainer.getTag() != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && searchContainer != null && searchContainer.getTag() != null) {
TransitionSet transition = new TransitionSet(); TransitionSet transition = new TransitionSet();
ChangeBounds changeBounds = new ChangeBounds(); ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setDuration(150); changeBounds.setDuration(150);
@ -1055,11 +1056,13 @@ public class ActionBarMenuItem extends FrameLayout {
TransitionManager.beginDelayedTransition(searchFilterLayout, transition); TransitionManager.beginDelayedTransition(searchFilterLayout, transition);
} }
for (int i = 0; i < searchFilterLayout.getChildCount(); i++) { if (searchFilterLayout != null) {
boolean removed = localFilters.remove(((SearchFilterView) searchFilterLayout.getChildAt(i)).getFilter()); for (int i = 0; i < searchFilterLayout.getChildCount(); i++) {
if (!removed) { boolean removed = localFilters.remove(((SearchFilterView) searchFilterLayout.getChildAt(i)).getFilter());
searchFilterLayout.removeViewAt(i); if (!removed) {
i--; searchFilterLayout.removeViewAt(i);
i--;
}
} }
} }
@ -2041,10 +2044,11 @@ public class ActionBarMenuItem extends FrameLayout {
reactionCount.count = 1; reactionCount.count = 1;
reactionCount.reaction = data.reaction.toTLReaction(); reactionCount.reaction = data.reaction.toTLReaction();
reactionButton = new ReactionsLayoutInBubble.ReactionButton(null, UserConfig.selectedAccount, this, reactionCount, false, resourcesProvider) { reactionButton = new ReactionsLayoutInBubble.ReactionButton(null, UserConfig.selectedAccount, this, reactionCount, false, true, resourcesProvider) {
@Override @Override
protected void updateColors(float progress) { protected void updateColors(float progress) {
lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, Theme.getColor(Theme.key_chat_inReactionButtonBackground, resourcesProvider), progress); lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, Theme.getColor(Theme.key_chat_inReactionButtonBackground, resourcesProvider), progress);
lastDrawnTagDotColor = ColorUtils.blendARGB(fromTagDotColor, 0x5affffff, progress);
} }
@Override @Override
@ -2052,6 +2056,7 @@ public class ActionBarMenuItem extends FrameLayout {
return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_EMOJI_STATUS; return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_EMOJI_STATUS;
} }
}; };
reactionButton.isTag = true;
reactionButton.width = dp(44.33f); reactionButton.width = dp(44.33f);
reactionButton.height = dp(28); reactionButton.height = dp(28);
reactionButton.choosen = true; reactionButton.choosen = true;

View file

@ -37,7 +37,7 @@ public class ActionBarMenuSubItem extends FrameLayout {
private int itemHeight = 48; private int itemHeight = 48;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
Runnable openSwipeBackLayout; public Runnable openSwipeBackLayout;
public ActionBarMenuSubItem(Context context, boolean top, boolean bottom) { public ActionBarMenuSubItem(Context context, boolean top, boolean bottom) {
this(context, false, top, bottom); this(context, false, top, bottom);

View file

@ -65,6 +65,7 @@ import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedFloat; import org.telegram.ui.Components.AnimatedFloat;
import org.telegram.ui.Components.EffectsTextView; import org.telegram.ui.Components.EffectsTextView;
import org.telegram.ui.Components.LayoutHelper; import org.telegram.ui.Components.LayoutHelper;
@ -85,11 +86,12 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
public static final int ALERT_TYPE_LOADING = 2; public static final int ALERT_TYPE_LOADING = 2;
public static final int ALERT_TYPE_SPINNER = 3; public static final int ALERT_TYPE_SPINNER = 3;
private int customWidth = -1;
private View customView; private View customView;
private View bottomView; private View bottomView;
private View aboveMessageView; private View aboveMessageView;
private int customViewHeight = LayoutHelper.WRAP_CONTENT; private int customViewHeight = LayoutHelper.WRAP_CONTENT;
private TextView titleTextView; private SpoilersTextView titleTextView;
private TextView secondTitleTextView; private TextView secondTitleTextView;
private TextView subtitleTextView; private TextView subtitleTextView;
private TextView messageTextView; private TextView messageTextView;
@ -343,6 +345,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
inLayout = true; inLayout = true;
int width = MeasureSpec.getSize(widthMeasureSpec); int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec);
if (customWidth > 0) {
width = customWidth + backgroundPaddings.left + backgroundPaddings.right;
}
int maxContentHeight; int maxContentHeight;
int availableHeight = maxContentHeight = height - getPaddingTop() - getPaddingBottom(); int availableHeight = maxContentHeight = height - getPaddingTop() - getPaddingBottom();
int availableWidth = width - getPaddingLeft() - getPaddingRight(); int availableWidth = width - getPaddingLeft() - getPaddingRight();
@ -598,7 +605,13 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
} }
containerView.setFitsSystemWindows(Build.VERSION.SDK_INT >= 21); containerView.setFitsSystemWindows(Build.VERSION.SDK_INT >= 21);
if (setContent) { if (setContent) {
setContentView(containerView); if (customWidth > 0) {
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.CENTER;
setContentView(containerView, lp);
} else {
setContentView(containerView);
}
} }
final boolean hasButtons = positiveButtonText != null || negativeButtonText != null || neutralButtonText != null; final boolean hasButtons = positiveButtonText != null || negativeButtonText != null || neutralButtonText != null;
@ -670,6 +683,8 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
containerView.addView(titleContainer, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, topAnimationIsNew ? Gravity.CENTER_HORIZONTAL : 0, 24, 0, 24, 0)); containerView.addView(titleContainer, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, topAnimationIsNew ? Gravity.CENTER_HORIZONTAL : 0, 24, 0, 24, 0));
titleTextView = new SpoilersTextView(getContext(), false); titleTextView = new SpoilersTextView(getContext(), false);
NotificationCenter.listenEmojiLoading(titleTextView);
titleTextView.cacheType = AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW;
titleTextView.setText(title); titleTextView.setText(title);
titleTextView.setTextColor(getThemedColor(Theme.key_dialogTextBlack)); titleTextView.setTextColor(getThemedColor(Theme.key_dialogTextBlack));
titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
@ -1546,6 +1561,11 @@ public class AlertDialog extends Dialog implements Drawable.Callback, Notificati
return this; return this;
} }
public Builder setWidth(int width) {
alertDialog.customWidth = width;
return this;
}
public Builder aboveMessageView(View view) { public Builder aboveMessageView(View view) {
alertDialog.aboveMessageView = view; alertDialog.aboveMessageView = view;
return this; return this;

View file

@ -9,6 +9,7 @@ import android.content.res.TypedArray;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Build; import android.os.Build;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.view.Gravity; import android.view.Gravity;
@ -25,6 +26,7 @@ import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsCompat;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.Stories.recorder.KeyboardNotifier;
public class AlertDialogDecor extends AlertDialog { public class AlertDialogDecor extends AlertDialog {
@ -102,11 +104,8 @@ public class AlertDialogDecor extends AlertDialog {
container.addView(dimView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT)); container.addView(dimView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
final FrameLayout contentWrapper = new FrameLayout(getContext()); final FrameLayout contentWrapper = new FrameLayout(getContext());
contentWrapper.addView(contentView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)); contentWrapper.addView(contentView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
container.addView(contentWrapper, new FrameLayout.LayoutParams(params.width, FrameLayout.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
FrameLayout.LayoutParams containerParams = new FrameLayout.LayoutParams(params.width, FrameLayout.LayoutParams.WRAP_CONTENT);
containerParams.gravity = Gravity.CENTER;
container.addView(contentWrapper, containerParams);
rootView = container; rootView = container;
getDecorView().addView(rootView); getDecorView().addView(rootView);

View file

@ -16,7 +16,10 @@ import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.view.animation.DecelerateInterpolator; import android.view.animation.DecelerateInterpolator;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Utilities;
public class BackDrawable extends Drawable { public class BackDrawable extends Drawable {
@ -111,11 +114,7 @@ public class BackDrawable extends Drawable {
invalidateSelf(); invalidateSelf();
} }
int rD = rotated ? (int) ((Color.red(rotatedColor) - Color.red(color)) * currentRotation) : 0; paint.setColor(ColorUtils.blendARGB(color, rotatedColor, currentRotation));
int rG = rotated ? (int) ((Color.green(rotatedColor) - Color.green(color)) * currentRotation) : 0;
int rB = rotated ? (int) ((Color.blue(rotatedColor) - Color.blue(color)) * currentRotation) : 0;
int c = Color.rgb(Color.red(color) + rD, Color.green(color) + rG, Color.blue(color) + rB);
paint.setColor(c);
canvas.save(); canvas.save();
canvas.translate(getIntrinsicWidth() / 2, getIntrinsicHeight() / 2); canvas.translate(getIntrinsicWidth() / 2, getIntrinsicHeight() / 2);

View file

@ -0,0 +1,154 @@
package org.telegram.ui.ActionBar;
import android.graphics.Color;
import androidx.core.graphics.ColorUtils;
import org.telegram.messenger.Utilities;
// https://gist.github.com/dkaraush/65d19d61396f5f3cd8ba7d1b4b3c9432
public class OKLCH {
public static final double[] XYZtoLMS_M = new double[] {
0.8190224379967030, 0.3619062600528904, -0.1288737815209879,
0.0329836539323885, 0.9292868615863434, 0.0361446663506424,
0.0481771893596242, 0.2642395317527308, 0.6335478284694309
};
public static final double[] LMStoXYZ_M = new double[] {
1.2268798758459243, -0.5578149944602171, 0.2813910456659647,
-0.0405757452148008, 1.1122868032803170, -0.0717110580655164,
-0.0763729366746601, -0.4214933324022432, 1.5869240198367816
};
public static final double[] LMStoLab_M = new double[] {
0.2104542683093140, 0.7936177747023054, -0.0040720430116193,
1.9779985324311684, -2.4285922420485799, 0.4505937096174110,
0.0259040424655478, 0.7827717124575296, -0.8086757549230774
};
public static final double[] LabtoLMS_M = new double[] {
1., 0.3963377773761749, 0.2158037573099136,
1., -0.1055613458156586, -0.0638541728258133,
1., -0.0894841775298119, -1.2914855480194092,
};
public static final double[] toXYZ_M = new double[] {
0.41239079926595934, 0.357584339383878, 0.1804807884018343,
0.21263900587151027, 0.715168678767756, 0.07219231536073371,
0.01933081871559182, 0.11919477979462598, 0.9505321522496607
};
public static final double[] fromXYZ_M = new double[] {
3.2409699419045226, -1.537383177570094, -0.4986107602930034,
-0.9692436362808796, 1.8759675015077202, 0.04155505740717559,
0.05563007969699366, -0.20397695888897652, 1.0569715142428786
};
public static double[] oklch2oklab(double[] lch) {
final double L = lch[0];
final double C = lch[1];
final double H = lch[2];
return new double[] {
L,
Double.isNaN(H) ? 0 : C * Math.cos(H * Math.PI / 180),
Double.isNaN(H) ? 0 : C * Math.sin(H * Math.PI / 180)
};
}
public static double[] oklab2oklch(double[] lab) {
final double L = lab[0];
final double A = lab[1];
final double B = lab[2];
return new double[] {
L,
Math.sqrt(Math.pow(A, 2) + Math.pow(B, 2)),
Math.abs(A) < 0.0002 && Math.abs(B) < 0.0002 ? Double.NaN : (((Math.atan2(B, A) * 180) / Math.PI % 360) + 360) % 360
};
}
public static double[] rgb2srgbLinear(double[] rgb) {
double[] rgbLinear = new double[3];
for (int i = 0; i < rgb.length; ++i) {
rgbLinear[i] = Math.abs(rgb[i]) <= 0.04045 ?
rgb[i] / 12.92 :
(rgb[i] < 0 ? -1 : 1) * (Math.pow((Math.abs(rgb[i]) + 0.055) / 1.055, 2.4));
}
return rgbLinear;
}
public static double[] srgbLinear2rgb(double[] rgbLinear) {
double[] rgb = new double[3];
for (int i = 0; i < rgbLinear.length; ++i) {
rgb[i] = Math.abs(rgbLinear[i]) > 0.0031308 ?
(rgbLinear[i] < 0 ? -1 : 1) * (1.055 * Math.pow(Math.abs(rgbLinear[i]), (1 / 2.4)) - 0.055) :
12.92 * rgbLinear[i];
}
return rgb;
}
public static double[] oklab2xyz(double[] lab) {
final double[] LMS = multiply(LabtoLMS_M, lab);
for (int i = 0; i < LMS.length; ++i) {
LMS[i] = Math.pow(LMS[i], 3.0);
}
return multiply(LMStoXYZ_M, LMS);
}
public static double[] xyz2oklab(double[] xyz) {
final double[] LMSg = multiply(XYZtoLMS_M, xyz);
for (int i = 0; i < LMSg.length; ++i) {
LMSg[i] = Math.cbrt(LMSg[i]);
}
return multiply(LMStoLab_M, LMSg);
}
public static double[] xyz2rgbLinear(double[] xyz) {
return multiply(fromXYZ_M, xyz);
}
public static double[] rgbLinear2xyz(double[] rgb) {
return multiply(toXYZ_M, rgb);
}
public static double[] oklch2rgb(double[] lch) {
return srgbLinear2rgb(xyz2rgbLinear(oklab2xyz(oklch2oklab(lch))));
}
public static double[] rgb2oklch(double[] rgb) {
return oklab2oklch(xyz2oklab(rgbLinear2xyz(rgb2srgbLinear(rgb))));
}
public static double[] rgb(int color) {
return new double[] {
Color.red(color) / 255.0,
Color.green(color) / 255.0,
Color.blue(color) / 255.0
};
}
public static int rgb(double[] color) {
return Color.rgb(
(int) Math.round(Utilities.clamp(color[0], 1.0, 0.0) * 255.0),
(int) Math.round(Utilities.clamp(color[1], 1.0, 0.0) * 255.0),
(int) Math.round(Utilities.clamp(color[2], 1.0, 0.0) * 255.0)
);
}
// takes hue from `hueColor` color and applies to `baseColor`
public static int adapt(int baseColor, int hueColor) {
double[] hueoklch = rgb2oklch(rgb(hueColor));
double[] oklch = rgb2oklch(rgb(baseColor));
oklch[2] = hueoklch[2];
if (Double.isNaN(hueoklch[2])) {
oklch[1] = hueoklch[1];
}
return ColorUtils.setAlphaComponent(rgb(oklch2rgb(oklch)), Color.alpha(baseColor));
}
public static int adapt(int color, double c, double l) {
double[] oklch = rgb2oklch(rgb(color));
oklch[0] = Utilities.clamp(oklch[0] + l, 1.0, 0.0);
oklch[1] = Utilities.clamp(oklch[1] + c, 1.0, 0.0);
return ColorUtils.setAlphaComponent(rgb(oklch2rgb(oklch)), Color.alpha(color));
}
private static double[] multiply(double[] mat3, double[] vec3) {
return new double[] {
mat3[0] * vec3[0] + mat3[1] * vec3[1] + mat3[2] * vec3[2],
mat3[3] * vec3[0] + mat3[4] * vec3[1] + mat3[5] * vec3[2],
mat3[6] * vec3[0] + mat3[7] * vec3[1] + mat3[8] * vec3[2]
};
}
}

View file

@ -3643,6 +3643,7 @@ public class Theme {
public static final int key_chat_inBubbleShadow = colorsCount++; public static final int key_chat_inBubbleShadow = colorsCount++;
public static final int key_actionBarActionModeReaction = colorsCount++; public static final int key_actionBarActionModeReaction = colorsCount++;
public static final int key_actionBarActionModeReactionText = colorsCount++;
public static final int key_actionBarActionModeReactionDot = colorsCount++; public static final int key_actionBarActionModeReactionDot = colorsCount++;
//my messages bubbles //my messages bubbles
@ -3719,6 +3720,7 @@ public class Theme {
public static final int key_chat_outLocationIcon = colorsCount++; public static final int key_chat_outLocationIcon = colorsCount++;
public static final int key_chat_outContactBackground = colorsCount++; public static final int key_chat_outContactBackground = colorsCount++;
public static final int key_chat_outContactIcon = colorsCount++; public static final int key_chat_outContactIcon = colorsCount++;
public static final int key_chat_outReactionButtonBackground = colorsCount++;
public static final int myMessagesEndIndex = colorsCount; public static final int myMessagesEndIndex = colorsCount;
public static final int key_chat_outTextSelectionHighlight = colorsCount++; public static final int key_chat_outTextSelectionHighlight = colorsCount++;
@ -4101,7 +4103,6 @@ public class Theme {
public static final int key_color_cyan = colorsCount++; public static final int key_color_cyan = colorsCount++;
public static final int[] keys_colors = {key_color_lightblue, key_color_blue, key_color_green, key_color_lightgreen, key_color_red, key_color_orange, key_color_yellow, key_color_purple, key_color_cyan}; public static final int[] keys_colors = {key_color_lightblue, key_color_blue, key_color_green, key_color_lightgreen, key_color_red, key_color_orange, key_color_yellow, key_color_purple, key_color_cyan};
public static final int key_chat_outReactionButtonBackground = colorsCount++;
public static final int key_chat_inReactionButtonBackground = colorsCount++; public static final int key_chat_inReactionButtonBackground = colorsCount++;
public static final int key_chat_outReactionButtonText = colorsCount++; public static final int key_chat_outReactionButtonText = colorsCount++;
public static final int key_chat_inReactionButtonText = colorsCount++; public static final int key_chat_inReactionButtonText = colorsCount++;
@ -4395,6 +4396,7 @@ public class Theme {
fallbackKeys.put(key_statisticChartLine_cyan, key_color_cyan); fallbackKeys.put(key_statisticChartLine_cyan, key_color_cyan);
fallbackKeys.put(key_actionBarActionModeReaction, key_windowBackgroundGray); fallbackKeys.put(key_actionBarActionModeReaction, key_windowBackgroundGray);
fallbackKeys.put(key_actionBarActionModeReactionText, key_chat_inReactionButtonText);
for (int i = 0; i < keys_avatar_background.length; i++) { for (int i = 0; i < keys_avatar_background.length; i++) {
themeAccentExclusionKeys.add(keys_avatar_background[i]); themeAccentExclusionKeys.add(keys_avatar_background[i]);

View file

@ -138,8 +138,8 @@ public class ThemeColors {
defaultColors[key_avatar_text] = 0xffffffff; defaultColors[key_avatar_text] = 0xffffffff;
defaultColors[key_avatar_backgroundSaved] = 0xff69BFFA; defaultColors[key_avatar_backgroundSaved] = 0xff69BDF9;
defaultColors[key_avatar_background2Saved] = 0xff3D9DE0; defaultColors[key_avatar_background2Saved] = 0xff409FE1;
defaultColors[key_avatar_backgroundArchived] = 0xffB8C2CC; defaultColors[key_avatar_backgroundArchived] = 0xffB8C2CC;
defaultColors[key_avatar_backgroundArchivedHidden] = 0xff66bffa; defaultColors[key_avatar_backgroundArchivedHidden] = 0xff66bffa;
defaultColors[key_avatar_backgroundRed] = 0xffFF845E; defaultColors[key_avatar_backgroundRed] = 0xffFF845E;
@ -189,6 +189,7 @@ public class ThemeColors {
defaultColors[key_actionBarDefaultSubmenuSeparator] = 0xfff5f5f5; defaultColors[key_actionBarDefaultSubmenuSeparator] = 0xfff5f5f5;
defaultColors[key_actionBarActionModeDefaultSelector] = 0xffe2e2e2; defaultColors[key_actionBarActionModeDefaultSelector] = 0xffe2e2e2;
defaultColors[key_actionBarActionModeReaction] = 0xfff0f0f0; defaultColors[key_actionBarActionModeReaction] = 0xfff0f0f0;
defaultColors[key_actionBarActionModeReactionText] = 0xff82868a;
defaultColors[key_actionBarActionModeReactionDot] = 0xffc0c0c0; defaultColors[key_actionBarActionModeReactionDot] = 0xffc0c0c0;
defaultColors[key_actionBarTabActiveText] = 0xffffffff; defaultColors[key_actionBarTabActiveText] = 0xffffffff;
defaultColors[key_actionBarTabUnactiveText] = 0xffd5e8f7; defaultColors[key_actionBarTabUnactiveText] = 0xffd5e8f7;
@ -957,6 +958,7 @@ public class ThemeColors {
colorKeysMap.put(key_actionBarActionModeDefaultIcon, "actionBarActionModeDefaultIcon"); colorKeysMap.put(key_actionBarActionModeDefaultIcon, "actionBarActionModeDefaultIcon");
colorKeysMap.put(key_actionBarActionModeDefaultSelector, "actionBarActionModeDefaultSelector"); colorKeysMap.put(key_actionBarActionModeDefaultSelector, "actionBarActionModeDefaultSelector");
colorKeysMap.put(key_actionBarActionModeReaction, "actionBarActionModeReaction"); colorKeysMap.put(key_actionBarActionModeReaction, "actionBarActionModeReaction");
colorKeysMap.put(key_actionBarActionModeReactionText, "actionBarActionModeReactionText");
colorKeysMap.put(key_actionBarActionModeReactionDot, "actionBarActionModeReactionDot"); colorKeysMap.put(key_actionBarActionModeReactionDot, "actionBarActionModeReactionDot");
colorKeysMap.put(key_actionBarDefaultTitle, "actionBarDefaultTitle"); colorKeysMap.put(key_actionBarDefaultTitle, "actionBarDefaultTitle");
colorKeysMap.put(key_actionBarDefaultSubtitle, "actionBarDefaultSubtitle"); colorKeysMap.put(key_actionBarDefaultSubtitle, "actionBarDefaultSubtitle");

View file

@ -471,7 +471,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
ConnectionsManager.getInstance(currentAccount).cancelRequest(reqId, true); ConnectionsManager.getInstance(currentAccount).cancelRequest(reqId, true);
reqId = 0; reqId = 0;
} }
if (TextUtils.isEmpty(query)) { if (TextUtils.isEmpty(query) || delegate.getSearchForumDialogId() != 0) {
filteredRecentQuery = null; filteredRecentQuery = null;
searchResultMessages.clear(); searchResultMessages.clear();
searchForumResultMessages.clear(); searchForumResultMessages.clear();
@ -1107,7 +1107,7 @@ public class DialogsSearchAdapter extends RecyclerListView.SelectionAdapter {
if (searchId != lastSearchId) { if (searchId != lastSearchId) {
return; return;
} }
if (needMessagesSearch != 2 && dialogsType != DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY && dialogsType != DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY) { if (needMessagesSearch != 2 && dialogsType != DialogsActivity.DIALOGS_TYPE_GROUPS_ONLY && dialogsType != DialogsActivity.DIALOGS_TYPE_CHANNELS_ONLY && delegate.getSearchForumDialogId() == 0) {
searchAdapterHelper.queryServerSearch( searchAdapterHelper.queryServerSearch(
query, query,
true, true,

View file

@ -23,11 +23,14 @@ import org.telegram.ui.Cells.LoadingCell;
import org.telegram.ui.Components.RecyclerListView; import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
public class MessagesSearchAdapter extends RecyclerListView.SelectionAdapter { public class MessagesSearchAdapter extends RecyclerListView.SelectionAdapter {
private Context mContext; private Context mContext;
private HashSet<Integer> messageIds = new HashSet<>();
private ArrayList<MessageObject> searchResultMessages = new ArrayList<>(); private ArrayList<MessageObject> searchResultMessages = new ArrayList<>();
public int loadedCount;
private int currentAccount = UserConfig.selectedAccount; private int currentAccount = UserConfig.selectedAccount;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
@ -39,7 +42,17 @@ public class MessagesSearchAdapter extends RecyclerListView.SelectionAdapter {
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
searchResultMessages = MediaDataController.getInstance(currentAccount).getFoundMessageObjects(); searchResultMessages.clear();
messageIds.clear();
ArrayList<MessageObject> searchResults = MediaDataController.getInstance(currentAccount).getFoundMessageObjects();
for (int i = 0; i < searchResults.size(); ++i) {
MessageObject m = searchResults.get(i);
if ((!m.hasValidGroupId() || m.isPrimaryGroupMessage) && !messageIds.contains(m.getId())) {
searchResultMessages.add(m);
messageIds.add(m.getId());
}
}
loadedCount = searchResultMessages.size();
super.notifyDataSetChanged(); super.notifyDataSetChanged();
} }
@ -85,8 +98,26 @@ public class MessagesSearchAdapter extends RecyclerListView.SelectionAdapter {
if (holder.getItemViewType() == 0) { if (holder.getItemViewType() == 0) {
DialogCell cell = (DialogCell) holder.itemView; DialogCell cell = (DialogCell) holder.itemView;
cell.useSeparator = true; cell.useSeparator = true;
cell.isSavedDialog = true;
MessageObject messageObject = (MessageObject) getItem(position); MessageObject messageObject = (MessageObject) getItem(position);
cell.setDialog(messageObject.getDialogId(), messageObject, messageObject.messageOwner.date, true, false); int date;
boolean useMe = false;
long did;
if (messageObject.getDialogId() == UserConfig.getInstance(currentAccount).getClientUserId()) {
did = messageObject.getSavedDialogId();
if (messageObject.messageOwner.fwd_from != null && (messageObject.messageOwner.fwd_from.date != 0 || messageObject.messageOwner.fwd_from.saved_date != 0)) {
date = messageObject.messageOwner.fwd_from.date;
if (date == 0) {
date = messageObject.messageOwner.fwd_from.saved_date;
}
} else {
date = messageObject.messageOwner.date;
}
} else {
did = messageObject.getDialogId();
date = messageObject.messageOwner.date;
}
cell.setDialog(did, messageObject, date, useMe, false);
} }
} }

View file

@ -6487,7 +6487,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
} }
videoPlayer.seekTo(playFrom); videoPlayer.seekTo(playFrom);
videoPlayer.preparePlayer(uri, true); videoPlayer.preparePlayer(uri, true, 1f);
videoPlayer.play(); videoPlayer.play();
} }

View file

@ -476,7 +476,13 @@ public class CalendarActivity extends BaseFragment implements NotificationCenter
req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo(); req.filter = new TLRPC.TL_inputMessagesFilterPhotoVideo();
} }
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(dialogId); req.peer = getMessagesController().getInputPeer(dialogId);
if (topicId != 0) {
if (dialogId == getUserConfig().getClientUserId()) {
req.flags |= 4;
req.saved_peer_id = getMessagesController().getInputPeer(topicId);
}
}
req.offset_id = lastId; req.offset_id = lastId;
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();

View file

@ -187,6 +187,14 @@ public class AboutLinkCell extends FrameLayout {
setWillNotDraw(false); setWillNotDraw(false);
} }
protected int processColor(int color) {
return color;
}
public void updateColors() {
Theme.profile_aboutTextPaint.linkColor = processColor(Theme.getColor(Theme.key_chat_messageLinkIn, resourcesProvider));
}
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX(); int x = (int) event.getX();
@ -283,7 +291,7 @@ public class AboutLinkCell extends FrameLayout {
canvas.translate(0, textY = AndroidUtilities.dp(8)); canvas.translate(0, textY = AndroidUtilities.dp(8));
try { try {
Theme.profile_aboutTextPaint.linkColor = Theme.getColor(Theme.key_chat_messageLinkIn, resourcesProvider); Theme.profile_aboutTextPaint.linkColor = processColor(Theme.getColor(Theme.key_chat_messageLinkIn, resourcesProvider));
if (firstThreeLinesLayout == null || !shouldExpand) { if (firstThreeLinesLayout == null || !shouldExpand) {
if (textLayout != null) { if (textLayout != null) {
textLayout.draw(canvas); textLayout.draw(canvas);
@ -461,7 +469,8 @@ public class AboutLinkCell extends FrameLayout {
Spannable buffer = (Spannable) textLayout.getText(); Spannable buffer = (Spannable) textLayout.getText();
ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class); ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);
if (link.length != 0 && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) { if (link.length != 0 && !AndroidUtilities.isAccessibilityScreenReaderEnabled()) {
LinkSpanDrawable linkDrawable = new LinkSpanDrawable(link[0], parentFragment.getResourceProvider(), ex, ey); LinkSpanDrawable linkDrawable = new LinkSpanDrawable(link[0], resourcesProvider, ex, ey);
linkDrawable.setColor(processColor(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider)));
int start = buffer.getSpanStart(link[0]); int start = buffer.getSpanStart(link[0]);
int end = buffer.getSpanEnd(link[0]); int end = buffer.getSpanEnd(link[0]);
LinkPath path = linkDrawable.obtainNewPath(); LinkPath path = linkDrawable.obtainNewPath();
@ -490,11 +499,12 @@ public class AboutLinkCell extends FrameLayout {
links.removeLoading(currentLoading, true); links.removeLoading(currentLoading, true);
} }
currentLoading = thisLoading = LinkSpanDrawable.LinkCollector.makeLoading(layout, pressedLink, yOffset); currentLoading = thisLoading = LinkSpanDrawable.LinkCollector.makeLoading(layout, pressedLink, yOffset);
final int color = processColor(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider));
thisLoading.setColors( thisLoading.setColors(
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), .8f), Theme.multAlpha(color, .8f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), 1.3f), Theme.multAlpha(color, 1.3f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), 1f), Theme.multAlpha(color, 1f),
Theme.multAlpha(Theme.getColor(Theme.key_chat_linkSelectBackground, resourcesProvider), 4f) Theme.multAlpha(color, 4f)
); );
thisLoading.strokePaint.setStrokeWidth(AndroidUtilities.dpf2(1.25f)); thisLoading.strokePaint.setStrokeWidth(AndroidUtilities.dpf2(1.25f));
links.addLoading(thisLoading); links.addLoading(thisLoading);

View file

@ -62,6 +62,7 @@ import android.text.style.CharacterStyle;
import android.text.style.ClickableSpan; import android.text.style.ClickableSpan;
import android.text.style.LeadingMarginSpan; import android.text.style.LeadingMarginSpan;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.util.Log;
import android.util.Property; import android.util.Property;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.StateSet; import android.util.StateSet;
@ -383,11 +384,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
public void setScrimReaction(String scrimViewReaction) { public void setScrimReaction(Integer scrimViewReaction) {
reactionsLayoutInBubble.setScrimReaction(scrimViewReaction); reactionsLayoutInBubble.setScrimReaction(scrimViewReaction);
} }
public void drawScrimReaction(Canvas canvas, String scrimViewReaction) { public void drawScrimReaction(Canvas canvas, Integer scrimViewReaction) {
if ((currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) { if ((currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & MessageObject.POSITION_FLAG_LEFT) != 0)) && !reactionsLayoutInBubble.isSmall) {
reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, scrimViewReaction); reactionsLayoutInBubble.draw(canvas, transitionParams.animateChangeProgress, scrimViewReaction);
} }
@ -656,6 +657,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
default void didPressEmojiStatus() { default void didPressEmojiStatus() {
} }
default boolean doNotShowLoadingReply(MessageObject msg) {
return msg != null && msg.getDialogId() == UserObject.REPLY_BOT;
}
} }
private final static int DOCUMENT_ATTACH_TYPE_NONE = 0; private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
@ -757,7 +762,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private static class InstantViewButton { private static class InstantViewButton {
private int type; private int type;
private int buttonWidth; private float buttonWidth;
private float textX; private float textX;
private StaticLayout layout; private StaticLayout layout;
private final RectF rect = new RectF(); private final RectF rect = new RectF();
@ -2512,7 +2517,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
private boolean checkInstantButtonMotionEvent(MotionEvent event) { private boolean checkInstantButtonMotionEvent(MotionEvent event) {
if (!currentMessageObject.isSponsored() && (!drawInstantView || currentMessageObject.type == MessageObject.TYPE_TEXT)) { if (!currentMessageObject.isSponsored() && !currentMessageObject.isUnsupported() && (!drawInstantView || currentMessageObject.type == MessageObject.TYPE_TEXT)) {
return false; return false;
} }
int x = (int) event.getX(); int x = (int) event.getX();
@ -4862,7 +4867,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
boolean pollChanged = false; boolean pollChanged = false;
if (!messageIdChanged && currentMessageObject != null) { if (!messageIdChanged && currentMessageObject != null) {
int oldStableId = messageObject.stableId;
messageObject.copyStableParams(currentMessageObject); messageObject.copyStableParams(currentMessageObject);
if (currentMessageObject.isSavedFiltered && messageObject.isSavedFiltered) {
messageObject.stableId = oldStableId;
}
} }
accessibilityText = null; accessibilityText = null;
if (drawCommentButton || useTranscribeButton || drawSideButton == 3 && !((hasDiscussion && messageObject.isLinkedToChat(linkedChatId) || isRepliesChat) && (currentPosition == null || currentPosition.siblingHeights == null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 || currentPosition.siblingHeights != null && (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0))) { if (drawCommentButton || useTranscribeButton || drawSideButton == 3 && !((hasDiscussion && messageObject.isLinkedToChat(linkedChatId) || isRepliesChat) && (currentPosition == null || currentPosition.siblingHeights == null && (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 || currentPosition.siblingHeights != null && (currentPosition.flags & MessageObject.POSITION_FLAG_TOP) == 0))) {
@ -4924,7 +4933,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!groupChanged && groupedMessages != null) { if (!groupChanged && groupedMessages != null) {
MessageObject.GroupedMessagePosition newPosition; MessageObject.GroupedMessagePosition newPosition;
if (groupedMessages.messages.size() > 1) { if (groupedMessages.messages.size() > 1) {
newPosition = currentMessagesGroup.positions.get(currentMessageObject); newPosition = currentMessagesGroup.getPosition(currentMessageObject);
} else { } else {
newPosition = null; newPosition = null;
} }
@ -4948,7 +4957,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
widthBeforeNewTimeLine = -1; widthBeforeNewTimeLine = -1;
if (currentMessagesGroup != null && (currentMessagesGroup.posArray.size() > 1)) { if (currentMessagesGroup != null && (currentMessagesGroup.posArray.size() > 1)) {
currentPosition = currentMessagesGroup.positions.get(currentMessageObject); currentPosition = currentMessagesGroup.getPosition(currentMessageObject);
if (currentPosition == null) { if (currentPosition == null) {
currentMessagesGroup = null; currentMessagesGroup = null;
} }
@ -5163,15 +5172,20 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (messageIdChanged || messageObject.reactionsChanged || wasPlayingRound != isPlayingRound) { if (messageIdChanged || messageObject.reactionsChanged || wasPlayingRound != isPlayingRound) {
messageObject.reactionsChanged = false; messageObject.reactionsChanged = false;
boolean isTag = messageObject.messageOwner != null && messageObject.messageOwner.reactions != null && messageObject.messageOwner.reactions.reactions_as_tags;
if (messageObject.shouldDrawReactions() && !messageObject.isExpiredStory() && (currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0))) { if (messageObject.shouldDrawReactions() && !messageObject.isExpiredStory() && (currentPosition == null || ((currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0))) {
boolean isSmall = !messageObject.shouldDrawReactionsInLayout(); boolean isSmall = !messageObject.shouldDrawReactionsInLayout();
if (currentPosition != null) { if (currentPosition != null) {
reactionsLayoutInBubble.setMessage(groupedMessages.findPrimaryMessageObject(), !messageObject.shouldDrawReactionsInLayout(), resourcesProvider); MessageObject primaryMessage = groupedMessages.findPrimaryMessageObject();
if (!isTag) {
isTag = primaryMessage.messageOwner.reactions != null && primaryMessage.messageOwner.reactions.reactions_as_tags;
}
reactionsLayoutInBubble.setMessage(groupedMessages.findPrimaryMessageObject(), !messageObject.shouldDrawReactionsInLayout(), isTag, resourcesProvider);
} else { } else {
reactionsLayoutInBubble.setMessage(messageObject, isSmall, resourcesProvider); reactionsLayoutInBubble.setMessage(messageObject, isSmall, isTag, resourcesProvider);
} }
} else { } else {
reactionsLayoutInBubble.setMessage(null, false, resourcesProvider); reactionsLayoutInBubble.setMessage(null, false, false, resourcesProvider);
} }
} }
@ -5381,7 +5395,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
if (!drawInstantView) { if (!drawInstantView) {
if (messageObject.isSponsored()) { if (messageObject.isUnsupported()) {
drawInstantView = true;
drawInstantViewType = 21;
} else if (messageObject.isSponsored()) {
drawInstantView = true; drawInstantView = true;
hasLinkPreview = true; hasLinkPreview = true;
instantViewButtonText = messageObject.sponsoredButtonText; instantViewButtonText = messageObject.sponsoredButtonText;
@ -5658,7 +5675,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
linkPreviewMaxWidth = getParentWidth() - AndroidUtilities.dp(80 + (drawAvatar ? 52 : 0)); linkPreviewMaxWidth = getParentWidth() - AndroidUtilities.dp(80 + (drawAvatar ? 52 : 0));
} }
if (drawSideButton != 0) { if (drawSideButton != 0) {
linkPreviewMaxWidth -= AndroidUtilities.dp(20); linkPreviewMaxWidth -= AndroidUtilities.dp(currentMessageObject.isSaved && currentMessageObject.isOutOwner() ? 25 : 20);
} }
int site_name_additionalWidth = 0; int site_name_additionalWidth = 0;
CharSequence site_name; CharSequence site_name;
@ -6624,6 +6641,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
blurredPhotoImage.getBitmap().recycle(); blurredPhotoImage.getBitmap().recycle();
blurredPhotoImage.setImageBitmap((Bitmap) null); blurredPhotoImage.setImageBitmap((Bitmap) null);
} }
if (messageObject.isUnsupported()) {
createInstantViewButton();
}
} }
} else if (messageObject.type == MessageObject.TYPE_PHONE_CALL) { } else if (messageObject.type == MessageObject.TYPE_PHONE_CALL) {
createSelectorDrawable(0); createSelectorDrawable(0);
@ -7271,30 +7292,20 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
if (!reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) { if (!reactionsLayoutInBubble.isSmall && !reactionsLayoutInBubble.isEmpty) {
if (!drawPhotoImage) { if (!drawPhotoImage) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(2); reactionsLayoutInBubble.positionOffsetY += dp(2);
} }
if (captionLayout != null && currentPosition != null && currentMessagesGroup != null && currentMessagesGroup.isDocuments) { reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + dp(!drawPhotoImage || captionLayout == null ? 8 : 0);
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
} else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && ((docTitleLayout != null && docTitleLayout.getLineCount() > 1) || currentMessageObject.hasValidReplyMessageObject()) && !currentMessageObject.isForwarded()) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
} else if (!drawPhotoImage && !TextUtils.isEmpty(messageObject.caption) && !currentMessageObject.isOutOwner()) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
}
reactionsLayoutInBubble.totalHeight = reactionsLayoutInBubble.height + AndroidUtilities.dp(8);
measureTime(messageObject); measureTime(messageObject);
if (drawPhotoImage && captionLayout == null) { if (drawPhotoImage && captionLayout == null) {
reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(8); reactionsLayoutInBubble.totalHeight += dp(8);
}
if (!drawPhotoImage && captionLayout != null && currentMessageObject != null && currentMessageObject.isOutOwner() && currentMessageObject.isDocument() && currentMessagesGroup == null && !currentMessageObject.isForwarded() && !currentMessageObject.isReply()) {
reactionsLayoutInBubble.positionOffsetY += AndroidUtilities.dp(10);
} }
int timeLeft = backgroundWidth - reactionsLayoutInBubble.lastLineX - AndroidUtilities.dp(31); int timeLeft = backgroundWidth - reactionsLayoutInBubble.lastLineX - dp(42);
if (timeLeft < timeWidth) { if (timeLeft < timeWidth) {
reactionsLayoutInBubble.totalHeight += AndroidUtilities.dp(12); reactionsLayoutInBubble.totalHeight += dp(captionLayout == null ? 15 : 12);
reactionsLayoutInBubble.positionOffsetY -= AndroidUtilities.dp(12); reactionsLayoutInBubble.positionOffsetY -= dp(15);
} }
additionHeight += reactionsLayoutInBubble.totalHeight; additionHeight += reactionsLayoutInBubble.totalHeight;
} }
@ -8387,7 +8398,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
invalidate(); invalidate();
} }
if ((currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.isDocument()) && !messageObject.isAnyKindOfSticker() && addedCaptionHeight == 0 && !messageObject.isExpiredStory()) { if ((currentPosition == null || currentMessageObject.isMusic() || currentMessageObject.isDocument()) && !messageObject.isAnyKindOfSticker() && addedCaptionHeight == 0 && !messageObject.isExpiredStory() && !messageObject.isUnsupported()) {
int addCaptionLayoutWidth = 0; int addCaptionLayoutWidth = 0;
if (!messageObject.isRestrictedMessage && captionLayout == null && (messageObject.caption != null || messageObject.isVoiceTranscriptionOpen())) { if (!messageObject.isRestrictedMessage && captionLayout == null && (messageObject.caption != null || messageObject.isVoiceTranscriptionOpen())) {
currentCaption = messageObject.isVoiceTranscriptionOpen() ? messageObject.getVoiceTranscription() : messageObject.caption; currentCaption = messageObject.isVoiceTranscriptionOpen() ? messageObject.getVoiceTranscription() : messageObject.caption;
@ -9317,6 +9328,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
useTranscribeButton = ( useTranscribeButton = (
currentMessageObject != null && currentMessageObject != null &&
!currentMessageObject.isRepostPreview &&
(!currentMessageObject.isOutOwner() || currentMessageObject.isSent()) && (!currentMessageObject.isOutOwner() || currentMessageObject.isSent()) &&
( (
UserConfig.getInstance(currentAccount).isPremium() UserConfig.getInstance(currentAccount).isPremium()
@ -9566,6 +9578,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
int newLineForTimeDp = 14; int newLineForTimeDp = 14;
if (currentMessageObject.isUnsupported()) {
newLineForTime = true;
}
if ( if (
currentMessageObject.hasCodeAtBottom && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) || currentMessageObject.hasCodeAtBottom && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) ||
currentMessageObject.hasQuoteAtBottom && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall) currentMessageObject.hasQuoteAtBottom && (reactionsLayoutInBubble.isEmpty || reactionsLayoutInBubble.isSmall)
@ -9858,7 +9873,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
@Override @Override
protected boolean verifyDrawable(Drawable who) { protected boolean verifyDrawable(Drawable who) {
return super.verifyDrawable(who) || who == selectorDrawable[0] || who == selectorDrawable[1] || who == linkPreviewSelector || who == nameLayoutSelector || who == replySelector; return super.verifyDrawable(who) || who == selectorDrawable[0] || who == selectorDrawable[1] || who == linkPreviewSelector || who == nameLayoutSelector || who == replySelector || reactionsLayoutInBubble != null && reactionsLayoutInBubble.verifyDrawable(who);
} }
@Override @Override
@ -9941,7 +9956,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return; return;
} }
int color; int color;
if (psaHintPressed) { if (currentMessageObject.isUnsupported()) {
color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outPreviewInstantText : Theme.key_chat_inPreviewInstantText);
} else if (psaHintPressed) {
color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outViews : Theme.key_chat_inViews); color = getThemedColor(currentMessageObject.isOutOwner() ? Theme.key_chat_outViews : Theme.key_chat_inViews);
} else if (linkLine != null) { } else if (linkLine != null) {
color = linkLine.getColor(); color = linkLine.getColor();
@ -10088,6 +10105,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
str = LocaleController.getString("BoostingHowItWork", R.string.BoostingHowItWork); str = LocaleController.getString("BoostingHowItWork", R.string.BoostingHowItWork);
} else if (drawInstantViewType == 20) { } else if (drawInstantViewType == 20) {
str = LocaleController.getString(R.string.OpenGift); str = LocaleController.getString(R.string.OpenGift);
} else if (drawInstantViewType == 21) {
str = LocaleController.getString(R.string.AppUpdate);
} else { } else {
str = LocaleController.getString(R.string.InstantView); str = LocaleController.getString(R.string.InstantView);
} }
@ -10147,7 +10166,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (needRecreate) { if (needRecreate) {
drawnContactButtonsFlag = 0; drawnContactButtonsFlag = 0;
int mWidth = (backgroundWidth - AndroidUtilities.dp(10 + 24 + 10 + 31)) / buttonsCount; int mWidth = (backgroundWidth - AndroidUtilities.dp(10 + 24 + 10 + 31)) / buttonsCount;
int parentWidth = (backgroundWidth - AndroidUtilities.dp(37)) / buttonsCount; float parentWidth = (backgroundWidth - AndroidUtilities.dpf2(37)) / buttonsCount;
if (contactButtons == null) { if (contactButtons == null) {
contactButtons = new ArrayList<>(buttonsCount); contactButtons = new ArrayList<>(buttonsCount);
@ -10177,7 +10196,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
private InstantViewButton createInstantViewButton(int type, String str, int availableWidth, int parentWidth) { private InstantViewButton createInstantViewButton(int type, String str, int availableWidth, float parentWidth) {
InstantViewButton instantViewButton = new InstantViewButton(); InstantViewButton instantViewButton = new InstantViewButton();
instantViewButton.type = type; instantViewButton.type = type;
instantViewButton.layout = new StaticLayout(TextUtils.ellipsize(str, Theme.chat_instantViewPaint, availableWidth, TextUtils.TruncateAt.END), Theme.chat_instantViewPaint, availableWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); instantViewButton.layout = new StaticLayout(TextUtils.ellipsize(str, Theme.chat_instantViewPaint, availableWidth, TextUtils.TruncateAt.END), Theme.chat_instantViewPaint, availableWidth + AndroidUtilities.dp(2), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
@ -11616,7 +11635,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (hasNewLineForTime && !(drawForwardedName && hasLinkPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO)) { if (hasNewLineForTime && !(drawForwardedName && hasLinkPreview && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO)) {
reactionsLayoutInBubble.y -= AndroidUtilities.dp(16); reactionsLayoutInBubble.y -= AndroidUtilities.dp(16);
} }
if (captionLayout != null && ((currentMessageObject.type != MessageObject.TYPE_VOICE && !(currentMessageObject.isOut() && drawForwardedName && !drawPhotoImage) && !(currentMessageObject.type == MessageObject.TYPE_FILE && drawPhotoImage)) || (currentPosition != null && currentMessagesGroup != null))) { if (currentMessageObject.type != MessageObject.TYPE_FILE && (captionLayout != null && ((currentMessageObject.type != MessageObject.TYPE_VOICE && !(currentMessageObject.isOut() && drawForwardedName && !drawPhotoImage)) || (currentPosition != null && currentMessagesGroup != null)))) {
reactionsLayoutInBubble.y -= AndroidUtilities.dp(14); reactionsLayoutInBubble.y -= AndroidUtilities.dp(14);
} }
reactionsLayoutInBubble.y += reactionsLayoutInBubble.positionOffsetY; reactionsLayoutInBubble.y += reactionsLayoutInBubble.positionOffsetY;
@ -11743,7 +11762,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
public void drawLinkPreview(Canvas canvas, float alpha) { public void drawLinkPreview(Canvas canvas, float alpha) {
if (!currentMessageObject.isSponsored() && !hasLinkPreview && !hasGamePreview && !hasInvoicePreview) { if (!currentMessageObject.isSponsored() && !currentMessageObject.isUnsupported() && !hasLinkPreview && !hasGamePreview && !hasInvoicePreview) {
return; return;
} }
int restoreCount = canvas.getSaveCount(); int restoreCount = canvas.getSaveCount();
@ -11807,7 +11826,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
boolean restore = false; boolean restore = false;
boolean drawInstantButtonInside = false; boolean drawInstantButtonInside = false;
boolean loading = delegate != null && delegate.isProgressLoading(this, ChatActivity.PROGRESS_INSTANT); boolean loading = delegate != null && delegate.isProgressLoading(this, ChatActivity.PROGRESS_INSTANT);
if (!hasInvoicePreview && !currentMessageObject.isGiveawayOrGiveawayResults()) { if (!hasInvoicePreview && !currentMessageObject.isGiveawayOrGiveawayResults() && !currentMessageObject.isUnsupported()) {
drawInstantButtonInside = true; drawInstantButtonInside = true;
if (linkPreviewBounce == null) { if (linkPreviewBounce == null) {
@ -12223,7 +12242,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} else { } else {
int color = getThemedColor(Theme.key_chat_inPreviewInstantText); int color = getThemedColor(Theme.key_chat_inPreviewInstantText);
if (linkLine != null) { if (linkLine != null && !currentMessageObject.isUnsupported()) {
color = linkLine.getColor(); color = linkLine.getColor();
} }
if (this.instantDrawable == null) { if (this.instantDrawable == null) {
@ -12274,7 +12293,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.restore(); canvas.restore();
} }
} else { } else {
int instantY = startY + linkPreviewHeight + AndroidUtilities.dp(10); int instantY = startY + linkPreviewHeight + AndroidUtilities.dp(currentMessageObject.isUnsupported() ? -5 : 10);
if (instantButtonLoading != null && !loading && !instantButtonLoading.isDisappeared() && !instantButtonLoading.isDisappearing()) { if (instantButtonLoading != null && !loading && !instantButtonLoading.isDisappeared() && !instantButtonLoading.isDisappearing()) {
instantButtonLoading.disappear(); instantButtonLoading.disappear();
} }
@ -12420,17 +12439,18 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.drawRect(contactRect.left + AndroidUtilities.dp(3 + 7), instantY + AndroidUtilities.dp(2), contactRect.right - AndroidUtilities.dp(7), instantY + AndroidUtilities.dp(2) + Math.max(1, AndroidUtilities.dp(0.66f)), Theme.chat_instantViewPaint); canvas.drawRect(contactRect.left + AndroidUtilities.dp(3 + 7), instantY + AndroidUtilities.dp(2), contactRect.right - AndroidUtilities.dp(7), instantY + AndroidUtilities.dp(2) + Math.max(1, AndroidUtilities.dp(0.66f)), Theme.chat_instantViewPaint);
Theme.chat_instantViewPaint.setAlpha(wasAlpha); Theme.chat_instantViewPaint.setAlpha(wasAlpha);
instantY += AndroidUtilities.dp(2); instantY += AndroidUtilities.dp(2);
textX += AndroidUtilities.dp(3); float instantButtonLeft = textX + AndroidUtilities.dp(3);
boolean needCreateSelectorDrawable = contactButtons != null && contactButtons.size() > 1; boolean needCreateSelectorDrawable = contactButtons != null && contactButtons.size() > 1;
int rippleColor = contactLine.getBackgroundColor(); int rippleColor = contactLine.getBackgroundColor();
for (int i = 0; i < contactButtons.size(); i++) { for (int i = 0; i < contactButtons.size(); i++) {
InstantViewButton instantViewButton = contactButtons.get(i); InstantViewButton instantViewButton = contactButtons.get(i);
instantViewButton.rect.set(textX, instantY, textX + instantViewButton.buttonWidth, instantY + AndroidUtilities.dp(36)); float right = Math.min(instantButtonLeft + instantViewButton.buttonWidth, contactRect.right);
instantViewButton.rect.set(instantButtonLeft, instantY, right, instantY + AndroidUtilities.dp(36));
if (needCreateSelectorDrawable && instantViewButton.selectorDrawable == null) { if (needCreateSelectorDrawable && instantViewButton.selectorDrawable == null) {
instantViewButton.selectorDrawable = Theme.createRadSelectorDrawable(linkPreviewSelectorColor = rippleColor, 0, 0, i == (contactButtons.size() - 1) ? rad : 0, 0); instantViewButton.selectorDrawable = Theme.createRadSelectorDrawable(linkPreviewSelectorColor = rippleColor, 0, 0, i == (contactButtons.size() - 1) ? rad : 0, 0);
} }
if (instantViewButton.selectorDrawable != null) { if (instantViewButton.selectorDrawable != null) {
instantViewButton.selectorDrawable.setBounds(textX, instantY, textX + instantViewButton.buttonWidth, instantY + AndroidUtilities.dp(36)); instantViewButton.selectorDrawable.setBounds((int) instantButtonLeft, instantY, (int) right, instantY + AndroidUtilities.dp(36));
instantViewButton.selectorDrawable.draw(canvas); instantViewButton.selectorDrawable.draw(canvas);
} }
float buttonScale = 1f; float buttonScale = 1f;
@ -12447,14 +12467,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
if (instantViewButton.layout != null) { if (instantViewButton.layout != null) {
canvas.save(); canvas.save();
canvas.translate(textX + instantViewButton.textX, instantY + AndroidUtilities.dp(10.5f)); canvas.translate(instantButtonLeft + instantViewButton.textX, instantY + AndroidUtilities.dp(10.5f));
instantViewButton.layout.draw(canvas); instantViewButton.layout.draw(canvas);
canvas.restore(); canvas.restore();
} }
if (needButtonScale) { if (needButtonScale) {
canvas.restore(); canvas.restore();
} }
textX += instantViewButton.buttonWidth; instantButtonLeft += instantViewButton.buttonWidth;
} }
} }
if (needContactViewScale) { if (needContactViewScale) {
@ -12858,7 +12878,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
restore = canvas.saveLayerAlpha(rect, (int) (alpha * 255), Canvas.ALL_SAVE_FLAG); restore = canvas.saveLayerAlpha(rect, (int) (alpha * 255), Canvas.ALL_SAVE_FLAG);
} }
} }
int spoilersColor = currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount) ? getThemedColor(Theme.key_chat_outTimeText) : Theme.chat_msgTextPaint.getColor(); int spoilersColor = currentMessageObject.isOutOwner() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount) ? getThemedColor(Theme.key_chat_outTimeText) : Theme.chat_msgTextPaint.getColor();
if (quoteHighlight != null && currentMessagesGroup == null) { if (quoteHighlight != null && currentMessagesGroup == null) {
Theme.MessageDrawable backgroundDrawable = currentBackgroundDrawable; Theme.MessageDrawable backgroundDrawable = currentBackgroundDrawable;
if (backgroundDrawable != null) { if (backgroundDrawable != null) {
@ -13157,17 +13177,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER || currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) { if (documentAttachType == DOCUMENT_ATTACH_TYPE_STICKER || documentAttachType == DOCUMENT_ATTACH_TYPE_WALLPAPER || currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
int maxWidth; int maxWidth;
if (AndroidUtilities.isTablet()) { if (AndroidUtilities.isTablet()) {
if (needDrawAvatar()) { maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(needDrawAvatar() ? 42 : 0);
maxWidth = AndroidUtilities.getMinTabletSide() - AndroidUtilities.dp(42);
} else {
maxWidth = AndroidUtilities.getMinTabletSide();
}
} else { } else {
if (needDrawAvatar()) { maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(needDrawAvatar() ? 42 : 0);
maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y) - AndroidUtilities.dp(42); }
} else { if (currentMessageObject != null && currentMessageObject.isSaved && currentMessageObject.isOutOwner() && checkNeedDrawShareButton(currentMessageObject)) {
maxWidth = Math.min(getParentWidth(), AndroidUtilities.displaySize.y); maxWidth -= dp(25);
}
} }
if (isPlayingRound && (currentMessageObject == null || !currentMessageObject.isVoiceTranscriptionOpen())) { if (isPlayingRound && (currentMessageObject == null || !currentMessageObject.isVoiceTranscriptionOpen())) {
int backgroundWidthLocal = backgroundWidth - (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize); int backgroundWidthLocal = backgroundWidth - (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize);
@ -13195,7 +13210,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) { } else if (currentMessageObject.type == MessageObject.TYPE_EMOJIS) {
return Math.max(currentMessageObject.textWidth, (int) ((AndroidUtilities.displaySize.x - AndroidUtilities.dp(52) - (isAvatarVisible ? AndroidUtilities.dp(48) : 0)) * .5f)); return Math.max(currentMessageObject.textWidth, (int) ((AndroidUtilities.displaySize.x - AndroidUtilities.dp(52) - (isAvatarVisible ? AndroidUtilities.dp(48) : 0)) * .5f));
} else { } else {
return backgroundWidth - AndroidUtilities.dp(mediaBackground ? 22 : 31); int width = backgroundWidth;
if (currentMessageObject != null && currentMessageObject.isSaved && currentMessageObject.isOutOwner() && checkNeedDrawShareButton(currentMessageObject)) {
width -= dp(25);
}
width -= dp(mediaBackground ? 22 : 31);
return width;
} }
} }
@ -14254,6 +14274,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
timeString = LocaleController.formatSmallDateChat(messageObject.messageOwner.date) + ", " + LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000); timeString = LocaleController.formatSmallDateChat(messageObject.messageOwner.date) + ", " + LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
} else if (edited) { } else if (edited) {
timeString = LocaleController.getString("EditedMessage", R.string.EditedMessage) + " " + LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000); timeString = LocaleController.getString("EditedMessage", R.string.EditedMessage) + " " + LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
} else if (currentMessageObject.isSaved && currentMessageObject.messageOwner.fwd_from != null && (currentMessageObject.messageOwner.fwd_from.date != 0 || currentMessageObject.messageOwner.fwd_from.saved_date != 0)) {
int date = currentMessageObject.messageOwner.fwd_from.date;
if (date == 0) {
date = currentMessageObject.messageOwner.fwd_from.saved_date;
}
timeString = LocaleController.formatSeenDate(date);
} else { } else {
timeString = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000); timeString = LocaleController.getInstance().formatterDay.format((long) (messageObject.messageOwner.date) * 1000);
} }
@ -14368,7 +14394,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
if (currentMessagesGroup != null && currentPosition != null) { if (currentMessagesGroup != null && currentPosition != null) {
final boolean last = (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & (messageObject.isOutOwner() ? MessageObject.POSITION_FLAG_LEFT : MessageObject.POSITION_FLAG_RIGHT)) != 0; final boolean last = (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0 && (currentPosition.flags & (messageObject.isOutOwner() ? MessageObject.POSITION_FLAG_LEFT : MessageObject.POSITION_FLAG_RIGHT)) != 0;
if ((!currentMessagesGroup.reversed && !currentMessagesGroup.isDocuments && !last || currentMessagesGroup.reversed && !last)) { if (!currentMessagesGroup.isDocuments && !last) {
return false; return false;
} }
} }
@ -14735,7 +14761,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
topicButton = null; topicButton = null;
} }
if (!messageObject.isGiveawayResults() && (!isThreadChat || messageObject.getReplyTopMsgId(isForum) != 0 || isForumGeneral) && messageObject.hasValidReplyMessageObject() || messageObject.messageOwner.fwd_from != null && messageObject.isDice() || (messageObject.messageOwner.reply_to != null && (messageObject.messageOwner.reply_to.story_id != 0 || !TextUtils.isEmpty(messageObject.messageOwner.reply_to.quote_text) || messageObject.messageOwner.reply_to.reply_from != null))) { if ((!messageObject.isGiveawayResults() && (!isThreadChat || isSavedChat || messageObject.getReplyTopMsgId(isForum) != 0 || isForumGeneral) && messageObject.hasValidReplyMessageObject() || messageObject.messageOwner.fwd_from != null && messageObject.isDice() || (messageObject.messageOwner.reply_to != null && (messageObject.messageOwner.reply_to.story_id != 0 || !TextUtils.isEmpty(messageObject.messageOwner.reply_to.quote_text) || messageObject.messageOwner.reply_to.reply_from != null))) && !messageObject.isRepostPreview) {
if (currentPosition == null || currentPosition.minY == 0) { if (currentPosition == null || currentPosition.minY == 0) {
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO || messageObject.type == MessageObject.TYPE_EMOJIS) { if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO || messageObject.type == MessageObject.TYPE_EMOJIS) {
namesOffset += AndroidUtilities.dp(20) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize()); namesOffset += AndroidUtilities.dp(20) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
@ -14753,7 +14779,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!messageObject.shouldDrawWithoutBackground()) { if (!messageObject.shouldDrawWithoutBackground()) {
maxWidth -= AndroidUtilities.dp(messageObject.isOutOwner() ? 20 : 10); maxWidth -= AndroidUtilities.dp(messageObject.isOutOwner() ? 20 : 10);
if (messageObject.type != MessageObject.TYPE_TEXT || messageObject.needDrawShareButton()) { if (messageObject.type != MessageObject.TYPE_TEXT || messageObject.needDrawShareButton()) {
maxWidth -= AndroidUtilities.dp(10); maxWidth -= AndroidUtilities.dp(messageObject.isSaved && messageObject.isOutOwner() ? 35 : 10);
} }
} else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) { } else if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
maxWidth += AndroidUtilities.dp(13); maxWidth += AndroidUtilities.dp(13);
@ -14785,7 +14811,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
stringFinalText = StoriesUtilities.createReplyStoryString(); stringFinalText = StoriesUtilities.createReplyStoryString();
maxWidth -= AndroidUtilities.dp(16) + (textPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize()); maxWidth -= AndroidUtilities.dp(16) + (textPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
} }
} else if ((!isThreadChat || messageObject.getReplyTopMsgId(isForum) != 0 || isForumGeneral) && messageObject.hasValidReplyMessageObject() || hasReplyQuote || messageObject.messageOwner.reply_to != null && messageObject.messageOwner.reply_to.reply_from != null) { } else if ((!isThreadChat || isSavedChat || messageObject.getReplyTopMsgId(isForum) != 0 || isForumGeneral) && messageObject.hasValidReplyMessageObject() || hasReplyQuote || messageObject.messageOwner.reply_to != null && messageObject.messageOwner.reply_to.reply_from != null) {
lastReplyMessage = messageObject.replyMessageObject == null ? null : messageObject.replyMessageObject.messageOwner; lastReplyMessage = messageObject.replyMessageObject == null ? null : messageObject.replyMessageObject.messageOwner;
int cacheType = 1; int cacheType = 1;
int size = 0; int size = 0;
@ -15050,7 +15076,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyTextWidth -= sz; replyTextWidth -= sz;
maxWidth += sz; maxWidth += sz;
} }
if (changed || !isReplyQuote && (currentMessageObject.shouldDrawWithoutBackground() || Build.VERSION.SDK_INT < Build.VERSION_CODES.M)) { if (changed || !isReplyQuote) {
stringFinalText = TextUtils.ellipsize(sb, textPaint, maxWidth, TextUtils.TruncateAt.END); stringFinalText = TextUtils.ellipsize(sb, textPaint, maxWidth, TextUtils.TruncateAt.END);
} else { } else {
stringFinalText = sb; stringFinalText = sb;
@ -15103,8 +15129,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
FileLog.e(e); FileLog.e(e);
} }
} }
} else if (!isThreadChat && messageObject.getReplyMsgId() != 0 && !messageObject.isGiveawayResults()) { } else if (!isThreadChat && messageObject.getReplyMsgId() != 0 && !messageObject.isGiveawayResults() && !messageObject.isRepostPreview) {
if (!(messageObject.replyMessageObject != null && (messageObject.replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty || messageObject.replyMessageObject.messageOwner != null && messageObject.replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionTopicCreate)) && messageObject.getDialogId() != UserObject.REPLY_BOT) { if (!(messageObject.replyMessageObject != null && (messageObject.replyMessageObject.messageOwner instanceof TLRPC.TL_messageEmpty || messageObject.replyMessageObject.messageOwner != null && messageObject.replyMessageObject.messageOwner.action instanceof TLRPC.TL_messageActionTopicCreate)) && (delegate == null || delegate.doNotShowLoadingReply(messageObject))) {
if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) { if (!messageObject.isAnyKindOfSticker() && messageObject.type != MessageObject.TYPE_ROUND_VIDEO) {
namesOffset += AndroidUtilities.dp(14 + 4) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize()); namesOffset += AndroidUtilities.dp(14 + 4) + (Theme.chat_replyTextPaint.getTextSize() + Theme.chat_replyNamePaint.getTextSize());
if (messageObject.type != MessageObject.TYPE_TEXT) { if (messageObject.type != MessageObject.TYPE_TEXT) {
@ -16432,8 +16458,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} }
} }
} }
if (drawSideButton != 4 && sideStartY < (layoutHeight - AndroidUtilities.dp(32)) / 2f) { if (drawSideButton != 4) {
sideStartY = (layoutHeight - AndroidUtilities.dp(32)) / 2f; float sideMin = (layoutHeight + transitionParams.deltaBottom - AndroidUtilities.dp(32)) / 2f;
if (sideStartY < sideMin) {
sideStartY = sideMin;
}
} }
if (!currentMessageObject.isOutOwner() && isRoundVideo && !hasLinkPreview) { if (!currentMessageObject.isOutOwner() && isRoundVideo && !hasLinkPreview) {
float offsetSize = isAvatarVisible ? ((AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f) : AndroidUtilities.dp(50); float offsetSize = isAvatarVisible ? ((AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f) : AndroidUtilities.dp(50);
@ -16689,7 +16718,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
replyForwardAlpha = 0; replyForwardAlpha = 0;
} }
} }
if (drawNameLayout && nameLayout != null) { if ((drawNameLayout || transitionParams.animateDrawNameLayout) && nameLayout != null) {
float nameAlpha = !transitionParams.animateDrawNameLayout ? 1f : (drawNameLayout ? transitionParams.animateChangeProgress : 1f - transitionParams.animateChangeProgress);
canvas.save(); canvas.save();
int oldAlpha; int oldAlpha;
@ -16813,6 +16843,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
(int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(4)), (int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(4)),
(int) (nameY + nameLayout.getHeight() + dp(1.33f)) (int) (nameY + nameLayout.getHeight() + dp(1.33f))
); );
nameLayoutSelector.setAlpha((int) (0xFF * nameAlpha));
nameLayoutSelector.draw(canvas); nameLayoutSelector.draw(canvas);
if (currentNameStatus != null) { if (currentNameStatus != null) {
@ -16828,12 +16859,16 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
(int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(4 + 12 + 4 + 4)), (int) (nx + (viaNameWidth > 0 ? viaNameWidth - dp(4 + 28) : nameLayoutWidth) + dp(4 + 12 + 4 + 4)),
(int) (nameY + nameLayout.getHeight() + dp(1.33f + 2)) (int) (nameY + nameLayout.getHeight() + dp(1.33f + 2))
); );
nameStatusSelector.setAlpha((int) (0xFF * nameAlpha));
nameStatusSelector.draw(canvas); nameStatusSelector.draw(canvas);
} }
} }
canvas.translate(nx, nameY); canvas.translate(nx, nameY);
oldAlpha = Theme.chat_namePaint.getAlpha();
Theme.chat_namePaint.setAlpha((int) (oldAlpha * nameAlpha));
nameLayout.draw(canvas); nameLayout.draw(canvas);
Theme.chat_namePaint.setAlpha(oldAlpha);
canvas.restore(); canvas.restore();
float end; float end;
if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) { if (currentMessagesGroup != null && !currentMessagesGroup.isDocuments) {
@ -17379,7 +17414,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
canvas.restore(); canvas.restore();
} }
int spoilersColor; int spoilersColor;
if (currentMessageObject != null && currentMessageObject.isOut() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount)) { if (currentMessageObject != null && currentMessageObject.isOutOwner() && !ChatObject.isChannelAndNotMegaGroup(currentMessageObject.getChatId(), currentAccount)) {
spoilersColor = getThemedColor(Theme.key_chat_outTimeText); spoilersColor = getThemedColor(Theme.key_chat_outTimeText);
} else { } else {
spoilersColor = Theme.chat_replyTextPaint.getColor(); spoilersColor = Theme.chat_replyTextPaint.getColor();
@ -20324,7 +20359,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int h = 0; int h = 0;
for (int i = 0; i < groupedMessages.messages.size(); i++) { for (int i = 0; i < groupedMessages.messages.size(); i++) {
MessageObject o = groupedMessages.messages.get(i); MessageObject o = groupedMessages.messages.get(i);
MessageObject.GroupedMessagePosition position = groupedMessages.positions.get(o); MessageObject.GroupedMessagePosition position = groupedMessages.getPosition(o);
if (position != null && (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) { if (position != null && (position.flags & MessageObject.POSITION_FLAG_LEFT) != 0) {
setMessageContent(o, groupedMessages, false, false); setMessageContent(o, groupedMessages, false, false);
if (withCaption && !TextUtils.isEmpty(currentCaption)) { if (withCaption && !TextUtils.isEmpty(currentCaption)) {
@ -20792,7 +20827,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (drawInstantView && !instantButtonRect.isEmpty()) { if (drawInstantView && !instantButtonRect.isEmpty()) {
info.addChild(ChatMessageCell.this, INSTANT_VIEW); info.addChild(ChatMessageCell.this, INSTANT_VIEW);
} }
if (drawContact && !contactRect.isEmpty()) { if (drawContact && contactRect != null && !contactRect.isEmpty()) {
info.addChild(ChatMessageCell.this, CONTACT); info.addChild(ChatMessageCell.this, CONTACT);
if (contactButtons != null && contactButtons.size() > 1) { if (contactButtons != null && contactButtons.size() > 1) {
for (InstantViewButton instantViewButton : contactButtons) { for (InstantViewButton instantViewButton : contactButtons) {
@ -21608,6 +21643,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public boolean animateRecommendationsExpanded; public boolean animateRecommendationsExpanded;
public boolean animateFromRecommendationsExpanded; public boolean animateFromRecommendationsExpanded;
public boolean lastDrawNameLayout;
public boolean animateDrawNameLayout;
public void recordDrawingState() { public void recordDrawingState() {
wasDraw = true; wasDraw = true;
lastDrawingImageX = photoImage.getImageX(); lastDrawingImageX = photoImage.getImageX();
@ -21701,6 +21739,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else { } else {
lastDrawReplyY = 0; lastDrawReplyY = 0;
} }
lastDrawNameLayout = drawNameLayout;
} }
public void recordDrawingStatePreview() { public void recordDrawingStatePreview() {
@ -21748,6 +21788,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, currentMessageObject.textLayoutBlocks); animatedEmojiStack = AnimatedEmojiSpan.update(AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES, ChatMessageCell.this, animatedEmojiStack, currentMessageObject.textLayoutBlocks);
} }
} }
animateDrawNameLayout = false;
if (drawNameLayout != lastDrawNameLayout) {
animateDrawNameLayout = true;
changed = true;
}
if (replyTextLayout != lastDrawnReplyTextLayout) { if (replyTextLayout != lastDrawnReplyTextLayout) {
CharSequence newText = replyTextLayout != null ? replyTextLayout.getText() : null; CharSequence newText = replyTextLayout != null ? replyTextLayout.getText() : null;
CharSequence oldText = lastDrawnReplyTextLayout != null ? lastDrawnReplyTextLayout.getText() : null; CharSequence oldText = lastDrawnReplyTextLayout != null ? lastDrawnReplyTextLayout.getText() : null;
@ -22056,6 +22101,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
animateRadius = false; animateRadius = false;
animateChangeProgress = 1f; animateChangeProgress = 1f;
animateMessageText = false; animateMessageText = false;
animateDrawNameLayout = false;
animateOutTextBlocks = null; animateOutTextBlocks = null;
animateEditedLayout = null; animateEditedLayout = null;
animateTimeLayout = null; animateTimeLayout = null;
@ -22209,4 +22255,12 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
protected boolean drawPhotoImage(Canvas canvas) { protected boolean drawPhotoImage(Canvas canvas) {
return photoImage.draw(canvas); return photoImage.draw(canvas);
} }
public boolean areTags() {
MessageObject msg = getPrimaryMessageObject();
if (msg == null) return false;
if (msg.messageOwner == null) return false;
if (msg.messageOwner.reactions == null) return false;
return msg.messageOwner.reactions.reactions_as_tags;
}
} }

View file

@ -171,6 +171,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
private Paint timerPaint2; private Paint timerPaint2;
SharedResources sharedResources; SharedResources sharedResources;
public boolean isSavedDialog; public boolean isSavedDialog;
public boolean isSavedDialogCell;
public final StoriesUtilities.AvatarStoryParams storyParams = new StoriesUtilities.AvatarStoryParams(false) { public final StoriesUtilities.AvatarStoryParams storyParams = new StoriesUtilities.AvatarStoryParams(false) {
@Override @Override
@ -331,7 +332,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
private int currentDialogFolderId; private int currentDialogFolderId;
private int currentDialogFolderDialogsCount; private int currentDialogFolderDialogsCount;
private int currentEditDate; private int currentEditDate;
private boolean isDialogCell; public boolean isDialogCell;
private int lastMessageDate; private int lastMessageDate;
private int unreadCount; private int unreadCount;
private boolean markUnread; private boolean markUnread;
@ -950,6 +951,11 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
if (useForceThreeLines || SharedConfig.useThreeLinesLayout) { if (useForceThreeLines || SharedConfig.useThreeLinesLayout) {
Theme.dialogs_namePaint[0].setTextSize(AndroidUtilities.dp(17));
Theme.dialogs_nameEncryptedPaint[0].setTextSize(AndroidUtilities.dp(17));
Theme.dialogs_messagePaint[0].setTextSize(AndroidUtilities.dp(16));
Theme.dialogs_messagePrintingPaint[0].setTextSize(AndroidUtilities.dp(16));
Theme.dialogs_namePaint[1].setTextSize(AndroidUtilities.dp(16)); Theme.dialogs_namePaint[1].setTextSize(AndroidUtilities.dp(16));
Theme.dialogs_nameEncryptedPaint[1].setTextSize(AndroidUtilities.dp(16)); Theme.dialogs_nameEncryptedPaint[1].setTextSize(AndroidUtilities.dp(16));
Theme.dialogs_messagePaint[1].setTextSize(AndroidUtilities.dp(15)); Theme.dialogs_messagePaint[1].setTextSize(AndroidUtilities.dp(15));
@ -1226,7 +1232,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
if (draftMessage != null && TextUtils.isEmpty(draftMessage.message)) { if (draftMessage != null && TextUtils.isEmpty(draftMessage.message)) {
draftMessage = null; draftMessage = null;
} }
} else if (isDialogCell) { } else if (isDialogCell || isSavedDialogCell) {
draftMessage = MediaDataController.getInstance(currentAccount).getDraft(currentDialogId, 0); draftMessage = MediaDataController.getInstance(currentAccount).getDraft(currentDialogId, 0);
} else { } else {
draftMessage = null; draftMessage = null;
@ -1425,9 +1431,13 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} else { } else {
needEmoji = true; needEmoji = true;
updateMessageThumbs(); updateMessageThumbs();
if (chat != null && chat.id > 0 && fromChat == null && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat)) && !ForumUtilities.isTopicCreateMessage(message)) { String triedMessageName = null;
messageNameString = getMessageNameString(); if (!isSavedDialog && user != null && user.self && !message.isOutOwner()) {
if (chat.forum && !isTopic && !useFromUserAsAvatar) { triedMessageName = getMessageNameString();
}
if (isSavedDialog && user != null && !user.self && message != null && message.isOutOwner() || triedMessageName != null || chat != null && chat.id > 0 && fromChat == null && (!ChatObject.isChannel(chat) || ChatObject.isMegagroup(chat)) && !ForumUtilities.isTopicCreateMessage(message)) {
messageNameString = triedMessageName != null ? triedMessageName : getMessageNameString();
if (chat != null && chat.forum && !isTopic && !useFromUserAsAvatar) {
CharSequence topicName = MessagesController.getInstance(currentAccount).getTopicsController().getTopicIconName(chat, message, currentMessagePaint); CharSequence topicName = MessagesController.getInstance(currentAccount).getTopicsController().getTopicIconName(chat, message, currentMessagePaint);
if (!TextUtils.isEmpty(topicName)) { if (!TextUtils.isEmpty(topicName)) {
SpannableStringBuilder arrowSpan = new SpannableStringBuilder("-"); SpannableStringBuilder arrowSpan = new SpannableStringBuilder("-");
@ -2205,7 +2215,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 TypefaceSpan || 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 || !isFolderCell() && 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);
} }
} }
@ -3041,7 +3051,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
reactionsMentionsAnimator.start(); reactionsMentionsAnimator.start();
} }
avatarImage.setRoundRadius(chat != null && chat.forum && currentDialogFolderId == 0 && !useFromUserAsAvatar ? AndroidUtilities.dp(16) : AndroidUtilities.dp(28)); avatarImage.setRoundRadius(chat != null && chat.forum && currentDialogFolderId == 0 && !useFromUserAsAvatar || !isSavedDialog && user != null && user.self && MessagesController.getInstance(currentAccount).savedViewAsChats ? dp(16) : dp(28));
} }
if (!isTopic && (getMeasuredWidth() != 0 || getMeasuredHeight() != 0)) { if (!isTopic && (getMeasuredWidth() != 0 || getMeasuredHeight() != 0)) {
rebuildLayout = true; rebuildLayout = true;
@ -4797,6 +4807,24 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
TLRPC.User fromUser = null; TLRPC.User fromUser = null;
TLRPC.Chat fromChat = null; TLRPC.Chat fromChat = null;
long fromId = message.getFromChatId(); long fromId = message.getFromChatId();
final long selfId = UserConfig.getInstance(currentAccount).getClientUserId();
if (!isSavedDialog && currentDialogId == selfId) {
long savedDialogId = message.getSavedDialogId();
if (savedDialogId == selfId) {
return null;
} else if (savedDialogId != UserObject.ANONYMOUS) {
if (message.messageOwner != null && message.messageOwner.fwd_from != null) {
long fwdId = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.saved_from_id);
if (fwdId == 0) {
fwdId = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.from_id);
}
if (fwdId > 0 && fwdId != savedDialogId) {
return null;
}
}
fromId = savedDialogId;
}
}
if (isSavedDialog && message.messageOwner != null && message.messageOwner.fwd_from != null) { if (isSavedDialog && message.messageOwner != null && message.messageOwner.fwd_from != null) {
fromId = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.saved_from_id); fromId = DialogObject.getPeerDialogId(message.messageOwner.fwd_from.saved_from_id);
if (fromId == 0) { if (fromId == 0) {
@ -4809,7 +4837,14 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
fromChat = MessagesController.getInstance(currentAccount).getChat(-fromId); fromChat = MessagesController.getInstance(currentAccount).getChat(-fromId);
} }
if (message.isOutOwner()) { if (currentDialogId == selfId) {
if (fromUser != null) {
return UserObject.getFirstName(fromUser).replace("\n", "");
} else if (fromChat != null) {
return fromChat.title.replace("\n", "");
}
return null;
} else if (message.isOutOwner()) {
return LocaleController.getString("FromYou", R.string.FromYou); return LocaleController.getString("FromYou", R.string.FromYou);
} else if (!isSavedDialog && message != null && message.messageOwner != null && message.messageOwner.from_id instanceof TLRPC.TL_peerUser && (user = MessagesController.getInstance(currentAccount).getUser(message.messageOwner.from_id.user_id)) != null) { } else if (!isSavedDialog && message != null && message.messageOwner != null && message.messageOwner.from_id instanceof TLRPC.TL_peerUser && (user = MessagesController.getInstance(currentAccount).getUser(message.messageOwner.from_id.user_id)) != null) {
return UserObject.getFirstName(user).replace("\n", ""); return UserObject.getFirstName(user).replace("\n", "");
@ -4827,7 +4862,7 @@ public class DialogCell extends BaseCell implements StoriesListPlaceProvider.Ava
} }
} else if (fromChat != null && fromChat.title != null) { } else if (fromChat != null && fromChat.title != null) {
return fromChat.title.replace("\n", ""); return fromChat.title.replace("\n", "");
}else { } else {
return "DELETED"; return "DELETED";
} }
} }

View file

@ -14,6 +14,7 @@ import android.text.TextUtils;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
@ -36,7 +37,17 @@ public class ExpiredStoryView {
public void measure(ChatMessageCell parent) { public void measure(ChatMessageCell parent) {
CharSequence title = StoriesUtilities.createExpiredStoryString(); CharSequence title = StoriesUtilities.createExpiredStoryString();
TLRPC.TL_messageMediaStory mediaStory = (TLRPC.TL_messageMediaStory) parent.getMessageObject().messageOwner.media; MessageObject messageObject = parent.getMessageObject();
TLRPC.TL_messageMediaStory mediaStory;
if (messageObject != null && messageObject.messageOwner != null && messageObject.messageOwner.media instanceof TLRPC.TL_messageMediaStory) {
mediaStory = (TLRPC.TL_messageMediaStory) messageObject.messageOwner.media;
} else {
verticalPadding = AndroidUtilities.dp(4);
horizontalPadding = AndroidUtilities.dp(12);
height = 0;
width = 0;
return;
}
TLRPC.User user = MessagesController.getInstance(parent.currentAccount).getUser(mediaStory.user_id); TLRPC.User user = MessagesController.getInstance(parent.currentAccount).getUser(mediaStory.user_id);
String fromName = user == null ? "DELETED" : user.first_name; String fromName = user == null ? "DELETED" : user.first_name;
int forwardedNameWidth; int forwardedNameWidth;
@ -119,9 +130,13 @@ public class ExpiredStoryView {
canvas.save(); canvas.save();
canvas.translate(textX, textY); canvas.translate(textX, textY);
titleLayout.draw(canvas); if (titleLayout != null) {
canvas.translate(0, titleLayout.getHeight() + AndroidUtilities.dp(2)); titleLayout.draw(canvas);
subtitleLayout.draw(canvas); canvas.translate(0, titleLayout.getHeight() + AndroidUtilities.dp(2));
}
if (subtitleLayout != null) {
subtitleLayout.draw(canvas);
}
canvas.restore(); canvas.restore();
} }
} }

View file

@ -399,8 +399,13 @@ public class StickerSetCell extends FrameLayout {
} else { } else {
sideButtons.setVisibility(checked ? VISIBLE : INVISIBLE); sideButtons.setVisibility(checked ? VISIBLE : INVISIBLE);
if (!checked) { if (!checked) {
sideButtons.setAlpha(0f);
sideButtons.setScaleX(0.1f); sideButtons.setScaleX(0.1f);
sideButtons.setScaleY(0.1f); sideButtons.setScaleY(0.1f);
} else {
sideButtons.setAlpha(1f);
sideButtons.setScaleX(1f);
sideButtons.setScaleY(1f);
} }
} }
} else if (option == 3) { } else if (option == 3) {
@ -424,8 +429,13 @@ public class StickerSetCell extends FrameLayout {
} else { } else {
optionsButton.setVisibility(checked ? VISIBLE : INVISIBLE); optionsButton.setVisibility(checked ? VISIBLE : INVISIBLE);
if (!checked) { if (!checked) {
optionsButton.setAlpha(0f);
optionsButton.setScaleX(0.1f); optionsButton.setScaleX(0.1f);
optionsButton.setScaleY(0.1f); optionsButton.setScaleY(0.1f);
} else {
optionsButton.setAlpha(1f);
optionsButton.setScaleX(1f);
optionsButton.setScaleY(1f);
} }
} }
} }

View file

@ -268,7 +268,7 @@ public class TextCell extends FrameLayout {
int textKey = textView.getTag() instanceof Integer ? (int) textView.getTag() : Theme.key_windowBackgroundWhiteBlackText; int textKey = textView.getTag() instanceof Integer ? (int) textView.getTag() : Theme.key_windowBackgroundWhiteBlackText;
textView.setTextColor(processColor(Theme.getColor(textKey, resourcesProvider))); textView.setTextColor(processColor(Theme.getColor(textKey, resourcesProvider)));
if (imageView.getTag() instanceof Integer) { if (imageView.getTag() instanceof Integer) {
imageView.setColorFilter(new PorterDuffColorFilter(processColor(Theme.getColor((int) imageView.getTag(), resourcesProvider)), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor((int) imageView.getTag(), resourcesProvider), PorterDuff.Mode.MULTIPLY));
} }
subtitleView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText, resourcesProvider))); subtitleView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText, resourcesProvider)));
valueTextView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteValueText, resourcesProvider))); valueTextView.setTextColor(processColor(Theme.getColor(Theme.key_windowBackgroundWhiteValueText, resourcesProvider)));
@ -279,7 +279,7 @@ public class TextCell extends FrameLayout {
textView.setTextColor(processColor(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(processColor(Theme.getColor(icon, resourcesProvider)), PorterDuff.Mode.MULTIPLY)); imageView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(icon, resourcesProvider), PorterDuff.Mode.MULTIPLY));
imageView.setTag(icon); imageView.setTag(icon);
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@ import android.widget.FrameLayout;
import com.google.android.exoplayer2.util.Log; import com.google.android.exoplayer2.util.Log;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.DrawerLayoutContainer; import org.telegram.ui.ActionBar.DrawerLayoutContainer;
import org.telegram.ui.ActionBar.INavigationLayout; import org.telegram.ui.ActionBar.INavigationLayout;
@ -30,14 +31,27 @@ public class ChatActivityContainer extends FrameLayout {
private final INavigationLayout parentLayout; private final INavigationLayout parentLayout;
private View fragmentView; private View fragmentView;
public ChatActivityContainer(Context context, INavigationLayout parentLayout, Bundle args) { public ChatActivityContainer(Context context, Utilities.Callback0Return<FrameLayout> resizableView, INavigationLayout parentLayout, Bundle args) {
super(context); super(context);
this.parentLayout = parentLayout; this.parentLayout = parentLayout;
chatActivity = new ChatActivity(args); chatActivity = new ChatActivity(args) {
@Override
public void setNavigationBarColor(int color) {}
@Override
protected void onSearchLoadingUpdate(boolean loading) {
ChatActivityContainer.this.onSearchLoadingUpdate(loading);
}
};
chatActivity.insideContainerResizableView = resizableView;
chatActivity.isInsideContainer = true; chatActivity.isInsideContainer = true;
} }
protected void onSearchLoadingUpdate(boolean loading) {
}
@Override @Override
protected void onAttachedToWindow() { protected void onAttachedToWindow() {
super.onAttachedToWindow(); super.onAttachedToWindow();
@ -57,6 +71,7 @@ public class ChatActivityContainer extends FrameLayout {
parent.removeView(fragmentView); parent.removeView(fragmentView);
} }
} }
chatActivity.openedInstantly();
addView(fragmentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); addView(fragmentView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
if (isActive) { if (isActive) {
chatActivity.onResume(); chatActivity.onResume();

View file

@ -199,6 +199,7 @@ public class ChatReactionsEditActivity extends BaseFragment implements Notificat
infoCell.setText(ChatObject.isChannelAndNotMegaGroup(currentChat) ? LocaleController.getString("EnableReactionsChannelInfo", R.string.EnableReactionsChannelInfo) : infoCell.setText(ChatObject.isChannelAndNotMegaGroup(currentChat) ? LocaleController.getString("EnableReactionsChannelInfo", R.string.EnableReactionsChannelInfo) :
LocaleController.getString("EnableReactionsGroupInfo", R.string.EnableReactionsGroupInfo)); LocaleController.getString("EnableReactionsGroupInfo", R.string.EnableReactionsGroupInfo));
} else { } else {
infoCell.setForeground(Theme.getThemedDrawableByKey(getContext(), R.drawable.greydivider_bottom, Theme.key_windowBackgroundGrayShadow));
if (selectedType == SELECT_TYPE_SOME) { if (selectedType == SELECT_TYPE_SOME) {
infoCell.setText(LocaleController.getString("EnableSomeReactionsInfo", R.string.EnableSomeReactionsInfo)); infoCell.setText(LocaleController.getString("EnableSomeReactionsInfo", R.string.EnableSomeReactionsInfo));
} else if (selectedType == SELECT_TYPE_ALL) { } else if (selectedType == SELECT_TYPE_ALL) {

View file

@ -24,7 +24,7 @@ import org.telegram.ui.Components.SpeedIconDrawable;
public class ChooseSpeedLayout { public class ChooseSpeedLayout {
ActionBarPopupWindow.ActionBarPopupWindowLayout speedSwipeBackLayout; public ActionBarPopupWindow.ActionBarPopupWindowLayout speedSwipeBackLayout;
ActionBarMenuSlider.SpeedSlider slider; ActionBarMenuSlider.SpeedSlider slider;
private static final float MIN_SPEED = 0.2f; private static final float MIN_SPEED = 0.2f;

View file

@ -604,7 +604,7 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.setLayerNum(6656); imageReceiver.setLayerNum(6656);
} }
imageReceiver.setAspectFit(true); imageReceiver.setAspectFit(true);
if (cacheType == CACHE_TYPE_RENDERING_VIDEO || cacheType == STANDARD_LOTTIE_FRAME || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) { if (cacheType == CACHE_TYPE_RENDERING_VIDEO || cacheType == CACHE_TYPE_SAVED_REACTION || cacheType == STANDARD_LOTTIE_FRAME || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) {
imageReceiver.setAllowStartAnimation(false); imageReceiver.setAllowStartAnimation(false);
imageReceiver.setAllowStartLottieAnimation(false); imageReceiver.setAllowStartLottieAnimation(false);
imageReceiver.setAutoRepeat(0); imageReceiver.setAutoRepeat(0);
@ -628,7 +628,7 @@ public class AnimatedEmojiDrawable extends Drawable {
imageReceiver.setAutoRepeatCount(2); imageReceiver.setAutoRepeatCount(2);
} else if (cacheType == CACHE_TYPE_FORUM_TOPIC_LARGE || cacheType == CACHE_TYPE_SAVED_REACTION || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) { } else if (cacheType == CACHE_TYPE_FORUM_TOPIC_LARGE || cacheType == CACHE_TYPE_SAVED_REACTION || cacheType == CACHE_TYPE_AVATAR_CONSTRUCTOR_PREVIEW || cacheType == CACHE_TYPE_TAB_STRIP || cacheType == CACHE_TYPE_ALERT_PREVIEW_TAB_STRIP) {
imageReceiver.setAutoRepeatCount(1); imageReceiver.setAutoRepeatCount(1);
} else if (cacheType == CACHE_TYPE_EMOJI_CALL){ } else if (cacheType == CACHE_TYPE_EMOJI_CALL) {
imageReceiver.setAutoRepeatCount(0); imageReceiver.setAutoRepeatCount(0);
} }
} }

View file

@ -1,5 +1,7 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.lerp;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator; import android.animation.TimeInterpolator;
@ -93,6 +95,8 @@ public class AnimatedTextView extends View {
private TimeInterpolator animateInterpolator = CubicBezierInterpolator.EASE_OUT_QUINT; private TimeInterpolator animateInterpolator = CubicBezierInterpolator.EASE_OUT_QUINT;
private float moveAmplitude = 1f; private float moveAmplitude = 1f;
private float scaleAmplitude = 0;
private int alpha = 255; private int alpha = 255;
private final Rect bounds = new Rect(); private final Rect bounds = new Rect();
@ -163,8 +167,8 @@ public class AnimatedTextView extends View {
int fullWidth = bounds.width(); int fullWidth = bounds.width();
int fullHeight = bounds.height(); int fullHeight = bounds.height();
if (currentParts != null && oldParts != null && t != 1) { if (currentParts != null && oldParts != null && t != 1) {
float width = AndroidUtilities.lerp(oldWidth, currentWidth, t); float width = lerp(oldWidth, currentWidth, t);
float height = AndroidUtilities.lerp(oldHeight, currentHeight, t); float height = lerp(oldHeight, currentHeight, t);
canvas.translate(0, (fullHeight - height) / 2f); canvas.translate(0, (fullHeight - height) / 2f);
for (int i = 0; i < currentParts.length; ++i) { for (int i = 0; i < currentParts.length; ++i) {
Part current = currentParts[i]; Part current = currentParts[i];
@ -179,7 +183,7 @@ public class AnimatedTextView extends View {
if (isRTL && !ignoreRTL) { if (isRTL && !ignoreRTL) {
oldX = oldWidth - (oldX + old.width); oldX = oldWidth - (oldX + old.width);
} }
x = AndroidUtilities.lerp(oldX - old.left, x - current.left, t); x = lerp(oldX - old.left, x - current.left, t);
applyAlphaInternal(1f); applyAlphaInternal(1f);
} else { } else {
x -= current.left; x -= current.left;
@ -198,6 +202,10 @@ public class AnimatedTextView extends View {
} }
} }
canvas.translate(x, y); canvas.translate(x, y);
if (j < 0 && scaleAmplitude > 0) {
final float s = lerp(1f - scaleAmplitude, 1f, t);
canvas.scale(s, s, current.width / 2f, current.layout.getHeight() / 2f);
}
current.layout.draw(canvas); current.layout.draw(canvas);
canvas.restore(); canvas.restore();
} }
@ -225,6 +233,10 @@ public class AnimatedTextView extends View {
} }
} }
canvas.translate(x, y); canvas.translate(x, y);
if (scaleAmplitude > 0) {
final float s = lerp(1f, 1f - scaleAmplitude, t);
canvas.scale(s, s, old.width / 2f, old.layout.getHeight() / 2f);
}
old.layout.draw(canvas); old.layout.draw(canvas);
canvas.restore(); canvas.restore();
} }
@ -249,7 +261,6 @@ public class AnimatedTextView extends View {
x += fullWidth - currentWidth; x += fullWidth - currentWidth;
} }
} }
// boolean isAppeared = currentLayoutToOldIndex != null && i < currentLayoutToOldIndex.length && currentLayoutToOldIndex[i] < 0;
canvas.translate(x, 0); canvas.translate(x, 0);
current.layout.draw(canvas); current.layout.draw(canvas);
canvas.restore(); canvas.restore();
@ -445,7 +456,7 @@ public class AnimatedTextView extends View {
public float getCurrentWidth() { public float getCurrentWidth() {
if (currentParts != null && oldParts != null) { if (currentParts != null && oldParts != null) {
return AndroidUtilities.lerp(oldWidth, currentWidth, t); return lerp(oldWidth, currentWidth, t);
} }
return currentWidth; return currentWidth;
} }
@ -458,7 +469,7 @@ public class AnimatedTextView extends View {
if (oldParts == null || otherTextDrawable.oldParts == null) { if (oldParts == null || otherTextDrawable.oldParts == null) {
return Math.max(getCurrentWidth(), otherTextDrawable.getCurrentWidth()); return Math.max(getCurrentWidth(), otherTextDrawable.getCurrentWidth());
} }
return AndroidUtilities.lerp( return lerp(
Math.max(oldWidth, otherTextDrawable.oldWidth), Math.max(oldWidth, otherTextDrawable.oldWidth),
Math.max(currentWidth, otherTextDrawable.currentWidth), Math.max(currentWidth, otherTextDrawable.currentWidth),
Math.max(t, otherTextDrawable.t) Math.max(t, otherTextDrawable.t)
@ -865,6 +876,10 @@ public class AnimatedTextView extends View {
animateInterpolator = interpolator; animateInterpolator = interpolator;
} }
public void setScaleProperty(float scale) {
this.scaleAmplitude = scale;
}
public void copyStylesFrom(TextPaint paint) { public void copyStylesFrom(TextPaint paint) {
setTextColor(paint.getColor()); setTextColor(paint.getColor());
setTextSize(paint.getTextSize()); setTextSize(paint.getTextSize());
@ -913,7 +928,7 @@ public class AnimatedTextView extends View {
} }
public float isNotEmpty() { public float isNotEmpty() {
return AndroidUtilities.lerp( return lerp(
oldText == null || oldText.length() <= 0 ? 0f : 1f, oldText == null || oldText.length() <= 0 ? 0f : 1f,
currentText == null || currentText.length() <= 0 ? 0f : 1f, currentText == null || currentText.length() <= 0 ? 0f : 1f,
oldText == null ? 1f : t oldText == null ? 1f : t
@ -1055,6 +1070,10 @@ public class AnimatedTextView extends View {
drawable.setAnimationProperties(moveAmplitude, startDelay, duration, interpolator); drawable.setAnimationProperties(moveAmplitude, startDelay, duration, interpolator);
} }
public void setScaleProperty(float scale) {
drawable.setScaleProperty(scale);
}
public AnimatedTextDrawable getDrawable() { public AnimatedTextDrawable getDrawable() {
return drawable; return drawable;
} }

View file

@ -80,6 +80,7 @@ import org.telegram.messenger.R;
import org.telegram.messenger.SendMessagesHelper; import org.telegram.messenger.SendMessagesHelper;
import org.telegram.messenger.SharedConfig; import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.messenger.audioinfo.AudioInfo; import org.telegram.messenger.audioinfo.AudioInfo;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
@ -457,6 +458,12 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
actionBar.setTitle(ContactsController.formatName(user.first_name, user.last_name)); actionBar.setTitle(ContactsController.formatName(user.first_name, user.last_name));
} }
} }
} else if (did == UserConfig.getInstance(currentAccount).getClientUserId()) {
if (messageObject.getSavedDialogId() == UserObject.ANONYMOUS) {
actionBar.setTitle(LocaleController.getString(R.string.AnonymousForward));
} else {
actionBar.setTitle(LocaleController.getString(R.string.SavedMessages));
}
} else if (DialogObject.isUserDialog(did)) { } else if (DialogObject.isUserDialog(did)) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(did); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(did);
if (user != null) { if (user != null) {

View file

@ -349,6 +349,10 @@ public class BackupImageView extends View {
invalidate(); invalidate();
} }
public AnimatedEmojiDrawable getAnimatedEmojiDrawable() {
return animatedEmojiDrawable;
}
ValueAnimator roundRadiusAnimator; ValueAnimator roundRadiusAnimator;
public void animateToRoundRadius(int animateToRad) { public void animateToRoundRadius(int animateToRad) {

View file

@ -15,7 +15,7 @@ import org.telegram.messenger.SharedConfig;
public class BlurredFrameLayout extends FrameLayout { public class BlurredFrameLayout extends FrameLayout {
private final SizeNotifierFrameLayout sizeNotifierFrameLayout; protected final SizeNotifierFrameLayout sizeNotifierFrameLayout;
protected Paint backgroundPaint; protected Paint backgroundPaint;
public int backgroundColor = Color.TRANSPARENT; public int backgroundColor = Color.TRANSPARENT;
public int backgroundPaddingBottom; public int backgroundPaddingBottom;

View file

@ -160,10 +160,10 @@ public abstract class BottomSheetWithRecyclerListView extends BottomSheet {
actionBar.setBackgroundColor(getThemedColor(Theme.key_dialogBackground)); actionBar.setBackgroundColor(getThemedColor(Theme.key_dialogBackground));
actionBar.setTitleColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); actionBar.setTitleColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultSelector), false); actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultSelector), false);
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setItemsColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon), false); actionBar.setItemsColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon), false);
actionBar.setCastShadows(true); actionBar.setCastShadows(true);
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setTitle(getTitle()); actionBar.setTitle(getTitle());
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() { actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override @Override

View file

@ -22,10 +22,15 @@ import android.graphics.Shader;
import android.graphics.Typeface; import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
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.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.util.Property; import android.util.Property;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.GestureDetector; import android.view.GestureDetector;
@ -57,14 +62,20 @@ import androidx.dynamicanimation.animation.SpringForce;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji; import org.telegram.messenger.Emoji;
import org.telegram.messenger.LocaleController; import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R; import org.telegram.messenger.R;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.support.SparseLongArray;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity; import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.DialogsActivity; import org.telegram.ui.DialogsActivity;
import org.telegram.ui.LaunchActivity;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.util.ArrayList; import java.util.ArrayList;
@ -1023,12 +1034,16 @@ public class Bulletin {
private Matrix clipMatrix; private Matrix clipMatrix;
private Paint clipPaint; private Paint clipPaint;
protected int getMeasuredBackgroundHeight() {
return getMeasuredHeight();
}
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
if (bulletin == null) { if (bulletin == null) {
return; return;
} }
background.setBounds(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getMeasuredHeight() - getPaddingBottom()); background.setBounds(getPaddingLeft(), getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getMeasuredBackgroundHeight() - getPaddingBottom());
if (isTransitionRunning() && delegate != null) { if (isTransitionRunning() && delegate != null) {
final float top = delegate.getTopOffset(bulletin.tag) - getY(); final float top = delegate.getTopOffset(bulletin.tag) - getY();
final float bottom = ((View) getParent()).getMeasuredHeight() - getBottomOffset() - getY(); final float bottom = ((View) getParent()).getMeasuredHeight() - getBottomOffset() - getY();
@ -1044,7 +1059,7 @@ public class Bulletin {
if (clipPaint == null) { if (clipPaint == null) {
clipPaint = new Paint(Paint.ANTI_ALIAS_FLAG); clipPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
clipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); clipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
clipGradient = new LinearGradient(0, 0, 0, AndroidUtilities.dp(8), this.top ? new int[] {0xff000000, 0} : new int[] {0, 0xff000000}, new float[] { 0, 1 }, Shader.TileMode.CLAMP); clipGradient = new LinearGradient(0, 0, 0, AndroidUtilities.dp(8), this.top ? new int[]{0xff000000, 0} : new int[]{0, 0xff000000}, new float[]{0, 1}, Shader.TileMode.CLAMP);
clipMatrix = new Matrix(); clipMatrix = new Matrix();
clipGradient.setLocalMatrix(clipMatrix); clipGradient.setLocalMatrix(clipMatrix);
clipPaint.setShader(clipGradient); clipPaint.setShader(clipGradient);
@ -1090,6 +1105,7 @@ public class Bulletin {
} }
private boolean wrapWidth; private boolean wrapWidth;
public void setWrapWidth() { public void setWrapWidth() {
wrapWidth = true; wrapWidth = true;
} }
@ -1307,10 +1323,156 @@ public class Bulletin {
} }
} }
public static class LottieLayoutWithReactions extends LottieLayout implements NotificationCenter.NotificationCenterDelegate {
private ReactionsContainerLayout reactionsContainerLayout;
private SparseLongArray newMessagesByIds;
private final BaseFragment fragment;
private final int messagesCount;
public LottieLayoutWithReactions(BaseFragment fragment, int messagesCount) {
super(fragment.getContext(), fragment.getResourceProvider());
this.fragment = fragment;
this.messagesCount = messagesCount;
init();
}
private Bulletin bulletin;
public void setBulletin(Bulletin b) {
this.bulletin = b;
}
public void init() {
textView.setLayoutParams(LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.TOP, 56, 6, 8, 0));
imageView.setLayoutParams(LayoutHelper.createFrameRelatively(56, 48, Gravity.START | Gravity.TOP));
reactionsContainerLayout = new ReactionsContainerLayout(ReactionsContainerLayout.TYPE_TAGS, fragment, getContext(), fragment.getCurrentAccount(), fragment.getResourceProvider()) {
@Override
protected void onShownCustomEmojiReactionDialog() {
Bulletin bulletin = Bulletin.getVisibleBulletin();
if (bulletin != null) {
bulletin.setCanHide(false);
}
reactionsContainerLayout.getReactionsWindow().windowView.setOnClickListener(v -> {
hideReactionsDialog();
Bulletin.hideVisible();
});
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
if (bulletin != null) {
bulletin.setCanHide(false);
}
} else if (ev.getAction() == MotionEvent.ACTION_UP) {
if (bulletin != null) {
bulletin.setCanHide(true);
}
}
return super.dispatchTouchEvent(ev);
}
};
reactionsContainerLayout.setPadding(AndroidUtilities.dp(4), AndroidUtilities.dp(24), AndroidUtilities.dp(4), AndroidUtilities.dp(0));
reactionsContainerLayout.setDelegate(new ReactionsContainerLayout.ReactionsContainerDelegate() {
@Override
public void onReactionClicked(View view, ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean longpress, boolean addToRecent) {
if (newMessagesByIds == null) {
return;
}
final long selfId = UserConfig.getInstance(fragment.getCurrentAccount()).getClientUserId();
boolean isFragmentSavedMessages = fragment instanceof ChatActivity && ((ChatActivity) fragment).getDialogId() == selfId;
int lastMessageId = 0;
for (int i = 0; i < newMessagesByIds.size(); i++) {
int key = newMessagesByIds.keyAt(i);
TLRPC.Message message = new TLRPC.Message();
message.dialog_id = fragment.getUserConfig().getClientUserId();
message.id = key;
MessageObject messageObject = new MessageObject(fragment.getCurrentAccount(), message, false, false);
ArrayList<ReactionsLayoutInBubble.VisibleReaction> visibleReactions = new ArrayList<>();
visibleReactions.add(visibleReaction);
fragment.getSendMessagesHelper().sendReaction(messageObject, visibleReactions, visibleReaction, false, false, fragment, null);
lastMessageId = message.id;
}
hideReactionsDialog();
Bulletin.hideVisible();
showTaggedReactionToast(visibleReaction, fragment.getCurrentAccount(), lastMessageId, !isFragmentSavedMessages);
}
private void showTaggedReactionToast(ReactionsLayoutInBubble.VisibleReaction visibleReaction, int currentAccount, int messageId, boolean addViewButton) {
AndroidUtilities.runOnUIThread(() -> {
BaseFragment baseFragment = LaunchActivity.getLastFragment();
TLRPC.Document document;
if (visibleReaction.documentId == 0) {
TLRPC.TL_availableReaction availableReaction = MediaDataController.getInstance(UserConfig.selectedAccount).getReactionsMap().get(visibleReaction.emojicon);
if (availableReaction == null) {
return;
}
document = availableReaction.activate_animation;
} else {
document = AnimatedEmojiDrawable.findDocument(UserConfig.selectedAccount, visibleReaction.documentId);
}
if (document == null || baseFragment == null) {
return;
}
BulletinFactory.of(baseFragment).createMessagesTaggedBulletin(messagesCount, document, addViewButton ? () -> {
Bundle args = new Bundle();
args.putLong("user_id", UserConfig.getInstance(currentAccount).getClientUserId());
args.putInt("message_id", messageId);
baseFragment.presentFragment(new ChatActivity(args));
} : null).show(true);
}, 300);
}
});
reactionsContainerLayout.setTop(true);
reactionsContainerLayout.setClipChildren(false);
reactionsContainerLayout.setClipToPadding(false);
reactionsContainerLayout.setVisibility(View.VISIBLE);
reactionsContainerLayout.setBubbleOffset(-AndroidUtilities.dp(80));
reactionsContainerLayout.setHint(LocaleController.getString(R.string.SavedTagReactionsHint));
addView(reactionsContainerLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 92.5f, Gravity.CENTER_HORIZONTAL, 0, 36, 0, 0));
reactionsContainerLayout.setMessage(null, null);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
NotificationCenter.getInstance(UserConfig.selectedAccount).addObserver(this, NotificationCenter.savedMessagesForwarded);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
NotificationCenter.getInstance(UserConfig.selectedAccount).removeObserver(this, NotificationCenter.savedMessagesForwarded);
}
public void hideReactionsDialog() {
if (reactionsContainerLayout.getReactionsWindow() != null) {
reactionsContainerLayout.dismissWindow();
if (reactionsContainerLayout.getReactionsWindow().containerView != null) {
reactionsContainerLayout.getReactionsWindow().containerView.animate().alpha(0).setDuration(180).start();
}
}
}
@Override
protected int getMeasuredBackgroundHeight() {
return textView.getMeasuredHeight() + AndroidUtilities.dp(30);
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.savedMessagesForwarded) {
newMessagesByIds = (SparseLongArray) args[0];
}
}
}
public static class LottieLayout extends ButtonLayout { public static class LottieLayout extends ButtonLayout {
public RLottieImageView imageView; public RLottieImageView imageView;
public LinkSpanDrawable.LinksTextView textView; public TextView textView;
private int textColor; private int textColor;
@ -1322,6 +1484,10 @@ public class Bulletin {
addView(imageView, LayoutHelper.createFrameRelatively(56, 48, Gravity.START | Gravity.CENTER_VERTICAL)); addView(imageView, LayoutHelper.createFrameRelatively(56, 48, Gravity.START | Gravity.CENTER_VERTICAL));
textView = new LinkSpanDrawable.LinksTextView(context) { textView = new LinkSpanDrawable.LinksTextView(context) {
{
setDisablePaddingsOffset(true);
}
@Override @Override
public void setText(CharSequence text, BufferType type) { public void setText(CharSequence text, BufferType type) {
text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(13), false); text = Emoji.replaceEmoji(text, getPaint().getFontMetricsInt(), AndroidUtilities.dp(13), false);
@ -1329,7 +1495,6 @@ public class Bulletin {
} }
}; };
NotificationCenter.listenEmojiLoading(textView); NotificationCenter.listenEmojiLoading(textView);
textView.setDisablePaddingsOffset(true);
textView.setSingleLine(); textView.setSingleLine();
textView.setTypeface(Typeface.SANS_SERIF); textView.setTypeface(Typeface.SANS_SERIF);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15); textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
@ -1786,11 +1951,12 @@ public class Bulletin {
} }
private final BulletinWindowLayout container; private final BulletinWindowLayout container;
private BulletinWindow(Context context, Delegate delegate) { private BulletinWindow(Context context, Delegate delegate) {
super(context); super(context);
setContentView( setContentView(
container = new BulletinWindowLayout(context), container = new BulletinWindowLayout(context),
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
); );
if (Build.VERSION.SDK_INT >= 21) { if (Build.VERSION.SDK_INT >= 21) {
container.setFitsSystemWindows(true); container.setFitsSystemWindows(true);
@ -1804,7 +1970,7 @@ public class Bulletin {
} }
}); });
if (Build.VERSION.SDK_INT >= 30) { if (Build.VERSION.SDK_INT >= 30) {
container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
} else { } else {
container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); container.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
} }

View file

@ -3,19 +3,22 @@ package org.telegram.ui.Components;
import android.content.Context; import android.content.Context;
import android.graphics.PorterDuff; import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle;
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.TextPaint; import android.text.TextPaint;
import android.text.TextUtils;
import android.text.style.ClickableSpan; import android.text.style.ClickableSpan;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.CheckResult; import androidx.annotation.CheckResult;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -40,6 +43,7 @@ import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.BaseFragment; import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.HintView2; import org.telegram.ui.Stories.recorder.HintView2;
@ -1028,6 +1032,32 @@ public final class BulletinFactory {
return Bulletin.make(containerLayout, layout, Bulletin.DURATION_SHORT); return Bulletin.make(containerLayout, layout, Bulletin.DURATION_SHORT);
} }
public boolean showForwardedBulletinWithTag(long did, int messagesCount) {
if (!UserConfig.getInstance(UserConfig.selectedAccount).isPremium()) {
return false;
}
final Bulletin.LottieLayoutWithReactions layout = new Bulletin.LottieLayoutWithReactions(fragment, messagesCount);
CharSequence text;
if (did == UserConfig.getInstance(UserConfig.selectedAccount).clientUserId) {
if (messagesCount <= 1) {
text = AndroidUtilities.replaceSingleTag(LocaleController.getString(R.string.FwdMessageToSavedMessages), -1, AndroidUtilities.REPLACING_TAG_TYPE_LINKBOLD, SavedMessagesController::openSavedMessages);
} else {
text = AndroidUtilities.replaceSingleTag(LocaleController.getString(R.string.FwdMessagesToSavedMessages), -1, AndroidUtilities.REPLACING_TAG_TYPE_LINKBOLD, SavedMessagesController::openSavedMessages);
}
} else {
return false;
}
layout.setAnimation(R.raw.saved_messages, 36, 36);
layout.textView.setText(text);
layout.textView.setSingleLine(false);
layout.textView.setMaxLines(2);
Bulletin bulletin = create(layout, 3500);
layout.setBulletin(bulletin);
bulletin.hideAfterBottomSheet(false);
bulletin.show(true);
return true;
}
@CheckResult @CheckResult
public static Bulletin createForwardedBulletin(Context context, FrameLayout containerLayout, int dialogsCount, long did, int messagesCount, int backgroundColor, int textColor) { public static Bulletin createForwardedBulletin(Context context, FrameLayout containerLayout, int dialogsCount, long did, int messagesCount, int backgroundColor, int textColor) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(context, null, backgroundColor, textColor); final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(context, null, backgroundColor, textColor);
@ -1182,6 +1212,39 @@ public final class BulletinFactory {
layout.textView.setText(text); layout.textView.setText(text);
return Bulletin.make(fragment, layout, Bulletin.DURATION_SHORT); return Bulletin.make(fragment, layout, Bulletin.DURATION_SHORT);
} }
public Bulletin createMessagesTaggedBulletin(int messagesCount, TLRPC.Document document, Runnable onViewButton) {
final Bulletin.LottieLayout layout = new Bulletin.LottieLayout(getContext(), resourcesProvider);
layout.setAnimation(R.raw.tag_icon_3, 36, 36);
layout.removeView(layout.textView);
layout.textView = new AnimatedEmojiSpan.TextViewEmojis(layout.getContext());
layout.textView.setTypeface(Typeface.SANS_SERIF);
layout.textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
layout.textView.setEllipsize(TextUtils.TruncateAt.END);
layout.textView.setPadding(0, 0, 0, AndroidUtilities.dp(8));
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(AndroidUtilities.dp(20));
SpannableString spannable = new SpannableString("d");
spannable.setSpan(new AnimatedEmojiSpan(document, textPaint.getFontMetricsInt()), 0, spannable.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
layout.textView.setText(
new SpannableStringBuilder(messagesCount > 1 ?
LocaleController.formatPluralString("SavedTagMessagesTagged", messagesCount) :
LocaleController.getString(R.string.SavedTagMessageTagged))
.append(" ")
.append(spannable)
);
if (onViewButton != null) {
layout.setButton(new Bulletin.UndoButton(getContext(), true, resourcesProvider).setText(LocaleController.getString(R.string.ViewAction)).setUndoAction(onViewButton));
}
layout.setTextColor(Theme.getColor(Theme.key_undo_infoColor, resourcesProvider));
layout.addView(layout.textView, LayoutHelper.createFrameRelatively(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL, 56, 2, 8, 0));
return create(layout, Bulletin.DURATION_LONG);
}
//endregion //endregion
public static class UndoObject { public static class UndoObject {

View file

@ -1072,9 +1072,14 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
return super.onSetAlpha(alpha); return super.onSetAlpha(alpha);
} }
private VirtualViewHelper virtualViewHelper;
public ControlsView(Context context) { public ControlsView(Context context) {
super(context); super(context);
virtualViewHelper = new VirtualViewHelper(this);
ViewCompat.setAccessibilityDelegate(this, virtualViewHelper);
periodDrawable = new CaptionContainerView.PeriodDrawable(); periodDrawable = new CaptionContainerView.PeriodDrawable();
periodDrawable.setCallback(this); periodDrawable.setCallback(this);
periodDrawable.setValue(1, voiceOnce, false); periodDrawable.setValue(1, voiceOnce, false);
@ -1498,6 +1503,11 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
} }
} }
@Override
protected boolean dispatchHoverEvent(MotionEvent event) {
return super.dispatchHoverEvent(event) || virtualViewHelper.dispatchHoverEvent(event);
}
public void updateColors() { public void updateColors() {
periodDrawable.updateColors( periodDrawable.updateColors(
getThemedColor(Theme.key_chat_messagePanelVoiceLock), getThemedColor(Theme.key_chat_messagePanelVoiceLock),
@ -1580,6 +1590,53 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
protected boolean verifyDrawable(@NonNull Drawable who) { protected boolean verifyDrawable(@NonNull Drawable who) {
return who == periodDrawable || super.verifyDrawable(who); return who == periodDrawable || super.verifyDrawable(who);
} }
private class VirtualViewHelper extends ExploreByTouchHelper {
public VirtualViewHelper(@NonNull View host) {
super(host);
}
@Override
protected int getVirtualViewAt(float x, float y) {
if (sendButtonVisible && recordCircle != null && pauseRect.contains(x, y)) {
return 2;
}
if (onceVisible && (recordCircle != null && snapAnimationProgress > .1f) && onceRect.contains(x, y)) {
return 4;
}
return HOST_ID;
}
@Override
protected void getVisibleVirtualViews(List<Integer> list) {
if (sendButtonVisible) {
list.add(2);
}
if (onceVisible && (recordCircle != null && snapAnimationProgress > .1f)) {
list.add(4);
}
}
@Override
protected void onPopulateNodeForVirtualView(int id, @NonNull AccessibilityNodeInfoCompat info) {
if (id == 2) {
rect.set((int) pauseRect.left, (int) pauseRect.top, (int) pauseRect.right, (int) pauseRect.bottom);
info.setBoundsInParent(rect);
info.setText(LocaleController.getString(transformToSeekbar > .5f ? R.string.AccActionResume : R.string.AccActionPause));
} else if (id == 4) {
rect.set((int) onceRect.left, (int) onceRect.top, (int) onceRect.right, (int) onceRect.bottom);
info.setBoundsInParent(rect);
info.setText(LocaleController.getString(voiceOnce ? R.string.AccActionOnceDeactivate : R.string.AccActionOnceActivate));
}
}
@Override
protected boolean onPerformActionForVirtualView(int id, int action, @Nullable Bundle args) {
return true;
}
}
} }
private float scale; private float scale;
@ -2763,6 +2820,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
sendButtonContainer.addView(audioVideoButtonContainer, LayoutHelper.createFrame(48, 48)); sendButtonContainer.addView(audioVideoButtonContainer, LayoutHelper.createFrame(48, 48));
audioVideoButtonContainer.setFocusable(true); audioVideoButtonContainer.setFocusable(true);
audioVideoButtonContainer.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); audioVideoButtonContainer.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
// audioVideoButtonContainer.setOnTouchListener((view, motionEvent) -> { // audioVideoButtonContainer.setOnTouchListener((view, motionEvent) -> {
// createRecordCircle(); // createRecordCircle();
// if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { // if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
@ -2932,9 +2990,9 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
// }); // });
audioVideoSendButton = new ChatActivityEnterViewAnimatedIconView(context); audioVideoSendButton = new ChatActivityEnterViewAnimatedIconView(context);
audioVideoSendButton.setFocusable(true); audioVideoSendButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
audioVideoSendButton.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); // audioVideoSendButton.setFocusable(true);
audioVideoSendButton.setAccessibilityDelegate(mediaMessageButtonsDelegate); // audioVideoSendButton.setAccessibilityDelegate(mediaMessageButtonsDelegate);
padding = dp(9.5f); padding = dp(9.5f);
audioVideoSendButton.setPadding(padding, padding, padding, padding); audioVideoSendButton.setPadding(padding, padding, padding, padding);
audioVideoSendButton.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_messagePanelIcons), PorterDuff.Mode.SRC_IN)); audioVideoSendButton.setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_chat_messagePanelIcons), PorterDuff.Mode.SRC_IN));
@ -4165,7 +4223,7 @@ public class ChatActivityEnterView extends BlurredFrameLayout implements Notific
if (sendWhenOnlineButton != null) { if (sendWhenOnlineButton != null) {
TLRPC.User user = parentFragment.getCurrentUser(); TLRPC.User user = parentFragment.getCurrentUser();
if (user != null && !user.bot && !(user.status instanceof TLRPC.TL_userStatusEmpty) && !(user.status instanceof TLRPC.TL_userStatusOnline) && !(user.status instanceof TLRPC.TL_userStatusRecently)) { if (user != null && !user.bot && !(user.status instanceof TLRPC.TL_userStatusEmpty) && !(user.status instanceof TLRPC.TL_userStatusOnline) && !(user.status instanceof TLRPC.TL_userStatusRecently) && !(user.status instanceof TLRPC.TL_userStatusLastMonth) && !(user.status instanceof TLRPC.TL_userStatusLastWeek)) {
sendWhenOnlineButton.setVisibility(VISIBLE); sendWhenOnlineButton.setVisibility(VISIBLE);
} else { } else {
sendWhenOnlineButton.setVisibility(GONE); sendWhenOnlineButton.setVisibility(GONE);

View file

@ -25,6 +25,7 @@ import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView; import android.widget.ImageView;
@ -298,7 +299,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
} }
if (parentFragment != null && (parentFragment.getChatMode() == 0 || parentFragment.getChatMode() == ChatActivity.MODE_SAVED)) { if (parentFragment != null && (parentFragment.getChatMode() == 0 || parentFragment.getChatMode() == ChatActivity.MODE_SAVED)) {
if ((!parentFragment.isThreadChat() || parentFragment.isTopic) && !UserObject.isReplyUser(parentFragment.getCurrentUser()) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) { if ((!parentFragment.isThreadChat() || parentFragment.isTopic) && !UserObject.isReplyUser(parentFragment.getCurrentUser())) {
setOnClickListener(v -> openProfile(false)); setOnClickListener(v -> openProfile(false));
} }
@ -315,6 +316,62 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
} }
emojiStatusDrawable = new AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable(titleTextView, AndroidUtilities.dp(24)); emojiStatusDrawable = new AnimatedEmojiDrawable.SwapAnimatedEmojiDrawable(titleTextView, AndroidUtilities.dp(24));
setOnLongClickListener(v -> {
if (canSearch()) {
openSearch();
return true;
}
return false;
});
}
private ButtonBounce bounce = new ButtonBounce(this);
private Runnable onLongClick = () -> {
pressed = false;
bounce.setPressed(false);
if (canSearch()) {
openSearch();
}
};
private boolean pressed;
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN && canSearch()) {
pressed = true;
bounce.setPressed(true);
AndroidUtilities.cancelRunOnUIThread(this.onLongClick);
AndroidUtilities.runOnUIThread(this.onLongClick, ViewConfiguration.getLongPressTimeout());
return true;
} else if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
if (pressed) {
bounce.setPressed(false);
pressed = false;
if (isClickable()) {
openProfile(false);
}
AndroidUtilities.cancelRunOnUIThread(this.onLongClick);
}
}
return super.onTouchEvent(ev);
}
@Override
protected void dispatchDraw(Canvas canvas) {
canvas.save();
final float s = bounce.getScale(.02f);
canvas.scale(s, s, getWidth() / 2f, getHeight() / 2f);
super.dispatchDraw(canvas);
canvas.restore();
}
protected boolean canSearch() {
return false;
}
protected void openSearch() {
} }
protected boolean onAvatarClick() { protected boolean onAvatarClick() {
@ -406,10 +463,10 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
} }
public void openProfile(boolean byAvatar) { public void openProfile(boolean byAvatar) {
openProfile(byAvatar, true); openProfile(byAvatar, true, false);
} }
public void openProfile(boolean byAvatar, boolean fromChatAnimation) { public void openProfile(boolean byAvatar, boolean fromChatAnimation, boolean removeLast) {
if (byAvatar && (AndroidUtilities.isTablet() || AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y || !avatarImageView.getImageReceiver().hasNotThumb())) { if (byAvatar && (AndroidUtilities.isTablet() || AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y || !avatarImageView.getImageReceiver().hasNotThumb())) {
byAvatar = false; byAvatar = false;
} }
@ -427,13 +484,17 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (user != null) { if (user != null) {
Bundle args = new Bundle(); Bundle args = new Bundle();
if (UserObject.isUserSelf(user) && parentFragment.getChatMode() != ChatActivity.MODE_SAVED) { if (UserObject.isUserSelf(user)) {
if (!sharedMediaPreloader.hasSharedMedia()) {
return;
}
args.putLong("dialog_id", parentFragment.getDialogId()); args.putLong("dialog_id", parentFragment.getDialogId());
int[] media = new int[MediaDataController.MEDIA_TYPES_COUNT]; if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
System.arraycopy(sharedMediaPreloader.getLastMediaCount(), 0, media, 0, media.length); args.putLong("topic_id", parentFragment.getSavedDialogId());
}
MediaActivity fragment = new MediaActivity(args, sharedMediaPreloader); MediaActivity fragment = new MediaActivity(args, sharedMediaPreloader);
fragment.setChatInfo(parentFragment.getCurrentChatInfo()); fragment.setChatInfo(parentFragment.getCurrentChatInfo());
parentFragment.presentFragment(fragment); parentFragment.presentFragment(fragment, removeLast);
} else { } else {
if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) { if (parentFragment.getChatMode() == ChatActivity.MODE_SAVED) {
long dialogId = parentFragment.getSavedDialogId(); long dialogId = parentFragment.getSavedDialogId();
@ -456,7 +517,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (fromChatAnimation) { if (fromChatAnimation) {
fragment.setPlayProfileAnimation(byAvatar ? 2 : 1); fragment.setPlayProfileAnimation(byAvatar ? 2 : 1);
} }
parentFragment.presentFragment(fragment); parentFragment.presentFragment(fragment, removeLast);
} }
} else if (chat != null) { } else if (chat != null) {
Bundle args = new Bundle(); Bundle args = new Bundle();
@ -471,7 +532,7 @@ public class ChatAvatarContainer extends FrameLayout implements NotificationCent
if (fromChatAnimation) { if (fromChatAnimation) {
fragment.setPlayProfileAnimation(byAvatar ? 2 : 1); fragment.setPlayProfileAnimation(byAvatar ? 2 : 1);
} }
parentFragment.presentFragment(fragment); parentFragment.presentFragment(fragment, removeLast);
} }
} }

View file

@ -95,7 +95,7 @@ public class ChatGreetingsView extends LinearLayout {
} }
} }
private ImageView premiumIconView; private RLottieImageView premiumIconView;
private TextView premiumTextView; private TextView premiumTextView;
private TextView premiumButtonView; private TextView premiumButtonView;
@ -105,12 +105,17 @@ public class ChatGreetingsView extends LinearLayout {
premiumLock = lock; premiumLock = lock;
if (premiumLock) { if (premiumLock) {
if (premiumIconView == null) { if (premiumIconView == null) {
premiumIconView = new ImageView(getContext()); premiumIconView = new RLottieImageView(getContext());
premiumIconView.setScaleType(ImageView.ScaleType.CENTER); premiumIconView.setScaleType(ImageView.ScaleType.CENTER);
premiumIconView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN)); premiumIconView.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
premiumIconView.setBackground(Theme.createCircleDrawable(dp(78), 0x1c000000)); premiumIconView.setBackground(Theme.createCircleDrawable(dp(78), 0x1c000000));
premiumIconView.setImageResource(R.drawable.large_message_lock); premiumIconView.setAnimation(R.raw.large_message_lock, 80, 80);
premiumIconView.setOnClickListener(v -> {
premiumIconView.setProgress(0);
premiumIconView.playAnimation();
});
} }
premiumIconView.playAnimation();
if (premiumTextView == null) { if (premiumTextView == null) {
premiumTextView = new TextView(getContext()); premiumTextView = new TextView(getContext());
premiumTextView.setTextAlignment(TEXT_ALIGNMENT_CENTER); premiumTextView.setTextAlignment(TEXT_ALIGNMENT_CENTER);

View file

@ -1,6 +1,9 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.content.Context; import android.content.Context;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -25,6 +28,11 @@ public class ChatScrimPopupContainerLayout extends LinearLayout {
setOrientation(LinearLayout.VERTICAL); setOrientation(LinearLayout.VERTICAL);
} }
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (maxHeight != 0) { if (maxHeight != 0) {
@ -46,20 +54,27 @@ public class ChatScrimPopupContainerLayout extends LinearLayout {
if (reactionsLayout.showCustomEmojiReaction()) { if (reactionsLayout.showCustomEmojiReaction()) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY); widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.EXACTLY);
} }
reactionsLayout.measureHint();
int reactionsLayoutTotalWidth = reactionsLayout.getTotalWidth(); int reactionsLayoutTotalWidth = reactionsLayout.getTotalWidth();
View menuContainer = popupWindowLayout.getSwipeBack() != null ? popupWindowLayout.getSwipeBack().getChildAt(0) : popupWindowLayout.getChildAt(0); View menuContainer = popupWindowLayout.getSwipeBack() != null ? popupWindowLayout.getSwipeBack().getChildAt(0) : popupWindowLayout.getChildAt(0);
int maxReactionsLayoutWidth = menuContainer.getMeasuredWidth() + AndroidUtilities.dp(16) + AndroidUtilities.dp(16) + AndroidUtilities.dp(36); int maxReactionsLayoutWidth = menuContainer.getMeasuredWidth() + dp(16) + dp(16) + dp(36);
if (maxReactionsLayoutWidth > maxWidth) { int hintTextWidth = reactionsLayout.getHintTextWidth();
if (hintTextWidth > maxReactionsLayoutWidth) {
maxReactionsLayoutWidth = hintTextWidth;
} else if (maxReactionsLayoutWidth > maxWidth) {
maxReactionsLayoutWidth = maxWidth; maxReactionsLayoutWidth = maxWidth;
} }
reactionsLayout.bigCircleOffset = AndroidUtilities.dp(36); reactionsLayout.bigCircleOffset = dp(36);
if (reactionsLayout.showCustomEmojiReaction()) { if (reactionsLayout.showCustomEmojiReaction()) {
reactionsLayout.getLayoutParams().width = reactionsLayoutTotalWidth; reactionsLayout.getLayoutParams().width = reactionsLayoutTotalWidth;
reactionsLayout.bigCircleOffset = Math.max(reactionsLayoutTotalWidth - menuContainer.getMeasuredWidth() - AndroidUtilities.dp(36), AndroidUtilities.dp(36)); reactionsLayout.bigCircleOffset = Math.max(reactionsLayoutTotalWidth - menuContainer.getMeasuredWidth() - dp(36), dp(36));
} else if (reactionsLayoutTotalWidth > maxReactionsLayoutWidth) { } else if (reactionsLayoutTotalWidth > maxReactionsLayoutWidth) {
int maxFullCount = ((maxReactionsLayoutWidth - AndroidUtilities.dp(16)) / AndroidUtilities.dp(36)) + 1; int maxFullCount = ((maxReactionsLayoutWidth - dp(16)) / dp(36)) + 1;
int newWidth = maxFullCount * AndroidUtilities.dp(36) + AndroidUtilities.dp(16) - AndroidUtilities.dp(8); int newWidth = maxFullCount * dp(36) + dp(8);
if (hintTextWidth + dp(24) > newWidth) {
newWidth = hintTextWidth + dp(24);
}
if (newWidth > reactionsLayoutTotalWidth || maxFullCount == reactionsLayout.getItemsCount()) { if (newWidth > reactionsLayoutTotalWidth || maxFullCount == reactionsLayout.getItemsCount()) {
newWidth = reactionsLayoutTotalWidth; newWidth = reactionsLayoutTotalWidth;
} }
@ -73,7 +88,7 @@ public class ChatScrimPopupContainerLayout extends LinearLayout {
widthDiff = popupWindowLayout.getSwipeBack().getMeasuredWidth() - popupWindowLayout.getSwipeBack().getChildAt(0).getMeasuredWidth(); widthDiff = popupWindowLayout.getSwipeBack().getMeasuredWidth() - popupWindowLayout.getSwipeBack().getChildAt(0).getMeasuredWidth();
} }
if (reactionsLayout.getLayoutParams().width != LayoutHelper.WRAP_CONTENT && reactionsLayout.getLayoutParams().width + widthDiff > maxWidth) { if (reactionsLayout.getLayoutParams().width != LayoutHelper.WRAP_CONTENT && reactionsLayout.getLayoutParams().width + widthDiff > maxWidth) {
widthDiff = maxWidth - reactionsLayout.getLayoutParams().width + AndroidUtilities.dp(8); widthDiff = maxWidth - reactionsLayout.getLayoutParams().width + dp(8);
} }
if (widthDiff < 0) { if (widthDiff < 0) {
widthDiff = 0; widthDiff = 0;
@ -84,23 +99,23 @@ public class ChatScrimPopupContainerLayout extends LinearLayout {
} else { } else {
popupLayoutLeftOffset = (maxWidth - menuContainer.getMeasuredWidth()) * 0.25f; popupLayoutLeftOffset = (maxWidth - menuContainer.getMeasuredWidth()) * 0.25f;
reactionsLayout.bigCircleOffset -= popupLayoutLeftOffset; reactionsLayout.bigCircleOffset -= popupLayoutLeftOffset;
if (reactionsLayout.bigCircleOffset < AndroidUtilities.dp(36)) { if (reactionsLayout.bigCircleOffset < dp(36)) {
popupLayoutLeftOffset = 0; popupLayoutLeftOffset = 0;
reactionsLayout.bigCircleOffset = AndroidUtilities.dp(36); reactionsLayout.bigCircleOffset = dp(36);
} }
updatePopupTranslation(); updatePopupTranslation();
} }
if (bottomView != null) { if (bottomView != null) {
if (reactionsLayout.showCustomEmojiReaction()) { if (reactionsLayout.showCustomEmojiReaction()) {
bottomView.getLayoutParams().width = menuContainer.getMeasuredWidth() + AndroidUtilities.dp(16); bottomView.getLayoutParams().width = menuContainer.getMeasuredWidth() + dp(16);
updatePopupTranslation(); updatePopupTranslation();
} else { } else {
bottomView.getLayoutParams().width = LayoutHelper.MATCH_PARENT; bottomView.getLayoutParams().width = LayoutHelper.MATCH_PARENT;
} }
if (popupWindowLayout.getSwipeBack() != null) { if (popupWindowLayout.getSwipeBack() != null) {
((LayoutParams) bottomView.getLayoutParams()).rightMargin = widthDiff + AndroidUtilities.dp(36); ((LayoutParams) bottomView.getLayoutParams()).rightMargin = widthDiff + dp(36);
} else { } else {
((LayoutParams) bottomView.getLayoutParams()).rightMargin = AndroidUtilities.dp(36); ((LayoutParams) bottomView.getLayoutParams()).rightMargin = dp(36);
} }
} }
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec);

View file

@ -12,6 +12,7 @@ import android.text.Layout;
import android.text.SpannableStringBuilder; import android.text.SpannableStringBuilder;
import android.text.StaticLayout; import android.text.StaticLayout;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.view.animation.OvershootInterpolator; import android.view.animation.OvershootInterpolator;
@ -82,9 +83,11 @@ public class CounterView extends View {
public boolean addServiceGradient; public boolean addServiceGradient;
int currentCount; int currentCount;
CharSequence currentText;
private boolean countAnimationIncrement; private boolean countAnimationIncrement;
private ValueAnimator countAnimator; private ValueAnimator countAnimator;
public float countChangeProgress = 1f; public float countChangeProgress = 1f;
private float countLayoutWidth;
private StaticLayout countLayout; private StaticLayout countLayout;
private StaticLayout countOldLayout; private StaticLayout countOldLayout;
private StaticLayout countAnimationStableLayout; private StaticLayout countAnimationStableLayout;
@ -172,7 +175,15 @@ public class CounterView extends View {
} }
public void setCount(int count, boolean animated) { public void setCount(int count, boolean animated) {
if (count == currentCount) { setText(getStringOfCCount(count), animated, count, false);
}
public void setText(CharSequence text, boolean animated) {
setText(text, animated, 1, true);
}
public void setText(CharSequence text, boolean animated, int count, boolean isText) {
if (TextUtils.equals(text, currentText)) {
return; return;
} }
if (countAnimator != null) { if (countAnimator != null) {
@ -186,21 +197,23 @@ public class CounterView extends View {
} }
if (!animated) { if (!animated) {
currentCount = count; currentCount = count;
currentText = text;
if (count == 0) { if (count == 0) {
if (updateVisibility && parent != null) { if (updateVisibility && parent != null) {
parent.setVisibility(View.GONE); parent.setVisibility(View.GONE);
} }
return; return;
} }
String newStr = getStringOfCCount(count); CharSequence newStr = text; // getStringOfCCount(count);
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(newStr))); countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(newStr.toString())));
countLayout = new StaticLayout(newStr, textPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); countLayout = new StaticLayout(newStr, textPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
countLayoutWidth = countLayout.getLineCount() >= 1 ? countLayout.getLineWidth(0) : 0;
if (parent != null) { if (parent != null) {
parent.invalidate(); parent.invalidate();
} }
return; return;
} }
String newStr = getStringOfCCount(count); CharSequence newStr = text; // getStringOfCCount(count);
if (animated) { if (animated) {
if (countAnimator != null) { if (countAnimator != null) {
@ -244,9 +257,9 @@ public class CounterView extends View {
countAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT); countAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
} }
if (countLayout != null) { if (countLayout != null) {
String oldStr = getStringOfCCount(currentCount); CharSequence oldStr = currentText; // getStringOfCCount(currentCount);
if (oldStr.length() == newStr.length()) { if (oldStr.length() == newStr.length() && !isText) {
SpannableStringBuilder oldSpannableStr = new SpannableStringBuilder(oldStr); SpannableStringBuilder oldSpannableStr = new SpannableStringBuilder(oldStr);
SpannableStringBuilder newSpannableStr = new SpannableStringBuilder(newStr); SpannableStringBuilder newSpannableStr = new SpannableStringBuilder(newStr);
SpannableStringBuilder stableStr = new SpannableStringBuilder(newStr); SpannableStringBuilder stableStr = new SpannableStringBuilder(newStr);
@ -259,7 +272,7 @@ public class CounterView extends View {
} }
} }
int countOldWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(oldStr))); int countOldWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(oldStr.toString())));
countOldLayout = new StaticLayout(oldSpannableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); countOldLayout = new StaticLayout(oldSpannableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
countAnimationStableLayout = new StaticLayout(stableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); countAnimationStableLayout = new StaticLayout(stableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
countAnimationInLayout = new StaticLayout(newSpannableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); countAnimationInLayout = new StaticLayout(newSpannableStr, textPaint, countOldWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
@ -272,16 +285,22 @@ public class CounterView extends View {
countAnimator.start(); countAnimator.start();
} }
if (count > 0) { if (count > 0) {
countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(newStr))); countWidth = Math.max(AndroidUtilities.dp(12), (int) Math.ceil(textPaint.measureText(newStr.toString())));
countLayout = new StaticLayout(newStr, textPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false); countLayout = new StaticLayout(newStr, textPaint, countWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
countLayoutWidth = countLayout.getLineCount() >= 1 ? countLayout.getLineWidth(0) : 0;
} }
currentCount = count; currentCount = count;
currentText = newStr;
if (parent != null) { if (parent != null) {
parent.invalidate(); parent.invalidate();
} }
} }
public int getCurrentWidth() {
return (int) Math.ceil(countLayoutWidth);
}
private String getStringOfCCount(int count) { private String getStringOfCCount(int count) {
if (shortFormat) { if (shortFormat) {
return AndroidUtilities.formatWholeNumber(count, 0); return AndroidUtilities.formatWholeNumber(count, 0);

View file

@ -651,6 +651,7 @@ public class EditTextBoldCursor extends EditTextEffects {
} }
} }
hintLayout = new StaticLayout(text, paint, AndroidUtilities.dp(1000), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false); hintLayout = new StaticLayout(text, paint, AndroidUtilities.dp(1000), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
invalidate();
} }
} }

View file

@ -269,35 +269,23 @@ public class EditTextCaption extends EditTextBoldCursor {
AndroidUtilities.showKeyboard(editText); AndroidUtilities.showKeyboard(editText);
}); });
creationLinkDialog.showDelayed(250); creationLinkDialog.showDelayed(250);
if (editText != null) {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams();
if (layoutParams != null) {
if (layoutParams instanceof FrameLayout.LayoutParams) {
((FrameLayout.LayoutParams) layoutParams).gravity = Gravity.CENTER_HORIZONTAL;
}
layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(24);
layoutParams.height = AndroidUtilities.dp(36);
editText.setLayoutParams(layoutParams);
}
editText.setSelection(0, editText.getText().length());
}
} else { } else {
builder.show().setOnShowListener(dialog -> { builder.show().setOnShowListener(dialog -> {
editText.requestFocus(); editText.requestFocus();
AndroidUtilities.showKeyboard(editText); AndroidUtilities.showKeyboard(editText);
}); });
if (editText != null) { }
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams(); if (editText != null) {
if (layoutParams != null) { ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) editText.getLayoutParams();
if (layoutParams instanceof FrameLayout.LayoutParams) { if (layoutParams != null) {
((FrameLayout.LayoutParams) layoutParams).gravity = Gravity.CENTER_HORIZONTAL; if (layoutParams instanceof FrameLayout.LayoutParams) {
} ((FrameLayout.LayoutParams) layoutParams).gravity = Gravity.CENTER_HORIZONTAL;
layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(24);
layoutParams.height = AndroidUtilities.dp(36);
editText.setLayoutParams(layoutParams);
} }
editText.setSelection(0, editText.getText().length()); layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(24);
layoutParams.height = AndroidUtilities.dp(36);
editText.setLayoutParams(layoutParams);
} }
editText.setSelection(0, editText.getText().length());
} }
} }

View file

@ -476,6 +476,10 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not
editText.setSelection(selection); editText.setSelection(selection);
} }
public void setSelection(int from, int to) {
editText.setSelection(from, to);
}
public void hidePopup(boolean byBackButton) { public void hidePopup(boolean byBackButton) {
if (isPopupShowing()) { if (isPopupShowing()) {
showPopup(0); showPopup(0);
@ -521,6 +525,7 @@ public class EditTextEmoji extends FrameLayout implements NotificationCenter.Not
} }
public void openKeyboard() { public void openKeyboard() {
editText.requestFocus();
AndroidUtilities.showKeyboard(editText); AndroidUtilities.showKeyboard(editText);
} }

View file

@ -1648,7 +1648,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
break; break;
case DO_SHUTDOWN_MESSAGE: case DO_SHUTDOWN_MESSAGE:
finish(); finish();
if (recording && inputMessage.arg2 != -2) { if (recording && inputMessage.arg2 != -2 && videoEncoder != null) {
videoEncoder.stopRecording(inputMessage.arg1, inputMessage.arg2); videoEncoder.stopRecording(inputMessage.arg1, inputMessage.arg2);
} }
Looper looper = Looper.myLooper(); Looper looper = Looper.myLooper();

View file

@ -80,6 +80,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
private TLRPC.ChatFull currentChatInfo; private TLRPC.ChatFull currentChatInfo;
private TLRPC.UserFull currentUserInfo; private TLRPC.UserFull currentUserInfo;
private long dialogId; private long dialogId;
private long topicId;
private FrameLayout titlesContainer; private FrameLayout titlesContainer;
private FrameLayout[] titles = new FrameLayout[2]; private FrameLayout[] titles = new FrameLayout[2];
private SimpleTextView[] nameTextView = new SimpleTextView[2]; private SimpleTextView[] nameTextView = new SimpleTextView[2];
@ -116,6 +117,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
public boolean onFragmentCreate() { public boolean onFragmentCreate() {
type = getArguments().getInt("type", TYPE_MEDIA); type = getArguments().getInt("type", TYPE_MEDIA);
dialogId = getArguments().getLong("dialog_id"); dialogId = getArguments().getLong("dialog_id");
topicId = getArguments().getLong("topic_id", 0);
int defaultTab = SharedMediaLayout.TAB_PHOTOVIDEO; int defaultTab = SharedMediaLayout.TAB_PHOTOVIDEO;
if (type == TYPE_ARCHIVED_CHANNEL_STORIES) { if (type == TYPE_ARCHIVED_CHANNEL_STORIES) {
defaultTab = SharedMediaLayout.TAB_ARCHIVED_STORIES; defaultTab = SharedMediaLayout.TAB_ARCHIVED_STORIES;
@ -126,7 +128,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
getNotificationCenter().addObserver(this, NotificationCenter.userInfoDidLoad); getNotificationCenter().addObserver(this, NotificationCenter.userInfoDidLoad);
getNotificationCenter().addObserver(this, NotificationCenter.currentUserPremiumStatusChanged); getNotificationCenter().addObserver(this, NotificationCenter.currentUserPremiumStatusChanged);
getNotificationCenter().addObserver(this, NotificationCenter.storiesEnabledUpdate); getNotificationCenter().addObserver(this, NotificationCenter.storiesEnabledUpdate);
if (DialogObject.isUserDialog(dialogId)) { if (DialogObject.isUserDialog(dialogId) && topicId == 0) {
TLRPC.User user = getMessagesController().getUser(dialogId); TLRPC.User user = getMessagesController().getUser(dialogId);
if (UserObject.isUserSelf(user)) { if (UserObject.isUserSelf(user)) {
getMessagesController().loadUserInfo(user, false, this.classGuid); getMessagesController().loadUserInfo(user, false, this.classGuid);
@ -210,10 +212,12 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
} }
} else if (id == 10) { } else if (id == 10) {
sharedMediaLayout.showMediaCalendar(sharedMediaLayout.getClosestTab(), false); sharedMediaLayout.showMediaCalendar(sharedMediaLayout.getClosestTab(), false);
} else if (id == 11) {
sharedMediaLayout.closeActionMode(true);
sharedMediaLayout.getSearchItem().openSearch(false);
} }
} }
}); });
actionBar.setColorFilterMode(PorterDuff.Mode.SRC_IN);
FrameLayout avatarContainer = new FrameLayout(context); FrameLayout avatarContainer = new FrameLayout(context);
SizeNotifierFrameLayout fragmentView = new SizeNotifierFrameLayout(context) { SizeNotifierFrameLayout fragmentView = new SizeNotifierFrameLayout(context) {
@ -386,7 +390,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
} }
}; };
avatarImageView.getImageReceiver().setAllowDecodeSingleFrame(true); avatarImageView.getImageReceiver().setAllowDecodeSingleFrame(true);
avatarImageView.setRoundRadius(dp(21)); avatarImageView.setRoundRadius(dp(getDialogId() == getUserConfig().getClientUserId() && topicId == 0 && getMessagesController().savedViewAsChats ? 13 : 21));
avatarImageView.setPivotX(0); avatarImageView.setPivotX(0);
avatarImageView.setPivotY(0); avatarImageView.setPivotY(0);
AvatarDrawable avatarDrawable = new AvatarDrawable(); AvatarDrawable avatarDrawable = new AvatarDrawable();
@ -537,7 +541,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
hideFloatingButton(true, false); hideFloatingButton(true, false);
} }
if (type == TYPE_MEDIA && dialogId == getUserConfig().getClientUserId() && !getMessagesController().getSavedMessagesController().unsupported && getMessagesController().getSavedMessagesController().getAllCount() > 0) { if (type == TYPE_MEDIA && dialogId == getUserConfig().getClientUserId() && topicId == 0 && !getMessagesController().getSavedMessagesController().unsupported && getMessagesController().getSavedMessagesController().hasDialogs()) {
initialTab = SharedMediaLayout.TAB_SAVED_DIALOGS; initialTab = SharedMediaLayout.TAB_SAVED_DIALOGS;
} }
sharedMediaLayout = new SharedMediaLayout(context, dialogId, sharedMediaPreloader, 0, null, currentChatInfo, currentUserInfo, initialTab, this, new SharedMediaLayout.Delegate() { sharedMediaLayout = new SharedMediaLayout(context, dialogId, sharedMediaPreloader, 0, null, currentChatInfo, currentUserInfo, initialTab, this, new SharedMediaLayout.Delegate() {
@ -616,7 +620,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
@Override @Override
protected boolean includeSavedDialogs() { protected boolean includeSavedDialogs() {
return type == TYPE_MEDIA && dialogId == getUserConfig().getClientUserId(); return type == TYPE_MEDIA && dialogId == getUserConfig().getClientUserId() && topicId == 0;
} }
@Override @Override
@ -752,9 +756,15 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
} }
} }
}; };
if (sharedMediaLayout.getSearchOptionsItem() != null) {
sharedMediaLayout.getSearchOptionsItem().setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_windowBackgroundWhiteBlackText), PorterDuff.Mode.MULTIPLY));
}
sharedMediaLayout.setPinnedToTop(true); sharedMediaLayout.setPinnedToTop(true);
sharedMediaLayout.getSearchItem().setTranslationY(0); sharedMediaLayout.getSearchItem().setTranslationY(0);
sharedMediaLayout.photoVideoOptionsItem.setTranslationY(0); sharedMediaLayout.photoVideoOptionsItem.setTranslationY(0);
if (sharedMediaLayout.getSearchOptionsItem() != null) {
sharedMediaLayout.getSearchOptionsItem().setTranslationY(0);
}
if (type == TYPE_STORIES || type == TYPE_ARCHIVED_CHANNEL_STORIES) { if (type == TYPE_STORIES || type == TYPE_ARCHIVED_CHANNEL_STORIES) {
fragmentView.addView(sharedMediaLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL, 0, 0, 0, 64)); fragmentView.addView(sharedMediaLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.FILL, 0, 0, 0, 64));
@ -779,14 +789,26 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
fragmentView.addView(buttonContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 64, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL)); fragmentView.addView(buttonContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 64, Gravity.BOTTOM | Gravity.FILL_HORIZONTAL));
} }
long avatarDialogId = dialogId;
if (topicId != 0 && dialogId == getUserConfig().getClientUserId()) {
avatarDialogId = topicId;
}
TLObject avatarObject = null; TLObject avatarObject = null;
if (type == TYPE_ARCHIVED_CHANNEL_STORIES) { if (type == TYPE_ARCHIVED_CHANNEL_STORIES) {
nameTextView[0].setText(LocaleController.getString("ProfileStoriesArchive")); nameTextView[0].setText(LocaleController.getString("ProfileStoriesArchive"));
} else if (type == TYPE_STORIES) { } else if (type == TYPE_STORIES) {
nameTextView[0].setText(LocaleController.getString("ProfileMyStories")); nameTextView[0].setText(LocaleController.getString("ProfileMyStories"));
nameTextView[1].setText(LocaleController.getString("ProfileStoriesArchive")); nameTextView[1].setText(LocaleController.getString("ProfileStoriesArchive"));
} else if (DialogObject.isEncryptedDialog(dialogId)) { } else if (avatarDialogId == UserObject.ANONYMOUS) {
TLRPC.EncryptedChat encryptedChat = getMessagesController().getEncryptedChat(DialogObject.getEncryptedChatId(dialogId)); nameTextView[0].setText(LocaleController.getString(R.string.AnonymousForward));
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_ANONYMOUS);
avatarDrawable.setScaleSize(.75f);
} else if (topicId != 0 && avatarDialogId == getUserConfig().getClientUserId()) {
nameTextView[0].setText(LocaleController.getString(R.string.MyNotes));
avatarDrawable.setAvatarType(AvatarDrawable.AVATAR_TYPE_MY_NOTES);
avatarDrawable.setScaleSize(.75f);
} else if (DialogObject.isEncryptedDialog(avatarDialogId)) {
TLRPC.EncryptedChat encryptedChat = getMessagesController().getEncryptedChat(DialogObject.getEncryptedChatId(avatarDialogId));
if (encryptedChat != null) { if (encryptedChat != null) {
TLRPC.User user = getMessagesController().getUser(encryptedChat.user_id); TLRPC.User user = getMessagesController().getUser(encryptedChat.user_id);
if (user != null) { if (user != null) {
@ -795,8 +817,8 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
avatarObject = user; avatarObject = user;
} }
} }
} else if (DialogObject.isUserDialog(dialogId)) { } else if (DialogObject.isUserDialog(avatarDialogId)) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(dialogId); TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(avatarDialogId);
if (user != null) { if (user != null) {
if (user.self) { if (user.self) {
nameTextView[0].setText(LocaleController.getString("SavedMessages", R.string.SavedMessages)); nameTextView[0].setText(LocaleController.getString("SavedMessages", R.string.SavedMessages));
@ -809,7 +831,7 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
} }
} }
} else { } else {
TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-dialogId); TLRPC.Chat chat = MessagesController.getInstance(currentAccount).getChat(-avatarDialogId);
if (chat != null) { if (chat != null) {
nameTextView[0].setText(chat.title); nameTextView[0].setText(chat.title);
avatarDrawable.setInfo(currentAccount, chat); avatarDrawable.setInfo(currentAccount, chat);
@ -827,6 +849,13 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
if (sharedMediaLayout.isSearchItemVisible() && type != TYPE_STORIES) { if (sharedMediaLayout.isSearchItemVisible() && type != TYPE_STORIES) {
sharedMediaLayout.getSearchItem().setVisibility(View.VISIBLE); sharedMediaLayout.getSearchItem().setVisibility(View.VISIBLE);
} }
if (sharedMediaLayout.searchItemIcon != null && initialTab != SharedMediaLayout.TAB_SAVED_DIALOGS) {
sharedMediaLayout.searchItemIcon.setVisibility(View.GONE);
}
if (sharedMediaLayout.getSearchOptionsItem() != null && type != TYPE_STORIES) {
sharedMediaLayout.animateSearchToOptions(!sharedMediaLayout.isSearchItemVisible(), false);
sharedMediaLayout.getSearchOptionsItem().setVisibility(View.VISIBLE);
}
if (sharedMediaLayout.isCalendarItemVisible() && type != TYPE_STORIES) { if (sharedMediaLayout.isCalendarItemVisible() && type != TYPE_STORIES) {
sharedMediaLayout.photoVideoOptionsItem.setVisibility(View.VISIBLE); sharedMediaLayout.photoVideoOptionsItem.setVisibility(View.VISIBLE);
} else { } else {
@ -1114,8 +1143,12 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
private void updateColors() { private void updateColors() {
if (sharedMediaLayout.getSearchOptionsItem() != null) {
sharedMediaLayout.getSearchOptionsItem().setColorFilter(new PorterDuffColorFilter(getThemedColor(Theme.key_windowBackgroundWhiteBlackText), PorterDuff.Mode.MULTIPLY));
}
actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite)); actionBar.setBackgroundColor(Theme.getColor(Theme.key_windowBackgroundWhite));
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), false); actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), false);
actionBar.setItemsColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText), true);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), false); actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), false);
actionBar.setTitleColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); actionBar.setTitleColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
nameTextView[0].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText)); nameTextView[0].setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText));
@ -1160,11 +1193,9 @@ public class MediaActivity extends BaseFragment implements SharedMediaLayout.Sha
} }
private class StoriesTabsView extends BottomPagerTabs { private class StoriesTabsView extends BottomPagerTabs {
public StoriesTabsView(Context context, Theme.ResourcesProvider resourcesProvider) { public StoriesTabsView(Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, resourcesProvider); super(context, resourcesProvider);
} }
@Override @Override
public Tab[] createTabs() { public Tab[] createTabs() {
Tab[] tabs = new Tab[] { Tab[] tabs = new Tab[] {

View file

@ -693,7 +693,7 @@ public class MessagePreviewView extends FrameLayout {
MessageObject message = messages.previewMessages.get(position); MessageObject message = messages.previewMessages.get(position);
MessageObject.GroupedMessages group = getValidGroupedMessage(message); MessageObject.GroupedMessages group = getValidGroupedMessage(message);
if (group != null) { if (group != null) {
MessageObject.GroupedMessagePosition pos = group.positions.get(message); MessageObject.GroupedMessagePosition pos = group.getPosition(message);
if (pos.minX == pos.maxX || pos.minY != pos.maxY || pos.minY == 0) { if (pos.minX == pos.maxX || pos.minY != pos.maxY || pos.minY == 0) {
return false; return false;
} }
@ -733,7 +733,7 @@ public class MessagePreviewView extends FrameLayout {
MessageObject message = messages.previewMessages.get(idx); MessageObject message = messages.previewMessages.get(idx);
MessageObject.GroupedMessages groupedMessages = getValidGroupedMessage(message); MessageObject.GroupedMessages groupedMessages = getValidGroupedMessage(message);
if (groupedMessages != null) { if (groupedMessages != null) {
return groupedMessages.positions.get(message).spanSize; return groupedMessages.getPosition(message).spanSize;
} }
} }
return 1000; return 1000;
@ -1691,7 +1691,7 @@ public class MessagePreviewView extends FrameLayout {
MessageObject.GroupedMessages groupedMessages = null; MessageObject.GroupedMessages groupedMessages = null;
if (message.getGroupId() != 0) { if (message.getGroupId() != 0) {
groupedMessages = messages.groupedMessagesMap.get(message.getGroupId()); groupedMessages = messages.groupedMessagesMap.get(message.getGroupId());
if (groupedMessages != null && (groupedMessages.messages.size() <= 1 || groupedMessages.positions.get(message) == null)) { if (groupedMessages != null && (groupedMessages.messages.size() <= 1 || groupedMessages.getPosition(message) == null)) {
groupedMessages = null; groupedMessages = null;
} }
} }

View file

@ -43,6 +43,8 @@ import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.Stories.recorder.ButtonWithCounterView; import org.telegram.ui.Stories.recorder.ButtonWithCounterView;
import org.telegram.ui.Stories.recorder.HintView2; import org.telegram.ui.Stories.recorder.HintView2;
import java.util.Date;
public class MessagePrivateSeenView extends FrameLayout { public class MessagePrivateSeenView extends FrameLayout {
private final int currentAccount; private final int currentAccount;
@ -57,12 +59,15 @@ public class MessagePrivateSeenView extends FrameLayout {
private final int messageId; private final int messageId;
private final Runnable dismiss; private final Runnable dismiss;
private final int messageDiff;
public MessagePrivateSeenView(Context context, @NonNull MessageObject messageObject, Runnable dismiss, Theme.ResourcesProvider resourcesProvider) { public MessagePrivateSeenView(Context context, @NonNull MessageObject messageObject, Runnable dismiss, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
currentAccount = messageObject.currentAccount; currentAccount = messageObject.currentAccount;
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
this.dismiss = dismiss; this.dismiss = dismiss;
messageDiff = ConnectionsManager.getInstance(currentAccount).getCurrentTime() - messageObject.messageOwner.date;
dialogId = messageObject.getDialogId(); dialogId = messageObject.getDialogId();
messageId = messageObject.getId(); messageId = messageObject.getId();
@ -126,7 +131,7 @@ public class MessagePrivateSeenView extends FrameLayout {
} }
} else if (res instanceof TLRPC.TL_outboxReadDate) { } else if (res instanceof TLRPC.TL_outboxReadDate) {
TLRPC.TL_outboxReadDate r = (TLRPC.TL_outboxReadDate) res; TLRPC.TL_outboxReadDate r = (TLRPC.TL_outboxReadDate) res;
valueTextView.setText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatSeenDate(r.date))); valueTextView.setText(LocaleController.formatPmSeenDate(r.date));
premiumTextView.setVisibility(View.GONE); premiumTextView.setVisibility(View.GONE);
} }
valueLayout.animate().alpha(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(320).start(); valueLayout.animate().alpha(1f).setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT).setDuration(320).start();
@ -302,22 +307,29 @@ public class MessagePrivateSeenView extends FrameLayout {
if (minWidth < 0) { if (minWidth < 0) {
minWidth = 0; minWidth = 0;
final long date = System.currentTimeMillis();
minWidth = Math.max(minWidth, dp(40 + 96 + 8)); minWidth = Math.max(minWidth, dp(40 + 96 + 8));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.getString(R.string.PmReadUnknown))); minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.getString(R.string.PmReadUnknown)));
minWidth = Math.max(minWidth, dp(40 + 16 + 8) + valueTextView.getPaint().measureText(LocaleController.getString(R.string.PmRead) + premiumTextView.getPaint().measureText(LocaleController.getString(R.string.PmReadShowWhen)))); minWidth = Math.max(minWidth, dp(40 + 16 + 8) + valueTextView.getPaint().measureText(LocaleController.getString(R.string.PmRead) + premiumTextView.getPaint().measureText(LocaleController.getString(R.string.PmReadShowWhen))));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatString(R.string.TodayAtFormattedWithToday, "99:99")))); minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadTodayAt, LocaleController.getInstance().formatterDay.format(new Date(date)))));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatString(R.string.YesterdayAtFormatted, "99:99")))); if (messageDiff > 60 * 60 * 24) {
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadAt, LocaleController.formatString(R.string.formatDateAtTime, "99.99.99", "99:99")))); minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadYesterdayAt, LocaleController.getInstance().formatterDay.format(new Date(date)))));
}
if (messageDiff > 60 * 60 * 24 * 2) {
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadDateTimeAt, LocaleController.getInstance().formatterDayMonth.format(new Date(date)), LocaleController.getInstance().formatterDay.format(new Date(date)))));
minWidth = Math.max(minWidth, dp(40 + 8) + valueTextView.getPaint().measureText(LocaleController.formatString(R.string.PmReadDateTimeAt, LocaleController.getInstance().formatterYear.format(new Date(date)), LocaleController.getInstance().formatterDay.format(new Date(date)))));
}
} }
if (width < minWidth) {
width = (int) minWidth;
}
if (parent != null && parent.getWidth() > 0) { if (parent != null && parent.getWidth() > 0) {
width = parent.getWidth(); width = parent.getWidth();
widthMode = MeasureSpec.EXACTLY; widthMode = MeasureSpec.EXACTLY;
} }
if (width < minWidth || widthMode == MeasureSpec.AT_MOST) {
width = (int) minWidth;
widthMode = MeasureSpec.EXACTLY;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec); super.onMeasure(MeasureSpec.makeMeasureSpec(width, widthMode), heightMeasureSpec);
} }
} }

View file

@ -792,7 +792,7 @@ public class MessageEntityView extends EntityView {
MessageObject message = messageObjects.get(position); MessageObject message = messageObjects.get(position);
boolean pinnedTop = false; boolean pinnedTop = false;
if (groupedMessages != null) { if (groupedMessages != null) {
MessageObject.GroupedMessagePosition p = groupedMessages.positions.get(message); MessageObject.GroupedMessagePosition p = groupedMessages.getPosition(message);
if (p != null) { if (p != null) {
pinnedTop = p.minY != 0; pinnedTop = p.minY != 0;
} }
@ -825,7 +825,7 @@ public class MessageEntityView extends EntityView {
position = messageObjects.size() - 1 - position; position = messageObjects.size() - 1 - position;
if (groupedMessages != null && position >= 0 && position < messageObjects.size()) { if (groupedMessages != null && position >= 0 && position < messageObjects.size()) {
MessageObject message = messageObjects.get(position); MessageObject message = messageObjects.get(position);
MessageObject.GroupedMessagePosition pos = groupedMessages.positions.get(message); MessageObject.GroupedMessagePosition pos = groupedMessages.getPosition(message);
if (pos == null || pos.minX == pos.maxX || pos.minY != pos.maxY || pos.minY == 0) { if (pos == null || pos.minX == pos.maxX || pos.minY != pos.maxY || pos.minY == 0) {
return false; return false;
} }
@ -849,7 +849,7 @@ public class MessageEntityView extends EntityView {
position = messageObjects.size() - 1 - position; position = messageObjects.size() - 1 - position;
if (groupedMessages != null && position >= 0 && position < groupedMessages.messages.size()) { if (groupedMessages != null && position >= 0 && position < groupedMessages.messages.size()) {
MessageObject message = groupedMessages.messages.get(position); MessageObject message = groupedMessages.messages.get(position);
MessageObject.GroupedMessagePosition groupedPosition = groupedMessages.positions.get(message); MessageObject.GroupedMessagePosition groupedPosition = groupedMessages.getPosition(message);
if (groupedPosition != null) { if (groupedPosition != null) {
return groupedPosition.spanSize; return groupedPosition.spanSize;
} }

View file

@ -648,6 +648,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
fireworksOverlay.start(); fireworksOverlay.start();
fireworksOverlay.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); fireworksOverlay.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
headerView.boostCounterView.setCount(canApplyBoost.boostCount, true); headerView.boostCounterView.setCount(canApplyBoost.boostCount, true);
recyclerListView.smoothScrollToPosition(0);
} }
private void sendInviteMessages() { private void sendInviteMessages() {
@ -1092,7 +1093,7 @@ public class LimitReachedBottomSheet extends BottomSheetWithRecyclerListView imp
view.setPadding(0, 0, 0, AndroidUtilities.dp(8)); view.setPadding(0, 0, 0, AndroidUtilities.dp(8));
break; break;
case VIEW_TYPE_USER: case VIEW_TYPE_USER:
view = new GroupCreateUserCell(context, 1, 8, false); view = new GroupCreateUserCell(context, 1, 0, false);
break; break;
case VIEW_TYPE_PROGRESS: case VIEW_TYPE_PROGRESS:
FlickerLoadingView flickerLoadingView = new FlickerLoadingView(context, null); FlickerLoadingView flickerLoadingView = new FlickerLoadingView(context, null);

View file

@ -488,8 +488,6 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) {
premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumReactions)); premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumReactions));
premiumButtonView.setIcon(R.raw.unlock_icon); premiumButtonView.setIcon(R.raw.unlock_icon);
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || startType == PremiumPreviewFragment.PREMIUM_FEATURE_DOWNLOAD_SPEED || startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT || startType == PremiumPreviewFragment.PREMIUM_FEATURE_VOICE_TO_TEXT) {
premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.AboutTelegramPremium));
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) { } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) {
premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumIcons)); premiumButtonView.buttonTextView.setText(LocaleController.getString(R.string.UnlockPremiumIcons));
premiumButtonView.setIcon(R.raw.unlock_icon); premiumButtonView.setIcon(R.raw.unlock_icon);
@ -534,6 +532,7 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
actionBar.setTitleColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); actionBar.setTitleColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultSelector), false); actionBar.setItemsBackgroundColor(getThemedColor(Theme.key_actionBarActionModeDefaultSelector), false);
actionBar.setItemsColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon), false); actionBar.setItemsColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon), false);
actionBar.setItemsColor(getThemedColor(Theme.key_actionBarActionModeDefaultIcon), true);
actionBar.setCastShadows(true); actionBar.setCastShadows(true);
actionBar.setExtraHeight(AndroidUtilities.dp(2)); actionBar.setExtraHeight(AndroidUtilities.dp(2));
@ -677,8 +676,11 @@ public class PremiumFeatureBottomSheet extends BottomSheet implements Notificati
title.setText(LocaleController.getString("AdditionalReactions", R.string.AdditionalReactions)); title.setText(LocaleController.getString("AdditionalReactions", R.string.AdditionalReactions));
description.setText(AndroidUtilities.replaceTags(LocaleController.getString("AdditionalReactionsDescription", R.string.AdditionalReactionsDescription))); description.setText(AndroidUtilities.replaceTags(LocaleController.getString("AdditionalReactionsDescription", R.string.AdditionalReactionsDescription)));
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS) { } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_ADS) {
title.setText(LocaleController.getString("PremiumPreviewNoAds", R.string.PremiumPreviewNoAds)); title.setText(LocaleController.getString(R.string.PremiumPreviewNoAds));
description.setText(AndroidUtilities.replaceTags(LocaleController.getString("PremiumPreviewNoAdsDescription2", R.string.PremiumPreviewNoAdsDescription2))); description.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PremiumPreviewNoAdsDescription2)));
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS) {
title.setText(LocaleController.getString(R.string.PremiumPreviewTags));
description.setText(AndroidUtilities.replaceTags(LocaleController.getString(R.string.PremiumPreviewTagsDescription)));
} else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) { } else if (startType == PremiumPreviewFragment.PREMIUM_FEATURE_APPLICATION_ICONS) {
title.setText(LocaleController.getString("PremiumPreviewAppIcon", R.string.PremiumPreviewAppIcon)); title.setText(LocaleController.getString("PremiumPreviewAppIcon", R.string.PremiumPreviewAppIcon));
description.setText(AndroidUtilities.replaceTags(LocaleController.getString("PremiumPreviewAppIconDescription2", R.string.PremiumPreviewAppIconDescription2))); description.setText(AndroidUtilities.replaceTags(LocaleController.getString("PremiumPreviewAppIconDescription2", R.string.PremiumPreviewAppIconDescription2)));

View file

@ -17,6 +17,7 @@ import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.ImageReceiver;
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.AnimatedEmojiDrawable;
import org.telegram.ui.Components.voip.CellFlickerDrawable; import org.telegram.ui.Components.voip.CellFlickerDrawable;
public class PremiumLockIconView extends ImageView { public class PremiumLockIconView extends ImageView {
@ -61,6 +62,7 @@ public class PremiumLockIconView extends ImageView {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint oldShaderPaint; Paint oldShaderPaint;
ImageReceiver imageReceiver; ImageReceiver imageReceiver;
AnimatedEmojiDrawable emojiDrawable;
float shaderCrossfadeProgress = 1f; float shaderCrossfadeProgress = 1f;
boolean waitingImage; boolean waitingImage;
boolean wasDrawn; boolean wasDrawn;
@ -106,6 +108,14 @@ public class PremiumLockIconView extends ImageView {
if (imageReceiver != null && imageReceiver.getBitmap() != null) { if (imageReceiver != null && imageReceiver.getBitmap() != null) {
waitingImage = false; waitingImage = false;
setColor(AndroidUtilities.getDominantColor(imageReceiver.getBitmap())); setColor(AndroidUtilities.getDominantColor(imageReceiver.getBitmap()));
} else if (emojiDrawable != null) {
int color = AnimatedEmojiDrawable.getDominantColor(emojiDrawable);
if (color != 0) {
waitingImage = false;
setColor(color);
} else {
invalidate();
}
} else { } else {
invalidate(); invalidate();
} }
@ -163,6 +173,14 @@ public class PremiumLockIconView extends ImageView {
} }
} }
public void setAnimatedEmojiDrawable(AnimatedEmojiDrawable emojiDrawable) {
this.emojiDrawable = emojiDrawable;
if (emojiDrawable != null) {
waitingImage = true;
invalidate();
}
}
public ImageReceiver getImageReceiver() { public ImageReceiver getImageReceiver() {
return imageReceiver; return imageReceiver;
} }

View file

@ -267,6 +267,18 @@ public class StarParticlesView extends View {
stars[i] = SvgHelper.getBitmap(R.raw.premium_object_star2, size, size, ColorUtils.setAlphaComponent(Theme.getColor(colorKey, resourcesProvider), 30)); stars[i] = SvgHelper.getBitmap(R.raw.premium_object_star2, size, size, ColorUtils.setAlphaComponent(Theme.getColor(colorKey, resourcesProvider), 30));
svg = true; svg = true;
continue; continue;
} else if (type == PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS) {
int res;
if (i == 0) {
res = R.raw.premium_object_tag;
} else if (i == 1) {
res = R.raw.premium_object_check;
} else {
res = R.raw.premium_object_star;
}
stars[i] = SvgHelper.getBitmap(res, size, size, ColorUtils.setAlphaComponent(Theme.getColor(colorKey, resourcesProvider), 30));
svg = true;
continue;
} }
bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
@ -540,6 +552,7 @@ public class StarParticlesView extends View {
type == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT || type == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS || type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI || type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_WALLPAPER || type == PremiumPreviewFragment.PREMIUM_FEATURE_WALLPAPER ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS type == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS

View file

@ -61,6 +61,11 @@ public class StoriesPageView extends BaseListPageView {
LocaleController.getString("PremiumStoriesStealthDescription", R.string.PremiumStoriesStealthDescription), LocaleController.getString("PremiumStoriesStealthDescription", R.string.PremiumStoriesStealthDescription),
PremiumPreviewFragment.PREMIUM_FEATURE_STORIES_STEALTH_MODE PremiumPreviewFragment.PREMIUM_FEATURE_STORIES_STEALTH_MODE
)); ));
itemsTmp.add(new Item(VIEW_TYPE_ITEM, R.drawable.menu_quality_hd,
LocaleController.getString(R.string.PremiumStoriesQuality),
LocaleController.getString(R.string.PremiumStoriesQualityDescription),
PremiumPreviewFragment.PREMIUM_FEATURE_STORIES_QUALITY
));
itemsTmp.add(new Item(VIEW_TYPE_ITEM, R.drawable.msg_stories_views, itemsTmp.add(new Item(VIEW_TYPE_ITEM, R.drawable.msg_stories_views,
LocaleController.getString("PremiumStoriesViews", R.string.PremiumStoriesViews), LocaleController.getString("PremiumStoriesViews", R.string.PremiumStoriesViews),
LocaleController.getString("PremiumStoriesViewsDescription", R.string.PremiumStoriesViewsDescription), LocaleController.getString("PremiumStoriesViewsDescription", R.string.PremiumStoriesViewsDescription),

View file

@ -131,12 +131,14 @@ public class VideoScreenPreview extends FrameLayout implements PagerHeaderView,
type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS || type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI || type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { type == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS
) {
starDrawable = new StarParticlesView.Drawable(40); starDrawable = new StarParticlesView.Drawable(40);
starDrawable.speedScale = 3; starDrawable.speedScale = 3;
starDrawable.type = type; starDrawable.type = type;
if (type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS) { if (type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || type == PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS) {
starDrawable.size1 = 14; starDrawable.size1 = 14;
starDrawable.size2 = 18; starDrawable.size2 = 18;
starDrawable.size3 = 18; starDrawable.size3 = 18;
@ -325,6 +327,7 @@ public class VideoScreenPreview extends FrameLayout implements PagerHeaderView,
type == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT || type == PremiumPreviewFragment.PREMIUM_FEATURE_ADVANCED_CHAT_MANAGEMENT ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS || type == PremiumPreviewFragment.PREMIUM_FEATURE_ADS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS || type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_AVATARS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI || type == PremiumPreviewFragment.PREMIUM_FEATURE_ANIMATED_EMOJI ||
type == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) { type == PremiumPreviewFragment.PREMIUM_FEATURE_REACTIONS) {
starDrawable.rect.set(0, 0, getMeasuredWidth(), getMeasuredHeight()); starDrawable.rect.set(0, 0, getMeasuredWidth(), getMeasuredHeight());

View file

@ -444,8 +444,13 @@ public class UserSelectorBottomSheet extends BottomSheetWithRecyclerListView imp
actionButton.setShowZero(false); actionButton.setShowZero(false);
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(); SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
if (selectedIds.size() == 0) { if (selectedIds.size() == 0) {
stringBuilder.append("d").setSpan(recipientsBtnSpaceSpan, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); if (LocaleController.isRTL) {
stringBuilder.append(LocaleController.getString("GiftPremiumChooseRecipientsBtn", R.string.GiftPremiumChooseRecipientsBtn)); stringBuilder.append(LocaleController.getString("GiftPremiumChooseRecipientsBtn", R.string.GiftPremiumChooseRecipientsBtn));
stringBuilder.append("d").setSpan(recipientsBtnSpaceSpan, stringBuilder.length() - 1, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} else {
stringBuilder.append("d").setSpan(recipientsBtnSpaceSpan, 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.append(LocaleController.getString("GiftPremiumChooseRecipientsBtn", R.string.GiftPremiumChooseRecipientsBtn));
}
} else { } else {
stringBuilder.append(LocaleController.getString("GiftPremiumProceedBtn", R.string.GiftPremiumProceedBtn)); stringBuilder.append(LocaleController.getString("GiftPremiumProceedBtn", R.string.GiftPremiumProceedBtn));
} }

View file

@ -11,6 +11,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition; import android.animation.LayoutTransition;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.text.Editable; import android.text.Editable;
import android.text.Layout; import android.text.Layout;
import android.text.SpannableString; import android.text.SpannableString;
@ -706,7 +707,12 @@ public class ChatCustomReactionsEditActivity extends BaseFragment implements Not
private boolean closeKeyboard() { private boolean closeKeyboard() {
if (emojiKeyboardVisible) { if (emojiKeyboardVisible) {
emojiKeyboardVisible = false; emojiKeyboardVisible = false;
editText.clearFocus(); if (isClearFocusNotWorking()) {
switchLayout.setFocusableInTouchMode(true);
switchLayout.requestFocus();
} else {
editText.clearFocus();
}
updateScrollViewMarginBottom(0); updateScrollViewMarginBottom(0);
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 512); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 512);
bottomDialogLayout.animate().setListener(null).cancel(); bottomDialogLayout.animate().setListener(null).cancel();
@ -717,6 +723,9 @@ public class ChatCustomReactionsEditActivity extends BaseFragment implements Not
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 512); NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 512);
bottomDialogLayout.setVisibility(View.INVISIBLE); bottomDialogLayout.setVisibility(View.INVISIBLE);
if (isClearFocusNotWorking()) {
switchLayout.setFocusableInTouchMode(false);
}
} }
}).start(); }).start();
return true; return true;
@ -724,6 +733,10 @@ public class ChatCustomReactionsEditActivity extends BaseFragment implements Not
return false; return false;
} }
private boolean isClearFocusNotWorking() {
return Build.MODEL.toLowerCase().startsWith("zte") && Build.VERSION.SDK_INT <= Build.VERSION_CODES.P;
}
private void updateScrollViewMarginBottom(int margin) { private void updateScrollViewMarginBottom(int margin) {
ViewGroup.MarginLayoutParams marginLayoutParams = ((ViewGroup.MarginLayoutParams) scrollView.getLayoutParams()); ViewGroup.MarginLayoutParams marginLayoutParams = ((ViewGroup.MarginLayoutParams) scrollView.getLayoutParams());
marginLayoutParams.bottomMargin = margin; marginLayoutParams.bottomMargin = margin;

View file

@ -66,7 +66,9 @@ public class ChatSelectionReactionMenuOverlay extends FrameLayout {
private void checkCreateReactionsLayout() { private void checkCreateReactionsLayout() {
if (reactionsContainerLayout == null) { if (reactionsContainerLayout == null) {
reactionsContainerLayout = new ReactionsContainerLayout(ReactionsContainerLayout.TYPE_DEFAULT, parentFragment, getContext(), parentFragment.getCurrentAccount(), parentFragment.getResourceProvider()) { final boolean tags = parentFragment.getUserConfig().getClientUserId() == parentFragment.getDialogId();
reactionsContainerLayout = new ReactionsContainerLayout(tags ? ReactionsContainerLayout.TYPE_TAGS : ReactionsContainerLayout.TYPE_DEFAULT, parentFragment, getContext(), parentFragment.getCurrentAccount(), parentFragment.getResourceProvider()) {
float enabledAlpha = 1f; float enabledAlpha = 1f;
long lastUpdate; long lastUpdate;
@ -110,7 +112,7 @@ public class ChatSelectionReactionMenuOverlay extends FrameLayout {
reactionsContainerLayout.setDelegate(new ReactionsContainerLayout.ReactionsContainerDelegate() { reactionsContainerLayout.setDelegate(new ReactionsContainerLayout.ReactionsContainerDelegate() {
@Override @Override
public void onReactionClicked(View view, ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean longpress, boolean addToRecent) { public void onReactionClicked(View view, ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean longpress, boolean addToRecent) {
parentFragment.selectReaction(currentPrimaryObject, reactionsContainerLayout, view, 0, 0, visibleReaction, false, longpress, addToRecent); parentFragment.selectReaction(currentPrimaryObject, reactionsContainerLayout, view, 0, 0, visibleReaction, false, longpress, addToRecent, false);
AndroidUtilities.runOnUIThread(() -> { AndroidUtilities.runOnUIThread(() -> {
if (reactionsContainerLayout != null) { if (reactionsContainerLayout != null) {
reactionsContainerLayout.dismissParent(true); reactionsContainerLayout.dismissParent(true);

View file

@ -2,6 +2,7 @@ package org.telegram.ui.Components.Reactions;
import static org.telegram.ui.Components.ReactionsContainerLayout.TYPE_STORY; import static org.telegram.ui.Components.ReactionsContainerLayout.TYPE_STORY;
import static org.telegram.ui.Components.ReactionsContainerLayout.TYPE_STORY_LIKES; import static org.telegram.ui.Components.ReactionsContainerLayout.TYPE_STORY_LIKES;
import static org.telegram.ui.Components.ReactionsContainerLayout.TYPE_TAGS;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
@ -66,7 +67,7 @@ import java.util.List;
public class CustomEmojiReactionsWindow { public class CustomEmojiReactionsWindow {
ContainerView containerView; public ContainerView containerView;
WindowManager windowManager; WindowManager windowManager;
public FrameLayout windowView; public FrameLayout windowView;
boolean attachToParent; boolean attachToParent;
@ -164,7 +165,7 @@ public class CustomEmojiReactionsWindow {
// sizeNotifierFrameLayout.setFitsSystemWindows(true); // sizeNotifierFrameLayout.setFitsSystemWindows(true);
containerView = new ContainerView(context); containerView = new ContainerView(context);
int dialogType = reactionsContainerLayout.showExpandableReactions() ? SelectAnimatedEmojiDialog.TYPE_EXPANDABLE_REACTIONS : SelectAnimatedEmojiDialog.TYPE_REACTIONS; final int dialogType = reactionsContainerLayout.getWindowType();
selectAnimatedEmojiDialog = new SelectAnimatedEmojiDialog(baseFragment, context, false, null, dialogType, type != TYPE_STORY, resourcesProvider, 16) { selectAnimatedEmojiDialog = new SelectAnimatedEmojiDialog(baseFragment, context, false, null, dialogType, type != TYPE_STORY, resourcesProvider, 16) {
@Override @Override
@ -309,7 +310,7 @@ public class CustomEmojiReactionsWindow {
private WindowManager.LayoutParams createLayoutParams(boolean focusable) { private WindowManager.LayoutParams createLayoutParams(boolean focusable) {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT; lp.width = lp.height = WindowManager.LayoutParams.MATCH_PARENT;
lp.type = type == ReactionsContainerLayout.TYPE_DEFAULT ? WindowManager.LayoutParams.TYPE_APPLICATION_PANEL : WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; lp.type = (type == ReactionsContainerLayout.TYPE_DEFAULT || type == ReactionsContainerLayout.TYPE_TAGS) ? WindowManager.LayoutParams.TYPE_APPLICATION_PANEL : WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
if (focusable) { if (focusable) {
lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
@ -699,7 +700,7 @@ public class CustomEmojiReactionsWindow {
} }
} }
private class ContainerView extends FrameLayout { public class ContainerView extends FrameLayout {
Drawable shadow; Drawable shadow;
Rect shadowPad = new Rect(); Rect shadowPad = new Rect();
@ -781,7 +782,7 @@ public class CustomEmojiReactionsWindow {
} }
if (reactionsContainerLayout.hintView != null) { if (reactionsContainerLayout.hintView != null) {
canvas.save(); canvas.save();
canvas.translate(drawingRect.left, drawingRect.top + reactionsContainerLayout.hintView.getY()); canvas.translate(drawingRect.left, drawingRect.top + reactionsContainerLayout.hintView.getY() - (type == TYPE_TAGS ? reactionsContainerLayout.rect.top : 0));
canvas.saveLayerAlpha( 0, 0, reactionsContainerLayout.hintView.getMeasuredWidth(), reactionsContainerLayout.hintView.getMeasuredHeight(), (int) (255 * reactionsContainerLayout.hintView.getAlpha() * (1f - enterTransitionProgress)), Canvas.ALL_SAVE_FLAG); canvas.saveLayerAlpha( 0, 0, reactionsContainerLayout.hintView.getMeasuredWidth(), reactionsContainerLayout.hintView.getMeasuredHeight(), (int) (255 * reactionsContainerLayout.hintView.getAlpha() * (1f - enterTransitionProgress)), Canvas.ALL_SAVE_FLAG);
reactionsContainerLayout.hintView.draw(canvas); reactionsContainerLayout.hintView.draw(canvas);
canvas.restore(); canvas.restore();

View file

@ -12,6 +12,9 @@ import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode; import android.graphics.PorterDuffXfermode;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.RectF; import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextPaint; import android.text.TextPaint;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.Gravity; import android.view.Gravity;
@ -19,14 +22,18 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.ChatListItemAnimator; import androidx.recyclerview.widget.ChatListItemAnimator;
import org.checkerframework.checker.units.qual.A;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader; import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.DocumentObject; import org.telegram.messenger.DocumentObject;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.ImageLocation; import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.ImageReceiver; import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject; import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
@ -38,8 +45,13 @@ import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Cells.ChatMessageCell; import org.telegram.ui.Cells.ChatMessageCell;
import org.telegram.ui.Components.AnimatedEmojiDrawable; import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import org.telegram.ui.Components.AnimatedFileDrawable;
import org.telegram.ui.Components.AnimatedTextView;
import org.telegram.ui.Components.AvatarsDrawable; import org.telegram.ui.Components.AvatarsDrawable;
import org.telegram.ui.Components.CounterView; import org.telegram.ui.Components.CounterView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.RLottieDrawable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -58,6 +70,14 @@ public class ReactionsLayoutInBubble {
private static Paint tagPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private static Paint tagPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static Paint cutTagPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private static Paint cutTagPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG); private static TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
public static void initPaints(Theme.ResourcesProvider resourcesProvider) {
paint.setColor(Theme.getColor(Theme.key_chat_inLoader, resourcesProvider));
textPaint.setColor(Theme.getColor(Theme.key_featuredStickers_buttonText, resourcesProvider));
textPaint.setTextSize(dp(12));
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
cutTagPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
public boolean isSmall; public boolean isSmall;
public int x; public int x;
@ -79,14 +99,14 @@ public class ReactionsLayoutInBubble {
public boolean isEmpty; public boolean isEmpty;
private float touchSlop; private float touchSlop;
public int lastLineX; public int lastLineX;
ArrayList<ReactionButton> reactionButtons = new ArrayList<>(); public ArrayList<ReactionButton> reactionButtons = new ArrayList<>();
ArrayList<ReactionButton> outButtons = new ArrayList<>(); ArrayList<ReactionButton> outButtons = new ArrayList<>();
HashMap<String, ReactionButton> lastDrawingReactionButtons = new HashMap<>(); HashMap<String, ReactionButton> lastDrawingReactionButtons = new HashMap<>();
HashMap<String, ReactionButton> lastDrawingReactionButtonsTmp = new HashMap<>(); HashMap<String, ReactionButton> lastDrawingReactionButtonsTmp = new HashMap<>();
ChatMessageCell parentView; ChatMessageCell parentView;
MessageObject messageObject; MessageObject messageObject;
Theme.ResourcesProvider resourcesProvider; Theme.ResourcesProvider resourcesProvider;
private String scrimViewReaction; private Integer scrimViewReaction;
int availableWidth; int availableWidth;
private int lastDrawnWidth; private int lastDrawnWidth;
@ -117,12 +137,8 @@ public class ReactionsLayoutInBubble {
public ReactionsLayoutInBubble(ChatMessageCell parentView) { public ReactionsLayoutInBubble(ChatMessageCell parentView) {
this.parentView = parentView; this.parentView = parentView;
currentAccount = UserConfig.selectedAccount; currentAccount = UserConfig.selectedAccount;
paint.setColor(Theme.getColor(Theme.key_chat_inLoader, resourcesProvider)); initPaints(resourcesProvider);
textPaint.setColor(Theme.getColor(Theme.key_featuredStickers_buttonText, resourcesProvider));
textPaint.setTextSize(dp(12));
textPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
touchSlop = ViewConfiguration.get(ApplicationLoader.applicationContext).getScaledTouchSlop(); touchSlop = ViewConfiguration.get(ApplicationLoader.applicationContext).getScaledTouchSlop();
cutTagPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
} }
public static boolean equalsTLReaction(TLRPC.Reaction reaction, TLRPC.Reaction reaction1) { public static boolean equalsTLReaction(TLRPC.Reaction reaction, TLRPC.Reaction reaction1) {
@ -135,9 +151,10 @@ public class ReactionsLayoutInBubble {
return false; return false;
} }
public void setMessage(MessageObject messageObject, boolean isSmall, Theme.ResourcesProvider resourcesProvider) { public void setMessage(MessageObject messageObject, boolean isSmall, boolean isTag, Theme.ResourcesProvider resourcesProvider) {
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
this.isSmall = isSmall; this.isSmall = isSmall;
this.tags = isTag;
this.messageObject = messageObject; this.messageObject = messageObject;
ArrayList<ReactionButton> oldButtons = new ArrayList<>(reactionButtons); ArrayList<ReactionButton> oldButtons = new ArrayList<>(reactionButtons);
hasUnreadReactions = false; hasUnreadReactions = false;
@ -159,9 +176,9 @@ public class ReactionsLayoutInBubble {
// break; // break;
// } // }
// } // }
ReactionButton button = new ReactionLayoutButton(old, reactionCount, isSmall); ReactionButton button = new ReactionLayoutButton(old, reactionCount, isSmall, isTag);
reactionButtons.add(button); reactionButtons.add(button);
if (!isSmall && messageObject.messageOwner.reactions.recent_reactions != null) { if (!isSmall && !isTag && messageObject.messageOwner.reactions.recent_reactions != null) {
ArrayList<TLObject> users = null; ArrayList<TLObject> users = null;
if (messageObject.getDialogId() > 0 && !UserObject.isReplyUser(messageObject.getDialogId())) { if (messageObject.getDialogId() > 0 && !UserObject.isReplyUser(messageObject.getDialogId())) {
@ -212,7 +229,7 @@ public class ReactionsLayoutInBubble {
} }
} }
if (isSmall && reactionCount.count > 1 && reactionCount.chosen) { if (isSmall && reactionCount.count > 1 && reactionCount.chosen) {
ReactionButton button2 = new ReactionLayoutButton(null, reactionCount, isSmall); ReactionButton button2 = new ReactionLayoutButton(null, reactionCount, isSmall, isTag);
reactionButtons.add(button2); reactionButtons.add(button2);
reactionButtons.get(0).isSelected = false; reactionButtons.get(0).isSelected = false;
reactionButtons.get(1).isSelected = true; reactionButtons.get(1).isSelected = true;
@ -261,6 +278,14 @@ public class ReactionsLayoutInBubble {
if (button.isSmall) { if (button.isSmall) {
button.width = dp(14); button.width = dp(14);
button.height = dp(14); button.height = dp(14);
} else if (button.isTag) {
button.width = dp(42);
button.height = dp(26);
if (button.hasName) {
button.width += button.textDrawable.getAnimateToWidth() + dp(8);
} else if (button.counterDrawable != null && button.count > 1) {
button.width += button.counterDrawable.getCurrentWidth() + dp(8);
}
} else { } else {
button.width = (int) (dp(8) + dp(20) + dp(4)); button.width = (int) (dp(8) + dp(20) + dp(4));
if (button.avatarsDrawable != null && button.users.size() > 0) { if (button.avatarsDrawable != null && button.users.size() > 0) {
@ -269,8 +294,10 @@ public class ReactionsLayoutInBubble {
int c2 = button.users.size() > 1 ? button.users.size() - 1 : 0; int c2 = button.users.size() > 1 ? button.users.size() - 1 : 0;
button.width += dp(2) + c1 * dp(20) + c2 * dp(20) * 0.8f + dp(1); button.width += dp(2) + c1 * dp(20) + c2 * dp(20) * 0.8f + dp(1);
button.avatarsDrawable.height = dp(26); button.avatarsDrawable.height = dp(26);
} else if (button.hasName) {
button.width += button.textDrawable.getAnimateToWidth() + dp(8);
} else { } else {
button.width += button.counterDrawable.textPaint.measureText(button.countText) + dp(8); button.width += button.counterDrawable.getCurrentWidth() + dp(8);
} }
button.height = dp(26); button.height = dp(26);
} }
@ -314,7 +341,7 @@ public class ReactionsLayoutInBubble {
drawServiceShaderBackground = 0f; drawServiceShaderBackground = 0f;
} }
public void draw(Canvas canvas, float animationProgress, String drawOnlyReaction) { public void draw(Canvas canvas, float animationProgress, Integer drawOnlyReaction) {
if (isEmpty && outButtons.isEmpty()) { if (isEmpty && outButtons.isEmpty()) {
return; return;
} }
@ -329,7 +356,7 @@ public class ReactionsLayoutInBubble {
} }
for (int i = 0; i < reactionButtons.size(); i++) { for (int i = 0; i < reactionButtons.size(); i++) {
ReactionButton reactionButton = reactionButtons.get(i); ReactionButton reactionButton = reactionButtons.get(i);
if (reactionButton.reaction.equals(scrimViewReaction) || (drawOnlyReaction != null && !reactionButton.reaction.equals(drawOnlyReaction))) { if ((Objects.equals(reactionButton.reaction.hashCode(), scrimViewReaction)) || (drawOnlyReaction != null && reactionButton.reaction.hashCode() != drawOnlyReaction)) {
continue; continue;
} }
canvas.save(); canvas.save();
@ -397,6 +424,7 @@ public class ReactionsLayoutInBubble {
button.fromTextColor = lastButton.lastDrawnTextColor; button.fromTextColor = lastButton.lastDrawnTextColor;
button.fromBackgroundColor = lastButton.lastDrawnBackgroundColor; button.fromBackgroundColor = lastButton.lastDrawnBackgroundColor;
button.fromTagDotColor = lastButton.lastDrawnTagDotColor;
button.animationType = ANIMATION_TYPE_MOVE; button.animationType = ANIMATION_TYPE_MOVE;
if (button.count != lastButton.count && button.counterDrawable != null) { if (button.count != lastButton.count && button.counterDrawable != null) {
@ -492,13 +520,13 @@ public class ReactionsLayoutInBubble {
return lastDrawingReactionButtons.get(hash); return lastDrawingReactionButtons.get(hash);
} }
public void setScrimReaction(String scrimViewReaction) { public void setScrimReaction(Integer scrimViewReaction) {
this.scrimViewReaction = scrimViewReaction; this.scrimViewReaction = scrimViewReaction;
} }
public class ReactionLayoutButton extends ReactionButton { public class ReactionLayoutButton extends ReactionButton {
public ReactionLayoutButton(ReactionButton reuseFrom, TLRPC.ReactionCount reactionCount, boolean isSmall) { public ReactionLayoutButton(ReactionButton reuseFrom, TLRPC.ReactionCount reactionCount, boolean isSmall, boolean isTag) {
super(reuseFrom, currentAccount, parentView, reactionCount, isSmall, resourcesProvider); super(reuseFrom, currentAccount, parentView, reactionCount, isSmall, isTag, resourcesProvider);
} }
@Override @Override
@ -532,6 +560,13 @@ public class ReactionsLayoutInBubble {
} }
} }
public boolean verifyDrawable(Drawable drawable) {
if (drawable instanceof AnimatedTextView.AnimatedTextDrawable) {
return true;
}
return false;
}
public static class ReactionButton { public static class ReactionButton {
private final TLRPC.ReactionCount reactionCount; private final TLRPC.ReactionCount reactionCount;
@ -541,6 +576,7 @@ public class ReactionsLayoutInBubble {
public int animateFromY; public int animateFromY;
public int animateFromWidth; public int animateFromWidth;
public int fromBackgroundColor; public int fromBackgroundColor;
public int fromTagDotColor;
public int fromTextColor; public int fromTextColor;
public int realCount; public int realCount;
public int choosenOrder; public int choosenOrder;
@ -555,15 +591,19 @@ public class ReactionsLayoutInBubble {
VisibleReaction visibleReaction; VisibleReaction visibleReaction;
android.graphics.Rect drawingImageRect = new Rect(); android.graphics.Rect drawingImageRect = new Rect();
public boolean hasName;
public String name;
public int count; public int count;
public int x; public int x;
public int y; public int y;
public int width; public int width;
public int height; public int height;
ImageReceiver imageReceiver; public ImageReceiver imageReceiver;
AnimatedEmojiDrawable animatedEmojiDrawable; public AnimatedEmojiDrawable animatedEmojiDrawable;
int animatedEmojiDrawableColor; int animatedEmojiDrawableColor;
public CounterView.CounterDrawable counterDrawable; public CounterView.CounterDrawable counterDrawable;
public AnimatedTextView.AnimatedTextDrawable textDrawable;
int backgroundColor; int backgroundColor;
int textColor; int textColor;
int serviceBackgroundColor; int serviceBackgroundColor;
@ -571,8 +611,10 @@ public class ReactionsLayoutInBubble {
public int lastDrawnTextColor; public int lastDrawnTextColor;
public int lastDrawnBackgroundColor; public int lastDrawnBackgroundColor;
public int lastDrawnTagDotColor;
boolean isSelected; boolean isSelected;
public boolean isTag;
AvatarsDrawable avatarsDrawable; AvatarsDrawable avatarsDrawable;
ArrayList<TLObject> users; ArrayList<TLObject> users;
@ -581,13 +623,17 @@ public class ReactionsLayoutInBubble {
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
protected int getCacheType() { protected int getCacheType() {
if (isTag) {
return AnimatedEmojiDrawable.CACHE_TYPE_SAVED_REACTION;
}
return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW; return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW;
} }
public ReactionButton(ReactionButton reuseFrom, int currentAccount, View parentView, TLRPC.ReactionCount reactionCount, boolean isSmall, Theme.ResourcesProvider resourcesProvider) { public ReactionButton(ReactionButton reuseFrom, int currentAccount, View parentView, TLRPC.ReactionCount reactionCount, boolean isSmall, boolean isTag, Theme.ResourcesProvider resourcesProvider) {
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.parentView = parentView; this.parentView = parentView;
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
this.isTag = isTag;
if (reuseFrom != null) { if (reuseFrom != null) {
counterDrawable = reuseFrom.counterDrawable; counterDrawable = reuseFrom.counterDrawable;
} }
@ -597,6 +643,14 @@ public class ReactionsLayoutInBubble {
if (counterDrawable == null) { if (counterDrawable == null) {
counterDrawable = new CounterView.CounterDrawable(parentView, false, null); counterDrawable = new CounterView.CounterDrawable(parentView, false, null);
} }
if (textDrawable == null) {
textDrawable = new AnimatedTextView.AnimatedTextDrawable(true, true, true);
textDrawable.setAnimationProperties(.4f, 0, 320, CubicBezierInterpolator.EASE_OUT_QUINT);
textDrawable.setTextSize(dp(13));
textDrawable.setCallback(parentView);
textDrawable.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
textDrawable.setOverrideFullWidth(AndroidUtilities.displaySize.x);
}
this.reactionCount = reactionCount; this.reactionCount = reactionCount;
this.reaction = reactionCount.reaction; this.reaction = reactionCount.reaction;
this.visibleReaction = VisibleReaction.fromTLReaction(reactionCount.reaction); this.visibleReaction = VisibleReaction.fromTLReaction(reactionCount.reaction);
@ -612,7 +666,6 @@ public class ReactionsLayoutInBubble {
} else { } else {
throw new RuntimeException("unsupported"); throw new RuntimeException("unsupported");
} }
countText = Integer.toString(reactionCount.count);
imageReceiver.setParentView(parentView); imageReceiver.setParentView(parentView);
isSelected = reactionCount.chosen; isSelected = reactionCount.chosen;
counterDrawable.updateVisibility = false; counterDrawable.updateVisibility = false;
@ -633,17 +686,54 @@ public class ReactionsLayoutInBubble {
counterDrawable.setSize(dp(26), dp(100)); counterDrawable.setSize(dp(26), dp(100));
counterDrawable.textPaint = textPaint; counterDrawable.textPaint = textPaint;
counterDrawable.setCount(count, false); if (isTag) {
name = MessagesController.getInstance(currentAccount).getSavedTagName(reaction);
hasName = !TextUtils.isEmpty(name);
}
if (hasName) {
textDrawable.setText(Emoji.replaceEmoji(name, textDrawable.getPaint().getFontMetricsInt(), false), !LocaleController.isRTL);
if (drawTextWithCounter()) {
countText = Integer.toString(reactionCount.count);
counterDrawable.setCount(count, false);
} else {
countText = "";
counterDrawable.setCount(0, false);
}
} else {
if (textDrawable != null) {
textDrawable.setText("", false);
}
countText = Integer.toString(reactionCount.count);
counterDrawable.setCount(count, false);
}
counterDrawable.setType(CounterView.CounterDrawable.TYPE_CHAT_REACTIONS); counterDrawable.setType(CounterView.CounterDrawable.TYPE_CHAT_REACTIONS);
counterDrawable.gravity = Gravity.LEFT; counterDrawable.gravity = Gravity.LEFT;
} }
private RectF bounds = new RectF(), rect2 = new RectF();
private final Path tagPath = new Path();
private void drawRoundRect(Canvas canvas, RectF rectF, float r, Paint paint) {
if (isTag) {
if (bounds.left != rectF.left || bounds.top != rectF.top || bounds.right != rectF.right || bounds.bottom != rectF.bottom) {
bounds.set(rectF);
fillTagPath(bounds, rect2, tagPath);
}
canvas.drawPath(tagPath, paint);
} else {
canvas.drawRoundRect(rectF, r, r, paint);
}
}
protected boolean isOutOwner() { protected boolean isOutOwner() {
return false; return false;
} }
protected boolean drawCounter() { protected boolean drawCounter() {
return count != 0 || counterDrawable.countChangeProgress != 1f; return count != 0 && (!isTag || hasName || count != 1) || counterDrawable.countChangeProgress != 1f;
}
protected boolean drawTextWithCounter() {
return false;
} }
public void draw(Canvas canvas, float x, float y, float progress, float alpha, boolean drawOverlayScrim) { public void draw(Canvas canvas, float x, float y, float progress, float alpha, boolean drawOverlayScrim) {
@ -672,7 +762,11 @@ public class ReactionsLayoutInBubble {
} }
updateColors(progress); updateColors(progress);
textPaint.setColor(lastDrawnTextColor); textPaint.setColor(lastDrawnTextColor);
if (textDrawable != null) {
textDrawable.setTextColor(lastDrawnTextColor);
}
paint.setColor(lastDrawnBackgroundColor); paint.setColor(lastDrawnBackgroundColor);
final boolean cutTagCircle = isTag && drawTagDot() && Color.alpha(lastDrawnTagDotColor) == 0;
if (alpha != 1f) { if (alpha != 1f) {
textPaint.setAlpha((int) (textPaint.getAlpha() * alpha)); textPaint.setAlpha((int) (textPaint.getAlpha() * alpha));
@ -695,20 +789,39 @@ public class ReactionsLayoutInBubble {
int oldAlpha2 = paint2.getAlpha(); int oldAlpha2 = paint2.getAlpha();
paint1.setAlpha((int) (oldAlpha * alpha * getDrawServiceShaderBackground())); paint1.setAlpha((int) (oldAlpha * alpha * getDrawServiceShaderBackground()));
paint2.setAlpha((int) (oldAlpha2 * alpha * getDrawServiceShaderBackground())); paint2.setAlpha((int) (oldAlpha2 * alpha * getDrawServiceShaderBackground()));
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, paint1); drawRoundRect(canvas, AndroidUtilities.rectTmp, rad, paint1);
if (resourcesProvider != null ? resourcesProvider.hasGradientService() : Theme.hasGradientService()) { if (resourcesProvider != null ? resourcesProvider.hasGradientService() : Theme.hasGradientService()) {
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, paint2); drawRoundRect(canvas, AndroidUtilities.rectTmp, rad, paint2);
} }
paint1.setAlpha(oldAlpha); paint1.setAlpha(oldAlpha);
paint2.setAlpha(oldAlpha2); paint2.setAlpha(oldAlpha2);
} }
if (drawOverlayScrim && getDrawServiceShaderBackground() < 1 && parentView instanceof ChatMessageCell) { if (drawOverlayScrim && getDrawServiceShaderBackground() < 1 && parentView instanceof ChatMessageCell) {
Theme.MessageDrawable messageBackground = ((ChatMessageCell) parentView).getCurrentBackgroundDrawable(false); Theme.MessageDrawable messageBackground = ((ChatMessageCell) parentView).getCurrentBackgroundDrawable(false);
if (messageBackground != null) { if (messageBackground != null && !isTag) {
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, messageBackground.getPaint()); canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, messageBackground.getPaint());
} }
} }
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, paint); if (cutTagCircle) {
AndroidUtilities.rectTmp.right += dp(4);
canvas.saveLayerAlpha(AndroidUtilities.rectTmp, 0xFF, Canvas.ALL_SAVE_FLAG);
AndroidUtilities.rectTmp.right -= dp(4);
}
drawRoundRect(canvas, AndroidUtilities.rectTmp, rad, paint);
if (isTag && drawTagDot()) {
Paint paint;
if (cutTagCircle) {
paint = cutTagPaint;
} else {
tagPaint.setColor(lastDrawnTagDotColor);
tagPaint.setAlpha((int) (tagPaint.getAlpha() * alpha));
paint = tagPaint;
}
canvas.drawCircle(AndroidUtilities.rectTmp.right - dp(8.4f), AndroidUtilities.rectTmp.centerY(), dp(2.66f), paint);
}
if (cutTagCircle) {
canvas.restore();
}
if (imageReceiver != null) { if (imageReceiver != null) {
int size, X; int size, X;
@ -722,31 +835,47 @@ public class ReactionsLayoutInBubble {
imageReceiver.setRoundRadius(0); imageReceiver.setRoundRadius(0);
} }
int Y = (int) ((height - size) / 2f); int Y = (int) ((height - size) / 2f);
if (isTag) {
X -= dp(2);
}
drawingImageRect.set((int) x + X, (int) y + Y, (int) x + X + size, (int) y + Y + size); drawingImageRect.set((int) x + X, (int) y + Y, (int) x + X + size, (int) y + Y + size);
imageReceiver.setImageCoords(drawingImageRect); imageReceiver.setImageCoords(drawingImageRect);
drawImage(canvas, alpha); drawImage(canvas, alpha);
} }
float tx = 0;
if (textDrawable != null && textDrawable.isNotEmpty() > 0) {
canvas.save();
canvas.translate(x + dp(hasName && !drawTagDot() ? 10 : (hasName ? 9 : 8)) + dp(20) + dp(2), y);
textDrawable.setBounds(0, 0, width, height);
textDrawable.draw(canvas);
textDrawable.setAlpha((int) (0xFF * alpha));
canvas.restore();
tx = textDrawable.getCurrentWidth() + dp(4) * textDrawable.isNotEmpty();
}
if (counterDrawable != null && drawCounter()) { if (counterDrawable != null && drawCounter()) {
canvas.save(); canvas.save();
canvas.translate(x + dp(8) + dp(20) + dp(2), y); canvas.translate(x + dp(hasName && !drawTagDot() ? 10 : (hasName ? 9 : 8)) + dp(20) + dp(2) + tx, y);
counterDrawable.draw(canvas); counterDrawable.draw(canvas);
canvas.restore(); canvas.restore();
} }
if (avatarsDrawable != null) { if (!isTag) {
canvas.save(); if (avatarsDrawable != null) {
canvas.translate(x + dp(10) + dp(20) + dp(2), y); canvas.save();
avatarsDrawable.setAlpha(alpha); canvas.translate(x + dp(10) + dp(20) + dp(2), y);
avatarsDrawable.setTransitionProgress(progress); avatarsDrawable.setAlpha(alpha);
avatarsDrawable.onDraw(canvas); avatarsDrawable.setTransitionProgress(progress);
canvas.restore(); avatarsDrawable.onDraw(canvas);
canvas.restore();
}
} }
} }
protected void updateColors(float progress) { protected void updateColors(float progress) {
lastDrawnTextColor = ColorUtils.blendARGB(fromTextColor, ColorUtils.blendARGB(textColor, serviceTextColor, getDrawServiceShaderBackground()), progress); lastDrawnTextColor = ColorUtils.blendARGB(fromTextColor, ColorUtils.blendARGB(textColor, serviceTextColor, getDrawServiceShaderBackground()), progress);
lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, ColorUtils.blendARGB(backgroundColor, serviceBackgroundColor, getDrawServiceShaderBackground()), progress); lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, ColorUtils.blendARGB(backgroundColor, serviceBackgroundColor, getDrawServiceShaderBackground()), progress);
lastDrawnTagDotColor = ColorUtils.blendARGB(fromTagDotColor, AndroidUtilities.computePerceivedBrightness(lastDrawnBackgroundColor) > .8f ? 0 : 0x5affffff, progress);
} }
protected boolean isPlaying() { protected boolean isPlaying() {
@ -870,6 +999,26 @@ public class ReactionsLayoutInBubble {
animatedEmojiDrawable.removeView(parentView); animatedEmojiDrawable.removeView(parentView);
} }
} }
public void startAnimation() {
ImageReceiver imageReceiver;
if (animatedEmojiDrawable != null && animatedEmojiDrawable.getImageReceiver() != null) {
imageReceiver = animatedEmojiDrawable.getImageReceiver();
} else {
imageReceiver = this.imageReceiver;
}
if (imageReceiver != null) {
RLottieDrawable rLottieDrawable = imageReceiver.getLottieAnimation();
if (rLottieDrawable != null) {
rLottieDrawable.restart(true);
} else {
AnimatedFileDrawable animatedFileDrawable = imageReceiver.getAnimation();
if (animatedFileDrawable != null) {
animatedFileDrawable.start();
}
}
}
}
} }
float lastX; float lastX;
@ -1017,6 +1166,13 @@ public class ReactionsLayoutInBubble {
imageReceiver.setAutoRepeat(0); imageReceiver.setAutoRepeat(0);
imageReceiver.onAttachedToWindow(); imageReceiver.onAttachedToWindow();
animatedReactions.put(reaction, imageReceiver); animatedReactions.put(reaction, imageReceiver);
} else if (tags && reaction.documentId != 0) {
for (int i = 0; i < reactionButtons.size(); ++i) {
if (reaction.isSame(reactionButtons.get(i).reaction)) {
reactionButtons.get(i).startAnimation();
return;
}
}
} }
} }
@ -1107,5 +1263,102 @@ public class ReactionsLayoutInBubble {
} }
return false; return false;
} }
@NonNull
@Override
public String toString() {
if (!TextUtils.isEmpty(emojicon))
return emojicon;
if (documentId != 0) {
TLRPC.Document document = AnimatedEmojiDrawable.findDocument(UserConfig.selectedAccount, documentId);
if (document != null) {
return MessageObject.findAnimatedEmojiEmoticon(document, null);
}
}
return "VisibleReaction{" + documentId + ", " + emojicon + "}";
}
public CharSequence toCharSequence(Paint.FontMetricsInt fontMetrics, int cacheType) {
if (!TextUtils.isEmpty(emojicon)) {
return emojicon;
}
SpannableString string = new SpannableString("😀");
AnimatedEmojiSpan emojiSpan = new AnimatedEmojiSpan(documentId, fontMetrics);
emojiSpan.cacheType = cacheType;
string.setSpan(emojiSpan, 0, string.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return string;
}
public CharSequence toCharSequence(Paint.FontMetricsInt fontMetrics) {
if (!TextUtils.isEmpty(emojicon)) {
return emojicon;
}
SpannableString string = new SpannableString("😀");
AnimatedEmojiSpan emojiSpan = new AnimatedEmojiSpan(documentId, fontMetrics);
string.setSpan(emojiSpan, 0, string.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return string;
}
public CharSequence toCharSequence(int textSizeDp) {
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(AndroidUtilities.dp(textSizeDp));
if (!TextUtils.isEmpty(emojicon)) {
CharSequence string = emojicon;
string = Emoji.replaceEmoji(string, textPaint.getFontMetricsInt(), false);
return string;
}
SpannableString string = new SpannableString("😀");
AnimatedEmojiSpan emojiSpan = new AnimatedEmojiSpan(documentId, textPaint.getFontMetricsInt());
string.setSpan(emojiSpan, 0, string.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
return string;
}
}
public static boolean reactionsEqual(TLRPC.Reaction a, TLRPC.Reaction b) {
if (a instanceof TLRPC.TL_reactionEmoji) {
if (!(b instanceof TLRPC.TL_reactionEmoji))
return false;
return TextUtils.equals(((TLRPC.TL_reactionEmoji) a).emoticon, ((TLRPC.TL_reactionEmoji) b).emoticon);
} else if (a instanceof TLRPC.TL_reactionCustomEmoji) {
if (!(b instanceof TLRPC.TL_reactionCustomEmoji))
return false;
return ((TLRPC.TL_reactionCustomEmoji) a).document_id == ((TLRPC.TL_reactionCustomEmoji) b).document_id;
}
return false;
}
public static void fillTagPath(RectF bounds, Path path) {
fillTagPath(bounds, AndroidUtilities.rectTmp, path);
}
public static void fillTagPath(RectF bounds, RectF tempRect, Path path) {
path.rewind();
tempRect.set(bounds.left, bounds.top, bounds.left + dp(12), bounds.top + dp(12));
path.arcTo(tempRect, -90, -90, false);
tempRect.set(bounds.left, bounds.bottom - dp(12), bounds.left + dp(12), bounds.bottom);
path.arcTo(tempRect, -180, -90, false);
float arrowRound = bounds.height() > dp(26) ? 1.4f : 0f;
float x = bounds.right - dpf2(9.09f);
float x1 = x - dpf2(0.056f);
float x1a = x + dpf2(1.22f);
float x2 = x + dpf2(3.07f);
float x2a = x + dpf2(2.406f);
float x3 = x + dpf2(8.27f + arrowRound);
float x3a = x + dpf2(8.923f + arrowRound);
float ty2 = bounds.top + dpf2(1.753f);
float by2 = bounds.bottom - dpf2(1.753f);
float ty2a = bounds.top + dpf2(0.663f);
float by2a = bounds.bottom - dpf2(0.663f);
float ty3 = bounds.top + dpf2(10.263f + arrowRound);
float by3 = bounds.bottom - dpf2(10.263f + arrowRound);
float ty3a = bounds.top + dpf2(11.333f + arrowRound);
float by3a = bounds.bottom - dpf2(11.333f + arrowRound);
path.lineTo(x1, bounds.bottom);
path.cubicTo(x1a, bounds.bottom, x2a, by2a, x2, by2);
path.lineTo(x3, by3);
path.cubicTo(x3a, by3a, x3a, ty3a, x3, ty3);
path.lineTo(x2, ty2);
path.cubicTo(x2a, ty2a, x1a, bounds.top, x1, bounds.top);
path.close();
} }
} }

View file

@ -1,5 +1,7 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.dp;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator; import android.animation.ObjectAnimator;
@ -19,7 +21,11 @@ import android.graphics.RectF;
import android.graphics.Shader; import android.graphics.Shader;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.provider.Settings; import android.provider.Settings;
import android.text.Layout;
import android.text.StaticLayout;
import android.util.LongSparseArray;
import android.util.Property; import android.util.Property;
import android.util.SparseArray;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
@ -27,6 +33,7 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewConfiguration; import android.view.ViewConfiguration;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.OvershootInterpolator; import android.view.animation.OvershootInterpolator;
import android.widget.FrameLayout; import android.widget.FrameLayout;
@ -58,6 +65,7 @@ import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.SvgHelper; import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities; import org.telegram.messenger.Utilities;
import org.telegram.messenger.support.LongSparseLongArray;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.tgnet.tl.TL_stories; import org.telegram.tgnet.tl.TL_stories;
import org.telegram.ui.ActionBar.AlertDialog; import org.telegram.ui.ActionBar.AlertDialog;
@ -72,6 +80,8 @@ import org.telegram.ui.Components.Reactions.ReactionsEffectOverlay;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.Components.Reactions.ReactionsUtils; import org.telegram.ui.Components.Reactions.ReactionsUtils;
import org.telegram.ui.PremiumPreviewFragment; import org.telegram.ui.PremiumPreviewFragment;
import org.telegram.ui.SelectAnimatedEmojiDialog;
import org.telegram.ui.Stories.recorder.HintView2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -102,6 +112,34 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public final RecyclerListView recyclerListView; public final RecyclerListView recyclerListView;
public final float durationScale; public final float durationScale;
private static final int VIEW_TYPE_REACTION = 0;
private static final int VIEW_TYPE_PREMIUM_BUTTON = 1;
private static final int VIEW_TYPE_CUSTOM_EMOJI_BUTTON = 2;
private static final int VIEW_TYPE_CUSTOM_REACTION = 3;
public ArrayList<InnerItem> items = new ArrayList<>();
public ArrayList<InnerItem> oldItems = new ArrayList<>();
class InnerItem extends AdapterWithDiffUtils.Item {
ReactionsLayoutInBubble.VisibleReaction reaction;
public InnerItem(int viewType, ReactionsLayoutInBubble.VisibleReaction reaction) {
super(viewType, false);
this.reaction = reaction;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InnerItem innerItem = (InnerItem) o;
if (viewType == innerItem.viewType && (viewType == VIEW_TYPE_REACTION || viewType == VIEW_TYPE_CUSTOM_REACTION)) {
return reaction != null && reaction.equals(innerItem.reaction);
}
return viewType == innerItem.viewType;
}
}
private Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint leftShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG), private Paint leftShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG),
rightShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG); rightShadowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@ -109,10 +147,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
private float transitionProgress = 1f; private float transitionProgress = 1f;
public RectF rect = new RectF(); public RectF rect = new RectF();
private Path mPath = new Path(); private Path mPath = new Path();
public float radius = AndroidUtilities.dp(72); public float radius = dp(72);
private float bigCircleRadius = AndroidUtilities.dp(8); private float bigCircleRadius = dp(8);
private float smallCircleRadius = bigCircleRadius / 2; private float smallCircleRadius = bigCircleRadius / 2;
public int bigCircleOffset = AndroidUtilities.dp(36); public int bigCircleOffset = dp(36);
private MessageObject messageObject; private MessageObject messageObject;
private int currentAccount; private int currentAccount;
private long waitingLoadingChatId; private long waitingLoadingChatId;
@ -179,9 +217,10 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public boolean skipEnterAnimation; public boolean skipEnterAnimation;
public boolean isHiddenNextReaction = true; public boolean isHiddenNextReaction = true;
private Runnable onSwitchedToLoopView; private Runnable onSwitchedToLoopView;
private boolean hasHint; public boolean hasHint;
public TextView hintView; public TextView hintView;
private float bubblesOffset; public int hintViewWidth, hintViewHeight;
public float bubblesOffset;
public ReactionsContainerLayout(int type, BaseFragment fragment, @NonNull Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider) { public ReactionsContainerLayout(int type, BaseFragment fragment, @NonNull Context context, int currentAccount, Theme.ResourcesProvider resourcesProvider) {
super(context); super(context);
@ -203,7 +242,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
animationEnabled = SharedConfig.animationsEnabled() && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW; animationEnabled = SharedConfig.animationsEnabled() && SharedConfig.getDevicePerformanceClass() != SharedConfig.PERFORMANCE_CLASS_LOW;
shadow = ContextCompat.getDrawable(context, R.drawable.reactions_bubble_shadow).mutate(); shadow = ContextCompat.getDrawable(context, R.drawable.reactions_bubble_shadow).mutate();
shadowPad.left = shadowPad.top = shadowPad.right = shadowPad.bottom = AndroidUtilities.dp(7); shadowPad.left = shadowPad.top = shadowPad.right = shadowPad.bottom = dp(7);
shadow.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_messagePanelShadow), PorterDuff.Mode.MULTIPLY)); shadow.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_chat_messagePanelShadow), PorterDuff.Mode.MULTIPLY));
recyclerListView = new RecyclerListView(context) { recyclerListView = new RecyclerListView(context) {
@ -289,14 +328,14 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
if (!showCustomEmojiReaction()) { if (!showCustomEmojiReaction()) {
int position = parent.getChildAdapterPosition(view); int position = parent.getChildAdapterPosition(view);
if (position == 0) { if (position == 0) {
outRect.left = AndroidUtilities.dp(6); outRect.left = dp(6);
} }
outRect.right = AndroidUtilities.dp(4); outRect.right = dp(4);
if (position == listAdapter.getItemCount() - 1) { if (position == listAdapter.getItemCount() - 1) {
if (showUnlockPremiumButton() || showCustomEmojiReaction()) { if (showUnlockPremiumButton() || showCustomEmojiReaction()) {
outRect.right = AndroidUtilities.dp(2); outRect.right = dp(2);
} else { } else {
outRect.right = AndroidUtilities.dp(6); outRect.right = dp(6);
} }
} }
} else { } else {
@ -331,7 +370,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
premiumLockIconView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY)); premiumLockIconView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY));
premiumLockIconView.setScaleX(0f); premiumLockIconView.setScaleX(0f);
premiumLockIconView.setScaleY(0f); premiumLockIconView.setScaleY(0f);
premiumLockIconView.setPadding(AndroidUtilities.dp(1), AndroidUtilities.dp(1), AndroidUtilities.dp(1), AndroidUtilities.dp(1)); premiumLockIconView.setPadding(dp(1), dp(1), dp(1), dp(1));
premiumLockContainer.addView(premiumLockIconView, LayoutHelper.createFrame(26, 26, Gravity.CENTER)); premiumLockContainer.addView(premiumLockIconView, LayoutHelper.createFrame(26, 26, Gravity.CENTER));
premiumLockIconView.setOnClickListener(v -> { premiumLockIconView.setOnClickListener(v -> {
int[] position = new int[2]; int[] position = new int[2];
@ -350,8 +389,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} else { } else {
customEmojiReactionsIconView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY)); customEmojiReactionsIconView.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY));
} }
customEmojiReactionsIconView.setBackground(Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(28), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector), 40))); customEmojiReactionsIconView.setBackground(Theme.createSimpleSelectorCircleDrawable(dp(28), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector), 40)));
customEmojiReactionsIconView.setPadding(AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2), AndroidUtilities.dp(2)); customEmojiReactionsIconView.setPadding(dp(2), dp(2), dp(2), dp(2));
customEmojiReactionsIconView.setContentDescription(LocaleController.getString(R.string.AccDescrExpandPanel)); customEmojiReactionsIconView.setContentDescription(LocaleController.getString(R.string.AccDescrExpandPanel));
customReactionsContainer.addView(customEmojiReactionsIconView, LayoutHelper.createFrame(30, 30, Gravity.CENTER)); customReactionsContainer.addView(customEmojiReactionsIconView, LayoutHelper.createFrame(30, 30, Gravity.CENTER));
customEmojiReactionsIconView.setOnClickListener(v -> { customEmojiReactionsIconView.setOnClickListener(v -> {
@ -361,8 +400,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
break; break;
} }
int size = getLayoutParams().height - (hasHint ? AndroidUtilities.dp(20) : 0) - getPaddingTop() - getPaddingBottom(); int size = getLayoutParams().height - (int) getTopOffset() - getPaddingTop() - getPaddingBottom();
view.setLayoutParams(new RecyclerView.LayoutParams(size - AndroidUtilities.dp(12), size)); view.setLayoutParams(new RecyclerView.LayoutParams(size - dp(12), size));
return new RecyclerListView.Holder(view); return new RecyclerListView.Holder(view);
} }
@ -376,6 +415,17 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
} }
@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
if (holder.getItemViewType() == VIEW_TYPE_REACTION || holder.getItemViewType() == VIEW_TYPE_CUSTOM_REACTION) {
int position = holder.getAdapterPosition();
if (position >= 0 && position < items.size()) {
((ReactionHolderView) holder.itemView).updateSelected(items.get(position).reaction);
}
}
super.onViewAttachedToWindow(holder);
}
@Override @Override
public int getItemCount() { public int getItemCount() {
return items.size(); return items.size();
@ -386,14 +436,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
return items.get(position).viewType; return items.get(position).viewType;
} }
ArrayList<InnerItem> items = new ArrayList<>();
ArrayList<InnerItem> oldItems = new ArrayList<>();
private static final int VIEW_TYPE_REACTION = 0;
private static final int VIEW_TYPE_PREMIUM_BUTTON = 1;
private static final int VIEW_TYPE_CUSTOM_EMOJI_BUTTON = 2;
private static final int VIEW_TYPE_CUSTOM_REACTION = 3;
@Override @Override
public void notifyDataSetChanged() { public void notifyDataSetChanged() {
oldItems.clear(); oldItems.clear();
@ -411,28 +453,6 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
setItems(oldItems, items); setItems(oldItems, items);
} }
class InnerItem extends AdapterWithDiffUtils.Item {
ReactionsLayoutInBubble.VisibleReaction reaction;
public InnerItem(int viewType, ReactionsLayoutInBubble.VisibleReaction reaction) {
super(viewType, false);
this.reaction = reaction;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
InnerItem innerItem = (InnerItem) o;
if (viewType == innerItem.viewType && (viewType == VIEW_TYPE_REACTION || viewType == VIEW_TYPE_CUSTOM_REACTION)) {
return reaction != null && reaction.equals(innerItem.reaction);
}
return viewType == innerItem.viewType;
}
}
}); });
recyclerListView.addOnScrollListener(new LeftRightShadowsListener()); recyclerListView.addOnScrollListener(new LeftRightShadowsListener());
recyclerListView.addOnScrollListener(new RecyclerView.OnScrollListener() { recyclerListView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@ -474,9 +494,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int i = parent.getChildAdapterPosition(view); int i = parent.getChildAdapterPosition(view);
if (i == 0) if (i == 0)
outRect.left = AndroidUtilities.dp(8); outRect.left = dp(8);
if (i == listAdapter.getItemCount() - 1) { if (i == listAdapter.getItemCount() - 1) {
outRect.right = AndroidUtilities.dp(8); outRect.right = dp(8);
} }
} }
}); });
@ -500,7 +520,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
invalidateShaders(); invalidateShaders();
int size = recyclerListView.getLayoutParams().height - recyclerListView.getPaddingTop() - recyclerListView.getPaddingBottom(); int size = recyclerListView.getLayoutParams().height - recyclerListView.getPaddingTop() - recyclerListView.getPaddingBottom();
nextRecentReaction.getLayoutParams().width = size - AndroidUtilities.dp(12); nextRecentReaction.getLayoutParams().width = size - dp(12);
nextRecentReaction.getLayoutParams().height = size; nextRecentReaction.getLayoutParams().height = size;
if (type == TYPE_STORY_LIKES) { if (type == TYPE_STORY_LIKES) {
@ -515,6 +535,16 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
return showExpandableReactions; return showExpandableReactions;
} }
public int getWindowType() {
if (type == TYPE_TAGS) {
return SelectAnimatedEmojiDialog.TYPE_TAGS;
}
if (showExpandableReactions) {
return SelectAnimatedEmojiDialog.TYPE_EXPANDABLE_REACTIONS;
}
return SelectAnimatedEmojiDialog.TYPE_REACTIONS;
}
private void animatePullingBack() { private void animatePullingBack() {
if (pullingLeftOffset != 0) { if (pullingLeftOffset != 0) {
pullingDownBackAnimator = ValueAnimator.ofFloat(pullingLeftOffset, 0); pullingDownBackAnimator = ValueAnimator.ofFloat(pullingLeftOffset, 0);
@ -535,7 +565,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
public void dismissWindow() { public void dismissWindow() {
reactionsWindow.dismiss(); if (reactionsWindow != null) {
reactionsWindow.dismiss();
}
} }
public CustomEmojiReactionsWindow getReactionsWindow() { public CustomEmojiReactionsWindow getReactionsWindow() {
@ -555,9 +587,14 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
delegate.onEmojiWindowDismissed(); delegate.onEmojiWindowDismissed();
} }
}); });
onShownCustomEmojiReactionDialog();
//animatePullingBack(); //animatePullingBack();
} }
protected void onShownCustomEmojiReactionDialog(){
}
private void invalidateLoopViews() { private void invalidateLoopViews() {
for (int i = 0; i < recyclerListView.getChildCount(); i++) { for (int i = 0; i < recyclerListView.getChildCount(); i++) {
View child = recyclerListView.getChildAt(i); View child = recyclerListView.getChildAt(i);
@ -612,7 +649,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
this.visibleReactionsList.clear(); this.visibleReactionsList.clear();
if (showCustomEmojiReaction()) { if (showCustomEmojiReaction()) {
int i = 0; int i = 0;
int n = (AndroidUtilities.displaySize.x - AndroidUtilities.dp(36)) / AndroidUtilities.dp(34); int n = (AndroidUtilities.displaySize.x - dp(36)) / dp(34);
if (n > 7) { if (n > 7) {
n = 7; n = 7;
} }
@ -637,8 +674,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
allReactionsList.clear(); allReactionsList.clear();
allReactionsList.addAll(visibleReactionsList); allReactionsList.addAll(visibleReactionsList);
// checkPremiumReactions(this.visibleReactionsList); // checkPremiumReactions(this.visibleReactionsList);
int size = getLayoutParams().height - (hasHint ? AndroidUtilities.dp(20) : 0) - getPaddingTop() - getPaddingBottom(); int size = getLayoutParams().height - (int) getTopOffset() - getPaddingTop() - getPaddingBottom();
if (size * visibleReactionsList.size() < AndroidUtilities.dp(200)) { if (size * visibleReactionsList.size() < dp(200)) {
getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT; getLayoutParams().width = ViewGroup.LayoutParams.WRAP_CONTENT;
} }
@ -708,7 +745,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
chatScrimPopupContainerLayout.setExpandSize(expandSize); chatScrimPopupContainerLayout.setExpandSize(expandSize);
} }
float transitionLeftOffset = (getWidth() - getPaddingRight()) * Math.min(1f, lt); float transitionLeftOffset = (getWidth() - getPaddingRight()) * Math.min(1f, lt);
float hintHeight = (hasHint ? AndroidUtilities.dp(20) : 0); float hintHeight = getTopOffset();
rect.set(getPaddingLeft() + transitionLeftOffset, getPaddingTop() + recyclerListView.getMeasuredHeight() * (1f - otherViewsScale) - expandSize, (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom() + expandSize); rect.set(getPaddingLeft() + transitionLeftOffset, getPaddingTop() + recyclerListView.getMeasuredHeight() * (1f - otherViewsScale) - expandSize, (getWidth() - getPaddingRight()) * rt, getHeight() - getPaddingBottom() + expandSize);
radius = ((rect.height() - hintHeight) - expandSize * 2f) / 2f; radius = ((rect.height() - hintHeight) - expandSize * 2f) / 2f;
@ -805,7 +842,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
if (pullingLeftOffsetProgress > 0) { if (pullingLeftOffsetProgress > 0) {
float progress = getPullingLeftProgress(); float progress = getPullingLeftProgress();
int reactionSize = nextRecentReaction.getMeasuredWidth() - AndroidUtilities.dp(2); int reactionSize = nextRecentReaction.getMeasuredWidth() - dp(2);
int left = lastReactionX + reactionSize; int left = lastReactionX + reactionSize;
float leftProgress = Utilities.clamp(left / (float) (getMeasuredWidth() - nextRecentReaction.getMeasuredWidth()), 1f, 0f); float leftProgress = Utilities.clamp(left / (float) (getMeasuredWidth() - nextRecentReaction.getMeasuredWidth()), 1f, 0f);
float pullingOffsetX = leftProgress * progress * reactionSize; float pullingOffsetX = leftProgress * progress * reactionSize;
@ -820,9 +857,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
nextRecentReaction.setScaleY(scale); nextRecentReaction.setScaleY(scale);
float additionalOffset = 0; float additionalOffset = 0;
if (type != TYPE_STORY && type != TYPE_STORY_LIKES) { if (type != TYPE_STORY && type != TYPE_STORY_LIKES) {
additionalOffset = - AndroidUtilities.dp(20); additionalOffset = - dp(20);
} else { } else {
additionalOffset = - AndroidUtilities.dp(8); additionalOffset = - dp(8);
} }
nextRecentReaction.setTranslationX(recyclerListView.getX() + left - pullingOffsetX + additionalOffset); nextRecentReaction.setTranslationX(recyclerListView.getX() + left - pullingOffsetX + additionalOffset);
if (nextRecentReaction.getVisibility() != View.VISIBLE) { if (nextRecentReaction.getVisibility() != View.VISIBLE) {
@ -887,12 +924,12 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
if (isTop) { if (isTop) {
canvas.clipRect(0, 0, getMeasuredWidth(), AndroidUtilities.lerp(rect.top, getMeasuredHeight(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)) - (int) Math.ceil(rect.height() / 2f * (1f - transitionProgress)) + 1); canvas.clipRect(0, 0, getMeasuredWidth(), AndroidUtilities.lerp(rect.top, getMeasuredHeight(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)) - (int) Math.ceil(rect.height() / 2f * (1f - transitionProgress)) + 1);
} else { } else {
canvas.clipRect(0, AndroidUtilities.lerp(rect.bottom, 0, CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)) - (int) Math.ceil(rect.height() / 2f * (1f - transitionProgress)) - 1, getMeasuredWidth(), AndroidUtilities.lerp(getMeasuredHeight() + AndroidUtilities.dp(8), getPaddingTop() - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress))); canvas.clipRect(0, AndroidUtilities.lerp(rect.bottom, 0, CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)) - (int) Math.ceil(rect.height() / 2f * (1f - transitionProgress)) - 1, getMeasuredWidth(), AndroidUtilities.lerp(getMeasuredHeight() + dp(8), getPaddingTop() - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)));
} }
float cx = LocaleController.isRTL || mirrorX ? bigCircleOffset : getWidth() - bigCircleOffset; float cx = LocaleController.isRTL || mirrorX ? bigCircleOffset : getWidth() - bigCircleOffset;
cx += bubblesOffset; cx += bubblesOffset;
float cy = isTop ? getPaddingTop() - expandSize() : getHeight() - getPaddingBottom() + expandSize(); float cy = isTop ? getPaddingTop() - expandSize() : getHeight() - getPaddingBottom() + expandSize();
int sPad = AndroidUtilities.dp(3); int sPad = dp(3);
shadow.setAlpha(alpha); shadow.setAlpha(alpha);
bgPaint.setAlpha(alpha); bgPaint.setAlpha(alpha);
shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr));
@ -906,9 +943,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
cx = LocaleController.isRTL || mirrorX ? bigCircleOffset - bigCircleRadius : getWidth() - bigCircleOffset + bigCircleRadius; cx = LocaleController.isRTL || mirrorX ? bigCircleOffset - bigCircleRadius : getWidth() - bigCircleOffset + bigCircleRadius;
cx += bubblesOffset; cx += bubblesOffset;
cy = isTop ? getPaddingTop() - expandSize() - AndroidUtilities.dp(16) : getHeight() - smallCircleRadius - sPad + expandSize(); cy = isTop ? getPaddingTop() - expandSize() - dp(16) : getHeight() - smallCircleRadius - sPad + expandSize();
cy = AndroidUtilities.lerp(cy, smallCircleRadius + sPad - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress)); cy = AndroidUtilities.lerp(cy, smallCircleRadius + sPad - expandSize(), CubicBezierInterpolator.DEFAULT.getInterpolation(flipVerticalProgress));
sPad = -AndroidUtilities.dp(1); sPad = -dp(1);
shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr)); shadow.setBounds((int) (cx - br - sPad * cPr), (int) (cy - br - sPad * cPr), (int) (cx + br + sPad * cPr), (int) (cy + br + sPad * cPr));
shadow.draw(canvas); shadow.draw(canvas);
if (delegate.drawBackground()) { if (delegate.drawBackground()) {
@ -943,8 +980,8 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
float pullingOffsetX = 0; float pullingOffsetX = 0;
if (pullingLeftOffset != 0) { if (pullingLeftOffset != 0) {
float progress = getPullingLeftProgress(); float progress = getPullingLeftProgress();
float leftProgress = Utilities.clamp(view.getLeft() / (float) (getMeasuredWidth() - AndroidUtilities.dp(34)), 1f, 0f); float leftProgress = Utilities.clamp(view.getLeft() / (float) (getMeasuredWidth() - dp(34)), 1f, 0f);
pullingOffsetX = leftProgress * progress * AndroidUtilities.dp(46); pullingOffsetX = leftProgress * progress * dp(46);
} }
if (view.currentReaction.equals(pressedReaction)) { if (view.currentReaction.equals(pressedReaction)) {
View imageView = view.loopImageView.getVisibility() == View.VISIBLE ? view.loopImageView : view.enterImageView; View imageView = view.loopImageView.getVisibility() == View.VISIBLE ? view.loopImageView : view.enterImageView;
@ -1012,7 +1049,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
public float getPullingLeftProgress() { public float getPullingLeftProgress() {
return Utilities.clamp(pullingLeftOffset / AndroidUtilities.dp(42), 2f, 0f); return Utilities.clamp(pullingLeftOffset / dp(42), 2f, 0f);
} }
@Override @Override
@ -1025,7 +1062,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
* Invalidates shaders * Invalidates shaders
*/ */
private void invalidateShaders() { private void invalidateShaders() {
int dp = AndroidUtilities.dp(24); int dp = dp(24);
float cy = getHeight() / 2f; float cy = getHeight() / 2f;
int clr = Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground); int clr = Theme.getColor(Theme.key_actionBarDefaultSubmenuBackground);
leftShadowPaint.setShader(new LinearGradient(0, cy, dp, cy, clr, Color.TRANSPARENT, Shader.TileMode.CLAMP)); leftShadowPaint.setShader(new LinearGradient(0, cy, dp, cy, clr, Color.TRANSPARENT, Shader.TileMode.CLAMP));
@ -1090,6 +1127,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
filterReactions(visibleReactions); filterReactions(visibleReactions);
showExpandableReactions = !allReactionsAvailable && visibleReactions.size() > 16 || allReactionsAvailable && !UserConfig.getInstance(currentAccount).isPremium() && MessagesController.getInstance(currentAccount).premiumFeaturesBlocked(); showExpandableReactions = !allReactionsAvailable && visibleReactions.size() > 16 || allReactionsAvailable && !UserConfig.getInstance(currentAccount).isPremium() && MessagesController.getInstance(currentAccount).premiumFeaturesBlocked();
if (type == TYPE_TAGS && !UserConfig.getInstance(currentAccount).isPremium()) {
showExpandableReactions = false;
}
setVisibleReactionsList(visibleReactions); setVisibleReactionsList(visibleReactions);
if (message != null && message.messageOwner.reactions != null && message.messageOwner.reactions.results != null) { if (message != null && message.messageOwner.reactions != null && message.messageOwner.reactions.results != null) {
@ -1118,6 +1158,74 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
listAdapter.notifyDataSetChanged(); listAdapter.notifyDataSetChanged();
} }
public void setSelectedReactions(ArrayList<MessageObject> messages) {
selectedReactions.clear();
for (int a = 0; a < messages.size(); ++a) {
MessageObject message = messages.get(a);
if (message != null && message.messageOwner.reactions != null && message.messageOwner.reactions.results != null) {
for (int i = 0; i < message.messageOwner.reactions.results.size(); i++) {
if (message.messageOwner.reactions.results.get(i).chosen) {
selectedReactions.add(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(message.messageOwner.reactions.results.get(i).reaction));
}
}
}
}
listAdapter.notifyDataSetChanged();
}
public HashSet<ReactionsLayoutInBubble.VisibleReaction> getSelectedReactions() {
return selectedReactions;
}
public static HashSet<ReactionsLayoutInBubble.VisibleReaction> getInclusiveReactions(ArrayList<MessageObject> messages) {
LongSparseArray<ReactionsLayoutInBubble.VisibleReaction> arr = new LongSparseArray<>();
HashSet<Long> messageReactions = new HashSet<>();
boolean firstMessage = true;
for (int k = 0; k < messages.size(); ++k) {
MessageObject message = messages.get(k);
messageReactions.clear();
if (message != null && message.messageOwner.reactions != null && message.messageOwner.reactions.results != null) {
for (int i = 0; i < message.messageOwner.reactions.results.size(); i++) {
if (message.messageOwner.reactions.results.get(i).chosen) {
ReactionsLayoutInBubble.VisibleReaction reaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(message.messageOwner.reactions.results.get(i).reaction);
if (firstMessage || arr.indexOfKey(reaction.hash) >= 0) {
messageReactions.add(reaction.hash);
arr.put(reaction.hash, reaction);
}
}
}
}
firstMessage = false;
for (int j = 0; j < arr.size(); ++j) {
if (!messageReactions.contains(arr.keyAt(j))) {
arr.removeAt(j);
j--;
}
}
}
HashSet<ReactionsLayoutInBubble.VisibleReaction> selectedReactions = new HashSet<>();
for (int j = 0; j < arr.size(); ++j) {
selectedReactions.add(arr.valueAt(j));
}
return selectedReactions;
}
public void setSelectedReactionsInclusive(ArrayList<MessageObject> messages) {
selectedReactions.clear();
selectedReactions.addAll(getInclusiveReactions(messages));
updateSelected();
}
private void updateSelected() {
AndroidUtilities.forEachViews(recyclerListView, child -> {
int position = recyclerListView.getChildAdapterPosition(child);
if (position < 0 || position >= items.size()) return;
if (child instanceof ReactionHolderView) {
((ReactionHolderView) child).updateSelected(items.get(position).reaction);
}
});
}
private void filterReactions(List<ReactionsLayoutInBubble.VisibleReaction> visibleReactions) { private void filterReactions(List<ReactionsLayoutInBubble.VisibleReaction> visibleReactions) {
HashSet<ReactionsLayoutInBubble.VisibleReaction> set = new HashSet<>(); HashSet<ReactionsLayoutInBubble.VisibleReaction> set = new HashSet<>();
for (int i = 0; i < visibleReactions.size(); i++) { for (int i = 0; i < visibleReactions.size(); i++) {
@ -1166,7 +1274,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
HashSet<ReactionsLayoutInBubble.VisibleReaction> hashSet = new HashSet<>(); HashSet<ReactionsLayoutInBubble.VisibleReaction> hashSet = new HashSet<>();
int added = 0; int added = 0;
if (type == TYPE_TAGS) { if (type == TYPE_TAGS) {
TLRPC.TL_messages_savedReactionsTags savedTags = MessagesController.getInstance(currentAccount).getSavedReactionTags(); TLRPC.TL_messages_savedReactionsTags savedTags = MessagesController.getInstance(currentAccount).getSavedReactionTags(0);
if (savedTags != null) { if (savedTags != null) {
for (int i = 0; i < savedTags.tags.size(); i++) { for (int i = 0; i < savedTags.tags.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(savedTags.tags.get(i).reaction); ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(savedTags.tags.get(i).reaction);
@ -1175,21 +1283,22 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
visibleReactions.add(visibleReaction); visibleReactions.add(visibleReaction);
added++; added++;
} }
if (added == 16) { // if (added == 16) {
break; // break;
} // }
} }
} }
} } else {
for (int i = 0; i < topReactions.size(); i++) { for (int i = 0; i < topReactions.size(); i++) {
ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(topReactions.get(i)); ReactionsLayoutInBubble.VisibleReaction visibleReaction = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(topReactions.get(i));
if (!hashSet.contains(visibleReaction) && (type == TYPE_TAGS || UserConfig.getInstance(currentAccount).isPremium() || visibleReaction.documentId == 0)) { if (!hashSet.contains(visibleReaction) && (type == TYPE_TAGS || UserConfig.getInstance(currentAccount).isPremium() || visibleReaction.documentId == 0)) {
hashSet.add(visibleReaction); hashSet.add(visibleReaction);
visibleReactions.add(visibleReaction); visibleReactions.add(visibleReaction);
added++; added++;
} }
if (added == 16) { // if (added == 16) {
break; // break;
// }
} }
} }
@ -1257,11 +1366,17 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public int getTotalWidth() { public int getTotalWidth() {
int itemsCount = getItemsCount(); int itemsCount = getItemsCount();
int width;
if (!showCustomEmojiReaction()) { if (!showCustomEmojiReaction()) {
return AndroidUtilities.dp(36) * itemsCount + AndroidUtilities.dp(2) * (itemsCount - 1) + AndroidUtilities.dp(16); width = dp(36) * itemsCount + dp(2) * (itemsCount - 1) + dp(16);
} else { } else {
return AndroidUtilities.dp(36) * itemsCount - AndroidUtilities.dp(4); width = dp(36) * itemsCount - dp(4);
} }
return width;
}
public int getHintTextWidth() {
return hintViewWidth;
} }
public int getItemsCount() { public int getItemsCount() {
@ -1298,7 +1413,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public void setCustomEmojiReactionsBackground(boolean isNeed) { public void setCustomEmojiReactionsBackground(boolean isNeed) {
if (isNeed) { if (isNeed) {
customEmojiReactionsIconView.setBackground(Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(28), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector), 40))); customEmojiReactionsIconView.setBackground(Theme.createSimpleSelectorCircleDrawable(dp(28), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_listSelector), 40)));
} else { } else {
customEmojiReactionsIconView.setBackground(null); customEmojiReactionsIconView.setBackground(null);
} }
@ -1404,18 +1519,64 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
invalidate(); invalidate();
} }
public void setHint(String storyReactionsHint) { public void setHint(CharSequence storyReactionsHint) {
hasHint = true; hasHint = true;
hintView = new TextView(getContext()); if (hintView == null) {
hintView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12); hintView = new LinkSpanDrawable.LinksTextView(getContext(), resourcesProvider);
hintView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider)); hintView.setPadding(dp(8), 0, dp(8), 0);
hintView.setClickable(true);
hintView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
if (type == TYPE_STORY || type == TYPE_STORY_LIKES) {
hintView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlackText, resourcesProvider));
hintView.setAlpha(0.5f);
} else {
hintView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2, resourcesProvider));
}
hintView.setGravity(Gravity.CENTER_HORIZONTAL);
addView(hintView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 6, 0, 0));
}
hintView.setText(storyReactionsHint); hintView.setText(storyReactionsHint);
hintView.setAlpha(0.5f); hintMeasured = false;
hintView.setGravity(Gravity.CENTER_HORIZONTAL);
addView(hintView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 0, 6, 0, 0));
((LayoutParams) nextRecentReaction.getLayoutParams()).topMargin = AndroidUtilities.dp(20); ((LayoutParams) nextRecentReaction.getLayoutParams()).topMargin = dp(20);
((LayoutParams) recyclerListView.getLayoutParams()).topMargin = AndroidUtilities.dp(20); ((LayoutParams) recyclerListView.getLayoutParams()).topMargin = dp(20);
}
private boolean hintMeasured;
public void measureHint() {
if (hintMeasured || !hasHint || getMeasuredWidth() <= 0) return;
int maxWidth = Math.min(dp(320), getMeasuredWidth() - dp(16));
StaticLayout layout = new StaticLayout(hintView.getText(), hintView.getPaint(), maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
hintViewHeight = layout.getHeight();
hintViewWidth = 0;
for (int i = 0; i < layout.getLineCount(); ++i) {
hintViewWidth = Math.max(hintViewWidth, (int) Math.ceil(layout.getLineWidth(i)));
}
if (layout.getLineCount() > 1 && !hintView.getText().toString().contains("\n")) {
maxWidth = HintView2.cutInFancyHalf(hintView.getText(), hintView.getPaint());
layout = new StaticLayout(hintView.getText(), hintView.getPaint(), maxWidth, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
hintViewHeight = layout.getHeight();
hintViewWidth = 0;
for (int i = 0; i < layout.getLineCount(); ++i) {
hintViewWidth = Math.max(hintViewWidth, (int) Math.ceil(layout.getLineWidth(i)));
}
hintView.setPadding(dp(24), 0, dp(24), 0);
hintView.setWidth(dp(48) + maxWidth);
} else {
hintView.setWidth(dp(16) + maxWidth);
}
int margin = Math.max(dp(20), dp(7) + hintViewHeight);
if (type == TYPE_STORY || type == TYPE_STORY_LIKES) {
margin = dp(20);
} else {
getLayoutParams().height = dp(52) + margin + dp(22);
}
((LayoutParams) nextRecentReaction.getLayoutParams()).topMargin = margin;
((LayoutParams) recyclerListView.getLayoutParams()).topMargin = margin;
hintMeasured = true;
} }
public void setTop(boolean isTop) { public void setTop(boolean isTop) {
@ -1423,7 +1584,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
public float getTopOffset() { public float getTopOffset() {
return hasHint ? AndroidUtilities.dp(20) : 0; return hasHint ? ((LayoutParams) recyclerListView.getLayoutParams()).topMargin : 0;
} }
public void setBubbleOffset(float v) { public void setBubbleOffset(float v) {
@ -1482,6 +1643,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
public BackupImageView pressedBackupImageView; public BackupImageView pressedBackupImageView;
private ImageReceiver preloadImageReceiver = new ImageReceiver(); private ImageReceiver preloadImageReceiver = new ImageReceiver();
public ReactionsLayoutInBubble.VisibleReaction currentReaction; public ReactionsLayoutInBubble.VisibleReaction currentReaction;
public PremiumLockIconView lockIconView;
public float sideScale = 1f; public float sideScale = 1f;
private boolean isEnter; private boolean isEnter;
public boolean hasEnterAnimation; public boolean hasEnterAnimation;
@ -1655,6 +1817,25 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
pressedBackupImageView.setLayerNum(Integer.MAX_VALUE); pressedBackupImageView.setLayerNum(Integer.MAX_VALUE);
} }
public boolean isLocked;
public void updateSelected(ReactionsLayoutInBubble.VisibleReaction react) {
boolean wasSelected = selected;
selected = selectedReactions.contains(react);
if (selected != wasSelected) {
if (selected) {
loopImageView.getLayoutParams().width = loopImageView.getLayoutParams().height = dp(26);
enterImageView.getLayoutParams().width = enterImageView.getLayoutParams().height = dp(26);
} else {
loopImageView.getLayoutParams().width = loopImageView.getLayoutParams().height = dp(34);
enterImageView.getLayoutParams().width = enterImageView.getLayoutParams().height = dp(34);
}
requestLayout();
invalidate();
}
}
private void setReaction(ReactionsLayoutInBubble.VisibleReaction react, int position) { private void setReaction(ReactionsLayoutInBubble.VisibleReaction react, int position) {
if (currentReaction != null && currentReaction.equals(react)) { if (currentReaction != null && currentReaction.equals(react)) {
this.position = position; this.position = position;
@ -1662,6 +1843,18 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
updateImage(react); updateImage(react);
return; return;
} }
isLocked = type == TYPE_TAGS && !UserConfig.getInstance(currentAccount).isPremium();
if (isLocked && lockIconView == null) {
lockIconView = new PremiumLockIconView(getContext(), PremiumLockIconView.TYPE_STICKERS_PREMIUM_LOCKED);
lockIconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
lockIconView.setImageReceiver(loopImageView.getImageReceiver());
addView(lockIconView, LayoutHelper.createFrame(18, 18, Gravity.CENTER, 8, 8, 0, 0));
}
if (lockIconView != null) {
lockIconView.setVisibility(isLocked ? View.VISIBLE : View.GONE);
}
resetAnimation(); resetAnimation();
currentReaction = react; currentReaction = react;
selected = selectedReactions.contains(react); selected = selectedReactions.contains(react);
@ -1673,15 +1866,26 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
if (enterImageView.getImageReceiver().getLottieAnimation() != null) { if (enterImageView.getImageReceiver().getLottieAnimation() != null) {
enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false); enterImageView.getImageReceiver().getLottieAnimation().setCurrentFrame(0, false);
} }
if (lockIconView != null) {
lockIconView.setAnimatedEmojiDrawable(null);
}
} else { } else {
pressedBackupImageView.getImageReceiver().clearImage(); pressedBackupImageView.getImageReceiver().clearImage();
loopImageView.getImageReceiver().clearImage(); loopImageView.getImageReceiver().clearImage();
AnimatedEmojiDrawable pressedDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_LARGE, currentAccount, currentReaction.documentId); AnimatedEmojiDrawable pressedDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW_LARGE, currentAccount, currentReaction.documentId);
pressedDrawable.setColorFilter(Theme.getAnimatedEmojiColorFilter(resourcesProvider));
pressedBackupImageView.setAnimatedEmojiDrawable(pressedDrawable); pressedBackupImageView.setAnimatedEmojiDrawable(pressedDrawable);
AnimatedEmojiDrawable loopDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW, currentAccount, currentReaction.documentId); AnimatedEmojiDrawable loopDrawable = new AnimatedEmojiDrawable(AnimatedEmojiDrawable.CACHE_TYPE_ALERT_PREVIEW, currentAccount, currentReaction.documentId);
loopDrawable.setColorFilter(Theme.getAnimatedEmojiColorFilter(resourcesProvider)); if (type == TYPE_STORY || type == TYPE_STORY_LIKES) {
pressedDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY));
loopDrawable.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY));
} else {
pressedDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY));
loopDrawable.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_dialogBackground), PorterDuff.Mode.MULTIPLY));
}
loopImageView.setAnimatedEmojiDrawable(loopDrawable); loopImageView.setAnimatedEmojiDrawable(loopDrawable);
if (lockIconView != null) {
lockIconView.setAnimatedEmojiDrawable(loopDrawable);
}
} }
setFocusable(true); setFocusable(true);
shouldSwitchToLoopView = hasEnterAnimation;// && !allReactionsIsDefault; shouldSwitchToLoopView = hasEnterAnimation;// && !allReactionsIsDefault;
@ -1695,11 +1899,11 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
loopImageView.setVisibility(View.GONE); loopImageView.setVisibility(View.GONE);
} }
if (selected) { if (selected) {
loopImageView.getLayoutParams().width = loopImageView.getLayoutParams().height = AndroidUtilities.dp(26); loopImageView.getLayoutParams().width = loopImageView.getLayoutParams().height = dp(26);
enterImageView.getLayoutParams().width = enterImageView.getLayoutParams().height = AndroidUtilities.dp(26); enterImageView.getLayoutParams().width = enterImageView.getLayoutParams().height = dp(26);
} else { } else {
loopImageView.getLayoutParams().width = loopImageView.getLayoutParams().height = AndroidUtilities.dp(34); loopImageView.getLayoutParams().width = loopImageView.getLayoutParams().height = dp(34);
enterImageView.getLayoutParams().width = enterImageView.getLayoutParams().height = AndroidUtilities.dp(34); enterImageView.getLayoutParams().width = enterImageView.getLayoutParams().height = dp(34);
} }
} }
@ -1727,6 +1931,9 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
preloadImageReceiver.setAllowStartLottieAnimation(false); preloadImageReceiver.setAllowStartLottieAnimation(false);
MediaDataController.getInstance(currentAccount).preloadImage(preloadImageReceiver, ImageLocation.getForDocument(defaultReaction.around_animation), ReactionsEffectOverlay.getFilterForAroundAnimation()); MediaDataController.getInstance(currentAccount).preloadImage(preloadImageReceiver, ImageLocation.getForDocument(defaultReaction.around_animation), ReactionsEffectOverlay.getFilterForAroundAnimation());
} }
if (lockIconView != null) {
lockIconView.setImageReceiver(loopImageView.getImageReceiver());
}
} }
} }
@ -1833,17 +2040,14 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
if (!touchable) { if (!touchable || cancelPressedAnimation != null) {
return false;
}
if (cancelPressedAnimation != null) {
return false; return false;
} }
if (event.getAction() == MotionEvent.ACTION_DOWN) { if (event.getAction() == MotionEvent.ACTION_DOWN) {
pressed = true; pressed = true;
pressedX = event.getX(); pressedX = event.getX();
pressedY = event.getY(); pressedY = event.getY();
if (sideScale == 1f) { if (sideScale == 1f && !isLocked && type != TYPE_TAGS) {
AndroidUtilities.runOnUIThread(longPressRunnable, ViewConfiguration.getLongPressTimeout()); AndroidUtilities.runOnUIThread(longPressRunnable, ViewConfiguration.getLongPressTimeout());
} }
} }
@ -1871,13 +2075,13 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
if (selected && drawSelected) { if (selected && drawSelected) {
canvas.drawCircle(getMeasuredWidth() >> 1, getMeasuredHeight() >> 1, (getMeasuredWidth() >> 1) - AndroidUtilities.dp(1), selectedPaint); canvas.drawCircle(getMeasuredWidth() >> 1, getMeasuredHeight() >> 1, (getMeasuredWidth() >> 1) - dp(1), selectedPaint);
} }
if (loopImageView.animatedEmojiDrawable != null && loopImageView.animatedEmojiDrawable.getImageReceiver() != null) { if (loopImageView.animatedEmojiDrawable != null && loopImageView.animatedEmojiDrawable.getImageReceiver() != null) {
if (position == 0) { if (position == 0) {
loopImageView.animatedEmojiDrawable.getImageReceiver().setRoundRadius(AndroidUtilities.dp(6), 0, 0, AndroidUtilities.dp(6)); loopImageView.animatedEmojiDrawable.getImageReceiver().setRoundRadius(dp(6), 0, 0, dp(6));
} else { } else {
loopImageView.animatedEmojiDrawable.getImageReceiver().setRoundRadius(selected ? AndroidUtilities.dp(6) : 0); loopImageView.animatedEmojiDrawable.getImageReceiver().setRoundRadius(selected ? dp(6) : 0);
} }
} }
super.dispatchDraw(canvas); super.dispatchDraw(canvas);
@ -2088,7 +2292,7 @@ public class ReactionsContainerLayout extends FrameLayout implements Notificatio
} }
public float expandSize() { public float expandSize() {
return (int) (getPullingLeftProgress() * AndroidUtilities.dp(6)); return (int) (getPullingLeftProgress() * dp(6));
} }
public void setParentLayout(ChatScrimPopupContainerLayout layout) { public void setParentLayout(ChatScrimPopupContainerLayout layout) {

View file

@ -1,60 +1,105 @@
package org.telegram.ui.Components; package org.telegram.ui.Components;
import static org.telegram.messenger.AndroidUtilities.cancelRunOnUIThread;
import static org.telegram.messenger.AndroidUtilities.dp; import static org.telegram.messenger.AndroidUtilities.dp;
import static org.telegram.messenger.AndroidUtilities.lerp; import static org.telegram.messenger.AndroidUtilities.lerp;
import static org.telegram.messenger.AndroidUtilities.runOnUIThread;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context; import android.content.Context;
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.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.CharacterStyle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import org.checkerframework.checker.units.qual.A;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.Emoji;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaDataController; import org.telegram.messenger.MediaDataController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController; import org.telegram.messenger.MessagesController;
import org.telegram.messenger.MessagesStorage;
import org.telegram.messenger.NotificationCenter; import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.AlertDialogDecor;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.Premium.PremiumFeatureBottomSheet;
import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble; import org.telegram.ui.Components.Reactions.ReactionsLayoutInBubble;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.PremiumPreviewFragment;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects;
public class SearchTagsList extends BlurredFrameLayout implements NotificationCenter.NotificationCenterDelegate { public class SearchTagsList extends BlurredFrameLayout implements NotificationCenter.NotificationCenterDelegate {
private final int currentAccount; private final int currentAccount;
private final BaseFragment fragment;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
public final RecyclerListView listView; public final RecyclerListView listView;
private final Adapter adapter; private final Adapter adapter;
private LinearLayout premiumLayout;
private long chosen; private long chosen;
private final ArrayList<Item> oldItems = new ArrayList<>(); private final ArrayList<Item> oldItems = new ArrayList<>();
private final ArrayList<Item> items = new ArrayList<>(); private final ArrayList<Item> items = new ArrayList<>();
private boolean shownPremiumLayout;
private static class Item { private static class Item {
ReactionsLayoutInBubble.VisibleReaction reaction; ReactionsLayoutInBubble.VisibleReaction reaction;
int count; int count;
String name;
int nameHash;
public static Item get(ReactionsLayoutInBubble.VisibleReaction reaction, int count) { public static Item get(ReactionsLayoutInBubble.VisibleReaction reaction, int count, String name) {
Item item = new Item(); Item item = new Item();
item.reaction = reaction; item.reaction = reaction;
item.count = count; item.count = count;
item.name = name;
item.nameHash = name == null ? -233 : name.hashCode();
return item; return item;
} }
@ -68,17 +113,130 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
return false; return false;
} }
Item that = (Item) obj; Item that = (Item) obj;
return this.count == that.count && this.reaction.hash == that.reaction.hash; return this.count == that.count && this.reaction.hash == that.reaction.hash && this.nameHash == that.nameHash;
} }
} }
public SearchTagsList(Context context, SizeNotifierFrameLayout contentView, int currentAccount, Theme.ResourcesProvider resourcesProvider) { public void setChosen(ReactionsLayoutInBubble.VisibleReaction visibleReaction, boolean notify) {
if (visibleReaction == null) {
chosen = 0;
if (notify) {
setFilter(null);
}
adapter.notifyDataSetChanged();
return;
}
for (int i = 0; i < items.size(); i++) {
SearchTagsList.Item item = items.get(i);
if (visibleReaction.hash == item.reaction.hash) {
chosen = item.hash();
if (notify) {
setFilter(item.reaction);
}
adapter.notifyDataSetChanged();
listView.scrollToPosition(i);
break;
}
}
}
private void createPremiumLayout() {
if (premiumLayout != null) {
return;
}
premiumLayout = new LinearLayout(getContext());
premiumLayout.setOnClickListener(v -> {
new PremiumFeatureBottomSheet(fragment, PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS, true).show();
});
premiumLayout.setOrientation(LinearLayout.HORIZONTAL);
ScaleStateListAnimator.apply(premiumLayout, 0.03f, 1.25f);
TextView tagView = new TextView(getContext()) {
private final Path path = new Path();
private final RectF bounds = new RectF();
private final Paint paint = new Paint();
@Override
protected void dispatchDraw(Canvas canvas) {
paint.setColor(Theme.multAlpha(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText2, resourcesProvider), 0.10f));
bounds.set(0, 0, getWidth(), getHeight());
ReactionsLayoutInBubble.fillTagPath(bounds, path);
canvas.drawPath(path, paint);
super.dispatchDraw(canvas);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
int left = getWidth(), right = 0;
for (int i = 0; i < getChildCount(); ++i) {
left = Math.min(left, getChildAt(i).getLeft());
right = Math.max(right, getChildAt(i).getRight());
}
setPivotX((left + right) / 2f);
}
};
tagView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText2, resourcesProvider));
tagView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
tagView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
SpannableStringBuilder ssb = new SpannableStringBuilder();
Drawable lockDrawable = getContext().getResources().getDrawable(R.drawable.msg_mini_lock3).mutate();
lockDrawable.setColorFilter(new PorterDuffColorFilter(Theme.key_chat_messageLinkIn, PorterDuff.Mode.SRC_IN));
ColoredImageSpan span = new ColoredImageSpan(lockDrawable);
span.setTranslateY(0);
span.setTranslateX(0);
span.setScale(.94f, .94f);
SpannableString lock = new SpannableString("l");
lock.setSpan(span, 0, lock.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
ssb.append(lock);
ssb.append(" ").append(LocaleController.getString(R.string.AddTagsToYourSavedMessages1));
tagView.setText(ssb);
tagView.setPadding(dp(4), dp(4), dp(9), dp(4));
TextView textView = new TextView(getContext());
textView.setTextColor(Theme.getColor(Theme.key_windowBackgroundWhiteBlueText2, resourcesProvider));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
textView.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
ssb = new SpannableStringBuilder(LocaleController.getString(R.string.AddTagsToYourSavedMessages2));
SpannableString arrow = new SpannableString(">");
Drawable imageDrawable = getContext().getResources().getDrawable(R.drawable.msg_arrowright).mutate();
imageDrawable.setColorFilter(new PorterDuffColorFilter(Theme.key_chat_messageLinkIn, PorterDuff.Mode.SRC_IN));
span = new ColoredImageSpan(imageDrawable);
span.setScale(.76f, .76f);
span.setTranslateX(-dp(1));
span.setTranslateY(dp(1));
arrow.setSpan(span, 0, arrow.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
ssb.append(arrow);
textView.setText(ssb);
textView.setPadding(dp(5.66f), dp(4), dp(9), dp(4));
premiumLayout.addView(tagView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
premiumLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
addView(premiumLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.FILL_HORIZONTAL, 16.33f, 0, 16.33f, 0));
}
private long topicId;
public SearchTagsList(Context context, BaseFragment fragment, SizeNotifierFrameLayout contentView, int currentAccount, long topicId, Theme.ResourcesProvider resourcesProvider, boolean showWithCut) {
super(context, contentView); super(context, contentView);
this.showWithCut = showWithCut;
this.currentAccount = currentAccount; this.currentAccount = currentAccount;
this.fragment = fragment;
this.resourcesProvider = resourcesProvider; this.resourcesProvider = resourcesProvider;
this.topicId = topicId;
ReactionsLayoutInBubble.initPaints(resourcesProvider);
listView = new RecyclerListView(context, resourcesProvider) { listView = new RecyclerListView(context, resourcesProvider) {
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (premiumLayout != null && premiumLayout.getAlpha() > 0.5f) {
return false;
}
return super.dispatchTouchEvent(ev);
}
@Override @Override
public Integer getSelectorColor(int position) { public Integer getSelectorColor(int position) {
return 0; return 0;
@ -90,59 +248,291 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
layoutManager.setOrientation(RecyclerView.HORIZONTAL); layoutManager.setOrientation(RecyclerView.HORIZONTAL);
listView.setLayoutManager(layoutManager); listView.setLayoutManager(layoutManager);
listView.setAdapter(adapter = new Adapter()); listView.setAdapter(adapter = new Adapter());
addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT)); listView.setOverScrollMode(OVER_SCROLL_NEVER);
addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48));
listView.setOnItemClickListener((view, position) -> { listView.setOnItemClickListener((view, position) -> {
if (position < 0 || position >= items.size()) { if (position < 0 || position >= items.size()) {
return; return;
} }
if (!UserConfig.getInstance(currentAccount).isPremium()) {
new PremiumFeatureBottomSheet(fragment, PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS, true).show();
return;
}
long hash = items.get(position).hash();
if (!setFilter(chosen == hash ? null : items.get(position).reaction)) {
return;
}
for (int i = 0; i < listView.getChildCount(); i++) {
View child = listView.getChildAt(i);
if (child == view) {
if (i <= 1) {
listView.smoothScrollBy(-dp(i == 0 ? 90 : 50), 0);
} else if (i >= listView.getChildCount() - 2) {
listView.smoothScrollBy(dp((i == listView.getChildCount() - 1) ? 80 : 50), 0);
}
}
}
listView.forAllChild(view2 -> { listView.forAllChild(view2 -> {
if (view2 instanceof TagButton) { if (view2 instanceof TagButton) {
((TagButton) view2).setChosen(false, true); ((TagButton) view2).setChosen(false, true);
} }
}); });
long hash = items.get(position).hash();
if (chosen == hash) { if (chosen == hash) {
chosen = 0; chosen = 0;
setFilter(null);
} else { } else {
chosen = hash; chosen = hash;
setFilter(items.get(position).reaction);
((TagButton) view).setChosen(true, true); ((TagButton) view).setChosen(true, true);
} }
}); });
listView.setOnItemLongClickListener((view, position) -> {
if (position < 0 || position >= items.size() || !UserConfig.getInstance(currentAccount).isPremium())
return false;
if (!UserConfig.getInstance(currentAccount).isPremium()) {
new PremiumFeatureBottomSheet(fragment, PremiumPreviewFragment.PREMIUM_FEATURE_SAVED_TAGS, true).show();
return true;
}
TagButton btn = (TagButton) view;
if (btn.reactionButton != null) {
btn.reactionButton.startAnimation();
}
final Item item = items.get(position);
ItemOptions.makeOptions(fragment, view)
.setGravity(Gravity.LEFT)
.add(R.drawable.menu_tag_rename, LocaleController.getString(TextUtils.isEmpty(item.name) ? R.string.SavedTagLabelTag : R.string.SavedTagRenameTag), () -> {
openRenameTagAlert(getContext(), currentAccount, item.reaction.toTLReaction(), resourcesProvider, false);
})
.show();
return true;
});
DefaultItemAnimator itemAnimator = new DefaultItemAnimator() { DefaultItemAnimator itemAnimator = new DefaultItemAnimator() {
@Override @Override
public boolean animateMove(RecyclerView.ViewHolder holder, ItemHolderInfo info, int fromX, int fromY, int toX, int toY) { public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder) {
int position = holder.getAdapterPosition(); return true;
if (position >= 0 && position < items.size()) {
Item item = items.get(position);
TagButton btn = (TagButton) holder.itemView;
boolean updatedChosen = btn.setChosen(chosen == item.hash(), true);
boolean updatedCount = btn.setCount(item.count);
if (updatedChosen || updatedCount) {
return true;
}
}
return super.animateMove(holder, info, fromX, fromY, toX, toY);
} }
@Override @Override
protected void animateMoveImpl(RecyclerView.ViewHolder holder, MoveInfo moveInfo) { public boolean animateMove(RecyclerView.ViewHolder holder, ItemHolderInfo info, int fromX, int fromY, int toX, int toY) {
super.animateMoveImpl(holder, moveInfo); final View view = holder.itemView;
if (view instanceof TagButton) {
((TagButton) view).startAnimate();
}
fromX += (int) holder.itemView.getTranslationX();
fromY += (int) holder.itemView.getTranslationY();
resetAnimation(holder);
int deltaX = toX - fromX;
int deltaY = toY - fromY;
if (deltaX == 0 && deltaY == 0) {
dispatchMoveFinished(holder);
return false;
}
if (deltaX != 0) {
view.setTranslationX(-deltaX);
}
if (deltaY != 0) {
view.setTranslationY(-deltaY);
}
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
checkIsRunning();
return true;
} }
}; };
itemAnimator.setSupportsChangeAnimations(false);
itemAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT); itemAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
itemAnimator.setDurations(320); itemAnimator.setDurations(320);
listView.setItemAnimator(itemAnimator); listView.setItemAnimator(itemAnimator);
MediaDataController.getInstance(currentAccount).loadSavedReactions(false); MediaDataController.getInstance(currentAccount).loadSavedReactions(false);
updateTags(); updateTags(false);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == listView && premiumLayout != null) {
if (premiumLayout.getAlpha() >= 1f)
return false;
canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), (int) (0xFF * (1f - premiumLayout.getAlpha())), Canvas.ALL_SAVE_FLAG);
boolean r = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return r;
}
return super.drawChild(canvas, child, drawingTime);
}
private static AlertDialog currentDialog;
public static boolean onBackPressedRenameTagAlert() {
if (currentDialog != null) {
currentDialog.dismiss();
currentDialog = null;
return true;
}
return false;
}
public static void openRenameTagAlert(Context context, int currentAccount, TLRPC.Reaction reaction, Theme.ResourcesProvider resourcesProvider, boolean forceNotAdaptive) {
Activity activity = AndroidUtilities.findActivity(context);
View currentFocus = activity != null ? activity.getCurrentFocus() : null;
final boolean adaptive = currentFocus instanceof EditText && !forceNotAdaptive;
AlertDialog[] dialog = new AlertDialog[1];
AlertDialog.Builder builder;
if (adaptive) {
builder = new AlertDialogDecor.Builder(context, resourcesProvider);
} else {
builder = new AlertDialog.Builder(context, resourcesProvider);
}
String[] hintText = new String[1];
String name = MessagesController.getInstance(currentAccount).getSavedTagName(reaction);
builder.setTitle(new SpannableStringBuilder(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(reaction).toCharSequence(20)).append(" ").append(LocaleController.getString(TextUtils.isEmpty(name) ? R.string.SavedTagLabelTag : R.string.SavedTagRenameTag)));
final int MAX_NAME_LENGTH = 12;
EditTextBoldCursor editText = new EditTextBoldCursor(context) {
AnimatedColor limitColor = new AnimatedColor(this);
private int limitCount;
AnimatedTextView.AnimatedTextDrawable limit = new AnimatedTextView.AnimatedTextDrawable(false, true, true); {
limit.setAnimationProperties(.2f, 0, 160, CubicBezierInterpolator.EASE_OUT_QUINT);
limit.setTextSize(dp(15.33f));
limit.setCallback(this);
limit.setGravity(Gravity.RIGHT);
}
@Override
protected boolean verifyDrawable(@NonNull Drawable who) {
return who == limit || super.verifyDrawable(who);
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
if (limit != null) {
limitCount = MAX_NAME_LENGTH - text.length();
limit.cancelAnimation();
limit.setText(limitCount > 4 ? "" : "" + limitCount);
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
limit.setTextColor(limitColor.set(Theme.getColor(limitCount < 0 ? Theme.key_text_RedRegular : Theme.key_dialogSearchHint, resourcesProvider)));
limit.setBounds(getScrollX(), 0, getScrollX() + getWidth(), getHeight());
limit.draw(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(36), MeasureSpec.EXACTLY));
}
};
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
String text = editText.getText().toString();
if (text.length() > MAX_NAME_LENGTH) {
AndroidUtilities.shakeView(editText);
return true;
}
MessagesController.getInstance(currentAccount).renameSavedReactionTag(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(reaction), text);
if (dialog[0] != null) {
dialog[0].dismiss();
}
if (dialog[0] == currentDialog) {
currentDialog = null;
}
if (currentFocus != null) {
currentFocus.requestFocus();
}
return true;
}
return false;
}
});
MediaDataController.getInstance(currentAccount).fetchNewEmojiKeywords(AndroidUtilities.getCurrentKeyboardLanguage(), true);
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
editText.setText(name == null ? "" : name);
editText.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
editText.setHintColor(Theme.getColor(Theme.key_groupcreate_hintText, resourcesProvider));
editText.setHintText(LocaleController.getString(R.string.SavedTagLabelPlaceholder));
editText.setSingleLine(true);
editText.setFocusable(true);
editText.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
editText.setLineColors(Theme.getColor(Theme.key_windowBackgroundWhiteInputField, resourcesProvider), Theme.getColor(Theme.key_windowBackgroundWhiteInputFieldActivated, resourcesProvider), Theme.getColor(Theme.key_text_RedRegular, resourcesProvider));
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setBackgroundDrawable(null);
editText.setPadding(0, 0, dp(42), 0);
// editText.addTextChangedListener(new TextWatcher() {
// boolean ignoreTextChange;
// @Override
// public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
// @Override
// public void onTextChanged(CharSequence s, int start, int before, int count) {}
// @Override
// public void afterTextChanged(Editable s) {
// if (ignoreTextChange) {
// return;
// }
// if (s.length() > MAX_NAME_LENGTH) {
// ignoreTextChange = true;
// s.delete(MAX_NAME_LENGTH, s.length());
// AndroidUtilities.shakeView(editText);
// editText.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
// ignoreTextChange = false;
// }
// }
// });
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlack, resourcesProvider));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setText(LocaleController.getString(R.string.SavedTagLabelTagText));
container.addView(textView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 24, 5, 24, 12));
container.addView(editText, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 24, 0, 24, 10));
builder.setView(container);
builder.setWidth(dp(292));
builder.setPositiveButton(LocaleController.getString(R.string.Save), (dialogInterface, i) -> {
String text = editText.getText().toString();
if (text.length() > MAX_NAME_LENGTH) {
AndroidUtilities.shakeView(editText);
return;
}
MessagesController.getInstance(currentAccount).renameSavedReactionTag(ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(reaction), text);
dialogInterface.dismiss();
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialogInterface, i) -> {
dialogInterface.dismiss();
});
if (adaptive) {
dialog[0] = currentDialog = builder.create();
currentDialog.setOnDismissListener(d -> {
currentDialog = null;
currentFocus.requestFocus();
});
currentDialog.setOnShowListener(d -> {
editText.requestFocus();
AndroidUtilities.showKeyboard(editText);
});
currentDialog.showDelayed(250);
} else {
dialog[0] = builder.create();
dialog[0].setOnDismissListener(d -> {
AndroidUtilities.hideKeyboard(editText);
});
dialog[0].setOnShowListener(d -> {
editText.requestFocus();
AndroidUtilities.showKeyboard(editText);
});
dialog[0].show();
}
dialog[0].setDismissDialogByButtons(false);
editText.setSelection(editText.getText().length());
} }
public boolean hasFilters() { public boolean hasFilters() {
return !items.isEmpty(); return !items.isEmpty() || shownPremiumLayout;
} }
public void clear() { public void clear() {
@ -154,68 +544,109 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
chosen = 0; chosen = 0;
} }
protected void setFilter(ReactionsLayoutInBubble.VisibleReaction reaction) { protected boolean setFilter(ReactionsLayoutInBubble.VisibleReaction reaction) {
return true;
} }
public void attach() { public void attach() {
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.savedReactionTagsUpdate); NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.savedReactionTagsUpdate);
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.emojiLoaded);
} }
public void detach() { public void detach() {
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.savedReactionTagsUpdate); NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.savedReactionTagsUpdate);
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.emojiLoaded);
} }
@Override @Override
public void didReceivedNotification(int id, int account, Object... args) { public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.savedReactionTagsUpdate) { if (id == NotificationCenter.savedReactionTagsUpdate) {
updateTags(); final long thisTopicId = (long) args[0];
if (thisTopicId == 0 || thisTopicId == topicId) {
updateTags(true);
}
} else if (id == NotificationCenter.emojiLoaded) {
invalidate();
AndroidUtilities.forEachViews(listView, View::invalidate);
} }
} }
public void updateTags() { public void updateTags(boolean notify) {
HashSet<Long> hashes = new HashSet<>(); HashSet<Long> hashes = new HashSet<>();
oldItems.clear(); oldItems.clear();
oldItems.addAll(items); oldItems.addAll(items);
items.clear(); items.clear();
TLRPC.TL_messages_savedReactionsTags savedReactionsTags = MessagesController.getInstance(currentAccount).getSavedReactionTags();
final MessagesController ms = MessagesController.getInstance(currentAccount);
TLRPC.TL_messages_savedReactionsTags savedReactionsTags = ms.getSavedReactionTags(topicId);
boolean hasChosen = false;
if (savedReactionsTags != null) { if (savedReactionsTags != null) {
for (int i = 0; i < savedReactionsTags.tags.size(); ++i) { for (int i = 0; i < savedReactionsTags.tags.size(); ++i) {
TLRPC.TL_savedReactionTag tag = savedReactionsTags.tags.get(i); TLRPC.TL_savedReactionTag tag = savedReactionsTags.tags.get(i);
ReactionsLayoutInBubble.VisibleReaction r = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(tag.reaction); ReactionsLayoutInBubble.VisibleReaction r = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(tag.reaction);
if (!hashes.contains(r.hash)) { if (!hashes.contains(r.hash)) {
items.add(Item.get(r, tag.count)); if (topicId != 0 && tag.count <= 0)
continue;
Item item = Item.get(r, tag.count, topicId != 0 ? ms.getSavedTagName(tag.reaction) : tag.title);
if (item.hash() == chosen) {
hasChosen = true;
}
items.add(item);
hashes.add(r.hash); hashes.add(r.hash);
} }
} }
} }
// ArrayList<TLRPC.Reaction> defaultReactions = MediaDataController.getInstance(currentAccount).getSavedReactions();
// for (int i = 0; i < defaultReactions.size(); ++i) {
// ReactionsLayoutInBubble.VisibleReaction r = ReactionsLayoutInBubble.VisibleReaction.fromTLReaction(defaultReactions.get(i));
// if (!hashes.contains(r.hash)) {
// items.add(Item.get(r, 0));
// hashes.add(r.hash);
// }
// }
DiffUtil.calculateDiff(new DiffUtil.Callback() { if (!hasChosen && chosen != 0) {
@Override chosen = 0;
public int getOldListSize() { setFilter(null);
return oldItems.size(); }
if (notify) {
DiffUtil.calculateDiff(new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return oldItems.size();
}
@Override
public int getNewListSize() {
return items.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).hash() == items.get(newItemPosition).hash();
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).equals(items.get(newItemPosition));
}
}).dispatchUpdatesTo(adapter);
} else {
adapter.notifyDataSetChanged();
}
if (shownPremiumLayout = !UserConfig.getInstance(currentAccount).isPremium()) {
createPremiumLayout();
if (!notify) {
premiumLayout.setVisibility(View.VISIBLE);
premiumLayout.setAlpha(0f);
premiumLayout.animate().alpha(1f).start();
} }
@Override } else if (premiumLayout != null) {
public int getNewListSize() { if (notify) {
return items.size(); premiumLayout.animate().alpha(0f).withEndAction(() -> {
premiumLayout.setVisibility(View.GONE);
}).start();
} else {
premiumLayout.setAlpha(1f);
premiumLayout.setVisibility(View.VISIBLE);
} }
@Override }
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).equals(items.get(newItemPosition));
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return oldItems.get(oldItemPosition).hash() == items.get(newItemPosition).hash();
}
}).dispatchUpdatesTo(adapter);
} }
@Override @Override
@ -231,36 +662,87 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
return super.dispatchTouchEvent(ev); return super.dispatchTouchEvent(ev);
} }
private float shownT; public float shownT;
public boolean showWithCut = true;
public void setShown(float shownT) { public void setShown(float shownT) {
this.shownT = shownT; this.shownT = shownT;
listView.setPivotX(listView.getWidth() / 2f); listView.setPivotX(listView.getWidth() / 2f);
listView.setPivotY(0); listView.setPivotY(0);
listView.setScaleX(lerp(0.8f, 1, shownT)); listView.setScaleX(lerp(0.8f, 1, shownT));
listView.setScaleY(lerp(0.8f, 1, shownT)); listView.setScaleY(lerp(0.8f, 1, shownT));
listView.setAlpha(shownT); if (showWithCut) {
listView.setAlpha(shownT);
} else {
setAlpha(shownT);
}
invalidate(); invalidate();
} }
protected void onShownUpdate(boolean finish) {
}
private float actionBarTagsT;
private ValueAnimator actionBarTagsAnimator;
public void show(boolean show) {
if (actionBarTagsAnimator != null) {
Animator a = actionBarTagsAnimator;
actionBarTagsAnimator = null;
a.cancel();
}
if (show) {
setVisibility(View.VISIBLE);
}
actionBarTagsAnimator = ValueAnimator.ofFloat(actionBarTagsT, show ? 1f : 0f);
actionBarTagsAnimator.addUpdateListener(valueAnimator1 -> {
actionBarTagsT = (float) valueAnimator1.getAnimatedValue();
setShown(actionBarTagsT);
onShownUpdate(false);
});
actionBarTagsAnimator.setInterpolator(CubicBezierInterpolator.EASE_OUT_QUINT);
actionBarTagsAnimator.setDuration(320);
actionBarTagsAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (animation != actionBarTagsAnimator) return;
actionBarTagsT = show ? 1f : 0f;
setShown(actionBarTagsT);
if (!show) {
setVisibility(View.GONE);
}
onShownUpdate(true);
}
});
actionBarTagsAnimator.start();
}
public boolean shown() { public boolean shown() {
return shownT > 0.5f; return shownT > 0.5f;
} }
// private final Paint backgroundPaint = new Paint();
// @Override
// public void setBackgroundColor(int color) {
// backgroundPaint.setColor(color);
// }
public int getCurrentHeight() { public int getCurrentHeight() {
return (int) (getMeasuredHeight() * shownT); return (int) (getMeasuredHeight() * shownT);
} }
private Paint backgroundPaint2;
@Override
public void setBackgroundColor(int color) {
if (SharedConfig.chatBlurEnabled() && super.sizeNotifierFrameLayout != null) {
super.setBackgroundColor(color);
} else {
backgroundPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
backgroundPaint2.setColor(color);
}
}
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
canvas.save(); canvas.save();
// canvas.drawRect(0, 0, getWidth(), getCurrentHeight(), backgroundPaint); if (showWithCut) {
canvas.clipRect(0, 0, getWidth(), getCurrentHeight()); canvas.clipRect(0, 0, getWidth(), getCurrentHeight());
}
if (backgroundPaint2 != null) {
canvas.drawRect(0, 0, getWidth(), getCurrentHeight(), backgroundPaint2);
}
super.dispatchDraw(canvas); super.dispatchDraw(canvas);
canvas.restore(); canvas.restore();
} }
@ -288,7 +770,16 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
if (position < 0 || position >= items.size()) return; if (position < 0 || position >= items.size()) return;
final Item item = items.get(position); final Item item = items.get(position);
((TagButton) holder.itemView).set(item.reaction.toTLReaction(), item.count); ((TagButton) holder.itemView).set(item);
((TagButton) holder.itemView).setChosen(item.hash() == chosen, false);
}
@Override
public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
super.onViewAttachedToWindow(holder);
int position = holder.getAdapterPosition();
if (position < 0 || position >= items.size()) return;
final Item item = items.get(position);
((TagButton) holder.itemView).setChosen(item.hash() == chosen, false); ((TagButton) holder.itemView).setChosen(item.hash() == chosen, false);
} }
@ -305,50 +796,93 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
private class TagButton extends View { private class TagButton extends View {
public ReactionsLayoutInBubble.ReactionButton reactionButton; public ReactionsLayoutInBubble.ReactionButton reactionButton;
private final AnimatedFloat progress = new AnimatedFloat(this, 0, 260, CubicBezierInterpolator.EASE_OUT_QUINT);
private int count;
public TagButton(Context context) { public TagButton(Context context) {
super(context); super(context);
ScaleStateListAnimator.apply(this); ScaleStateListAnimator.apply(this);
} }
private int count; private ReactionsLayoutInBubble.VisibleReaction lastReaction;
public void set(TLRPC.Reaction reaction, Integer count) { public void set(Item item) {
TLRPC.TL_reactionCount reactionCount = new TLRPC.TL_reactionCount(); boolean newReactionButton = lastReaction == null || !lastReaction.equals(item.reaction);
reactionCount.reaction = reaction; if (newReactionButton) {
reactionCount.count = this.count = count == null ? 0 : count; TLRPC.TL_reactionCount reactionCount = new TLRPC.TL_reactionCount();
reactionCount.reaction = item.reaction.toTLReaction();
reactionCount.count = item.count;
reactionButton = new ReactionsLayoutInBubble.ReactionButton(null, currentAccount, this, reactionCount, false, resourcesProvider) { reactionButton = new ReactionsLayoutInBubble.ReactionButton(null, currentAccount, this, reactionCount, false, true, resourcesProvider) {
@Override @Override
protected void updateColors(float progress) { protected void updateColors(float progress) {
lastDrawnTextColor = ColorUtils.blendARGB(fromTextColor, chosen ? Theme.getColor(Theme.key_chat_inReactionButtonTextSelected) : Theme.getColor(Theme.key_windowBackgroundWhiteGrayText2), progress); lastDrawnTextColor = ColorUtils.blendARGB(fromTextColor, chosen ? Theme.getColor(Theme.key_chat_inReactionButtonTextSelected, resourcesProvider) : Theme.getColor(Theme.key_actionBarActionModeReactionText, resourcesProvider), progress);
lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, chosen ? Theme.getColor(Theme.key_chat_inReactionButtonBackground, resourcesProvider) : Theme.getColor(Theme.key_actionBarActionModeReaction, resourcesProvider), progress); lastDrawnBackgroundColor = ColorUtils.blendARGB(fromBackgroundColor, chosen ? Theme.getColor(Theme.key_chat_inReactionButtonBackground, resourcesProvider) : Theme.getColor(Theme.key_actionBarActionModeReaction, resourcesProvider), progress);
} lastDrawnTextColor = Theme.blendOver(lastDrawnBackgroundColor, lastDrawnTextColor);
lastDrawnTagDotColor = ColorUtils.blendARGB(fromTagDotColor, chosen ? 0x5affffff : Theme.getColor(Theme.key_actionBarActionModeReactionDot, resourcesProvider), progress);
}
@Override @Override
protected boolean drawTagDot() { protected boolean drawTagDot() {
return !drawCounter(); return !drawCounter();
} }
@Override @Override
protected int getCacheType() { protected int getCacheType() {
return AnimatedEmojiDrawable.CACHE_TYPE_ALERT_EMOJI_STATUS; return AnimatedEmojiDrawable.CACHE_TYPE_SAVED_REACTION;
} }
@Override @Override
protected boolean drawCounter() { protected boolean drawCounter() {
return count > 0 || counterDrawable.countChangeProgress != 1f; return count > 0 || hasName || counterDrawable.countChangeProgress != 1f;
} }
};
@Override
protected boolean drawTextWithCounter() {
return true;
}
};
reactionButton.counterDrawable.setSize(dp(29), dp(100));
reactionButton.isTag = true;
} else {
reactionButton.count = item.count;
}
lastReaction = item.reaction;
if (!newReactionButton) {
reactionButton.animateFromWidth = reactionButton.width;
}
reactionButton.width = dp(44.33f); reactionButton.width = dp(44.33f);
reactionButton.counterDrawable.setCount(reactionCount.count, false); reactionButton.hasName = !TextUtils.isEmpty(item.name);
if (reactionButton.counterDrawable != null && reactionButton.count > 0) { if (reactionButton.hasName) {
reactionButton.width += reactionButton.counterDrawable.textPaint.measureText(reactionButton.countText); reactionButton.textDrawable.setText(Emoji.replaceEmoji(item.name, reactionButton.textDrawable.getPaint().getFontMetricsInt(), false), !newReactionButton);
} else if (reactionButton.textDrawable != null) {
reactionButton.textDrawable.setText("", !newReactionButton);
}
reactionButton.countText = Integer.toString(item.count);
reactionButton.counterDrawable.setCount(item.count, !newReactionButton);
if (reactionButton.counterDrawable != null && (reactionButton.count > 0 || reactionButton.hasName)) {
reactionButton.width += reactionButton.counterDrawable.getCurrentWidth() + dp(reactionButton.hasName ? 4 : 0) + reactionButton.textDrawable.getAnimateToWidth();
}
if (newReactionButton) {
reactionButton.animateFromWidth = reactionButton.width;
} }
reactionButton.height = dp(28); reactionButton.height = dp(28);
reactionButton.choosen = chosen; reactionButton.choosen = chosen;
if (attached) { if (attached) {
reactionButton.attach(); reactionButton.attach();
} }
if (!newReactionButton) {
requestLayout();
}
}
public void startAnimate() {
if (reactionButton == null) return;
reactionButton.fromTextColor = reactionButton.lastDrawnTextColor;
reactionButton.fromBackgroundColor = reactionButton.lastDrawnBackgroundColor;
reactionButton.fromTagDotColor = reactionButton.lastDrawnTagDotColor;
progress.set(0, true);
invalidate();
} }
private boolean chosen; private boolean chosen;
@ -361,6 +895,7 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
if (animated) { if (animated) {
reactionButton.fromTextColor = reactionButton.lastDrawnTextColor; reactionButton.fromTextColor = reactionButton.lastDrawnTextColor;
reactionButton.fromBackgroundColor = reactionButton.lastDrawnBackgroundColor; reactionButton.fromBackgroundColor = reactionButton.lastDrawnBackgroundColor;
reactionButton.fromTagDotColor = reactionButton.lastDrawnTagDotColor;
progress.set(0, true); progress.set(0, true);
} else { } else {
progress.set(1, true); progress.set(1, true);
@ -370,30 +905,11 @@ public class SearchTagsList extends BlurredFrameLayout implements NotificationCe
return true; return true;
} }
public boolean setCount(int count) {
if (this.count != count && reactionButton != null) {
reactionButton.animateFromWidth = reactionButton.width;
reactionButton.count = count;
reactionButton.width = dp(44.33f);
reactionButton.counterDrawable.setCount(count, true);
if (reactionButton.counterDrawable != null && reactionButton.count > 0) {
reactionButton.width += reactionButton.counterDrawable.textPaint.measureText(reactionButton.countText);
}
progress.set(0, true);
invalidate();
return true;
}
return false;
}
@Override @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(MeasureSpec.makeMeasureSpec(dp(8.67f) + (reactionButton != null ? reactionButton.width : dp(44.33f)), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(40), MeasureSpec.EXACTLY)); super.onMeasure(MeasureSpec.makeMeasureSpec(dp(8.67f) + (reactionButton != null ? reactionButton.width : dp(44.33f)), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dp(40), MeasureSpec.EXACTLY));
} }
private AnimatedFloat progress = new AnimatedFloat(this, 0, 260, CubicBezierInterpolator.EASE_OUT_QUINT);
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
reactionButton.draw(canvas, (getWidth() - reactionButton.width) / 2f, (getHeight() - reactionButton.height) / 2f, progress.set(1f), 1f, false); reactionButton.draw(canvas, (getWidth() - reactionButton.width) / 2f, (getHeight() - reactionButton.height) / 2f, progress.set(1f), 1f, false);

View file

@ -3022,8 +3022,10 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
TLRPC.Dialog dialog = new TLRPC.TL_dialog(); TLRPC.Dialog dialog = new TLRPC.TL_dialog();
if (object instanceof TLRPC.User) { if (object instanceof TLRPC.User) {
dialog.id = ((TLRPC.User) object).id; dialog.id = ((TLRPC.User) object).id;
} else { } else if (object instanceof TLRPC.Chat) {
dialog.id = -((TLRPC.Chat) object).id; dialog.id = -((TLRPC.Chat) object).id;
} else {
return null;
} }
return dialog; return dialog;
} }
@ -3042,8 +3044,10 @@ public class ShareAlert extends BottomSheet implements NotificationCenter.Notifi
TLRPC.Dialog dialog = new TLRPC.TL_dialog(); TLRPC.Dialog dialog = new TLRPC.TL_dialog();
if (object instanceof TLRPC.User) { if (object instanceof TLRPC.User) {
dialog.id = ((TLRPC.User) object).id; dialog.id = ((TLRPC.User) object).id;
} else { } else if (object instanceof TLRPC.Chat) {
dialog.id = -((TLRPC.Chat) object).id; dialog.id = -((TLRPC.Chat) object).id;
} else {
return null;
} }
return dialog; return dialog;
} }

View file

@ -30,6 +30,7 @@ import org.telegram.messenger.SvgHelper;
import org.telegram.messenger.UserConfig; import org.telegram.messenger.UserConfig;
import org.telegram.tgnet.TLRPC; import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme; import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.spoilers.SpoilersTextView;
import org.telegram.ui.LaunchActivity; import org.telegram.ui.LaunchActivity;
public class StickerEmptyView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate { public class StickerEmptyView extends FrameLayout implements NotificationCenter.NotificationCenterDelegate {
@ -43,7 +44,7 @@ public class StickerEmptyView extends FrameLayout implements NotificationCenter.
public LinearLayout linearLayout; public LinearLayout linearLayout;
public BackupImageView stickerView; public BackupImageView stickerView;
private RadialProgressView progressBar; private RadialProgressView progressBar;
public final TextView title; public final SpoilersTextView title;
public final LinkSpanDrawable.LinksTextView subtitle; public final LinkSpanDrawable.LinksTextView subtitle;
private boolean progressShowing; private boolean progressShowing;
private final Theme.ResourcesProvider resourcesProvider; private final Theme.ResourcesProvider resourcesProvider;
@ -103,9 +104,9 @@ public class StickerEmptyView extends FrameLayout implements NotificationCenter.
stickerView = new BackupImageView(context); stickerView = new BackupImageView(context);
stickerView.setOnClickListener(view -> stickerView.getImageReceiver().startAnimation()); stickerView.setOnClickListener(view -> stickerView.getImageReceiver().startAnimation());
title = new TextView(context); title = new SpoilersTextView(context);
title.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf")); title.setTypeface(AndroidUtilities.getTypeface(AndroidUtilities.TYPEFACE_ROBOTO_MEDIUM));
title.setTag(Theme.key_windowBackgroundWhiteBlackText); title.setTag(Theme.key_windowBackgroundWhiteBlackText);
title.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText)); title.setTextColor(getThemedColor(Theme.key_windowBackgroundWhiteBlackText));
title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20); title.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);

View file

@ -35,6 +35,7 @@ import android.text.TextWatcher;
import android.transition.Transition; import android.transition.Transition;
import android.transition.TransitionManager; import android.transition.TransitionManager;
import android.transition.TransitionValues; import android.transition.TransitionValues;
import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Gravity; import android.view.Gravity;

View file

@ -179,6 +179,9 @@ public class ThanosEffect extends TextureView {
} }
public void kill() { public void kill() {
if (destroyed) {
return;
}
destroyed = true; destroyed = true;
for (ToSet set : toSet) { for (ToSet set : toSet) {
if (set.doneCallback != null) { if (set.doneCallback != null) {
@ -366,27 +369,31 @@ public class ThanosEffect extends TextureView {
} }
private void resizeInternal(int width, int height) { private void resizeInternal(int width, int height) {
if (!alive) return; if (!alive) {
return;
}
this.width = width; this.width = width;
this.height = height; this.height = height;
GLES31.glViewport(0, 0, width, height); GLES31.glViewport(0, 0, width, height);
GLES31.glUniform2f(sizeHandle, width, height); GLES31.glUniform2f(sizeHandle, width, height);
} }
private boolean killed;
public void kill() { public void kill() {
if (killed) return; if (!alive) {
return;
}
try { try {
Handler handler = getHandler(); Handler handler = getHandler();
if (handler != null) { if (handler != null) {
handler.sendMessage(handler.obtainMessage(DO_KILL)); handler.sendMessage(handler.obtainMessage(DO_KILL));
} }
killed = true;
} catch (Exception e) {} } catch (Exception e) {}
} }
private void killInternal() { private void killInternal() {
if (!alive) return; if (!alive) {
return;
}
alive = false; alive = false;
for (int i = 0; i < pendingAnimations.size(); ++i) { for (int i = 0; i < pendingAnimations.size(); ++i) {
Animation animation = pendingAnimations.get(i); Animation animation = pendingAnimations.get(i);
@ -615,36 +622,49 @@ public class ThanosEffect extends TextureView {
} }
}; };
public void layoutAnimations() {
}
private final ArrayList<Animation> toAddAnimations = new ArrayList<>(); private final ArrayList<Animation> toAddAnimations = new ArrayList<>();
public void animateGroup(ArrayList<View> views, Runnable whenDone) { public void animateGroup(ArrayList<View> views, Runnable whenDone) {
if (!alive) return; if (!alive) {
Animation animation = new Animation(views, whenDone); for (int i = 0; i < views.size(); ++i) {
Handler handler = getHandler(); views.get(i).setVisibility(GONE);
running = true; }
if (handler == null) { if (whenDone != null) {
toAddAnimations.add(animation); AndroidUtilities.runOnUIThread(whenDone);
} else { }
handler.sendMessage(handler.obtainMessage(DO_ADD_ANIMATION, animation)); if (destroy != null) {
AndroidUtilities.runOnUIThread(destroy);
destroy = null;
}
return;
} }
Animation animation = new Animation(views, whenDone);
running = true;
postRunnable(() -> addAnimationInternal(animation));
} }
public void animate(View view, float durationMultipier, Runnable whenDone) { public void animate(View view, float durationMultipier, Runnable whenDone) {
if (!alive) return; if (!alive) {
if (view != null) {
view.setVisibility(GONE);
}
if (whenDone != null) {
AndroidUtilities.runOnUIThread(whenDone);
}
if (destroy != null) {
AndroidUtilities.runOnUIThread(destroy);
destroy = null;
}
return;
}
Animation animation = new Animation(view, durationMultipier, whenDone); Animation animation = new Animation(view, durationMultipier, whenDone);
Handler handler = getHandler(); Handler handler = getHandler();
running = true; running = true;
if (handler == null) { postRunnable(() -> addAnimationInternal(animation));
toAddAnimations.add(animation);
} else {
handler.sendMessage(handler.obtainMessage(DO_ADD_ANIMATION, animation));
}
} }
public void cancel(View view) { public void cancel(View view) {
if (!alive) return; if (!alive) {
return;
}
Handler handler = getHandler(); Handler handler = getHandler();
if (handler == null) { if (handler == null) {
for (int i = 0; i < toAddAnimations.size(); ++i) { for (int i = 0; i < toAddAnimations.size(); ++i) {
@ -672,15 +692,25 @@ public class ThanosEffect extends TextureView {
} }
public void animate(Matrix matrix, Bitmap bitmap, Runnable whenStart, Runnable whenDone) { public void animate(Matrix matrix, Bitmap bitmap, Runnable whenStart, Runnable whenDone) {
if (!alive) return; if (!alive) {
AndroidUtilities.runOnUIThread(() -> {
if (whenStart != null) {
whenStart.run();
}
if (whenDone != null) {
AndroidUtilities.runOnUIThread(whenDone);
}
});
if (destroy != null) {
AndroidUtilities.runOnUIThread(destroy);
destroy = null;
}
return;
}
Animation animation = new Animation(matrix, bitmap, whenStart, whenDone); Animation animation = new Animation(matrix, bitmap, whenStart, whenDone);
Handler handler = getHandler(); Handler handler = getHandler();
running = true; running = true;
if (handler == null) { postRunnable(() -> addAnimationInternal(animation));
toAddAnimations.add(animation);
} else {
handler.sendMessage(handler.obtainMessage(DO_ADD_ANIMATION, animation));
}
} }
private void cancelAnimationInternal(View view) { private void cancelAnimationInternal(View view) {
@ -823,7 +853,7 @@ public class ThanosEffect extends TextureView {
} }
MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup(); MessageObject.GroupedMessages group = cell.getCurrentMessagesGroup();
MessageObject.GroupedMessagePosition position = group == null || group.positions == null ? null : group.positions.get(cell.getMessageObject()); MessageObject.GroupedMessagePosition position = group == null || group.positions == null ? null : group.getPosition(cell.getMessageObject());
if (k == 0) { if (k == 0) {
if (position != null || cell.getTransitionParams().animateBackgroundBoundsInner) { if (position != null || cell.getTransitionParams().animateBackgroundBoundsInner) {
if (position == null || (position.last || position.minX == 0 && position.minY == 0)) { if (position == null || (position.last || position.minX == 0 && position.minY == 0)) {
@ -922,6 +952,8 @@ public class ThanosEffect extends TextureView {
t -= top; t -= top;
b -= top; b -= top;
l -= left;
r -= left;
boolean useScale = group.transitionParams.cell.getScaleX() != 1f || group.transitionParams.cell.getScaleY() != 1f; boolean useScale = group.transitionParams.cell.getScaleX() != 1f || group.transitionParams.cell.getScaleY() != 1f;
if (useScale) { if (useScale) {

View file

@ -2,13 +2,16 @@ package org.telegram.ui.Components.spoilers;
import android.content.Context; import android.content.Context;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter;
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.Rect; import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
import android.text.Layout; import android.text.Layout;
import android.text.Spannable;
import android.text.Spanned; import android.text.Spanned;
import android.text.StaticLayout; import android.text.StaticLayout;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -16,6 +19,8 @@ import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities; import org.telegram.messenger.AndroidUtilities;
import org.telegram.ui.Cells.TextSelectionHelper; import org.telegram.ui.Cells.TextSelectionHelper;
import org.telegram.ui.Components.AnimatedEmojiDrawable;
import org.telegram.ui.Components.AnimatedEmojiSpan;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -30,6 +35,9 @@ public class SpoilersTextView extends TextView implements TextSelectionHelper.Si
private Paint xRefPaint; private Paint xRefPaint;
public boolean allowClickSpoilers = true; public boolean allowClickSpoilers = true;
public int cacheType = AnimatedEmojiDrawable.CACHE_TYPE_MESSAGES;
private AnimatedEmojiSpan.EmojiGroupedSpans animatedEmoji;
public SpoilersTextView(Context context) { public SpoilersTextView(Context context) {
this(context, true); this(context, true);
} }
@ -68,6 +76,7 @@ public class SpoilersTextView extends TextView implements TextSelectionHelper.Si
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter); super.onTextChanged(text, start, lengthBefore, lengthAfter);
invalidateSpoilers(); invalidateSpoilers();
updateAnimatedEmoji(true);
} }
@Override @Override
@ -76,6 +85,13 @@ public class SpoilersTextView extends TextView implements TextSelectionHelper.Si
invalidateSpoilers(); invalidateSpoilers();
} }
private ColorFilter animatedEmojiColorFilter;
@Override
public void setTextColor(int color) {
super.setTextColor(color);
animatedEmojiColorFilter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
}
@Override @Override
protected void onDraw(Canvas canvas) { protected void onDraw(Canvas canvas) {
int pl = getPaddingLeft(), pt = getPaddingTop(); int pl = getPaddingLeft(), pt = getPaddingTop();
@ -100,6 +116,14 @@ public class SpoilersTextView extends TextView implements TextSelectionHelper.Si
super.onDraw(canvas); super.onDraw(canvas);
canvas.restore(); canvas.restore();
updateAnimatedEmoji(false);
if (animatedEmoji != null) {
canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
AnimatedEmojiSpan.drawAnimatedEmojis(canvas, getLayout(), animatedEmoji, 0, spoilers, 0, getHeight(), 0, 1f, animatedEmojiColorFilter);
canvas.restore();
}
if (!spoilers.isEmpty()) { if (!spoilers.isEmpty()) {
boolean useAlphaLayer = spoilers.get(0).getRippleProgress() != -1; boolean useAlphaLayer = spoilers.get(0).getRippleProgress() != -1;
if (useAlphaLayer) { if (useAlphaLayer) {
@ -127,12 +151,29 @@ public class SpoilersTextView extends TextView implements TextSelectionHelper.Si
} }
} }
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateAnimatedEmoji(true);
}
@Override @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) { protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom); super.onLayout(changed, left, top, right, bottom);
invalidateSpoilers(); invalidateSpoilers();
} }
private Layout lastLayout = null;
private int lastTextLength;
public void updateAnimatedEmoji(boolean force) {
int newTextLength = (getLayout() == null || getLayout().getText() == null) ? 0 : getLayout().getText().length();
if (force || lastLayout != getLayout() || lastTextLength != newTextLength) {
animatedEmoji = AnimatedEmojiSpan.update(cacheType, this, animatedEmoji, getLayout());
lastLayout = getLayout();
lastTextLength = newTextLength;
}
}
private void invalidateSpoilers() { private void invalidateSpoilers() {
if (spoilers == null) return; // Check for a super constructor if (spoilers == null) return; // Check for a super constructor
spoilersPool.addAll(spoilers); spoilersPool.addAll(spoilers);

View file

@ -401,6 +401,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
private boolean askingForPermissions; private boolean askingForPermissions;
private RLottieDrawable passcodeDrawable; private RLottieDrawable passcodeDrawable;
private SearchViewPager searchViewPager; private SearchViewPager searchViewPager;
private SharedMediaLayout.SharedMediaPreloader sharedMediaPreloader;
public DialogStoriesCell dialogStoriesCell; public DialogStoriesCell dialogStoriesCell;
public boolean dialogStoriesCellVisible; public boolean dialogStoriesCellVisible;
public float progressToDialogStoriesCell; public float progressToDialogStoriesCell;
@ -2718,6 +2719,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
getContactsController().loadGlobalPrivacySetting(); getContactsController().loadGlobalPrivacySetting();
if (getMessagesController().savedViewAsChats) {
getMessagesController().getSavedMessagesController().preloadDialogs(true);
}
return true; return true;
} }
@ -4979,6 +4984,11 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
animateToHasStories = false; animateToHasStories = false;
hasOnlySlefStories = false; hasOnlySlefStories = false;
hasStories = false; hasStories = false;
if (onlySelect && initialDialogsType == DIALOGS_TYPE_FORWARD) {
MessagesController.getInstance(currentAccount).getSavedReactionTags(0);
}
if (!onlySelect || initialDialogsType == DIALOGS_TYPE_FORWARD) { if (!onlySelect || initialDialogsType == DIALOGS_TYPE_FORWARD) {
final FrameLayout.LayoutParams layoutParams = LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT); final FrameLayout.LayoutParams layoutParams = LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT);
if (inPreviewMode && Build.VERSION.SDK_INT >= 21) { if (inPreviewMode && Build.VERSION.SDK_INT >= 21) {
@ -6055,7 +6065,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
totalOffset -= dialogsHintCell.getMeasuredHeight() * rightSlidingDialogContainer.openedProgress; totalOffset -= dialogsHintCell.getMeasuredHeight() * rightSlidingDialogContainer.openedProgress;
} }
dialogsHintCell.setTranslationY(totalOffset); dialogsHintCell.setTranslationY(totalOffset);
totalOffset += dialogsHintCell.getMeasuredHeight(); totalOffset += dialogsHintCell.getMeasuredHeight() * (1f - searchAnimationProgress);
} }
if (authHintCell != null && authHintCell.getVisibility() == View.VISIBLE) { if (authHintCell != null && authHintCell.getVisibility() == View.VISIBLE) {
if (rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment()) { if (rightSlidingDialogContainer != null && rightSlidingDialogContainer.hasFragment()) {
@ -7243,9 +7253,15 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
} }
} }
} }
if (fragmentContextView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fragmentContextView.setTranslationZ(1f);
}
searchAnimator.addListener(new AnimatorListenerAdapter() { searchAnimator.addListener(new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationEnd(Animator animation) { public void onAnimationEnd(Animator animation) {
if (fragmentContextView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
fragmentContextView.setTranslationZ(0f);
}
notificationsLocker.unlock(); notificationsLocker.unlock();
if (searchAnimator != animation) { if (searchAnimator != animation) {
return; return;
@ -7829,7 +7845,17 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (searchViewPager.actionModeShowing()) { if (searchViewPager.actionModeShowing()) {
searchViewPager.hideActionMode(); searchViewPager.hideActionMode();
} }
if (searchString != null) { if (dialogId == getUserConfig().getClientUserId() && getMessagesController().savedViewAsChats) {
args = new Bundle();
args.putLong("dialog_id", UserConfig.getInstance(currentAccount).getClientUserId());
args.putInt("type", MediaActivity.TYPE_MEDIA);
args.putInt("start_from", SharedMediaLayout.TAB_SAVED_DIALOGS);
if (sharedMediaPreloader == null) {
sharedMediaPreloader = new SharedMediaLayout.SharedMediaPreloader(this);
}
MediaActivity mediaActivity = new MediaActivity(args, sharedMediaPreloader);
presentFragment(mediaActivity);
} else if (searchString != null) {
if (getMessagesController().checkCanOpenChat(args, DialogsActivity.this)) { if (getMessagesController().checkCanOpenChat(args, DialogsActivity.this)) {
getNotificationCenter().postNotificationName(NotificationCenter.closeChats); getNotificationCenter().postNotificationName(NotificationCenter.closeChats);
presentFragment(new ChatActivity(args)); presentFragment(new ChatActivity(args));

View file

@ -316,7 +316,7 @@ public class GroupCreateFinalActivity extends BaseFragment implements Notificati
} }
if (!TextUtils.isEmpty(txt)) { if (!TextUtils.isEmpty(txt)) {
editText.setText(txt); editText.setText(txt);
editText.setSelection(editText.getText().length()); editText.setSelection(0, editText.getText().length());
} }
} }
} }

View file

@ -75,7 +75,7 @@ public class GroupStickersActivity extends BaseFragment implements NotificationC
private boolean removeStickerSet; private boolean removeStickerSet;
private TLRPC.ChatFull info; private TLRPC.ChatFull info;
private long chatId; private final long chatId;
private int infoRow; private int infoRow;
private int headerRow; private int headerRow;

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