Handle secret chat state for chat list

This commit is contained in:
Sebastian Wolf 2020-11-25 22:09:47 +01:00
parent a6d8328b10
commit 3b8d284b2b
5 changed files with 132 additions and 6 deletions

View file

@ -64,6 +64,7 @@ public:
RoleLastMessageText,
RoleLastMessageStatus,
RoleChatMemberStatus,
RoleSecretChatState,
RoleIsChannel
};
@ -86,6 +87,7 @@ public:
bool updateLastReadInboxMessageId(qlonglong messageId);
QVector<int> updateLastMessage(const QVariantMap &message);
QVector<int> updateGroup(const TDLibWrapper::Group *group);
QVector<int> updateSecretChat(const QVariantMap &secretChatDetails);
public:
QVariantMap chatData;
@ -94,6 +96,7 @@ public:
qlonglong groupId;
TDLibWrapper::ChatType chatType;
TDLibWrapper::ChatMemberStatus memberStatus;
TDLibWrapper::SecretChatState secretChatState;
QVariantMap userInformation;
};
@ -103,6 +106,7 @@ ChatListModel::ChatData::ChatData(const QVariantMap &data, const QVariantMap &us
order(data.value(ORDER).toLongLong()),
groupId(0),
memberStatus(TDLibWrapper::ChatMemberStatusUnknown),
secretChatState(TDLibWrapper::SecretChatStateUnknown),
userInformation(userInfo)
{
const QVariantMap type(data.value(TYPE).toMap());
@ -227,7 +231,11 @@ bool ChatListModel::ChatData::isHidden() const
break;
case TDLibWrapper::ChatTypeUnknown:
case TDLibWrapper::ChatTypePrivate:
break;
case TDLibWrapper::ChatTypeSecret:
if (secretChatState == TDLibWrapper::SecretChatStateClosed) {
return true;
}
break;
}
return false;
@ -288,6 +296,18 @@ QVector<int> ChatListModel::ChatData::updateGroup(const TDLibWrapper::Group *gro
return changedRoles;
}
QVector<int> ChatListModel::ChatData::updateSecretChat(const QVariantMap &secretChatDetails)
{
QVector<int> changedRoles;
TDLibWrapper::SecretChatState newSecretChatState = TDLibWrapper::secretChatStateFromString(secretChatDetails.value("state").toMap().value(_TYPE).toString());
if (newSecretChatState != secretChatState) {
secretChatState = newSecretChatState;
changedRoles.append(RoleSecretChatState);
}
return changedRoles;
}
ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false)
{
this->tdLibWrapper = tdLibWrapper;
@ -302,6 +322,8 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false
connect(tdLibWrapper, SIGNAL(chatNotificationSettingsUpdated(QString, QVariantMap)), this, SLOT(handleChatNotificationSettingsUpdated(QString, QVariantMap)));
connect(tdLibWrapper, SIGNAL(superGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong)));
connect(tdLibWrapper, SIGNAL(basicGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong)));
connect(tdLibWrapper, SIGNAL(secretChatUpdated(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
connect(tdLibWrapper, SIGNAL(secretChatReceived(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
// Don't start the timer until we have at least one chat
relativeTimeRefreshTimer = new QTimer(this);
@ -332,6 +354,7 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
roles.insert(ChatData::RoleLastMessageText, "last_message_text");
roles.insert(ChatData::RoleLastMessageStatus, "last_message_status");
roles.insert(ChatData::RoleChatMemberStatus, "chat_member_status");
roles.insert(ChatData::RoleSecretChatState, "secret_chat_state");
roles.insert(ChatData::RoleIsChannel, "is_channel");
return roles;
}
@ -359,6 +382,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
case ChatData::RoleLastMessageDate: return data->senderMessageDate();
case ChatData::RoleLastMessageStatus: return data->senderMessageStatus();
case ChatData::RoleChatMemberStatus: return data->memberStatus;
case ChatData::RoleSecretChatState: return data->secretChatState;
case ChatData::RoleIsChannel: return data->isChannel();
}
}
@ -492,6 +516,50 @@ void ChatListModel::updateChatVisibility(const TDLibWrapper::Group *group)
}
}
void ChatListModel::updateSecretChatVisibility(const QVariantMap secretChatDetails)
{
LOG("Updating secret chat visibility" << secretChatDetails.value(ID));
// See if any group has been removed from from view
for (int i = 0; i < chatList.size(); i++) {
ChatData *chat = chatList.at(i);
if (chat->chatType != TDLibWrapper::ChatTypeSecret) {
continue;
}
const QVector<int> changedRoles(chat->updateSecretChat(secretChatDetails));
if (chat->isHidden() && !showHiddenChats) {
LOG("Hiding chat" << chat->chatId << "at" << i);
beginRemoveRows(QModelIndex(), i, i);
chatList.removeAt(i);
// Update damaged part of the map
const int n = chatList.size();
for (int pos = i; pos < n; pos++) {
chatIndexMap.insert(chatList.at(pos)->chatId, pos);
}
i--;
hiddenChats.insert(chat->chatId, chat);
endRemoveRows();
} else if (!changedRoles.isEmpty()) {
const QModelIndex modelIndex(index(i));
emit dataChanged(modelIndex, modelIndex, changedRoles);
}
}
// And see if any group been added to the view
const QList<ChatData*> hiddenChatList = hiddenChats.values();
const int n = hiddenChatList.size();
for (int j = 0; j < n; j++) {
ChatData *chat = hiddenChatList.at(j);
if (chat->chatType != TDLibWrapper::ChatTypeSecret) {
continue;
}
chat->updateSecretChat(secretChatDetails);
if (!chat->isHidden() || showHiddenChats) {
hiddenChats.remove(chat->chatId);
addVisibleChat(chat);
}
}
}
bool ChatListModel::showAllChats() const
{
return showHiddenChats;
@ -509,10 +577,19 @@ void ChatListModel::setShowAllChats(bool showAll)
void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &chatToBeAdded)
{
ChatData *chat = new ChatData(chatToBeAdded, tdLibWrapper->getUserInformation());
const TDLibWrapper::Group *group = tdLibWrapper->getGroup(chat->groupId);
if (group) {
chat->updateGroup(group);
}
if (chat->chatType == TDLibWrapper::ChatTypeSecret) {
QVariantMap secretChatDetails = tdLibWrapper->getSecretChatFromCache(chatToBeAdded.value(TYPE).toMap().value("secret_chat_id").toString());
if (!secretChatDetails.isEmpty()) {
chat->updateSecretChat(secretChatDetails);
}
}
if (chat->isHidden()) {
LOG("Hidden chat" << chat->chatId);
hiddenChats.insert(chat->chatId, chat);
@ -707,6 +784,12 @@ void ChatListModel::handleGroupUpdated(qlonglong groupId)
updateChatVisibility(tdLibWrapper->getGroup(groupId));
}
void ChatListModel::handleSecretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat)
{
LOG("Updating visibility of secret chat " << secretChatId);
updateSecretChatVisibility(secretChat);
}
void ChatListModel::handleRelativeTimeRefreshTimer()
{
LOG("Refreshing timestamps");

View file

@ -54,6 +54,7 @@ private slots:
void handleMessageSendSucceeded(const QString &messageId, const QString &oldMessageId, const QVariantMap &message);
void handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings);
void handleGroupUpdated(qlonglong groupId);
void handleSecretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat);
void handleRelativeTimeRefreshTimer();
signals:
@ -65,6 +66,7 @@ private:
class ChatData;
void addVisibleChat(ChatData *chat);
void updateChatVisibility(const TDLibWrapper::Group *group);
void updateSecretChatVisibility(const QVariantMap secretChatDetails);
int updateChatOrder(int chatIndex);
private:

