Show topic title in the notifications.

This commit is contained in:
John Preston 2022-11-01 20:57:36 +04:00
parent 969b051c8f
commit e62bdd286d
6 changed files with 100 additions and 26 deletions

View File

@ -1031,7 +1031,7 @@ void TopBarWidget::updateControlsVisibility() {
&& _activeChat.key.peer()->canSendPolls()) && _activeChat.key.peer()->canSendPolls())
|| (topic && topic->canSendPolls()); || (topic && topic->canSendPolls());
const auto hasTopicMenu = [&] { const auto hasTopicMenu = [&] {
if (!topic) { if (!topic || section != Section::Replies) {
return false; return false;
} }
auto empty = true; auto empty = true;

View File

@ -14,6 +14,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <deque>
namespace MTP { namespace MTP {
class Instance; class Instance;

View File

@ -942,8 +942,8 @@ TextWithEntities Manager::ComposeReactionNotification(
return text(); return text();
} }
QString Manager::addTargetAccountName( TextWithEntities Manager::addTargetAccountName(
const QString &title, TextWithEntities title,
not_null<Main::Session*> session) { not_null<Main::Session*> session) {
const auto add = [&] { const auto add = [&] {
for (const auto &[index, account] : Core::App().domain().accounts()) { for (const auto &[index, account] : Core::App().domain().accounts()) {
@ -955,13 +955,19 @@ QString Manager::addTargetAccountName(
} }
return false; return false;
}(); }();
return add if (!add) {
? (title return title;
+ accountNameSeparator() }
+ (session->user()->username().isEmpty() return title.append(accountNameSeparator()).append(
(session->user()->username().isEmpty()
? session->user()->name() ? session->user()->name()
: session->user()->username())) : session->user()->username()));
: title; }
QString Manager::addTargetAccountName(
const QString &title,
not_null<Main::Session*> session) {
return addTargetAccountName(TextWithEntities{ title }, session).text;
} }
QString Manager::accountNameSeparator() { QString Manager::accountNameSeparator() {
@ -1099,11 +1105,16 @@ void NativeManager::doShowNotification(NotificationFields &&fields) {
&& !reactionFrom && !reactionFrom
&& (item->out() || peer->isSelf()) && (item->out() || peer->isSelf())
&& item->isFromScheduled(); && item->isFromScheduled();
const auto topicWithChat = [&] {
const auto name = peer->name();
const auto topic = item->topic();
return topic ? (topic->title() + u" ("_q + name + ')') : name;
};
const auto title = options.hideNameAndPhoto const auto title = options.hideNameAndPhoto
? AppName.utf16() ? AppName.utf16()
: (scheduled && peer->isSelf()) : (scheduled && peer->isSelf())
? tr::lng_notification_reminder(tr::now) ? tr::lng_notification_reminder(tr::now)
: peer->name(); : topicWithChat();
const auto fullTitle = addTargetAccountName(title, &peer->session()); const auto fullTitle = addTargetAccountName(title, &peer->session());
const auto subtitle = reactionFrom const auto subtitle = reactionFrom
? (reactionFrom != peer ? reactionFrom->name() : QString()) ? (reactionFrom != peer ? reactionFrom->name() : QString())

View File

@ -283,6 +283,9 @@ public:
const Data::ReactionId &reaction, const Data::ReactionId &reaction,
bool hideContent); bool hideContent);
[[nodiscard]] TextWithEntities addTargetAccountName(
TextWithEntities title,
not_null<Main::Session*> session);
[[nodiscard]] QString addTargetAccountName( [[nodiscard]] QString addTargetAccountName(
const QString &title, const QString &title,
not_null<Main::Session*> session); not_null<Main::Session*> session);

View File

@ -636,6 +636,7 @@ Notification::Notification(
, _peer(peer) , _peer(peer)
, _started(crl::now()) , _started(crl::now())
, _history(history) , _history(history)
, _topic(history->peer->forumTopicFor(topicRootId))
, _topicRootId(topicRootId) , _topicRootId(topicRootId)
, _userpicView(_peer->createUserpicView()) , _userpicView(_peer->createUserpicView())
, _author(author) , _author(author)
@ -650,6 +651,13 @@ Notification::Notification(
refreshLang(); refreshLang();
}, lifetime()); }, lifetime());
if (_topic) {
_topic->destroyed(
) | rpl::start_with_next([=] {
unlinkHistory();
}, lifetime());
}
auto position = computePosition(st::notifyMinHeight); auto position = computePosition(st::notifyMinHeight);
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight); updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight);
@ -779,18 +787,18 @@ void Notification::actionsOpacityCallback() {
} }
void Notification::customEmojiCallback() { void Notification::customEmojiCallback() {
if (_textRepaintScheduled) { if (_textsRepaintScheduled) {
return; return;
} }
_textRepaintScheduled = true; _textsRepaintScheduled = true;
crl::on_main(this, [=] { repaintText(); }); crl::on_main(this, [=] { repaintText(); });
} }
void Notification::repaintText() { void Notification::repaintText() {
if (!_textRepaintScheduled) { if (!_textsRepaintScheduled) {
return; return;
} }
_textRepaintScheduled = false; _textsRepaintScheduled = false;
if (_cache.isNull()) { if (_cache.isNull()) {
return; return;
} }
@ -798,11 +806,25 @@ void Notification::repaintText() {
const auto adjusted = Ui::Text::AdjustCustomEmojiSize(st::emojiSize); const auto adjusted = Ui::Text::AdjustCustomEmojiSize(st::emojiSize);
const auto skip = (adjusted - st::emojiSize + 1) / 2; const auto skip = (adjusted - st::emojiSize + 1) / 2;
const auto margin = QMargins{ skip, skip, skip, skip }; const auto margin = QMargins{ skip, skip, skip, skip };
p.fillRect(_titleRect.marginsAdded(margin), st::notificationBg);
p.fillRect(_textRect.marginsAdded(margin), st::notificationBg); p.fillRect(_textRect.marginsAdded(margin), st::notificationBg);
paintTitle(p);
paintText(p); paintText(p);
update(); update();
} }
void Notification::paintTitle(Painter &p) {
p.setPen(st::dialogsNameFg);
p.setFont(st::semiboldFont);
_titleCache.draw(p, {
.position = _titleRect.topLeft(),
.availableWidth = _titleRect.width(),
.palette = &st::dialogsTextPalette,
.spoiler = Ui::Text::DefaultSpoilerCache(),
.elisionLines = 1,
});
}
void Notification::paintText(Painter &p) { void Notification::paintText(Painter &p) {
p.setPen(st::dialogsTextFg); p.setPen(st::dialogsTextFg);
p.setFont(st::dialogsTextFont); p.setFont(st::dialogsTextFont);
@ -868,7 +890,10 @@ void Notification::updateNotifyDisplay() {
Ui::Emoji::Draw(p, emoji, Ui::Emoji::GetSizeNormal(), rectForName.left(), top); Ui::Emoji::Draw(p, emoji, Ui::Emoji::GetSizeNormal(), rectForName.left(), top);
rectForName.setLeft(rectForName.left() + size + st::semiboldFont->spacew); rectForName.setLeft(rectForName.left() + size + st::semiboldFont->spacew);
} }
if (const auto chatTypeIcon = Dialogs::Ui::ChatTypeIcon(_history->peer)) { const auto chatTypeIcon = _topic
? nullptr
: Dialogs::Ui::ChatTypeIcon(_history->peer);
if (chatTypeIcon) {
chatTypeIcon->paint(p, rectForName.topLeft(), w); chatTypeIcon->paint(p, rectForName.topLeft(), w);
rectForName.setLeft(rectForName.left() rectForName.setLeft(rectForName.left()
+ chatTypeIcon->width() + chatTypeIcon->width()
@ -941,18 +966,46 @@ void Notification::updateNotifyDisplay() {
itemWidth)); itemWidth));
} }
p.setPen(st::dialogsNameFg); const auto topicWithChat = [&]() -> TextWithEntities {
Ui::Text::String titleText; const auto name = _history->peer->name();
const auto title = options.hideNameAndPhoto const auto wrapIcon = [](DocumentId id) {
? qsl("Telegram Desktop") return TextWithEntities{
"@",
{ EntityInText(
EntityType::CustomEmoji,
0,
1,
Data::SerializeCustomEmojiId({.id = id }))
},
};
};
if (!_topic) {
return { name };
}
auto start = _topic->iconId()
? wrapIcon(_topic->iconId())
: TextWithEntities();
return start.append(_topic->title() + u" ("_q + name + ')');
};
auto title = options.hideNameAndPhoto
? TextWithEntities{ u"Telegram Desktop"_q }
: reminder : reminder
? tr::lng_notification_reminder(tr::now) ? tr::lng_notification_reminder(tr::now, Ui::Text::WithEntities)
: _history->peer->name(); : topicWithChat();
const auto fullTitle = manager()->addTargetAccountName( const auto fullTitle = manager()->addTargetAccountName(
title, std::move(title),
&_history->session()); &_history->session());
titleText.setText(st::semiboldTextStyle, fullTitle, Ui::NameTextOptions()); const auto context = Core::MarkedTextContext{
titleText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); .session = &_history->session(),
.customEmojiRepaint = [=] { customEmojiCallback(); },
};
_titleCache.setMarkedText(
st::semiboldTextStyle,
fullTitle,
Ui::NameTextOptions(),
context);
_titleRect = rectForName;
paintTitle(p);
} }
_cache = std::move(img); _cache = std::move(img);
@ -1104,6 +1157,7 @@ bool Notification::unlinkHistory(History *history, MsgId topicRootId) {
if (unlink) { if (unlink) {
hideFast(); hideFast();
_history = nullptr; _history = nullptr;
_topic = nullptr;
_item = nullptr; _item = nullptr;
} }
return unlink; return unlink;

View File

@ -265,6 +265,7 @@ private:
void updateGeometry(int x, int y, int width, int height) override; void updateGeometry(int x, int y, int width, int height) override;
void actionsOpacityCallback(); void actionsOpacityCallback();
void repaintText(); void repaintText();
void paintTitle(Painter &p);
void paintText(Painter &p); void paintText(Painter &p);
void customEmojiCallback(); void customEmojiCallback();
@ -273,18 +274,21 @@ private:
const not_null<PeerData*> _peer; const not_null<PeerData*> _peer;
QImage _cache; QImage _cache;
Ui::Text::String _titleCache;
Ui::Text::String _textCache; Ui::Text::String _textCache;
QRect _titleRect;
QRect _textRect; QRect _textRect;
bool _hideReplyButton = false; bool _hideReplyButton = false;
bool _actionsVisible = false; bool _actionsVisible = false;
bool _textRepaintScheduled = false; bool _textsRepaintScheduled = false;
Ui::Animations::Simple a_actionsOpacity; Ui::Animations::Simple a_actionsOpacity;
QPixmap _buttonsCache; QPixmap _buttonsCache;
crl::time _started; crl::time _started;
History *_history = nullptr; History *_history = nullptr;
Data::ForumTopic *_topic = nullptr;
MsgId _topicRootId = 0; MsgId _topicRootId = 0;
std::shared_ptr<Data::CloudImageView> _userpicView; std::shared_ptr<Data::CloudImageView> _userpicView;
QString _author; QString _author;