From 232049422acb313a98a190987ddab16a1213eba7 Mon Sep 17 00:00:00 2001 From: Sebastian Wolf Date: Thu, 31 Dec 2020 00:19:36 +0100 Subject: [PATCH] Add 'mark chat as read/unread' feature, fixes #240 --- qml/components/ChatListViewItem.qml | 18 +++++++++++++ qml/components/PhotoTextsListItem.qml | 5 ++-- qml/pages/ChatPage.qml | 1 + src/chatlistmodel.cpp | 30 +++++++++++++++++++++ src/chatlistmodel.h | 2 ++ src/tdlibreceiver.cpp | 7 +++++ src/tdlibreceiver.h | 2 ++ src/tdlibwrapper.cpp | 11 ++++++++ src/tdlibwrapper.h | 2 ++ translations/harbour-fernschreiber-de.ts | 8 ++++++ translations/harbour-fernschreiber-en.ts | 8 ++++++ translations/harbour-fernschreiber-es.ts | 8 ++++++ translations/harbour-fernschreiber-fi.ts | 8 ++++++ translations/harbour-fernschreiber-hu.ts | 8 ++++++ translations/harbour-fernschreiber-it.ts | 8 ++++++ translations/harbour-fernschreiber-pl.ts | 8 ++++++ translations/harbour-fernschreiber-ru.ts | 8 ++++++ translations/harbour-fernschreiber-sv.ts | 8 ++++++ translations/harbour-fernschreiber-zh_CN.ts | 8 ++++++ translations/harbour-fernschreiber.ts | 8 ++++++ 20 files changed, 164 insertions(+), 2 deletions(-) diff --git a/qml/components/ChatListViewItem.qml b/qml/components/ChatListViewItem.qml index 9ed98f4..74afedd 100644 --- a/qml/components/ChatListViewItem.qml +++ b/qml/components/ChatListViewItem.qml @@ -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: { diff --git a/qml/components/PhotoTextsListItem.qml b/qml/components/PhotoTextsListItem.qml index 8ea03af..f5fbb4b 100644 --- a/qml/components/PhotoTextsListItem.qml +++ b/qml/components/PhotoTextsListItem.qml @@ -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 } } diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml index 9384630..cc2f9d8 100644 --- a/qml/pages/ChatPage.qml +++ b/qml/pages/ChatPage.qml @@ -171,6 +171,7 @@ Page { stickerManager.setNeedsReload(false); } tdLibWrapper.getChatPinnedMessage(chatInformation.id); + tdLibWrapper.toggleChatIsMarkedAsUnread(chatInformation.id, false); } function getMessageStatusText(message, listItemIndex, lastReadSentIndex, useElapsed) { diff --git a/src/chatlistmodel.cpp b/src/chatlistmodel.cpp index 4de375b..64ad690 100644 --- a/src/chatlistmodel.cpp +++ b/src/chatlistmodel.cpp @@ -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 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 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 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"); diff --git a/src/chatlistmodel.h b/src/chatlistmodel.h index 734d51b..0768859 100644 --- a/src/chatlistmodel.h +++ b/src/chatlistmodel.h @@ -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: diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp index 57200e8..6d754dd 100644 --- a/src/tdlibreceiver.cpp +++ b/src/tdlibreceiver.cpp @@ -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()); +} diff --git a/src/tdlibreceiver.h b/src/tdlibreceiver.h index 58c182f..f466a5b 100644 --- a/src/tdlibreceiver.h +++ b/src/tdlibreceiver.h @@ -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 diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp index 43d361d..b6d1b20 100644 --- a/src/tdlibwrapper.cpp +++ b/src/tdlibwrapper.cpp @@ -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); diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h index 3d35219..db7b2a6 100644 --- a/src/tdlibwrapper.h +++ b/src/tdlibwrapper.h @@ -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); diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts index b0645d9..bafe6fa 100644 --- a/translations/harbour-fernschreiber-de.ts +++ b/translations/harbour-fernschreiber-de.ts @@ -264,6 +264,14 @@ No message in this chat. Keine Nachricht in diesem Chat + + Mark chat as unread + Chat als ungelesen markieren + + + Mark chat as read + Chat als gelesen markieren + ChatPage diff --git a/translations/harbour-fernschreiber-en.ts b/translations/harbour-fernschreiber-en.ts index 4345302..0c0e109 100644 --- a/translations/harbour-fernschreiber-en.ts +++ b/translations/harbour-fernschreiber-en.ts @@ -264,6 +264,14 @@ No message in this chat. No message in this chat. + + Mark chat as unread + Mark chat as unread + + + Mark chat as read + Mark chat as read + ChatPage diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts index 7efb477..44f4e5c 100644 --- a/translations/harbour-fernschreiber-es.ts +++ b/translations/harbour-fernschreiber-es.ts @@ -261,6 +261,14 @@ No message in this chat. No hay mensaje en esta charla. + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts index eb9f6b6..b4f1e6f 100644 --- a/translations/harbour-fernschreiber-fi.ts +++ b/translations/harbour-fernschreiber-fi.ts @@ -264,6 +264,14 @@ No message in this chat. Tässä keskustelussa ei ole viestejä. + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts index 63448a4..5e1fe8f 100644 --- a/translations/harbour-fernschreiber-hu.ts +++ b/translations/harbour-fernschreiber-hu.ts @@ -261,6 +261,14 @@ No message in this chat. + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts index 4fcac81..3781db2 100644 --- a/translations/harbour-fernschreiber-it.ts +++ b/translations/harbour-fernschreiber-it.ts @@ -264,6 +264,14 @@ No message in this chat. Nessun messaggio. + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts index 789ae0c..0e7796e 100644 --- a/translations/harbour-fernschreiber-pl.ts +++ b/translations/harbour-fernschreiber-pl.ts @@ -267,6 +267,14 @@ No message in this chat. Brak wiadomości na tym czacie. + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts index b14f5f3..5583389 100644 --- a/translations/harbour-fernschreiber-ru.ts +++ b/translations/harbour-fernschreiber-ru.ts @@ -267,6 +267,14 @@ No message in this chat. В чате нет сообщений + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts index bf6045f..d036298 100644 --- a/translations/harbour-fernschreiber-sv.ts +++ b/translations/harbour-fernschreiber-sv.ts @@ -264,6 +264,14 @@ No message in this chat. Inget meddelande i den här chatten. + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts index fad6d26..56924ea 100644 --- a/translations/harbour-fernschreiber-zh_CN.ts +++ b/translations/harbour-fernschreiber-zh_CN.ts @@ -261,6 +261,14 @@ No message in this chat. 该对话没有消息… + + Mark chat as unread + + + + Mark chat as read + + ChatPage diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts index 21a1b2f..5f1a8da 100644 --- a/translations/harbour-fernschreiber.ts +++ b/translations/harbour-fernschreiber.ts @@ -264,6 +264,14 @@ No message in this chat. + + Mark chat as unread + + + + Mark chat as read + + ChatPage