Add 'mark chat as read/unread' feature, fixes #240

This commit is contained in:
Sebastian Wolf 2020-12-31 00:19:36 +01:00
parent fa0aaf431e
commit 232049422a
No known key found for this signature in database
GPG key ID: CEA9522B5F38A90A
20 changed files with 164 additions and 2 deletions

View file

@ -22,6 +22,7 @@ PhotoTextsListItem {
tertiaryText.text: ( last_message_date ? ( last_message_date.length === 0 ? "" : Functions.getDateTimeElapsed(last_message_date) + Emoji.emojify(last_message_status, tertiaryText.font.pixelSize) ) : "" )
unreadCount: unread_count
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
isMarkedAsUnread: is_marked_as_unread
openMenuOnPressAndHold: true//chat_id != overviewPage.ownUserId
@ -45,10 +46,27 @@ PhotoTextsListItem {
visible: unread_count > 0
onClicked: {
tdLibWrapper.viewMessage(chat_id, display.last_message.id, true);
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, false);
}
text: qsTr("Mark all messages as read")
}
MenuItem {
visible: unread_count === 0 && !is_marked_as_unread
onClicked: {
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, true);
}
text: qsTr("Mark chat as unread")
}
MenuItem {
visible: unread_count === 0 && is_marked_as_unread
onClicked: {
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, false);
}
text: qsTr("Mark chat as read")
}
MenuItem {
visible: chat_id != listItem.ownUserId
onClicked: {

View file

@ -13,6 +13,7 @@ ListItem {
property int unreadCount: 0
property bool isSecret: false
property bool isVerified: false
property bool isMarkedAsUnread: false
property alias pictureThumbnail: pictureThumbnail
contentHeight: mainRow.height + separator.height + 2 * Theme.paddingMedium
@ -75,7 +76,7 @@ ListItem {
anchors.right: parent.right
anchors.bottom: parent.bottom
radius: parent.width / 2
visible: chatListViewItem.unreadCount > 0
visible: chatListViewItem.unreadCount > 0 || chatListViewItem.isMarkedAsUnread
}
Text {
@ -84,7 +85,7 @@ ListItem {
font.bold: true
color: Theme.primaryColor
anchors.centerIn: chatUnreadMessagesCountBackground
visible: chatUnreadMessagesCountBackground.visible
visible: chatListViewItem.unreadCount > 0
text: chatListViewItem.unreadCount > 99 ? "99+" : chatListViewItem.unreadCount
}
}

View file

@ -171,6 +171,7 @@ Page {
stickerManager.setNeedsReload(false);
}
tdLibWrapper.getChatPinnedMessage(chatInformation.id);
tdLibWrapper.toggleChatIsMarkedAsUnread(chatInformation.id, false);
}
function getMessageStatusText(message, listItemIndex, lastReadSentIndex, useElapsed) {

View file

@ -46,6 +46,7 @@ namespace {
const QString SENDING_STATE("sending_state");
const QString IS_CHANNEL("is_channel");
const QString IS_VERIFIED("is_verified");
const QString IS_MARKED_AS_UNREAD("is_marked_as_unread");
const QString PINNED_MESSAGE_ID("pinned_message_id");
const QString _TYPE("@type");
const QString SECRET_CHAT_ID("secret_chat_id");
@ -72,6 +73,7 @@ public:
QString senderMessageStatus() const;
bool isChannel() const;
bool isHidden() const;
bool isMarkedAsUnread() const;
bool updateUnreadCount(int unreadCount);
bool updateLastReadInboxMessageId(qlonglong messageId);
QVector<int> updateLastMessage(const QVariantMap &message);
@ -244,6 +246,11 @@ bool ChatListModel::ChatData::isHidden() const
return false;
}
bool ChatListModel::ChatData::isMarkedAsUnread() const
{
return chatData.value(IS_MARKED_AS_UNREAD).toBool();
}
bool ChatListModel::ChatData::updateUnreadCount(int count)
{
const int prevUnreadCount(unreadCount());
@ -335,6 +342,7 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false
connect(tdLibWrapper, SIGNAL(secretChatUpdated(qlonglong, QVariantMap)), this, SLOT(handleSecretChatUpdated(qlonglong, QVariantMap)));
connect(tdLibWrapper, SIGNAL(secretChatReceived(qlonglong, QVariantMap)), this, SLOT(handleSecretChatUpdated(qlonglong, QVariantMap)));
connect(tdLibWrapper, SIGNAL(chatTitleUpdated(QString, QString)), this, SLOT(handleChatTitleUpdated(QString, QString)));
connect(tdLibWrapper, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SLOT(handleChatIsMarkedAsUnreadUpdated(qlonglong, bool)));
// Don't start the timer until we have at least one chat
relativeTimeRefreshTimer = new QTimer(this);
@ -368,6 +376,7 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
roles.insert(ChatListModel::RoleSecretChatState, "secret_chat_state");
roles.insert(ChatListModel::RoleIsVerified, "is_verified");
roles.insert(ChatListModel::RoleIsChannel, "is_channel");
roles.insert(ChatListModel::RoleIsMarkedAsUnread, "is_marked_as_unread");
roles.insert(ChatListModel::RoleFilter, "filter");
return roles;
}
@ -398,6 +407,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
case ChatListModel::RoleSecretChatState: return data->secretChatState;
case ChatListModel::RoleIsVerified: return data->verified;
case ChatListModel::RoleIsChannel: return data->isChannel();
case ChatListModel::RoleIsMarkedAsUnread: return data->isMarkedAsUnread();
case ChatListModel::RoleFilter: return QString(data->title() + " " + data->senderMessageText()).trimmed();
}
}
@ -814,6 +824,26 @@ void ChatListModel::handleChatTitleUpdated(const QString &chatId, const QString
}
}
void ChatListModel::handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread)
{
if (chatIndexMap.contains(chatId)) {
LOG("Updating chat is marked as unread for" << chatId << chatIsMarkedAsUnread);
const int chatIndex = chatIndexMap.value(chatId);
ChatData *chat = chatList.at(chatIndex);
chat->chatData.insert(IS_MARKED_AS_UNREAD, chatIsMarkedAsUnread);
QVector<int> changedRoles;
changedRoles.append(ChatListModel::RoleIsMarkedAsUnread);
const QModelIndex modelIndex(index(chatIndex));
emit dataChanged(modelIndex, modelIndex, changedRoles);
} else {
ChatData *chat = hiddenChats.value(chatId);
if (chat) {
LOG("Updating chat is marked as unread for hidden chat" << chatId);
chat->chatData.insert(IS_MARKED_AS_UNREAD, chatIsMarkedAsUnread);
}
}
}
void ChatListModel::handleRelativeTimeRefreshTimer()
{
LOG("Refreshing timestamps");

View file

@ -46,6 +46,7 @@ public:
RoleSecretChatState,
RoleIsVerified,
RoleIsChannel,
RoleIsMarkedAsUnread,
RoleFilter
};
@ -76,6 +77,7 @@ private slots:
void handleGroupUpdated(qlonglong groupId);
void handleSecretChatUpdated(qlonglong secretChatId, const QVariantMap &secretChat);
void handleChatTitleUpdated(const QString &chatId, const QString &title);
void handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
void handleRelativeTimeRefreshTimer();
signals:

View file

@ -133,6 +133,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
handlers.insert("updateSecretChat", &TDLibReceiver::processUpdateSecretChat);
handlers.insert("importedContacts", &TDLibReceiver::processImportedContacts);
handlers.insert("updateMessageEdited", &TDLibReceiver::processUpdateMessageEdited);
handlers.insert("updateChatIsMarkedAsUnread", &TDLibReceiver::processUpdateChatIsMarkedAsUnread);
}
void TDLibReceiver::setActive(bool active)
@ -569,3 +570,9 @@ void TDLibReceiver::processImportedContacts(const QVariantMap &receivedInformati
LOG("Contacts were imported");
emit contactsImported(receivedInformation.value("importer_count").toList(), receivedInformation.value("user_ids").toList());
}
void TDLibReceiver::processUpdateChatIsMarkedAsUnread(const QVariantMap &receivedInformation)
{
LOG("The unread state of a chat was updated");
emit chatIsMarkedAsUnreadUpdated(receivedInformation.value(CHAT_ID).toLongLong(), receivedInformation.value("is_marked_as_unread").toBool());
}

View file

@ -90,6 +90,7 @@ signals:
void secretChat(qlonglong secretChatId, const QVariantMap &secretChat);
void secretChatUpdated(qlonglong secretChatId, const QVariantMap &secretChat);
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
void chatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
private:
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
@ -155,6 +156,7 @@ private:
void processUpdateSecretChat(const QVariantMap &receivedInformation);
void processUpdateMessageEdited(const QVariantMap &receivedInformation);
void processImportedContacts(const QVariantMap &receivedInformation);
void processUpdateChatIsMarkedAsUnread(const QVariantMap &receivedInformation);
};
#endif // TDLIBRECEIVER_H

