From 9febcd88d461a18a12a4c331e386f1ad9cfad20d Mon Sep 17 00:00:00 2001 From: 23rd <23rd@vivaldi.net> Date: Wed, 1 Apr 2026 11:16:18 +0300 Subject: [PATCH] Added unread media dot indicator for voice messages to dialog list. --- Telegram/SourceFiles/dialogs/dialogs.style | 4 +++ .../dialogs/ui/dialogs_message_view.cpp | 31 +++++++++++++++++++ .../dialogs/ui/dialogs_message_view.h | 1 + Telegram/SourceFiles/history/history_item.cpp | 5 +++ 4 files changed, 41 insertions(+) diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index 5f23106d72..a0dcfa91ca 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -540,6 +540,10 @@ dialogsScamFont: font(9px semibold); dialogsScamSkip: 4px; dialogsScamRadius: 2px; +dialogsUnreadMediaSize: 5px; +dialogsUnreadMediaSkip: 4px; +dialogsUnreadMediaTop: 7px; + dialogsMiniPreviewTop: 1px; dialogsMiniPreview: 16px; dialogsMiniPreviewRadius: 2px; diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.cpp b/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.cpp index a007fa48b5..3471f9858d 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.cpp +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.cpp @@ -144,6 +144,7 @@ bool MessageView::prepared( Data::Forum *forum, Data::SavedMessages *monoforum) const { return (_textCachedFor == item.get()) + && (_unreadMedia == item->isUnreadMedia()) && ((!forum && !monoforum) || (_topics && _topics->forum() == forum @@ -176,6 +177,7 @@ void MessageView::prepare( } } if (_textCachedFor == item.get()) { + _unreadMedia = item->isUnreadMedia(); return; } options.existing = &_imagesCache; @@ -310,6 +312,7 @@ void MessageView::prepare( DialogTextOptions(), std::move(context)); _textCachedFor = item; + _unreadMedia = item->isUnreadMedia(); _imagesCache = std::move(preview.images); if (!ranges::any_of(_imagesCache, &ItemPreviewImage::hasSpoiler)) { _spoiler = nullptr; @@ -379,6 +382,9 @@ int MessageView::countWidth() const { * (st::dialogsMiniPreview + st::dialogsMiniPreviewSkip)) + st::dialogsMiniPreviewRight; } + if (_unreadMedia) { + result += st::dialogsUnreadMediaSize + st::dialogsUnreadMediaSkip; + } return result + _textCache.maxWidth(); } @@ -502,6 +508,31 @@ void MessageView::paint( rect.setLeft(rect.x() + st::dialogsMiniPreviewRight); } // Style of _textCache. + if (_unreadMedia && rect.width() + >= st::dialogsUnreadMediaSize + st::dialogsUnreadMediaSkip) { + { + PainterHighQualityEnabler hq(p); + p.setPen(Qt::NoPen); + p.setBrush(context.active + ? st::dialogsTextFgServiceActive + : context.selected + ? st::dialogsTextFgServiceOver + : st::dialogsTextFgService); + p.drawEllipse( + rect.x(), + rect.y() + st::dialogsUnreadMediaTop, + st::dialogsUnreadMediaSize, + st::dialogsUnreadMediaSize); + } + p.setPen(context.active + ? st::dialogsTextFgActive + : context.selected + ? st::dialogsTextFgOver + : st::dialogsTextFg); + rect.setLeft(rect.x() + + st::dialogsUnreadMediaSize + + st::dialogsUnreadMediaSkip); + } static const auto ellipsisWidth = st::dialogsTextStyle.font->width( kQEllipsis); if (rect.width() > ellipsisWidth) { diff --git a/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.h b/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.h index 1cbe888a72..d2f8bbc960 100644 --- a/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.h +++ b/Telegram/SourceFiles/dialogs/ui/dialogs_message_view.h @@ -99,6 +99,7 @@ private: mutable const style::DialogsMiniIcon *_leftIcon = nullptr; mutable QImage _cornersCache; mutable bool _hasPlainLinkAtBegin = false; + mutable bool _unreadMedia = false; }; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 761a86153a..5777ba7b68 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -1628,8 +1628,13 @@ bool HistoryItem::isIncomingUnreadMedia() const { } void HistoryItem::markMediaAndMentionRead() { + const auto wasUnreadMedia = isUnreadMedia(); _flags &= ~MessageFlag::MediaIsUnread; + if (wasUnreadMedia) { + invalidateChatListEntry(); + } + if (mentionsMe()) { _history->updateChatListEntry(); _history->unreadMentions().erase(id);