View file

@ -44,6 +44,7 @@ namespace {
const QString UNREAD_COUNT("unread_count");
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
const QString SECRET_CHAT("secret_chat");
const QString TYPE("@type");
const QString EXTRA("@extra");
@ -529,11 +530,13 @@ void TDLibReceiver::nop(const QVariantMap &)
void TDLibReceiver::processSecretChat(const QVariantMap &receivedInformation)
{
LOG("Received a secret chat");
emit secretChat(receivedInformation.value(ID).toString(), receivedInformation);
QVariantMap discoveredSecretChat = receivedInformation.value(SECRET_CHAT).toMap();
emit secretChat(discoveredSecretChat.value(ID).toString(), discoveredSecretChat);
}
void TDLibReceiver::processUpdateSecretChat(const QVariantMap &receivedInformation)
{
LOG("A secret chat was updated");
emit secretChatUpdated(receivedInformation.value(ID).toString(), receivedInformation);
QVariantMap updatedSecretChat = receivedInformation.value(SECRET_CHAT).toMap();
emit secretChatUpdated(updatedSecretChat.value(ID).toString(), updatedSecretChat);
}

View file

@ -94,8 +94,8 @@ TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface,
connect(this->tdLibReceiver, SIGNAL(messagesDeleted(QString, QVariantList)), this, SIGNAL(messagesDeleted(QString, QVariantList)));
connect(this->tdLibReceiver, SIGNAL(chats(QVariantMap)), this, SIGNAL(chatsReceived(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(chat(QVariantMap)), this, SLOT(handleChatReceived(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(secretChat(QString, QVariantMap)), this, SIGNAL(secretChatReceived(QString, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(secretChatUpdated(QString, QVariantMap)), this, SIGNAL(secretChatUpdated(QString, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(secretChat(QString, QVariantMap)), this, SLOT(handleSecretChatReceived(QString, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(secretChatUpdated(QString, QVariantMap)), this, SLOT(handleSecretChatUpdated(QString, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(recentStickersUpdated(QVariantList)), this, SIGNAL(recentStickersUpdated(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(stickers(QVariantList)), this, SIGNAL(stickersReceived(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(installedStickerSetsUpdated(QVariantList)), this, SIGNAL(installedStickerSetsUpdated(QVariantList)));
@ -891,6 +891,11 @@ QVariantMap TDLibWrapper::getChat(const QString &chatId)
return this->chats.value(chatId).toMap();
}
QVariantMap TDLibWrapper::getSecretChatFromCache(const QString &secretChatId)
{
return this->secretChats.value(secretChatId).toMap();
}
QString TDLibWrapper::getOptionString(const QString &optionName)
{
return this->options.value(optionName).toString();
@ -1160,6 +1165,18 @@ void TDLibWrapper::handleOpenWithChanged()
}
}
void TDLibWrapper::handleSecretChatReceived(const QString &secretChatId, const QVariantMap &secretChat)
{
this->secretChats.insert(secretChatId, secretChat);
emit secretChatReceived(secretChatId, secretChat);
}
void TDLibWrapper::handleSecretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat)
{
this->secretChats.insert(secretChatId, secretChat);
emit secretChatUpdated(secretChatId, secretChat);
}
void TDLibWrapper::setInitialParameters()
{
LOG("Sending initial parameters to TD Lib");
@ -1172,7 +1189,7 @@ void TDLibWrapper::setInitialParameters()
initialParameters.insert("use_file_database", true);
initialParameters.insert("use_chat_info_database", true);
initialParameters.insert("use_message_database", true);
initialParameters.insert("use_secret_chats", false);
initialParameters.insert("use_secret_chats", true);
initialParameters.insert("system_language_code", QLocale::system().name());
QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat);
initialParameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString());
@ -1306,7 +1323,15 @@ TDLibWrapper::ChatMemberStatus TDLibWrapper::chatMemberStatusFromString(const QS
(status == QStringLiteral("chatMemberStatusAdministrator")) ? ChatMemberStatusAdministrator :
(status == QStringLiteral("chatMemberStatusRestricted")) ? ChatMemberStatusRestricted :
(status == QStringLiteral("chatMemberStatusBanned")) ? ChatMemberStatusBanned :
ChatMemberStatusUnknown;
ChatMemberStatusUnknown;
}
TDLibWrapper::SecretChatState TDLibWrapper::secretChatStateFromString(const QString &state)
{
return (state == QStringLiteral("secretChatStateClosed")) ? SecretChatStateClosed :
(state == QStringLiteral("secretChatStatePending")) ? SecretChatStatePending :
(state == QStringLiteral("secretChatStateReady")) ? SecretChatStateReady :
SecretChatStateUnknown;
}
TDLibWrapper::ChatMemberStatus TDLibWrapper::Group::chatMemberStatus() const

View file

@ -79,6 +79,14 @@ public:
};
Q_ENUM(ChatMemberStatus)
enum SecretChatState {
SecretChatStateUnknown,
SecretChatStateClosed,
SecretChatStatePending,
SecretChatStateReady,
};
Q_ENUM(SecretChatState)
class Group {
public:
Group(qlonglong id) : groupId(id) { }
@ -101,6 +109,7 @@ public:
Q_INVOKABLE QVariantMap getBasicGroup(qlonglong groupId) const;
Q_INVOKABLE QVariantMap getSuperGroup(qlonglong groupId) const;
Q_INVOKABLE QVariantMap getChat(const QString &chatId);
Q_INVOKABLE QVariantMap getSecretChatFromCache(const QString &secretChatId);
Q_INVOKABLE QString getOptionString(const QString &optionName);
Q_INVOKABLE void copyFileToDownloads(const QString &filePath);
Q_INVOKABLE void openFileOnDevice(const QString &filePath);
@ -175,6 +184,7 @@ public:
const Group* getGroup(qlonglong groupId) const;
static ChatType chatTypeFromString(const QString &type);
static ChatMemberStatus chatMemberStatusFromString(const QString &status);
static SecretChatState secretChatStateFromString(const QString &state);
signals:
void versionDetected(const QString &version);
@ -248,6 +258,8 @@ public slots:
void handleStickerSets(const QVariantList &stickerSets);
void handleEmojiSearchCompleted(const QString &queryString, const QVariantList &resultList);
void handleOpenWithChanged();
void handleSecretChatReceived(const QString &secretChatId, const QVariantMap &secretChat);
void handleSecretChatUpdated(const QString &secretChatId, const QVariantMap &secretChat);
private:
void setInitialParameters();
@ -270,6 +282,7 @@ private:
QVariantMap allUsers;
QVariantMap allUserNames;
QVariantMap chats;
QVariantMap secretChats;
QVariantMap unreadMessageInformation;
QVariantMap unreadChatInformation;
QHash<qlonglong,Group*> basicGroups;