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, RoleLastMessageText,
RoleLastMessageStatus, RoleLastMessageStatus,
RoleChatMemberStatus, RoleChatMemberStatus,
RoleSecretChatState,
RoleIsChannel RoleIsChannel
}; };
@ -86,6 +87,7 @@ public:
bool updateLastReadInboxMessageId(qlonglong messageId); bool updateLastReadInboxMessageId(qlonglong messageId);
QVector<int> updateLastMessage(const QVariantMap &message); QVector<int> updateLastMessage(const QVariantMap &message);
QVector<int> updateGroup(const TDLibWrapper::Group *group); QVector<int> updateGroup(const TDLibWrapper::Group *group);
QVector<int> updateSecretChat(const QVariantMap &secretChatDetails);
public: public:
QVariantMap chatData; QVariantMap chatData;
@ -94,6 +96,7 @@ public:
qlonglong groupId; qlonglong groupId;
TDLibWrapper::ChatType chatType; TDLibWrapper::ChatType chatType;
TDLibWrapper::ChatMemberStatus memberStatus; TDLibWrapper::ChatMemberStatus memberStatus;
TDLibWrapper::SecretChatState secretChatState;
QVariantMap userInformation; QVariantMap userInformation;
}; };
@ -103,6 +106,7 @@ ChatListModel::ChatData::ChatData(const QVariantMap &data, const QVariantMap &us
order(data.value(ORDER).toLongLong()), order(data.value(ORDER).toLongLong()),
groupId(0), groupId(0),
memberStatus(TDLibWrapper::ChatMemberStatusUnknown), memberStatus(TDLibWrapper::ChatMemberStatusUnknown),
secretChatState(TDLibWrapper::SecretChatStateUnknown),
userInformation(userInfo) userInformation(userInfo)
{ {
const QVariantMap type(data.value(TYPE).toMap()); const QVariantMap type(data.value(TYPE).toMap());
@ -227,7 +231,11 @@ bool ChatListModel::ChatData::isHidden() const
break; break;
case TDLibWrapper::ChatTypeUnknown: case TDLibWrapper::ChatTypeUnknown:
case TDLibWrapper::ChatTypePrivate: case TDLibWrapper::ChatTypePrivate:
break;
case TDLibWrapper::ChatTypeSecret: case TDLibWrapper::ChatTypeSecret:
if (secretChatState == TDLibWrapper::SecretChatStateClosed) {
return true;
}
break; break;
} }
return false; return false;
@ -288,6 +296,18 @@ QVector<int> ChatListModel::ChatData::updateGroup(const TDLibWrapper::Group *gro
return changedRoles; 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) ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false)
{ {
this->tdLibWrapper = tdLibWrapper; 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(chatNotificationSettingsUpdated(QString, QVariantMap)), this, SLOT(handleChatNotificationSettingsUpdated(QString, QVariantMap)));
connect(tdLibWrapper, SIGNAL(superGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong))); connect(tdLibWrapper, SIGNAL(superGroupUpdated(qlonglong)), this, SLOT(handleGroupUpdated(qlonglong)));
connect(tdLibWrapper, SIGNAL(basicGroupUpdated(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 // Don't start the timer until we have at least one chat
relativeTimeRefreshTimer = new QTimer(this); relativeTimeRefreshTimer = new QTimer(this);
@ -332,6 +354,7 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
roles.insert(ChatData::RoleLastMessageText, "last_message_text"); roles.insert(ChatData::RoleLastMessageText, "last_message_text");
roles.insert(ChatData::RoleLastMessageStatus, "last_message_status"); roles.insert(ChatData::RoleLastMessageStatus, "last_message_status");
roles.insert(ChatData::RoleChatMemberStatus, "chat_member_status"); roles.insert(ChatData::RoleChatMemberStatus, "chat_member_status");
roles.insert(ChatData::RoleSecretChatState, "secret_chat_state");
roles.insert(ChatData::RoleIsChannel, "is_channel"); roles.insert(ChatData::RoleIsChannel, "is_channel");
return roles; return roles;
} }
@ -359,6 +382,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
case ChatData::RoleLastMessageDate: return data->senderMessageDate(); case ChatData::RoleLastMessageDate: return data->senderMessageDate();
case ChatData::RoleLastMessageStatus: return data->senderMessageStatus(); case ChatData::RoleLastMessageStatus: return data->senderMessageStatus();
case ChatData::RoleChatMemberStatus: return data->memberStatus; case ChatData::RoleChatMemberStatus: return data->memberStatus;
case ChatData::RoleSecretChatState: return data->secretChatState;
case ChatData::RoleIsChannel: return data->isChannel(); 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 bool ChatListModel::showAllChats() const
{ {
return showHiddenChats; return showHiddenChats;
@ -509,10 +577,19 @@ void ChatListModel::setShowAllChats(bool showAll)
void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &chatToBeAdded) void ChatListModel::handleChatDiscovered(const QString &, const QVariantMap &chatToBeAdded)
{ {
ChatData *chat = new ChatData(chatToBeAdded, tdLibWrapper->getUserInformation()); ChatData *chat = new ChatData(chatToBeAdded, tdLibWrapper->getUserInformation());
const TDLibWrapper::Group *group = tdLibWrapper->getGroup(chat->groupId); const TDLibWrapper::Group *group = tdLibWrapper->getGroup(chat->groupId);
if (group) { if (group) {
chat->updateGroup(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()) { if (chat->isHidden()) {
LOG("Hidden chat" << chat->chatId); LOG("Hidden chat" << chat->chatId);
hiddenChats.insert(chat->chatId, chat); hiddenChats.insert(chat->chatId, chat);
@ -707,6 +784,12 @@ void ChatListModel::handleGroupUpdated(qlonglong groupId)
updateChatVisibility(tdLibWrapper->getGroup(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() void ChatListModel::handleRelativeTimeRefreshTimer()
{ {
LOG("Refreshing timestamps"); LOG("Refreshing timestamps");

View file

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

View file

@ -44,6 +44,7 @@ namespace {
const QString UNREAD_COUNT("unread_count"); const QString UNREAD_COUNT("unread_count");
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id"); 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 LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
const QString SECRET_CHAT("secret_chat");
const QString TYPE("@type"); const QString TYPE("@type");
const QString EXTRA("@extra"); const QString EXTRA("@extra");
@ -529,11 +530,13 @@ void TDLibReceiver::nop(const QVariantMap &)
void TDLibReceiver::processSecretChat(const QVariantMap &receivedInformation) void TDLibReceiver::processSecretChat(const QVariantMap &receivedInformation)
{ {
LOG("Received a secret chat"); 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) void TDLibReceiver::processUpdateSecretChat(const QVariantMap &receivedInformation)
{ {
LOG("A secret chat was updated"); 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(messagesDeleted(QString, QVariantList)), this, SIGNAL(messagesDeleted(QString, QVariantList)));
connect(this->tdLibReceiver, SIGNAL(chats(QVariantMap)), this, SIGNAL(chatsReceived(QVariantMap))); connect(this->tdLibReceiver, SIGNAL(chats(QVariantMap)), this, SIGNAL(chatsReceived(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(chat(QVariantMap)), this, SLOT(handleChatReceived(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(secretChat(QString, QVariantMap)), this, SLOT(handleSecretChatReceived(QString, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(secretChatUpdated(QString, QVariantMap)), this, SIGNAL(secretChatUpdated(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(recentStickersUpdated(QVariantList)), this, SIGNAL(recentStickersUpdated(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(stickers(QVariantList)), this, SIGNAL(stickersReceived(QVariantList))); connect(this->tdLibReceiver, SIGNAL(stickers(QVariantList)), this, SIGNAL(stickersReceived(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(installedStickerSetsUpdated(QVariantList)), this, SIGNAL(installedStickerSetsUpdated(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(); return this->chats.value(chatId).toMap();
} }
QVariantMap TDLibWrapper::getSecretChatFromCache(const QString &secretChatId)
{
return this->secretChats.value(secretChatId).toMap();
}
QString TDLibWrapper::getOptionString(const QString &optionName) QString TDLibWrapper::getOptionString(const QString &optionName)
{ {
return this->options.value(optionName).toString(); 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() void TDLibWrapper::setInitialParameters()
{ {
LOG("Sending initial parameters to TD Lib"); LOG("Sending initial parameters to TD Lib");
@ -1172,7 +1189,7 @@ void TDLibWrapper::setInitialParameters()
initialParameters.insert("use_file_database", true); initialParameters.insert("use_file_database", true);
initialParameters.insert("use_chat_info_database", true); initialParameters.insert("use_chat_info_database", true);
initialParameters.insert("use_message_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()); initialParameters.insert("system_language_code", QLocale::system().name());
QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat); QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat);
initialParameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString()); initialParameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString());
@ -1309,6 +1326,14 @@ TDLibWrapper::ChatMemberStatus TDLibWrapper::chatMemberStatusFromString(const QS
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 TDLibWrapper::ChatMemberStatus TDLibWrapper::Group::chatMemberStatus() const
{ {
const QString statusType(groupInfo.value(STATUS).toMap().value(_TYPE).toString()); const QString statusType(groupInfo.value(STATUS).toMap().value(_TYPE).toString());

View file

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