mirror of https://github.com/NekoX-Dev/NekoX.git
960 lines
41 KiB
Java
960 lines
41 KiB
Java
package org.telegram.messenger;
|
|
|
|
import android.content.SharedPreferences;
|
|
import android.text.TextPaint;
|
|
import android.text.TextUtils;
|
|
import android.util.SparseArray;
|
|
|
|
import androidx.collection.LongSparseArray;
|
|
|
|
import org.telegram.SQLite.SQLiteCursor;
|
|
import org.telegram.messenger.support.LongSparseIntArray;
|
|
import org.telegram.tgnet.ConnectionsManager;
|
|
import org.telegram.tgnet.NativeByteBuffer;
|
|
import org.telegram.tgnet.RequestDelegate;
|
|
import org.telegram.tgnet.TLObject;
|
|
import org.telegram.tgnet.TLRPC;
|
|
import org.telegram.ui.ActionBar.AlertDialog;
|
|
import org.telegram.ui.ActionBar.BaseFragment;
|
|
import org.telegram.ui.Components.Forum.ForumUtilities;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Comparator;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
|
|
public class TopicsController extends BaseController {
|
|
|
|
public static final int TOPIC_FLAG_TITLE = 1;
|
|
public static final int TOPIC_FLAG_ICON = 2;
|
|
public static final int TOPIC_FLAG_PIN = 4;
|
|
public static final int TOPIC_FLAG_CLOSE = 8;
|
|
|
|
|
|
private static final int MAX_PRELOAD_COUNT = 20;
|
|
|
|
public static final int LOAD_TYPE_PRELOAD = 0;
|
|
public static final int LOAD_TYPE_LOAD_NEXT = 1;
|
|
public static final int LOAD_TYPE_LOAD_UNKNOWN = 2;
|
|
|
|
LongSparseArray<ArrayList<TLRPC.TL_forumTopic>> topicsByChatId = new LongSparseArray<>();
|
|
LongSparseArray<LongSparseArray<TLRPC.TL_forumTopic>> topicsMapByChatId = new LongSparseArray<>();
|
|
LongSparseIntArray topicsIsLoading = new LongSparseIntArray();
|
|
LongSparseIntArray endIsReached = new LongSparseIntArray();
|
|
LongSparseArray<TLRPC.TL_forumTopic> topicsByTopMsgId = new LongSparseArray<>();
|
|
|
|
LongSparseIntArray currentOpenTopicsCounter = new LongSparseIntArray();
|
|
LongSparseIntArray openedTopicsBuChatId = new LongSparseIntArray();
|
|
|
|
public TopicsController(int num) {
|
|
super(num);
|
|
}
|
|
|
|
public void preloadTopics(long chatId) {
|
|
loadTopics(chatId, true, LOAD_TYPE_PRELOAD);
|
|
}
|
|
|
|
public void loadTopics(long chatId) {
|
|
loadTopics(chatId, false, LOAD_TYPE_LOAD_NEXT);
|
|
}
|
|
|
|
public void loadTopics(long chatId, boolean fromCache, int loadType) {
|
|
if (topicsIsLoading.get(chatId, 0) != 0) {
|
|
return;
|
|
}
|
|
|
|
if (BuildVars.DEBUG_PRIVATE_VERSION) {
|
|
FileLog.d("load topics " + chatId + " fromCache=" + fromCache + " loadType=" + loadType);
|
|
}
|
|
topicsIsLoading.put(chatId, 1);
|
|
|
|
if (fromCache) {
|
|
getMessagesStorage().loadTopics(-chatId, topics -> {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
if (BuildVars.DEBUG_PRIVATE_VERSION) {
|
|
FileLog.d("loaded from cache " + chatId + " topics_count=" + (topics == null ? 0 : topics.size()));
|
|
}
|
|
|
|
topicsIsLoading.put(chatId, 0);
|
|
processTopics(chatId, topics, null, fromCache, loadType, -1);
|
|
|
|
if (!endIsReached(chatId)) {
|
|
endIsReached.put(chatId, getUserConfig().getPreferences().getBoolean("topics_end_reached_" + chatId, false) ? 1 : 0);
|
|
}
|
|
});
|
|
});
|
|
return;
|
|
}
|
|
|
|
TLRPC.TL_channels_getForumTopics getForumTopics = new TLRPC.TL_channels_getForumTopics();
|
|
getForumTopics.channel = getMessagesController().getInputChannel(chatId);
|
|
if (loadType == LOAD_TYPE_PRELOAD) {
|
|
getForumTopics.limit = MAX_PRELOAD_COUNT;
|
|
} else if (loadType == LOAD_TYPE_LOAD_NEXT) {
|
|
getForumTopics.limit = 100;
|
|
TopicsLoadOffset loadOffsets = getLoadOffset(chatId);
|
|
getForumTopics.offset_date = loadOffsets.lastMessageDate;
|
|
getForumTopics.offset_id = loadOffsets.lastMessageId;
|
|
getForumTopics.offset_topic = loadOffsets.lastTopicId;
|
|
|
|
if (BuildVars.DEBUG_PRIVATE_VERSION) {
|
|
FileLog.d("offset_date=" + loadOffsets.lastMessageDate + " offset_id=" + loadOffsets.lastMessageId + " offset_topic=" + loadOffsets.lastTopicId);
|
|
}
|
|
}
|
|
|
|
getConnectionsManager().sendRequest(getForumTopics, (response, error) -> {
|
|
if (response != null) {
|
|
SparseArray<TLRPC.Message> messagesMap = new SparseArray<>();
|
|
TLRPC.TL_messages_forumTopics topics = (TLRPC.TL_messages_forumTopics) response;
|
|
for (int i = 0; i < topics.messages.size(); i++) {
|
|
messagesMap.put(topics.messages.get(i).id, topics.messages.get(i));
|
|
}
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
getMessagesStorage().putUsersAndChats(((TLRPC.TL_messages_forumTopics) response).users, ((TLRPC.TL_messages_forumTopics) response).chats, true, false);
|
|
getMessagesController().putUsers(((TLRPC.TL_messages_forumTopics) response).users, false);
|
|
getMessagesController().putChats(((TLRPC.TL_messages_forumTopics) response).chats, false);
|
|
|
|
topicsIsLoading.put(chatId, 0);
|
|
processTopics(chatId, topics.topics, messagesMap, false, loadType, ((TLRPC.TL_messages_forumTopics) response).count);
|
|
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0);
|
|
|
|
getMessagesStorage().saveTopics(-chatId, topicsByChatId.get(chatId), true, true);
|
|
|
|
if (!topics.topics.isEmpty() && loadType == LOAD_TYPE_LOAD_NEXT) {
|
|
TLRPC.TL_forumTopic lastTopic = topics.topics.get(topics.topics.size() - 1);
|
|
TLRPC.Message lastTopicMessage = messagesMap.get(lastTopic.top_message);
|
|
saveLoadOffset(chatId, lastTopic.top_message, lastTopicMessage == null ? 0 : lastTopicMessage.date, lastTopic.id);
|
|
} else if (getTopics(chatId) == null || getTopics(chatId).size() < topics.count) {
|
|
clearLoadingOffset(chatId);
|
|
loadTopics(chatId);
|
|
}
|
|
});
|
|
} else {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
topicsIsLoading.put(chatId, 0);
|
|
getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, false);
|
|
});
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
public void processTopics(long chatId, ArrayList<TLRPC.TL_forumTopic> newTopics, SparseArray<TLRPC.Message> messagesMap, boolean fromCache, int loadType, int totalCount) {
|
|
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
|
|
ArrayList<TLRPC.TL_forumTopic> topicsToReload = null;
|
|
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
|
|
|
|
if (topics == null) {
|
|
topics = new ArrayList<>();
|
|
topicsByChatId.put(chatId, topics);
|
|
}
|
|
if (topicsMap == null) {
|
|
topicsMap = new LongSparseArray<>();
|
|
topicsMapByChatId.put(chatId, topicsMap);
|
|
}
|
|
|
|
boolean changed = false;
|
|
if (newTopics != null) {
|
|
for (int i = 0; i < newTopics.size(); i++) {
|
|
TLRPC.TL_forumTopic newTopic = newTopics.get(i);
|
|
if (newTopic instanceof TLRPC.TL_forumTopicDeleted) {
|
|
continue;
|
|
}
|
|
if (!topicsMap.containsKey(newTopic.id)) {
|
|
if (messagesMap != null) {
|
|
newTopic.topMessage = messagesMap.get(newTopic.top_message);
|
|
newTopic.topicStartMessage = messagesMap.get(newTopic.id);
|
|
}
|
|
if (newTopic.topMessage == null && !newTopic.isShort) {
|
|
if (topicsToReload == null) {
|
|
topicsToReload = new ArrayList<>();
|
|
}
|
|
topicsToReload.add(newTopic);
|
|
}
|
|
if (newTopic.topicStartMessage == null) {
|
|
newTopic.topicStartMessage = new TLRPC.TL_message();
|
|
newTopic.topicStartMessage.message = "";
|
|
newTopic.topicStartMessage.id = newTopic.id;
|
|
newTopic.topicStartMessage.peer_id = getMessagesController().getPeer(-chatId);
|
|
newTopic.topicStartMessage.action = new TLRPC.TL_messageActionTopicCreate();
|
|
newTopic.topicStartMessage.action.title = newTopic.title;
|
|
}
|
|
topics.add(newTopic);
|
|
topicsMap.put(newTopic.id, newTopic);
|
|
topicsByTopMsgId.put(messageHash(newTopic.top_message, chatId), newTopic);
|
|
changed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
int pinnedTopics = 0;
|
|
for (int i = 0; i < topics.size(); ++i) {
|
|
TLRPC.TL_forumTopic topic = topics.get(i);
|
|
if (topic != null && topic.pinned) {
|
|
int newPinnedOrder = pinnedTopics++;
|
|
if (topic.pinnedOrder != newPinnedOrder) {
|
|
topic.pinnedOrder = newPinnedOrder;
|
|
changed = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (topicsToReload != null && loadType != LOAD_TYPE_LOAD_UNKNOWN) {
|
|
reloadTopics(chatId, topicsToReload);
|
|
} else if (loadType == LOAD_TYPE_LOAD_NEXT && topics.size() >= totalCount && totalCount >= 0) {
|
|
endIsReached.put(chatId, 1);
|
|
getUserConfig().getPreferences().edit().putBoolean("topics_end_reached_" + chatId, true).apply();
|
|
}
|
|
|
|
if (changed) {
|
|
sortTopics(chatId);
|
|
}
|
|
|
|
getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true);
|
|
|
|
if ((loadType == LOAD_TYPE_PRELOAD || (loadType == LOAD_TYPE_PRELOAD && !fromCache)) && fromCache && topicsByChatId.get(chatId).isEmpty()) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
loadTopics(chatId, false, LOAD_TYPE_PRELOAD);
|
|
});
|
|
}
|
|
}
|
|
|
|
private long messageHash(int messageId, long chatId) {
|
|
return chatId + ((long) messageId << 12);
|
|
}
|
|
|
|
|
|
public ArrayList<TLRPC.TL_forumTopic> getTopics(long chatId) {
|
|
return topicsByChatId.get(chatId);
|
|
}
|
|
|
|
private void sortTopics(long chatId) {
|
|
sortTopics(chatId, true);
|
|
}
|
|
|
|
public void sortTopics(long chatId, boolean notify) {
|
|
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
|
|
if (topics != null) {
|
|
if (openedTopicsBuChatId.get(chatId, 0) > 0) {
|
|
Collections.sort(topics, Comparator.comparingInt(o -> o.topMessage == null ? Integer.MAX_VALUE : -(o.pinned ? Integer.MAX_VALUE - o.pinnedOrder : o.topMessage.date)));
|
|
}
|
|
if (notify) {
|
|
getNotificationCenter().postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void updateTopicsWithDeletedMessages(long dialogId, ArrayList<Integer> messages) {
|
|
if (dialogId > 0) {
|
|
return;
|
|
}
|
|
long chatId = -dialogId;
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
getMessagesStorage().getStorageQueue().postRunnable(() -> {
|
|
ArrayList<TLRPC.TL_forumTopic> topicsToUpdate = null;
|
|
try {
|
|
SQLiteCursor cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT topic_id, top_message FROM topics WHERE did = %d AND top_message IN (%s)", dialogId, TextUtils.join(",", messages)));
|
|
while (cursor.next()) {
|
|
if (topicsToUpdate == null) {
|
|
topicsToUpdate = new ArrayList<>();
|
|
}
|
|
|
|
TLRPC.TL_forumTopic topic = new TLRPC.TL_forumTopic();
|
|
topic.id = cursor.intValue(0);
|
|
topic.top_message = cursor.intValue(1);
|
|
topic.from_id = getMessagesController().getPeer(getUserConfig().clientUserId);
|
|
topic.notify_settings = new TLRPC.TL_peerNotifySettings();
|
|
topicsToUpdate.add(topic);
|
|
}
|
|
cursor.dispose();
|
|
|
|
if (topicsToUpdate != null) {
|
|
for (int i = 0; i < topicsToUpdate.size(); i++) {
|
|
TLRPC.TL_forumTopic topic = topicsToUpdate.get(i);
|
|
cursor = getMessagesStorage().getDatabase().queryFinalized(String.format(Locale.US, "SELECT mid, data FROM messages_topics WHERE uid = %d AND topic_id = %d ORDER BY mid DESC LIMIT 1", dialogId, topic.id));
|
|
|
|
if (cursor.next()) {
|
|
NativeByteBuffer data = cursor.byteBufferValue(1);
|
|
if (data != null) {
|
|
TLRPC.Message message = TLRPC.Message.TLdeserialize(data, data.readInt32(false), false);
|
|
message.readAttachPath(data, getUserConfig().clientUserId);
|
|
data.reuse();
|
|
topicsByTopMsgId.remove(messageHash(topic.top_message, chatId));
|
|
topic.top_message = message.id;
|
|
topic.topMessage = message;
|
|
topic.groupedMessages = null;
|
|
topicsByTopMsgId.put(messageHash(topic.top_message, chatId), topic);
|
|
}
|
|
}
|
|
cursor.dispose();
|
|
}
|
|
|
|
for (int i = 0; i < topicsToUpdate.size(); i++) {
|
|
getMessagesStorage().getDatabase().executeFast(String.format(Locale.US, "UPDATE topics SET top_message = %d WHERE did = %d AND topic_id = %d", topicsToUpdate.get(i).top_message, dialogId, topicsToUpdate.get(i).id)).stepThis().dispose();
|
|
}
|
|
}
|
|
|
|
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
ArrayList<TLRPC.TL_forumTopic> finalTopicsToUpdate = topicsToUpdate;
|
|
getMessagesStorage().loadGroupedMessagesForTopics(dialogId, finalTopicsToUpdate);
|
|
if (finalTopicsToUpdate != null) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
boolean changed = false;
|
|
ArrayList<TLRPC.TL_forumTopic> topicsToReload = null;
|
|
|
|
for (int i = 0; i < finalTopicsToUpdate.size(); i++) {
|
|
TLRPC.TL_forumTopic fromUpdate = finalTopicsToUpdate.get(i);
|
|
LongSparseArray<TLRPC.TL_forumTopic> map = topicsMapByChatId.get(chatId);
|
|
TLRPC.TL_forumTopic toUpdate;
|
|
if (map != null) {
|
|
toUpdate = map.get(fromUpdate.id);
|
|
if (toUpdate != null && fromUpdate.top_message != -1 && fromUpdate.topMessage != null) {
|
|
topicsByTopMsgId.remove(messageHash(toUpdate.top_message, chatId));
|
|
toUpdate.top_message = fromUpdate.topMessage.id;
|
|
toUpdate.topMessage = fromUpdate.topMessage;
|
|
toUpdate.groupedMessages = fromUpdate.groupedMessages;
|
|
|
|
topicsByTopMsgId.put(messageHash(toUpdate.top_message, chatId), toUpdate);
|
|
changed = true;
|
|
} else if (fromUpdate.top_message == -1 || fromUpdate.topMessage == null) {
|
|
if (topicsToReload == null) {
|
|
topicsToReload = new ArrayList<>();
|
|
}
|
|
topicsToReload.add(fromUpdate);
|
|
}
|
|
}
|
|
}
|
|
if (changed) {
|
|
sortTopics(chatId);
|
|
}
|
|
if (topicsToReload != null) {
|
|
reloadTopics(chatId, topicsToReload);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
private void reloadTopics(long chatId, ArrayList<TLRPC.TL_forumTopic> topicsToReload) {
|
|
TLRPC.TL_channels_getForumTopicsByID req = new TLRPC.TL_channels_getForumTopicsByID();
|
|
for (int i = 0; i < topicsToReload.size(); i++) {
|
|
req.topics.add(topicsToReload.get(i).id);
|
|
}
|
|
req.channel = getMessagesController().getInputChannel(chatId);
|
|
getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
|
if (response != null) {
|
|
SparseArray<TLRPC.Message> messagesMap = new SparseArray<>();
|
|
TLRPC.TL_messages_forumTopics topics = (TLRPC.TL_messages_forumTopics) response;
|
|
for (int i = 0; i < topics.messages.size(); i++) {
|
|
messagesMap.put(topics.messages.get(i).id, topics.messages.get(i));
|
|
}
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
getMessagesController().putUsers(((TLRPC.TL_messages_forumTopics) response).users, false);
|
|
getMessagesController().putChats(((TLRPC.TL_messages_forumTopics) response).chats, false);
|
|
|
|
processTopics(chatId, topics.topics, messagesMap, false, LOAD_TYPE_LOAD_UNKNOWN, -1);
|
|
getMessagesStorage().putMessages(topics.messages, false, true, false, 0, false, 0);
|
|
getMessagesStorage().saveTopics(-chatId, topicsByChatId.get(chatId), true, true);
|
|
});
|
|
}
|
|
}));
|
|
}
|
|
|
|
public void updateMaxReadId(long chatId, int topicId, int readMaxId, int unreadCount, int mentionsUnread) {
|
|
TLRPC.TL_forumTopic topic = findTopic(chatId, topicId);
|
|
if (topic != null) {
|
|
topic.read_inbox_max_id = readMaxId;
|
|
topic.unread_count = unreadCount;
|
|
if (mentionsUnread >= 0) {
|
|
topic.unread_mentions_count = mentionsUnread;
|
|
}
|
|
sortTopics(chatId);
|
|
}
|
|
}
|
|
|
|
public TLRPC.TL_forumTopic findTopic(long chatId, int topicId) {
|
|
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
|
|
if (topicsMap != null) {
|
|
return topicsMap.get(topicId);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public String getTopicName(TLRPC.Chat chat, MessageObject message) {
|
|
if (message.messageOwner.reply_to == null) {
|
|
return null;
|
|
}
|
|
int topicId = message.messageOwner.reply_to.reply_to_top_id;
|
|
if (topicId == 0) {
|
|
topicId = message.messageOwner.reply_to.reply_to_msg_id;
|
|
}
|
|
if (topicId != 0) {
|
|
TLRPC.TL_forumTopic topic = findTopic(chat.id, topicId);
|
|
if (topic != null) {
|
|
return topic.title;
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public CharSequence getTopicIconName(TLRPC.Chat chat, MessageObject message, TextPaint paint) {
|
|
if (message.messageOwner.reply_to == null) {
|
|
return null;
|
|
}
|
|
int topicId = message.messageOwner.reply_to.reply_to_top_id;
|
|
if (topicId == 0) {
|
|
topicId = message.messageOwner.reply_to.reply_to_msg_id;
|
|
}
|
|
if (topicId != 0) {
|
|
TLRPC.TL_forumTopic topic = findTopic(chat.id, topicId);
|
|
if (topic != null) {
|
|
return ForumUtilities.getTopicSpannedName(topic, paint);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private final static int[] countsTmp = new int[4];
|
|
|
|
public int[] getForumUnreadCount(long chatId) {
|
|
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
|
|
Arrays.fill(countsTmp, 0);
|
|
if (topics != null) {
|
|
for (int i = 0; i < topics.size(); i++) {
|
|
TLRPC.TL_forumTopic topic = topics.get(i);
|
|
countsTmp[0] += topic.unread_count > 0 ? 1 : 0;
|
|
countsTmp[1] += topic.unread_mentions_count > 0 ? 1 : 0;
|
|
countsTmp[2] += topic.unread_reactions_count > 0 ? 1 : 0;
|
|
if (!getMessagesController().isDialogMuted(-chatId, topic.id)) {
|
|
countsTmp[3] += topic.unread_count;
|
|
}
|
|
|
|
}
|
|
}
|
|
return countsTmp;
|
|
}
|
|
|
|
public void onTopicCreated(long dialogId, TLRPC.TL_forumTopic forumTopic, boolean saveInDatabase) {
|
|
LongSparseArray<TLRPC.TL_forumTopic> map = topicsMapByChatId.get(-dialogId);
|
|
if (findTopic(-dialogId, forumTopic.id) != null) {
|
|
return;
|
|
}
|
|
if (map == null) {
|
|
map = new LongSparseArray<>();
|
|
topicsMapByChatId.put(-dialogId, map);
|
|
}
|
|
ArrayList<TLRPC.TL_forumTopic> list = topicsByChatId.get(-dialogId);
|
|
if (list == null) {
|
|
list = new ArrayList<>();
|
|
topicsByChatId.put(-dialogId, list);
|
|
}
|
|
map.put(forumTopic.id, forumTopic);
|
|
list.add(forumTopic);
|
|
if (saveInDatabase) {
|
|
getMessagesStorage().saveTopics(dialogId, Collections.singletonList(forumTopic), false, true);
|
|
}
|
|
sortTopics(-dialogId, true);
|
|
}
|
|
|
|
public void onTopicEdited(long dialogId, TLRPC.TL_forumTopic forumTopic) {
|
|
getMessagesStorage().updateTopicData(dialogId, forumTopic, TOPIC_FLAG_ICON + TOPIC_FLAG_TITLE);
|
|
sortTopics(-dialogId);
|
|
}
|
|
|
|
public void deleteTopics(long chatId, ArrayList<Integer> topicIds) {
|
|
ArrayList<TLRPC.TL_forumTopic> topicsArray = topicsByChatId.get(chatId);
|
|
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
|
|
if (topicsMap != null && topicsArray != null) {
|
|
for (int i = 0; i < topicIds.size(); i++) {
|
|
int topicId = topicIds.get(i);
|
|
TLRPC.TL_forumTopic topic = topicsMap.get(topicId);
|
|
topicsMap.remove(topicId);
|
|
if (topic != null) {
|
|
topicsByTopMsgId.remove(messageHash(topic.top_message, chatId));
|
|
topicsArray.remove(topic);
|
|
}
|
|
}
|
|
sortTopics(chatId);
|
|
}
|
|
for (int i = 0; i < topicIds.size(); i++) {
|
|
deleteTopic(chatId, topicIds.get(i), 0);
|
|
}
|
|
}
|
|
|
|
private void deleteTopic(long chatId, int topicId, int offset) {
|
|
TLRPC.TL_channels_deleteTopicHistory deleteTopicHistory = new TLRPC.TL_channels_deleteTopicHistory();
|
|
deleteTopicHistory.channel = getMessagesController().getInputChannel(chatId);
|
|
deleteTopicHistory.top_msg_id = topicId;
|
|
if (offset == 0) {
|
|
getMessagesStorage().removeTopic(-chatId, topicId);
|
|
}
|
|
ConnectionsManager.getInstance(currentAccount).sendRequest(deleteTopicHistory, new RequestDelegate() {
|
|
@Override
|
|
public void run(TLObject response, TLRPC.TL_error error) {
|
|
if (error == null) {
|
|
TLRPC.TL_messages_affectedHistory res = (TLRPC.TL_messages_affectedHistory) response;
|
|
getMessagesController().processNewChannelDifferenceParams(res.pts, res.pts_count, chatId);
|
|
if (res.offset > 0) {
|
|
deleteTopic(chatId, topicId, res.offset);
|
|
}
|
|
}
|
|
|
|
}
|
|
});
|
|
}
|
|
|
|
public void toggleCloseTopic(long chatId, int topicId, boolean close) {
|
|
TLRPC.TL_channels_editForumTopic req = new TLRPC.TL_channels_editForumTopic();
|
|
req.channel = getMessagesController().getInputChannel(chatId);
|
|
req.topic_id = topicId;
|
|
req.flags |= 4;
|
|
req.closed = close;
|
|
|
|
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
|
|
if (topicsMap != null) {
|
|
TLRPC.TL_forumTopic topic = topicsMap.get(topicId);
|
|
if (topic != null) {
|
|
topic.closed = close;
|
|
getMessagesStorage().updateTopicData(-chatId, topic, TOPIC_FLAG_CLOSE);
|
|
}
|
|
}
|
|
|
|
ConnectionsManager.getInstance(currentAccount).sendRequest(req, new RequestDelegate() {
|
|
@Override
|
|
public void run(TLObject response, TLRPC.TL_error error) {
|
|
if (error == null) {
|
|
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public ArrayList<Integer> getCurrentPinnedOrder(long chatId) {
|
|
ArrayList<TLRPC.TL_forumTopic> topics = getTopics(chatId);
|
|
ArrayList<Integer> newOrder = new ArrayList<>();
|
|
if (topics != null) {
|
|
for (int i = 0; i < topics.size(); ++i) {
|
|
TLRPC.TL_forumTopic topic = topics.get(i);
|
|
if (topic == null) {
|
|
continue;
|
|
}
|
|
if (topic.pinned) {
|
|
newOrder.add(topic.id);
|
|
}
|
|
}
|
|
}
|
|
return newOrder;
|
|
}
|
|
|
|
public void applyPinnedOrder(long chatId, ArrayList<Integer> order) {
|
|
applyPinnedOrder(chatId, order, true);
|
|
}
|
|
|
|
public void applyPinnedOrder(long chatId, ArrayList<Integer> order, boolean notify) {
|
|
if (order == null) {
|
|
return;
|
|
}
|
|
|
|
ArrayList<TLRPC.TL_forumTopic> topics = getTopics(chatId);
|
|
boolean updated = false;
|
|
if (topics != null) {
|
|
for (int i = 0; i < topics.size(); ++i) {
|
|
TLRPC.TL_forumTopic topic = topics.get(i);
|
|
if (topic == null) {
|
|
continue;
|
|
}
|
|
int newPinnedOrder = order.indexOf(topic.id);
|
|
boolean newPinned = newPinnedOrder >= 0;
|
|
if (topic.pinned != newPinned || newPinned && topic.pinnedOrder != newPinnedOrder) {
|
|
updated = true;
|
|
topic.pinned = newPinned;
|
|
topic.pinnedOrder = newPinnedOrder;
|
|
getMessagesStorage().updateTopicData(chatId, topic, TopicsController.TOPIC_FLAG_PIN);
|
|
}
|
|
}
|
|
} else {
|
|
updated = true;
|
|
}
|
|
|
|
if (notify && updated) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_SELECT_DIALOG);
|
|
});
|
|
}
|
|
}
|
|
|
|
public void pinTopic(long chatId, int topicId, boolean pin, BaseFragment fragment) {
|
|
TLRPC.TL_channels_updatePinnedForumTopic req = new TLRPC.TL_channels_updatePinnedForumTopic();
|
|
req.channel = getMessagesController().getInputChannel(chatId);
|
|
req.topic_id = topicId;
|
|
req.pinned = pin;
|
|
|
|
ArrayList<Integer> prevOrder = getCurrentPinnedOrder(chatId);
|
|
ArrayList<Integer> newOrder = new ArrayList<>(prevOrder);
|
|
newOrder.remove((Integer) topicId);
|
|
if (pin) {
|
|
newOrder.add(0, topicId);
|
|
}
|
|
applyPinnedOrder(chatId, newOrder);
|
|
|
|
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> {
|
|
if (error != null) {
|
|
if ("PINNED_TOO_MUCH".equals(error.text)) {
|
|
if (fragment == null) {
|
|
return;
|
|
}
|
|
applyPinnedOrder(chatId, prevOrder);
|
|
fragment.showDialog(
|
|
new AlertDialog.Builder(fragment.getContext())
|
|
.setTitle(LocaleController.getString("LimitReached", R.string.LimitReached))
|
|
.setMessage(LocaleController.formatString("LimitReachedPinnedTopics", R.string.LimitReachedPinnedTopics, MessagesController.getInstance(currentAccount).topicsPinnedLimit))
|
|
.setPositiveButton(LocaleController.getString("OK", R.string.OK), null)
|
|
.create()
|
|
);
|
|
} else if ("PINNED_TOPIC_NOT_MODIFIED".equals(error.text)) {
|
|
reloadTopics(chatId, false);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
public void reorderPinnedTopics(long chatId, ArrayList<Integer> topics) {
|
|
TLRPC.TL_channels_reorderPinnedForumTopics req = new TLRPC.TL_channels_reorderPinnedForumTopics();
|
|
req.channel = getMessagesController().getInputChannel(chatId);
|
|
if (topics != null) {
|
|
req.order.addAll(topics);
|
|
}
|
|
req.force = true;
|
|
applyPinnedOrder(chatId, topics, false);
|
|
ConnectionsManager.getInstance(currentAccount).sendRequest(req, null);
|
|
}
|
|
|
|
public void updateMentionsUnread(long dialogId, int topicId, int topicMentionsCount) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
|
|
if (topic != null) {
|
|
topic.unread_mentions_count = topicMentionsCount;
|
|
sortTopics(-dialogId, true);
|
|
}
|
|
});
|
|
}
|
|
|
|
public int updateReactionsUnread(long dialogId, int topicId, int count, boolean increment) {
|
|
TLRPC.TL_forumTopic topic = findTopic(-dialogId, topicId);
|
|
int totalCount = -1;
|
|
if (topic != null) {
|
|
if (increment) {
|
|
topic.unread_reactions_count += count;
|
|
if (topic.unread_reactions_count < 0) {
|
|
topic.unread_reactions_count = 0;
|
|
}
|
|
} else {
|
|
topic.unread_reactions_count = count;
|
|
}
|
|
totalCount = topic.unread_reactions_count;
|
|
sortTopics(-dialogId, true);
|
|
}
|
|
return totalCount;
|
|
}
|
|
|
|
public void markAllReactionsAsRead(long chatId, int topicId) {
|
|
TLRPC.TL_forumTopic topic = findTopic(chatId, topicId);
|
|
if (topic != null && topic.unread_reactions_count > 0) {
|
|
topic.unread_reactions_count = 0;
|
|
sortTopics(chatId);
|
|
}
|
|
}
|
|
|
|
LongSparseArray<TopicsLoadOffset> offsets = new LongSparseArray<>();
|
|
|
|
public TopicsLoadOffset getLoadOffset(long chatId) {
|
|
TopicsLoadOffset offset = offsets.get(chatId);
|
|
if (offset != null) {
|
|
return offset;
|
|
}
|
|
return new TopicsLoadOffset();
|
|
// SharedPreferences sharedPreferences = getUserConfig().getPreferences();
|
|
// TopicsLoadOffset topicsLoadOffset = new TopicsLoadOffset();
|
|
// topicsLoadOffset.lastMessageId = sharedPreferences.getInt("topics_load_offset_message_id_" + chatId, 0);
|
|
// topicsLoadOffset.lastMessageDate = sharedPreferences.getInt("topics_load_offset_date_" + chatId, 0);
|
|
// topicsLoadOffset.lastMessageId = sharedPreferences.getInt("topics_load_offset_topic_id_" + chatId, 0);
|
|
// return topicsLoadOffset;
|
|
}
|
|
|
|
public void saveLoadOffset(long chatId, int lastMessageId, int lastMessageDate, int lastTopicId) {
|
|
TopicsLoadOffset offset = new TopicsLoadOffset();
|
|
offset.lastMessageId = lastMessageId;
|
|
offset.lastMessageDate = lastMessageDate;
|
|
offset.lastTopicId = lastTopicId;
|
|
offsets.put(chatId, offset);
|
|
// SharedPreferences.Editor editor = getUserConfig().getPreferences().edit();
|
|
// editor.putInt("topics_load_offset_message_id_" + chatId, lastMessageId);
|
|
// editor.putInt("topics_load_offset_date_" + chatId, lastMessageDate);
|
|
// editor.putInt("topics_load_offset_topic_id_" + chatId, lastTopicId);
|
|
// editor.apply();
|
|
}
|
|
|
|
public void clearLoadingOffset(long chatId) {
|
|
offsets.remove(chatId);
|
|
// SharedPreferences.Editor editor = getUserConfig().getPreferences().edit();
|
|
// editor.remove("topics_load_offset_message_id_" + chatId);
|
|
// editor.remove("topics_load_offset_date_" + chatId);
|
|
// editor.remove("topics_load_offset_topic_id_" + chatId);
|
|
// editor.apply();
|
|
}
|
|
|
|
public boolean endIsReached(long chatId) {
|
|
return endIsReached.get(chatId, 0) == 1;
|
|
}
|
|
|
|
public void processUpdate(List<TopicUpdate> topicUpdates) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
HashSet<Long> changedDialogs = new HashSet<>();
|
|
LongSparseArray<ArrayList<TLRPC.TL_forumTopic>> topicsToReload = null;
|
|
for (int i = 0; i < topicUpdates.size(); i++) {
|
|
TopicUpdate update = topicUpdates.get(i);
|
|
if (update.reloadTopic) {
|
|
if (topicsToReload == null) {
|
|
topicsToReload = new LongSparseArray<>();
|
|
}
|
|
ArrayList<TLRPC.TL_forumTopic> arrayList = topicsToReload.get(update.dialogId);
|
|
if (arrayList == null) {
|
|
arrayList = new ArrayList<>();
|
|
topicsToReload.put(update.dialogId, arrayList);
|
|
}
|
|
TLRPC.TL_forumTopic forumTopic = new TLRPC.TL_forumTopic();
|
|
forumTopic.id = update.topicId;
|
|
arrayList.add(forumTopic);
|
|
} else {
|
|
TLRPC.TL_forumTopic topic = findTopic(-update.dialogId, update.topicId);
|
|
if (topic != null) {
|
|
if (update.onlyCounters) {
|
|
if (update.unreadCount >= 0) {
|
|
topic.unread_count = update.unreadCount;
|
|
}
|
|
if (update.unreadMentions >= 0) {
|
|
topic.unread_mentions_count = update.unreadMentions;
|
|
}
|
|
} else {
|
|
topicsByTopMsgId.remove(messageHash(topic.top_message, -update.dialogId));
|
|
topic.topMessage = update.topMessage;
|
|
topic.groupedMessages = update.groupedMessages;
|
|
topic.top_message = update.topMessageId;
|
|
topic.unread_count = update.unreadCount;
|
|
topic.unread_mentions_count = update.unreadMentions;
|
|
topicsByTopMsgId.put(messageHash(topic.top_message, -update.dialogId), topic);
|
|
}
|
|
changedDialogs.add(-update.dialogId);
|
|
}
|
|
}
|
|
}
|
|
for (Long changedDialog : changedDialogs) {
|
|
sortTopics(changedDialog, true);
|
|
}
|
|
|
|
if (topicsToReload != null) {
|
|
for (int i = 0; i < topicsToReload.size(); i++) {
|
|
long dialogId = topicsToReload.keyAt(i);
|
|
ArrayList<TLRPC.TL_forumTopic> topics = topicsToReload.valueAt(i);
|
|
reloadTopics(-dialogId, topics);
|
|
}
|
|
}
|
|
|
|
});
|
|
}
|
|
|
|
public boolean isLoading(long chatId) {
|
|
return topicsIsLoading.get(chatId, 0) == 1 && (topicsByChatId.get(chatId) == null || topicsByChatId.get(chatId).isEmpty());
|
|
}
|
|
|
|
public void onTopicsDeletedServerSide(ArrayList<MessagesStorage.TopicKey> topicsToDelete) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
HashSet<Long> changedChatId = new HashSet<>();
|
|
for (int i = 0; i < topicsToDelete.size(); i++) {
|
|
MessagesStorage.TopicKey topicKey = topicsToDelete.get(i);
|
|
long chatId = -topicKey.dialogId;
|
|
LongSparseArray<TLRPC.TL_forumTopic> topicsMap = topicsMapByChatId.get(chatId);
|
|
if (topicsMap != null) {
|
|
topicsMap.remove(topicKey.topicId);
|
|
}
|
|
ArrayList<TLRPC.TL_forumTopic> topics = topicsByChatId.get(chatId);
|
|
if (topics != null) {
|
|
for (int k = 0; k < topics.size(); k++) {
|
|
if (topics.get(k).id == topicKey.topicId) {
|
|
topics.remove(k);
|
|
getNotificationCenter().postNotificationName(NotificationCenter.dialogDeleted, -chatId, topicKey.topicId);
|
|
changedChatId.add(chatId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
for (Long chatId : changedChatId) {
|
|
sortTopics(chatId, true);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void reloadTopics(long chatId) {
|
|
reloadTopics(chatId, true);
|
|
}
|
|
|
|
public void reloadTopics(long chatId, boolean fromCache) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
getUserConfig().getPreferences().edit().remove("topics_end_reached_" + chatId).apply();
|
|
topicsByChatId.remove(chatId);
|
|
topicsMapByChatId.remove(chatId);
|
|
endIsReached.delete(chatId);
|
|
clearLoadingOffset(chatId);
|
|
|
|
|
|
TLRPC.Chat chat = getMessagesController().getChat(chatId);
|
|
if (chat != null && chat.forum) {
|
|
if (fromCache) {
|
|
preloadTopics(chatId);
|
|
} else {
|
|
loadTopics(chatId, false, LOAD_TYPE_PRELOAD);
|
|
}
|
|
}
|
|
sortTopics(chatId);
|
|
});
|
|
}
|
|
|
|
public void databaseCleared() {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
topicsByChatId.clear();
|
|
topicsMapByChatId.clear();
|
|
endIsReached.clear();
|
|
|
|
SharedPreferences.Editor editor = getUserConfig().getPreferences().edit();
|
|
for (String key : getUserConfig().getPreferences().getAll().keySet()) {
|
|
if (key.startsWith("topics_load_offset_message_id_")) {
|
|
editor.remove(key);
|
|
}
|
|
if (key.startsWith("topics_load_offset_date_")) {
|
|
editor.remove(key);
|
|
}
|
|
if (key.startsWith("topics_load_offset_topic_id_")) {
|
|
editor.remove(key);
|
|
}
|
|
if (key.startsWith("topics_end_reached_")) {
|
|
editor.remove(key);
|
|
}
|
|
}
|
|
editor.apply();
|
|
});
|
|
}
|
|
|
|
public void updateReadOutbox(HashMap<MessagesStorage.TopicKey, Integer> topicsReadOutbox) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
HashSet<Long> updatedChats = new HashSet<>();
|
|
for (MessagesStorage.TopicKey topicKey : topicsReadOutbox.keySet()) {
|
|
int value = topicsReadOutbox.get(topicKey);
|
|
TLRPC.TL_forumTopic topic = findTopic(-topicKey.dialogId, topicKey.topicId);
|
|
if (topic != null) {
|
|
topic.read_outbox_max_id = Math.max(topic.read_outbox_max_id, value);
|
|
updatedChats.add(-topicKey.dialogId);
|
|
if (topic.topMessage != null && topic.read_outbox_max_id >= topic.topMessage.id) {
|
|
topic.topMessage.unread = false;
|
|
}
|
|
}
|
|
}
|
|
//TODO topics
|
|
// optimize move to mask update
|
|
for (Long chatId : updatedChats) {
|
|
NotificationCenter.getInstance(currentAccount).postNotificationName(NotificationCenter.topicsDidLoaded, chatId, true);
|
|
}
|
|
});
|
|
}
|
|
|
|
public void updateTopicInUi(long dialogId, TLRPC.TL_forumTopic forumTopic, int flags) {
|
|
TLRPC.TL_forumTopic topic = findTopic(-dialogId, forumTopic.id);
|
|
if (topic != null) {
|
|
if ((flags & TOPIC_FLAG_TITLE) != 0) {
|
|
topic.title = forumTopic.title;
|
|
}
|
|
if ((flags & TOPIC_FLAG_ICON) != 0) {
|
|
topic.icon_emoji_id = forumTopic.icon_emoji_id;
|
|
}
|
|
if ((flags & TOPIC_FLAG_CLOSE) != 0) {
|
|
topic.closed = forumTopic.closed;
|
|
}
|
|
if ((flags & TOPIC_FLAG_PIN) != 0) {
|
|
topic.pinned = forumTopic.pinned;
|
|
}
|
|
sortTopics(-dialogId);
|
|
}
|
|
}
|
|
|
|
public void processEditedMessages(LongSparseArray<ArrayList<MessageObject>> editingMessagesFinal) {
|
|
HashSet<Long> changedChatId = new HashSet<>();
|
|
for (int i = 0; i < editingMessagesFinal.size(); i++) {
|
|
ArrayList<MessageObject> messageObjects = editingMessagesFinal.valueAt(i);
|
|
for (int j = 0; j < messageObjects.size(); j++) {
|
|
TLRPC.TL_forumTopic topic = topicsByTopMsgId.get(messageHash(messageObjects.get(j).getId(), -messageObjects.get(j).getDialogId()));
|
|
if (topic != null) {
|
|
topic.topMessage = messageObjects.get(j).messageOwner;
|
|
changedChatId.add(-messageObjects.get(j).getDialogId());
|
|
}
|
|
}
|
|
}
|
|
for (Long chatId : changedChatId) {
|
|
sortTopics(chatId, true);
|
|
}
|
|
}
|
|
|
|
public void processEditedMessage(TLRPC.Message newMsg) {
|
|
TLRPC.TL_forumTopic topic = topicsByTopMsgId.get(messageHash(newMsg.id, -newMsg.dialog_id));
|
|
if (topic != null) {
|
|
topic.topMessage = newMsg;
|
|
sortTopics(-newMsg.dialog_id, true);
|
|
}
|
|
}
|
|
|
|
private class TopicsLoadOffset {
|
|
int lastMessageId;
|
|
int lastMessageDate;
|
|
int lastTopicId;
|
|
}
|
|
|
|
public static class TopicUpdate {
|
|
long dialogId;
|
|
int topicId;
|
|
int unreadMentions;
|
|
int unreadCount;
|
|
int topMessageId;
|
|
TLRPC.Message topMessage;
|
|
ArrayList<MessageObject> groupedMessages;
|
|
boolean reloadTopic;
|
|
boolean onlyCounters;
|
|
}
|
|
|
|
|
|
public void onTopicFragmentResume(long chatId) {
|
|
int v = openedTopicsBuChatId.get(chatId, 0);
|
|
openedTopicsBuChatId.put(chatId, v + 1);
|
|
sortTopics(chatId);
|
|
}
|
|
|
|
public void onTopicFragmentPause(long chatId) {
|
|
int v = openedTopicsBuChatId.get(chatId, 0);
|
|
v--;
|
|
if (v < 0) {
|
|
v = 0;
|
|
}
|
|
openedTopicsBuChatId.put(chatId, v);
|
|
|
|
}
|
|
}
|