View file

@ -125,6 +125,7 @@ TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface,
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString, QString)), this, SLOT(handleErrorReceived(int, QString, QString)));
connect(this->tdLibReceiver, SIGNAL(contactsImported(QVariantList, QVariantList)), this, SIGNAL(contactsImported(QVariantList, QVariantList)));
connect(this->tdLibReceiver, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)));
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
@ -971,6 +972,16 @@ void TDLibWrapper::readAllChatMentions(qlonglong chatId)
this->sendRequest(requestObject);
}
void TDLibWrapper::toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsUnread)
{
LOG("Toggle chat is marked as unread" << chatId << isMarkedAsUnread);
QVariantMap requestObject;
requestObject.insert(_TYPE, "toggleChatIsMarkedAsUnread");
requestObject.insert(CHAT_ID, chatId);
requestObject.insert("is_marked_as_unread", isMarkedAsUnread);
this->sendRequest(requestObject);
}
void TDLibWrapper::searchEmoji(const QString &queryString)
{
LOG("Searching emoji" << queryString);

View file

@ -182,6 +182,7 @@ public:
Q_INVOKABLE void searchChatMessages(qlonglong chatId, const QString &query, qlonglong fromMessageId = 0);
Q_INVOKABLE void searchPublicChats(const QString &query);
Q_INVOKABLE void readAllChatMentions(qlonglong chatId);
Q_INVOKABLE void toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsUnread);
// Others (candidates for extraction ;))
Q_INVOKABLE void searchEmoji(const QString &queryString);
@ -251,6 +252,7 @@ signals:
void errorReceived(int code, const QString &message, const QString &extra);
void contactsImported(const QVariantList &importerCount, const QVariantList &userIds);
void messageNotFound(qlonglong chatId, qlonglong messageId);
void chatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
public slots:
void handleVersionDetected(const QString &version);

View file

@ -264,6 +264,14 @@
<source>No message in this chat.</source>
<translation>Keine Nachricht in diesem Chat</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation>Chat als ungelesen markieren</translation>
</message>
<message>
<source>Mark chat as read</source>
<translation>Chat als gelesen markieren</translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -264,6 +264,14 @@
<source>No message in this chat.</source>
<translation>No message in this chat.</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation>Mark chat as unread</translation>
</message>
<message>
<source>Mark chat as read</source>
<translation>Mark chat as read</translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -261,6 +261,14 @@
<source>No message in this chat.</source>
<translation>No hay mensaje en esta charla.</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -264,6 +264,14 @@
<source>No message in this chat.</source>
<translation>Tässä keskustelussa ei ole viestejä.</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -261,6 +261,14 @@
<source>No message in this chat.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -264,6 +264,14 @@
<source>No message in this chat.</source>
<translation>Nessun messaggio.</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -267,6 +267,14 @@
<source>No message in this chat.</source>
<translation>Brak wiadomości na tym czacie.</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -267,6 +267,14 @@
<source>No message in this chat.</source>
<translation>В чате нет сообщений</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -264,6 +264,14 @@
<source>No message in this chat.</source>
<translation>Inget meddelande i den här chatten.</translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -261,6 +261,14 @@
<source>No message in this chat.</source>
<translation></translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>

View file

@ -264,6 +264,14 @@
<source>No message in this chat.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as unread</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Mark chat as read</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatPage</name>