diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 3f548a70d..f2fd9a233 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1357,6 +1357,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_comments_open_count#one" = "{count} comment"; "lng_comments_open_count#other" = "{count} comments"; "lng_comments_open_none" = "Leave a comment"; +"lng_replies_messages" = "Replies"; "lng_archived_name" = "Archived chats"; "lng_archived_add" = "Archive"; diff --git a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp index 8b634248f..0c23ddb25 100644 --- a/Telegram/SourceFiles/boxes/edit_privacy_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_privacy_box.cpp @@ -86,7 +86,7 @@ void PrivacyExceptionsBoxController::rowClicked(not_null row) { } std::unique_ptr PrivacyExceptionsBoxController::createRow(not_null history) { - if (history->peer->isSelf()) { + if (history->peer->isSelf() || history->peer->isRepliesChat()) { return nullptr; } else if (!history->peer->isUser() && !history->peer->isChat() diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp index 081503c4f..40cc48323 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_box.cpp @@ -241,19 +241,31 @@ void FilterChatsPreview::paintEvent(QPaintEvent *e) { } for (auto &[history, userpic, button] : _removePeer) { const auto savedMessages = history->peer->isSelf(); - if (savedMessages) { - Ui::EmptyUserpic::PaintSavedMessages( - p, - iconLeft, - top + iconTop, - width(), - st.photoSize); + const auto repliesMessages = history->peer->isRepliesChat(); + if (savedMessages || repliesMessages) { + if (savedMessages) { + Ui::EmptyUserpic::PaintSavedMessages( + p, + iconLeft, + top + iconTop, + width(), + st.photoSize); + } else { + Ui::EmptyUserpic::PaintRepliesMessages( + p, + iconLeft, + top + iconTop, + width(), + st.photoSize); + } p.setPen(st::contactsNameFg); p.drawTextLeft( nameLeft, top + nameTop, width(), - tr::lng_saved_messages(tr::now)); + (savedMessages + ? tr::lng_saved_messages(tr::now) + : tr::lng_replies_messages(tr::now))); } else { history->peer->paintUserpicLeft( p, diff --git a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp index b5e56f369..427a803fb 100644 --- a/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp +++ b/Telegram/SourceFiles/boxes/filters/edit_filter_chats_list.cpp @@ -170,6 +170,8 @@ ExceptionRow::ExceptionRow(not_null history) : Row(history) { QString ExceptionRow::generateName() { return peer()->isSelf() ? tr::lng_saved_messages(tr::now) + : peer()->isRepliesChat() + ? tr::lng_replies_messages(tr::now) : Row::generateName(); } @@ -180,10 +182,13 @@ QString ExceptionRow::generateShortName() { PaintRoundImageCallback ExceptionRow::generatePaintUserpicCallback() { const auto peer = this->peer(); const auto saved = peer->isSelf(); + const auto replies = peer->isRepliesChat(); auto userpic = saved ? nullptr : ensureUserpicView(); return [=](Painter &p, int x, int y, int outerWidth, int size) mutable { if (saved) { Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size); + } else if (replies) { + Ui::EmptyUserpic::PaintRepliesMessages(p, x, y, outerWidth, size); } else { peer->paintUserpicLeft(p, userpic, x, y, outerWidth, size); } diff --git a/Telegram/SourceFiles/boxes/peer_list_box.cpp b/Telegram/SourceFiles/boxes/peer_list_box.cpp index 99decced3..ec4c6cf46 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_box.cpp @@ -36,10 +36,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL PaintRoundImageCallback PaintUserpicCallback( not_null peer, bool respectSavedMessagesChat) { - if (respectSavedMessagesChat && peer->isSelf()) { - return [](Painter &p, int x, int y, int outerWidth, int size) { - Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size); - }; + if (respectSavedMessagesChat) { + if (peer->isSelf()) { + return [](Painter &p, int x, int y, int outerWidth, int size) { + Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size); + }; + } else if (peer->isRepliesChat()) { + return [](Painter &p, int x, int y, int outerWidth, int size) { + Ui::EmptyUserpic::PaintRepliesMessages(p, x, y, outerWidth, size); + }; + } } auto userpic = std::shared_ptr(); return [=](Painter &p, int x, int y, int outerWidth, int size) mutable { @@ -318,6 +324,8 @@ void PeerListBox::addSelectItem( const auto respect = _controller->respectSavedMessagesChat(); const auto text = (respect && peer->isSelf()) ? tr::lng_saved_short(tr::now) + : (respect && peer->isRepliesChat()) + ? tr::lng_replies_messages(tr::now) : peer->shortName(); addSelectItem( peer->id, @@ -400,14 +408,16 @@ PeerListRow::PeerListRow(not_null peer, PeerListRowId id) , _peer(peer) , _initialized(false) , _isSearchResult(false) -, _isSavedMessagesChat(false) { +, _isSavedMessagesChat(false) +, _isRepliesMessagesChat(false) { } PeerListRow::PeerListRow(PeerListRowId id) : _id(id) , _initialized(false) , _isSearchResult(false) -, _isSavedMessagesChat(false) { +, _isSavedMessagesChat(false) +, _isRepliesMessagesChat(false) { } PeerListRow::~PeerListRow() = default; @@ -470,6 +480,8 @@ void PeerListRow::refreshName(const style::PeerListItem &st) { } const auto text = _isSavedMessagesChat ? tr::lng_saved_messages(tr::now) + : _isRepliesMessagesChat + ? tr::lng_replies_messages(tr::now) : generateName(); _name.setText(st.nameStyle, text, Ui::NameTextOptions()); } @@ -481,6 +493,8 @@ QString PeerListRow::generateName() { QString PeerListRow::generateShortName() { return _isSavedMessagesChat ? tr::lng_saved_short(tr::now) + : _isRepliesMessagesChat + ? tr::lng_replies_messages(tr::now) : peer()->shortName(); } @@ -493,11 +507,14 @@ std::shared_ptr PeerListRow::ensureUserpicView() { PaintRoundImageCallback PeerListRow::generatePaintUserpicCallback() { const auto saved = _isSavedMessagesChat; + const auto replies = _isRepliesMessagesChat; const auto peer = this->peer(); auto userpic = saved ? nullptr : ensureUserpicView(); return [=](Painter &p, int x, int y, int outerWidth, int size) mutable { if (saved) { Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size); + } else if (replies) { + Ui::EmptyUserpic::PaintRepliesMessages(p, x, y, outerWidth, size); } else { peer->paintUserpicLeft(p, userpic, x, y, outerWidth, size); } @@ -603,6 +620,8 @@ void PeerListRow::paintDisabledCheckUserpic( if (_isSavedMessagesChat) { Ui::EmptyUserpic::PaintSavedMessages(p, userpicLeft, userpicTop, outerWidth, userpicRadius * 2); + } else if (_isRepliesMessagesChat) { + Ui::EmptyUserpic::PaintRepliesMessages(p, userpicLeft, userpicTop, outerWidth, userpicRadius * 2); } else { peer()->paintUserpicLeft(p, _userpic, userpicLeft, userpicTop, outerWidth, userpicRadius * 2); } @@ -731,10 +750,12 @@ void PeerListContent::changeCheckState( } void PeerListContent::addRowEntry(not_null row) { - if (_controller->respectSavedMessagesChat() - && !row->special() - && row->peer()->isSelf()) { - row->setIsSavedMessagesChat(true); + if (_controller->respectSavedMessagesChat() && !row->special()) { + if (row->peer()->isSelf()) { + row->setIsSavedMessagesChat(true); + } else if (row->peer()->isRepliesChat()) { + row->setIsRepliesMessagesChat(true); + } } _rowsById.emplace(row->id(), row); if (!row->special()) { diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index 467299118..364ed1e8b 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -146,12 +146,12 @@ public: void setIsSearchResult(bool isSearchResult) { _isSearchResult = isSearchResult; } - bool isSavedMessagesChat() const { - return _isSavedMessagesChat; - } void setIsSavedMessagesChat(bool isSavedMessagesChat) { _isSavedMessagesChat = isSavedMessagesChat; } + void setIsRepliesMessagesChat(bool isRepliesMessagesChat) { + _isRepliesMessagesChat = isRepliesMessagesChat; + } template void setChecked( @@ -234,6 +234,7 @@ private: bool _initialized : 1; bool _isSearchResult : 1; bool _isSavedMessagesChat : 1; + bool _isRepliesMessagesChat : 1; }; diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index bf400ead7..fb9cd3ad9 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -584,8 +584,7 @@ void ChooseRecipientBoxController::rowClicked(not_null row) { auto ChooseRecipientBoxController::createRow( not_null history) -> std::unique_ptr { const auto peer = history->peer; - const auto skip = peer->isChannel() - && !peer->isMegagroup() - && !peer->canWrite(); + const auto skip = (peer->isBroadcast() && !peer->canWrite()) + || peer->isRepliesChat(); return skip ? nullptr : std::make_unique(history); } diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.h b/Telegram/SourceFiles/boxes/peer_list_controllers.h index b6ca666f9..02eb810b4 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.h +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.h @@ -203,8 +203,7 @@ public: protected: void prepareViewHook() override; - std::unique_ptr createRow( - not_null history) override; + std::unique_ptr createRow(not_null history) override; private: const not_null _navigation; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index b542788d2..eb377c0b3 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -635,7 +635,11 @@ void ShareBox::Inner::updateChat(not_null peer) { void ShareBox::Inner::updateChatName( not_null chat, not_null peer) { - const auto text = peer->isSelf() ? tr::lng_saved_messages(tr::now) : peer->name; + const auto text = peer->isSelf() + ? tr::lng_saved_messages(tr::now) + : peer->isRepliesChat() + ? tr::lng_replies_messages(tr::now) + : peer->name; chat->name.setText(st::shareNameStyle, text, Ui::NameTextOptions()); } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 5d7ca49f6..c97cf6f94 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -541,6 +541,13 @@ void PeerData::fillNames() { if (localized != english) { appendToIndex(localized); } + } else if (isRepliesChat()) { + const auto english = qsl("Replies"); + const auto localized = tr::lng_replies_messages(tr::now); + appendToIndex(english); + if (localized != english) { + appendToIndex(localized); + } } } else if (const auto channel = asChannel()) { appendToIndex(channel->username); @@ -743,6 +750,10 @@ bool PeerData::isBroadcast() const { return isChannel() ? asChannel()->isBroadcast() : false; } +bool PeerData::isRepliesChat() const { + return (id == peerFromUser(708513)); +} + bool PeerData::canWrite() const { if (const auto user = asUser()) { return user->canWrite(); diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index cd78adeaa..dad65e00f 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -159,6 +159,10 @@ public: [[nodiscard]] bool isScam() const; [[nodiscard]] bool isMegagroup() const; [[nodiscard]] bool isBroadcast() const; + [[nodiscard]] bool isRepliesChat() const; + [[nodiscard]] bool sharedMediaInfo() const { + return isSelf() || isRepliesChat(); + } [[nodiscard]] bool isNotificationsUser() const { return (id == peerFromUser(333000)) diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index d641331f1..5522d5ff9 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -170,6 +170,10 @@ rpl::producer PeerFlagValue( rpl::producer CanWriteValue(UserData *user) { using namespace rpl::mappers; + + if (user->isRepliesChat()) { + return rpl::single(false); + } return PeerFlagValue(user, MTPDuser::Flag::f_deleted) | rpl::map(!_1); } diff --git a/Telegram/SourceFiles/data/data_user.h b/Telegram/SourceFiles/data/data_user.h index 2bc65d897..299cedab8 100644 --- a/Telegram/SourceFiles/data/data_user.h +++ b/Telegram/SourceFiles/data/data_user.h @@ -140,7 +140,7 @@ public: } bool canWrite() const { // Duplicated in Data::CanWriteValue(). - return !isInaccessible(); + return !isInaccessible() && !isRepliesChat(); } bool canShareThisContact() const; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index c5bb51fda..5e266b7cf 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -819,6 +819,8 @@ void InnerWidget::paintSearchInChat(Painter &p) const { if (const auto peer = _searchInChat.peer()) { if (peer->isSelf()) { paintSearchInSaved(p, top, _searchInChatText); + } else if (peer->isRepliesChat()) { + paintSearchInReplies(p, top, _searchInChatText); } else { paintSearchInPeer(p, peer, _searchInChatUserpic, top, _searchInChatText); } @@ -896,6 +898,16 @@ void InnerWidget::paintSearchInSaved( paintSearchInFilter(p, paintUserpic, top, nullptr, text); } +void InnerWidget::paintSearchInReplies( + Painter &p, + int top, + const Ui::Text::String &text) const { + const auto paintUserpic = [&](Painter &p, int x, int y, int size) { + Ui::EmptyUserpic::PaintRepliesMessages(p, x, y, width(), size); + }; + paintSearchInFilter(p, paintUserpic, top, nullptr, text); +} + //void InnerWidget::paintSearchInFeed( // #feed // Painter &p, // not_null feed, @@ -2359,6 +2371,8 @@ void InnerWidget::refreshSearchInChatLabel() { if (const auto peer = _searchInChat.peer()) { if (peer->isSelf()) { return tr::lng_saved_messages(tr::now); + } else if (peer->isRepliesChat()) { + return tr::lng_replies_messages(tr::now); } return peer->name; //} else if (const auto feed = _searchInChat.feed()) { // #feed diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index 847f1228c..e6a245d1f 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -287,6 +287,10 @@ private: Painter &p, int top, const Ui::Text::String &text) const; + void paintSearchInReplies( + Painter &p, + int top, + const Ui::Text::String &text) const; //void paintSearchInFeed( // #feed // Painter &p, // not_null feed, diff --git a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp index 3832846f6..03dcae4d4 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_layout.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_layout.cpp @@ -39,7 +39,7 @@ constexpr int kRecentlyInSeconds = 20 * 3600; const auto kPsaBadgePrefix = "cloud_lng_badge_psa_"; bool ShowUserBotIcon(not_null user) { - return user->isBot() && !user->isSupport(); + return user->isBot() && !user->isSupport() && !user->isRepliesChat(); } void PaintRowTopRight(Painter &p, const QString &text, QRect &rectForName, bool active, bool selected) { @@ -209,7 +209,8 @@ enum class Flag { Selected = 0x02, SearchResult = 0x04, SavedMessages = 0x08, - AllowUserOnline = 0x10, + RepliesMessages = 0x10, + AllowUserOnline = 0x20, //FeedSearchResult = 0x10, // #feed }; inline constexpr bool is_flag_type(Flag) { return true; } @@ -257,6 +258,13 @@ void paintRow( st::dialogsPadding.y(), fullWidth, st::dialogsPhotoSize); + } else if (flags & Flag::RepliesMessages) { + Ui::EmptyUserpic::PaintRepliesMessages( + p, + st::dialogsPadding.x(), + st::dialogsPadding.y(), + fullWidth, + st::dialogsPhotoSize); } else if (from) { row->paintUserpic( p, @@ -433,8 +441,10 @@ void paintRow( sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth); } - if (flags & Flag::SavedMessages) { - auto text = tr::lng_saved_messages(tr::now); + if (flags & (Flag::SavedMessages | Flag::RepliesMessages)) { + auto text = (flags & Flag::SavedMessages) + ? tr::lng_saved_messages(tr::now) + : tr::lng_replies_messages(tr::now); const auto textWidth = st::msgNameFont->width(text); if (textWidth > rectForName.width()) { text = st::msgNameFont->elided(text, rectForName.width()); @@ -701,7 +711,8 @@ void RowPainter::paint( const auto flags = (active ? Flag::Active : Flag(0)) | (selected ? Flag::Selected : Flag(0)) | (allowUserOnline ? Flag::AllowUserOnline : Flag(0)) - | (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0)); + | (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0)) + | (peer && peer->isRepliesChat() ? Flag::RepliesMessages : Flag(0)); const auto paintItemCallback = [&](int nameleft, int namewidth) { const auto texttop = st::dialogsPadding.y() + st::msgNameFont->height @@ -881,10 +892,13 @@ void RowPainter::paint( }; const auto showSavedMessages = history->peer->isSelf() && !row->searchInChat(); + const auto showRepliesMessages = history->peer->isRepliesChat() + && !row->searchInChat(); const auto flags = (active ? Flag::Active : Flag(0)) | (selected ? Flag::Selected : Flag(0)) | Flag::SearchResult - | (showSavedMessages ? Flag::SavedMessages : Flag(0))/* // #feed + | (showSavedMessages ? Flag::SavedMessages : Flag(0)) + | (showRepliesMessages ? Flag::RepliesMessages : Flag(0))/* // #feed | (row->searchInChat().feed() ? Flag::FeedSearchResult : Flag(0))*/; paintRow( p, diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index 9904f4788..83b6419cc 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -1466,6 +1466,8 @@ DialogInfo::Type DialogTypeFromChat(const Chat &chat) { DialogInfo::Type DialogTypeFromUser(const User &user) { return user.isSelf ? DialogInfo::Type::Self + : user.isReplies + ? DialogInfo::Type::Replies : user.isBot ? DialogInfo::Type::Bot : DialogInfo::Type::Personal; diff --git a/Telegram/SourceFiles/export/data/export_data_types.h b/Telegram/SourceFiles/export/data/export_data_types.h index 2af60cb5a..5f26479c9 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.h +++ b/Telegram/SourceFiles/export/data/export_data_types.h @@ -209,6 +209,7 @@ struct User { int32 id; bool isBot = false; bool isSelf = false; + bool isReplies = false; MTPInputUser input = MTP_inputUserEmpty(); @@ -554,6 +555,7 @@ struct DialogInfo { enum class Type { Unknown, Self, + Replies, Personal, Bot, PrivateGroup, diff --git a/Telegram/SourceFiles/export/export_controller.cpp b/Telegram/SourceFiles/export/export_controller.cpp index 6615deed4..4f3240d1a 100644 --- a/Telegram/SourceFiles/export/export_controller.cpp +++ b/Telegram/SourceFiles/export/export_controller.cpp @@ -564,6 +564,8 @@ void ControllerObject::fillMessagesState( result.entityName = dialog->name; result.entityType = (dialog->type == Data::DialogInfo::Type::Self) ? ProcessingState::EntityType::SavedMessages + : (dialog->type == Data::DialogInfo::Type::Replies) + ? ProcessingState::EntityType::RepliesMessages : ProcessingState::EntityType::Chat; result.itemIndex = _messagesWritten + progress.itemIndex; result.itemCount = std::max(_messagesCount, result.itemIndex); diff --git a/Telegram/SourceFiles/export/export_controller.h b/Telegram/SourceFiles/export/export_controller.h index 9c060541a..122657d48 100644 --- a/Telegram/SourceFiles/export/export_controller.h +++ b/Telegram/SourceFiles/export/export_controller.h @@ -56,6 +56,7 @@ struct ProcessingState { enum class EntityType { Chat, SavedMessages, + RepliesMessages, Other, }; diff --git a/Telegram/SourceFiles/export/output/export_output_html.cpp b/Telegram/SourceFiles/export/output/export_output_html.cpp index ba9074d5a..281e17192 100644 --- a/Telegram/SourceFiles/export/output/export_output_html.cpp +++ b/Telegram/SourceFiles/export/output/export_output_html.cpp @@ -2466,6 +2466,7 @@ Result HtmlWriter::writeDialogEnd() { switch (type) { case Type::Unknown: return "unknown"; case Type::Self: + case Type::Replies: case Type::Personal: return "private"; case Type::Bot: return "bot"; case Type::PrivateGroup: @@ -2480,6 +2481,7 @@ Result HtmlWriter::writeDialogEnd() { switch (type) { case Type::Unknown: case Type::Self: + case Type::Replies: case Type::Personal: case Type::Bot: return "Deleted Account"; case Type::PrivateGroup: @@ -2494,6 +2496,8 @@ Result HtmlWriter::writeDialogEnd() { const Data::DialogInfo &dialog) -> QByteArray { if (dialog.type == Type::Self) { return "Saved messages"; + } else if (dialog.type == Type::Replies) { + return "Replies"; } return dialog.name; }; @@ -2514,7 +2518,7 @@ Result HtmlWriter::writeDialogEnd() { + (outgoing ? " outgoing messages" : " messages"); }; auto userpic = UserpicData{ - (_dialog.type == Type::Self + ((_dialog.type == Type::Self || _dialog.type == Type::Replies) ? kSavedMessagesColorIndex : Data::PeerColorIndex(Data::BarePeerId(_dialog.peerId))), kEntryUserpicSize diff --git a/Telegram/SourceFiles/export/output/export_output_json.cpp b/Telegram/SourceFiles/export/output/export_output_json.cpp index 43580ba36..1710332a2 100644 --- a/Telegram/SourceFiles/export/output/export_output_json.cpp +++ b/Telegram/SourceFiles/export/output/export_output_json.cpp @@ -1011,6 +1011,7 @@ Result JsonWriter::writeDialogStart(const Data::DialogInfo &data) { switch (type) { case Type::Unknown: return ""; case Type::Self: return "saved_messages"; + case Type::Replies: return "replies"; case Type::Personal: return "personal_chat"; case Type::Bot: return "bot_chat"; case Type::PrivateGroup: return "private_group"; @@ -1026,7 +1027,7 @@ Result JsonWriter::writeDialogStart(const Data::DialogInfo &data) { ? QByteArray() : prepareArrayItemStart(); block.append(pushNesting(Context::kObject)); - if (data.type != Type::Self) { + if (data.type != Type::Self && data.type != Type::Replies) { block.append(prepareObjectItemStart("name") + StringAllowNull(data.name)); } diff --git a/Telegram/SourceFiles/export/output/export_output_text.cpp b/Telegram/SourceFiles/export/output/export_output_text.cpp index e839deda3..3aaf1c046 100644 --- a/Telegram/SourceFiles/export/output/export_output_text.cpp +++ b/Telegram/SourceFiles/export/output/export_output_text.cpp @@ -883,6 +883,7 @@ Result TextWriter::writeDialogEnd() { switch (type) { case Type::Unknown: return "(unknown)"; case Type::Self: + case Type::Replies: case Type::Personal: return "Personal chat"; case Type::Bot: return "Bot chat"; case Type::PrivateGroup: return "Private group"; @@ -898,6 +899,8 @@ Result TextWriter::writeDialogEnd() { Type type) -> QByteArray { if (dialog.type == Type::Self) { return "Saved messages"; + } else if (dialog.type == Type::Replies) { + return "Replies"; } const auto name = dialog.name; if (!name.isEmpty()) { diff --git a/Telegram/SourceFiles/export/view/export_view_content.cpp b/Telegram/SourceFiles/export/view/export_view_content.cpp index 713f67e3a..cf0943b17 100644 --- a/Telegram/SourceFiles/export/view/export_view_content.cpp +++ b/Telegram/SourceFiles/export/view/export_view_content.cpp @@ -101,7 +101,9 @@ Content ContentFromState( ? tr::lng_deleted(tr::now) : (state.entityType == ProcessingState::EntityType::Chat) ? state.entityName - : tr::lng_saved_messages(tr::now)), + : (state.entityType == ProcessingState::EntityType::SavedMessages) + ? tr::lng_saved_messages(tr::now) + : tr::lng_replies_messages(tr::now)), (state.itemCount > 0 ? (QString::number(state.itemIndex) + " / " diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 78d2e2ed8..1d9666f00 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -388,7 +388,10 @@ void HistoryInner::enumerateItemsInHistory(History *history, int historytop, Met } bool HistoryInner::canHaveFromUserpics() const { - if (_peer->isUser() && !_peer->isSelf() && !Core::App().settings().chatWide()) { + if (_peer->isUser() + && !_peer->isSelf() + && !_peer->isRepliesChat() + && !Core::App().settings().chatWide()) { return false; } else if (_peer->isChannel() && !_peer->isMegagroup()) { return false; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 5d5226af7..c6d7c5118 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -259,7 +259,8 @@ bool HistoryItem::isDiscussionPost() const { PeerData *HistoryItem::displayFrom() const { if (const auto sender = discussionPostOriginalSender()) { return sender; - } else if (history()->peer->isSelf()) { + } else if (history()->peer->isSelf() + || history()->peer->isRepliesChat()) { return senderOriginal(); } return author().get(); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 88553c622..ff3a3d805 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -1935,7 +1935,9 @@ void HistoryWidget::updateFieldSubmitSettings() { } void HistoryWidget::updateNotifyControls() { - if (!_peer || !_peer->isChannel()) return; + if (!_peer || (!_peer->isChannel() && !_peer->isRepliesChat())) { + return; + } _muteUnmute->setText((_history->mute() ? tr::lng_channel_unmute(tr::now) @@ -3647,7 +3649,10 @@ bool HistoryWidget::isJoinChannel() const { } bool HistoryWidget::isMuteUnmute() const { - return _peer && _peer->isChannel() && _peer->asChannel()->isBroadcast() && !_peer->asChannel()->canPublish(); + return _peer + && ((_peer->isBroadcast() + && !_peer->asChannel()->canPublish()) + || _peer->isRepliesChat()); } bool HistoryWidget::showRecordButton() const { diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 444ccc9c4..1e996d0cb 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -429,7 +429,8 @@ bool Element::computeIsAttachToPrevious(not_null previous) { && mayBeAttached(item) && mayBeAttached(prev); if (possible) { - if (item->history()->peer->isSelf()) { + if (item->history()->peer->isSelf() + || item->history()->peer->isRepliesChat()) { return IsAttachedToPreviousInSavedMessages(prev, item); } else { return prev->from() == item->from(); diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 10589de66..1292e4a98 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -1018,6 +1018,11 @@ void Message::unloadHeavyPart() { _comments = nullptr; } +bool Message::showForwardsFromSender() const { + const auto peer = message()->history()->peer; + return peer->isSelf() || peer->isRepliesChat(); +} + bool Message::hasFromPhoto() const { if (isHidden()) { return false; @@ -1032,7 +1037,7 @@ bool Message::hasFromPhoto() const { return false; } else if (Core::App().settings().chatWide()) { return true; - } else if (item->history()->peer->isSelf()) { + } else if (showForwardsFromSender()) { return item->Has(); } return !item->out() && !item->history()->peer->isUser(); @@ -1844,7 +1849,7 @@ bool Message::hasFromName() const { const auto item = message(); return (!hasOutLayout() || item->from()->isMegagroup()) && (!item->history()->peer->isUser() - || item->history()->peer->isSelf()); + || showForwardsFromSender()); } break; case Context::ContactPreview: return false; @@ -1861,7 +1866,7 @@ bool Message::displayFromName() const { bool Message::displayForwardedFrom() const { const auto item = message(); - if (item->history()->peer->isSelf()) { + if (showForwardsFromSender()) { return false; } if (const auto forwarded = item->Get()) { @@ -1885,6 +1890,8 @@ bool Message::hasOutLayout() const { const auto item = message(); if (item->history()->peer->isSelf()) { return !item->Has(); + } else if (showForwardsFromSender()) { + return false; } return item->out() && !item->isPost(); } @@ -1934,7 +1941,7 @@ bool Message::displayFastShare() const { return !peer->isMegagroup(); } else if (const auto user = peer->asUser()) { if (const auto forwarded = item->Get()) { - return !peer->isSelf() + return !showForwardsFromSender() && !item->out() && forwarded->originalSender && forwarded->originalSender->isChannel() diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 45b36d86d..c871660e4 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -120,6 +120,7 @@ private: void refreshEditedBadge(); void fromNameUpdated(int width) const; + [[nodiscard]] bool showForwardsFromSender() const; [[nodiscard]] TextSelection skipTextSelection( TextSelection selection) const; [[nodiscard]] TextSelection unskipTextSelection( diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index 2587d7a5c..a1a6db939 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -329,7 +329,7 @@ void TopBarWidget::paintTopBar(Painter &p) { const auto history = _activeChat.history(); const auto folder = _activeChat.folder(); if (folder - || history->peer->isSelf() + || history->peer->sharedMediaInfo() || (_section == Section::Scheduled) || !_customTitleText.isEmpty()) { // #TODO feed name emoji. @@ -341,7 +341,9 @@ void TopBarWidget::paintTopBar(Painter &p) { : tr::lng_scheduled_messages(tr::now)) : folder ? folder->chatListName() - : tr::lng_saved_messages(tr::now); + : history->peer->isSelf() + ? tr::lng_saved_messages(tr::now) + : tr::lng_replies_messages(tr::now); const auto textWidth = st::historySavedFont->width(text); if (availableWidth < textWidth) { text = st::historySavedFont->elided(text, availableWidth); @@ -467,6 +469,10 @@ void TopBarWidget::infoClicked() { _controller->showSection(Info::Memento( _activeChat.peer(), Info::Section(Storage::SharedMediaType::Photo))); + } else if (_activeChat.peer()->isRepliesChat()) { + _controller->showSection(Info::Memento( + _activeChat.peer(), + Info::Section(Storage::SharedMediaType::Photo))); } else { _controller->showPeerInfo(_activeChat.peer()); } diff --git a/Telegram/SourceFiles/info/info_memento.cpp b/Telegram/SourceFiles/info/info_memento.cpp index dc47593b5..8f32c1578 100644 --- a/Telegram/SourceFiles/info/info_memento.cpp +++ b/Telegram/SourceFiles/info/info_memento.cpp @@ -86,7 +86,7 @@ std::vector> Memento::DefaultStack( } Section Memento::DefaultSection(not_null peer) { - if (peer->isSelf()) { + if (peer->sharedMediaInfo()) { return Section(Section::MediaType::Photo); } return Section(Section::Type::Profile); @@ -94,7 +94,7 @@ Section Memento::DefaultSection(not_null peer) { // // #feed //Section Memento::DefaultSection(Dialogs::Key key) { // if (const auto peer = key.peer()) { -// if (peer->isSelf()) { +// if (peer->sharedMediaInfo()) { // return Section(Section::MediaType::Photo); // } // } diff --git a/Telegram/SourceFiles/info/info_top_bar.cpp b/Telegram/SourceFiles/info/info_top_bar.cpp index cf2ea1944..23689f1b5 100644 --- a/Telegram/SourceFiles/info/info_top_bar.cpp +++ b/Telegram/SourceFiles/info/info_top_bar.cpp @@ -575,7 +575,7 @@ rpl::producer TitleValue( Unexpected("Bad peer type in Info::TitleValue()"); case Section::Type::Media: - if (peer->isSelf() && isStackBottom) { + if (peer->sharedMediaInfo() && isStackBottom) { return tr::lng_profile_shared_media(); } switch (section.mediaType()) { diff --git a/Telegram/SourceFiles/info/info_wrap_widget.cpp b/Telegram/SourceFiles/info/info_wrap_widget.cpp index 4925d1202..4190ed4a8 100644 --- a/Telegram/SourceFiles/info/info_wrap_widget.cpp +++ b/Telegram/SourceFiles/info/info_wrap_widget.cpp @@ -154,16 +154,16 @@ void WrapWidget::injectActivePeerProfile(not_null peer) { ? _historyStack.front().section->section().mediaType() : _controller->section().mediaType(); }(); - const auto expectedType = peer->isSelf() + const auto expectedType = peer->sharedMediaInfo() ? Section::Type::Media : Section::Type::Profile; - const auto expectedMediaType = peer->isSelf() + const auto expectedMediaType = peer->sharedMediaInfo() ? Section::MediaType::Photo : Section::MediaType::kCount; if (firstSectionType != expectedType || firstSectionMediaType != expectedMediaType || firstPeer != peer) { - auto section = peer->isSelf() + auto section = peer->sharedMediaInfo() ? Section(Section::MediaType::Photo) : Section(Section::Type::Profile); injectActiveProfileMemento(std::move( @@ -481,7 +481,7 @@ void WrapWidget::addProfileCallsButton() { const auto peer = key().peer(); const auto user = peer ? peer->asUser() : nullptr; if (!user - || user->isSelf() + || user->sharedMediaInfo() || !user->session().serverConfig().phoneCallsEnabled.current()) { return; } diff --git a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm index 5b625876b..1bda44df9 100644 --- a/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm +++ b/Telegram/SourceFiles/platform/mac/notifications_manager_mac.mm @@ -264,6 +264,8 @@ void Manager::Private::showNotification( if (!hideNameAndPhoto && [notification respondsToSelector:@selector(setContentImage:)]) { auto userpic = peer->isSelf() ? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize) + : peer->isRepliesChat() + ? Ui::EmptyUserpic::GenerateRepliesMessages(st::notifyMacPhotoSize) : peer->genUserpic(userpicView, st::notifyMacPhotoSize); NSImage *img = [qt_mac_create_nsimage(userpic) autorelease]; [notification setContentImage:img]; diff --git a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm index e032587e0..9a32a7738 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_pinned_chats_item.mm @@ -53,6 +53,10 @@ inline bool IsSelfPeer(PeerData *peer) { return peer && peer->isSelf(); } +inline bool IsRepliesPeer(PeerData *peer) { + return peer && peer->isRepliesChat(); +} + QImage PrepareImage() { const auto s = kCircleDiameter * cIntRetinaFactor(); auto result = QImage(QSize(s, s), QImage::Format_ARGB32_Premultiplied); @@ -69,6 +73,15 @@ QImage SavedMessagesUserpic() { return result; } +QImage RepliesMessagesUserpic() { + auto result = PrepareImage(); + Painter paint(&result); + + const auto s = result.width(); + Ui::EmptyUserpic::PaintRepliesMessages(paint, 0, 0, s, s); + return result; +} + QImage ArchiveUserpic(not_null folder) { auto result = PrepareImage(); Painter paint(&result); @@ -125,7 +138,7 @@ NSRect PeerRectByIndex(int index) { } TimeId CalculateOnlineTill(not_null peer) { - if (peer->isSelf()) { + if (peer->isSelf() || peer->isRepliesChat()) { return 0; } if (const auto user = peer->asUser()) { @@ -172,10 +185,12 @@ TimeId CalculateOnlineTill(not_null peer) { std::vector> _pins; QImage _savedMessages; + QImage _repliesMessages; QImage _archive; bool _hasArchive; bool _selfUnpinned; + bool _repliesUnpinned; rpl::event_stream> _touches; rpl::event_stream> _gestures; @@ -458,6 +473,7 @@ TimeId CalculateOnlineTill(not_null peer) { _session = session; _hasArchive = _selfUnpinned = false; _savedMessages = SavedMessagesUserpic(); + _repliesMessages = RepliesMessagesUserpic(); auto *gesture = [[[NSPressGestureRecognizer alloc] initWithTarget:self @@ -504,6 +520,9 @@ TimeId CalculateOnlineTill(not_null peer) { if (IsSelfPeer(pin->peer)) { pin->userpic = _savedMessages; return; + } else if (IsRepliesPeer(pin->peer)) { + pin->userpic = _repliesMessages; + return; } auto userpic = PrepareImage(); Painter p(&userpic); @@ -629,6 +648,7 @@ TimeId CalculateOnlineTill(not_null peer) { return std::make_unique(std::move(pin)); }) | ranges::to_vector; _selfUnpinned = ranges::none_of(peers, &PeerData::isSelf); + _repliesUnpinned = ranges::none_of(peers, &PeerData::isRepliesChat); peerChangedLifetime->destroy(); for (const auto &pin : _pins) { @@ -705,6 +725,7 @@ TimeId CalculateOnlineTill(not_null peer) { _archive = ArchiveUserpic(f); } _savedMessages = SavedMessagesUserpic(); + _repliesMessages = RepliesMessagesUserpic(); updateUserpics(); }); }, _lifetime); @@ -771,6 +792,8 @@ TimeId CalculateOnlineTill(not_null peer) { return _archive; } else if (_selfUnpinned) { return _savedMessages; + } else if (_repliesUnpinned) { + return _repliesMessages; } } return _pins[i]->userpic; diff --git a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp index 0486470c2..c6ee41750 100644 --- a/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp +++ b/Telegram/SourceFiles/settings/settings_privacy_controllers.cpp @@ -116,7 +116,8 @@ auto BlockPeerBoxController::createRow(not_null history) -> std::unique_ptr { if (!history->peer->isUser() || history->peer->isServiceUser() - || history->peer->isSelf()) { + || history->peer->isSelf() + || history->peer->isRepliesChat()) { return nullptr; } auto row = std::make_unique(history); diff --git a/Telegram/SourceFiles/ui/empty_userpic.cpp b/Telegram/SourceFiles/ui/empty_userpic.cpp index fdff7bf88..e296b9894 100644 --- a/Telegram/SourceFiles/ui/empty_userpic.cpp +++ b/Telegram/SourceFiles/ui/empty_userpic.cpp @@ -91,6 +91,15 @@ void PaintSavedMessagesInner( } } +void PaintRepliesMessagesInner( + Painter &p, + int x, + int y, + int size, + const style::color &bg, + const style::color &fg) { +} + template [[nodiscard]] QPixmap Generate(int size, Callback callback) { auto result = QImage( @@ -230,6 +239,76 @@ QPixmap EmptyUserpic::GenerateSavedMessagesRounded(int size) { }); } +void EmptyUserpic::PaintRepliesMessages( + Painter &p, + int x, + int y, + int outerWidth, + int size) { + const auto &bg = st::historyPeerSavedMessagesBg; + const auto &fg = st::historyPeerUserpicFg; + PaintRepliesMessages(p, x, y, outerWidth, size, bg, fg); +} + +void EmptyUserpic::PaintRepliesMessagesRounded( + Painter &p, + int x, + int y, + int outerWidth, + int size) { + const auto &bg = st::historyPeerSavedMessagesBg; + const auto &fg = st::historyPeerUserpicFg; + PaintRepliesMessagesRounded(p, x, y, outerWidth, size, bg, fg); +} + +void EmptyUserpic::PaintRepliesMessages( + Painter &p, + int x, + int y, + int outerWidth, + int size, + const style::color &bg, + const style::color &fg) { + x = rtl() ? (outerWidth - x - size) : x; + + PainterHighQualityEnabler hq(p); + p.setBrush(bg); + p.setPen(Qt::NoPen); + p.drawEllipse(x, y, size, size); + + PaintRepliesMessagesInner(p, x, y, size, bg, fg); +} + +void EmptyUserpic::PaintRepliesMessagesRounded( + Painter &p, + int x, + int y, + int outerWidth, + int size, + const style::color &bg, + const style::color &fg) { + x = rtl() ? (outerWidth - x - size) : x; + + PainterHighQualityEnabler hq(p); + p.setBrush(bg); + p.setPen(Qt::NoPen); + p.drawRoundedRect(x, y, size, size, st::buttonRadius, st::buttonRadius); + + PaintRepliesMessagesInner(p, x, y, size, bg, fg); +} + +QPixmap EmptyUserpic::GenerateRepliesMessages(int size) { + return Generate(size, [&](Painter &p) { + PaintRepliesMessages(p, 0, 0, size, size); + }); +} + +QPixmap EmptyUserpic::GenerateRepliesMessagesRounded(int size) { + return Generate(size, [&](Painter &p) { + PaintRepliesMessagesRounded(p, 0, 0, size, size); + }); +} + InMemoryKey EmptyUserpic::uniqueKey() const { const auto first = (uint64(0xFFFFFFFFU) << 32) | anim::getPremultiplied(_color->c); diff --git a/Telegram/SourceFiles/ui/empty_userpic.h b/Telegram/SourceFiles/ui/empty_userpic.h index e177baf4e..c49ceb2dc 100644 --- a/Telegram/SourceFiles/ui/empty_userpic.h +++ b/Telegram/SourceFiles/ui/empty_userpic.h @@ -65,6 +65,37 @@ public: static QPixmap GenerateSavedMessages(int size); static QPixmap GenerateSavedMessagesRounded(int size); + static void PaintRepliesMessages( + Painter &p, + int x, + int y, + int outerWidth, + int size); + static void PaintRepliesMessagesRounded( + Painter &p, + int x, + int y, + int outerWidth, + int size); + static void PaintRepliesMessages( + Painter &p, + int x, + int y, + int outerWidth, + int size, + const style::color &bg, + const style::color &fg); + static void PaintRepliesMessagesRounded( + Painter &p, + int x, + int y, + int outerWidth, + int size, + const style::color &bg, + const style::color &fg); + static QPixmap GenerateRepliesMessages(int size); + static QPixmap GenerateRepliesMessagesRounded(int size); + ~EmptyUserpic(); private: diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index 1792559c7..d26fa88bc 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -675,6 +675,13 @@ void UserpicButton::paintEvent(QPaintEvent *e) { photoPosition.y(), width(), _st.photoSize); + } else if (showRepliesMessages()) { + Ui::EmptyUserpic::PaintRepliesMessages( + p, + photoPosition.x(), + photoPosition.y(), + width(), + _st.photoSize); } else { if (_a_appearance.animating()) { p.drawPixmapLeft(photoPosition, width(), _oldUserpic); @@ -1032,6 +1039,10 @@ bool UserpicButton::showSavedMessages() const { return _showSavedMessagesOnSelf && _peer && _peer->isSelf(); } +bool UserpicButton::showRepliesMessages() const { + return _showSavedMessagesOnSelf && _peer && _peer->isRepliesChat(); +} + void UserpicButton::startChangeOverlayAnimation() { auto over = isOver() || isDown(); _changeOverlayShown.start( diff --git a/Telegram/SourceFiles/ui/special_buttons.h b/Telegram/SourceFiles/ui/special_buttons.h index 40236a077..86d908e01 100644 --- a/Telegram/SourceFiles/ui/special_buttons.h +++ b/Telegram/SourceFiles/ui/special_buttons.h @@ -222,6 +222,7 @@ private: void updateCursor(); void updateVideo(); bool showSavedMessages() const; + bool showRepliesMessages() const; void checkStreamedIsStarted(); bool createStreamingObjects(not_null photo); void clearStreaming(); diff --git a/Telegram/SourceFiles/window/notifications_utilities.cpp b/Telegram/SourceFiles/window/notifications_utilities.cpp index 0bc77640a..86dc2a905 100644 --- a/Telegram/SourceFiles/window/notifications_utilities.cpp +++ b/Telegram/SourceFiles/window/notifications_utilities.cpp @@ -66,6 +66,11 @@ QString CachedUserpics::get( ? Ui::EmptyUserpic::GenerateSavedMessagesRounded : Ui::EmptyUserpic::GenerateSavedMessages; method(st::notifyMacPhotoSize).save(v.path, "PNG"); + } else if (peer->isRepliesChat()) { + const auto method = (_type == Type::Rounded) + ? Ui::EmptyUserpic::GenerateRepliesMessagesRounded + : Ui::EmptyUserpic::GenerateRepliesMessages; + method(st::notifyMacPhotoSize).save(v.path, "PNG"); } else if (_type == Type::Rounded) { peer->saveUserpicRounded(view, v.path, st::notifyMacPhotoSize); } else {