From 324f2f68bab6915b88e6c92aeabd0aafcc891617 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 23 Nov 2023 11:16:32 +0400 Subject: [PATCH] Handle for_both chat wallpaper change. --- Telegram/Resources/langs/lang.strings | 10 +-- Telegram/SourceFiles/api/api_updates.cpp | 12 ++++ .../SourceFiles/data/data_media_types.cpp | 19 +++-- Telegram/SourceFiles/data/data_media_types.h | 8 ++- Telegram/SourceFiles/history/history.cpp | 5 ++ Telegram/SourceFiles/history/history_item.cpp | 20 ++++-- .../view/media/history_view_premium_gift.cpp | 6 +- .../view/media/history_view_premium_gift.h | 2 +- .../view/media/history_view_service_box.cpp | 45 ++++++------ .../view/media/history_view_service_box.h | 3 +- .../view/media/history_view_story_mention.cpp | 4 +- .../view/media/history_view_story_mention.h | 2 +- .../media/history_view_theme_document.cpp | 72 +++++++++++++++++-- .../view/media/history_view_theme_document.h | 2 +- .../media/history_view_userpic_suggestion.cpp | 8 +-- .../media/history_view_userpic_suggestion.h | 2 +- 16 files changed, 164 insertions(+), 56 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 9af5f4d34..a5772df70 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1647,11 +1647,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_action_suggested_video_button" = "View Video"; "lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it in the attachment menu."; "lng_action_webapp_bot_allowed" = "You allowed this bot to message you in his web-app."; -"lng_action_set_wallpaper_me" = "You set a new wallpaper for this chat"; -"lng_action_set_wallpaper" = "{user} set a new wallpaper for this chat"; +"lng_action_set_wallpaper_me" = "You set a new wallpaper for this chat."; +"lng_action_set_wallpaper" = "{user} set a new wallpaper for this chat."; +"lng_action_set_wallpaper_both_me" = "You set a new wallpaper for {user} and you."; "lng_action_set_wallpaper_button" = "View Wallpaper"; -"lng_action_set_same_wallpaper_me" = "You set the same wallpaper for this chat"; -"lng_action_set_same_wallpaper" = "{user} set the same wallpaper for this chat"; +"lng_action_set_wallpaper_remove" = "Remove"; +"lng_action_set_same_wallpaper_me" = "You set the same wallpaper for this chat."; +"lng_action_set_same_wallpaper" = "{user} set the same wallpaper for this chat."; "lng_action_topic_created_inside" = "Topic created"; "lng_action_topic_closed_inside" = "Topic closed"; "lng_action_topic_reopened_inside" = "Topic reopened"; diff --git a/Telegram/SourceFiles/api/api_updates.cpp b/Telegram/SourceFiles/api/api_updates.cpp index aeca3eb70..d3cf44dd6 100644 --- a/Telegram/SourceFiles/api/api_updates.cpp +++ b/Telegram/SourceFiles/api/api_updates.cpp @@ -1991,6 +1991,18 @@ void Updates::feedUpdate(const MTPUpdate &update) { } } break; + case mtpc_updatePeerWallpaper: { + const auto &d = update.c_updatePeerWallpaper(); + if (const auto peer = session().data().peerLoaded(peerFromMTP(d.vpeer()))) { + if (const auto paper = d.vwallpaper()) { + peer->setWallPaper( + Data::WallPaper::Create(&session(), *paper)); + } else { + peer->setWallPaper({}); + } + } + } break; + case mtpc_updateBotCommands: { const auto &d = update.c_updateBotCommands(); if (const auto peer = session().data().peerLoaded(peerFromMTP(d.vpeer()))) { diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 1132d75c4..396565750 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -437,6 +437,10 @@ const WallPaper *Media::paper() const { return nullptr; } +bool Media::paperForBoth() const { + return false; +} + FullStoryId Media::storyId() const { return {}; } @@ -1987,21 +1991,28 @@ std::unique_ptr MediaGiftBox::createView( MediaWallPaper::MediaWallPaper( not_null parent, - const WallPaper &paper) + const WallPaper &paper, + bool paperForBoth) : Media(parent) -, _paper(paper) { +, _paper(paper) +, _paperForBoth(paperForBoth) { } MediaWallPaper::~MediaWallPaper() = default; -std::unique_ptr MediaWallPaper::clone(not_null parent) { - return std::make_unique(parent, _paper); +std::unique_ptr MediaWallPaper::clone( + not_null parent) { + return std::make_unique(parent, _paper, _paperForBoth); } const WallPaper *MediaWallPaper::paper() const { return &_paper; } +bool MediaWallPaper::paperForBoth() const { + return _paperForBoth; +} + TextWithEntities MediaWallPaper::notificationText() const { return {}; } diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index b62cf9825..10c938963 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -131,6 +131,7 @@ public: virtual CloudImage *location() const; virtual PollData *poll() const; virtual const WallPaper *paper() const; + virtual bool paperForBoth() const; virtual FullStoryId storyId() const; virtual bool storyExpired(bool revalidate = false); virtual bool storyMention() const; @@ -568,12 +569,16 @@ private: class MediaWallPaper final : public Media { public: - MediaWallPaper(not_null parent, const WallPaper &paper); + MediaWallPaper( + not_null parent, + const WallPaper &paper, + bool paperForBoth); ~MediaWallPaper(); std::unique_ptr clone(not_null parent) override; const WallPaper *paper() const override; + bool paperForBoth() const override; TextWithEntities notificationText() const override; QString pinnedTextSubstring() const override; @@ -588,6 +593,7 @@ public: private: const WallPaper _paper; + const bool _paperForBoth = false; }; diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index ed9f07336..ce6b8af95 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -1192,6 +1192,11 @@ void History::applyServiceChanges( } }, [&](const MTPDmessageActionSetChatTheme &data) { peer->setThemeEmoji(qs(data.vemoticon())); + }, [&](const MTPDmessageActionSetChatWallPaper &data) { + if (item->out() || data.is_for_both()) { + peer->setWallPaper( + Data::WallPaper::Create(&session(), data.vwallpaper())); + } }, [&](const MTPDmessageActionChatJoinedByRequest &data) { processJoinedPeer(item->from()); }, [&](const MTPDmessageActionTopicCreate &data) { diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 8dfe07e5d..6b6705c8f 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -4501,6 +4501,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { const MTPDmessageActionSetChatWallPaper &action) { const auto isSelf = (_from->id == _from->session().userPeerId()); const auto same = action.is_same(); + const auto both = action.is_for_both(); const auto peer = isSelf ? history()->peer : _from; const auto user = peer->asUser(); const auto name = (user && !user->firstName.isEmpty()) @@ -4511,17 +4512,23 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) { result.links.push_back(peer->createOpenLink()); } result.text = isSelf - ? (same - ? tr::lng_action_set_same_wallpaper_me - : tr::lng_action_set_wallpaper_me)( + ? ((!same && both) + ? tr::lng_action_set_wallpaper_both_me( tr::now, + lt_user, + Ui::Text::Link(Ui::Text::Bold(name), 1), Ui::Text::WithEntities) + : (same + ? tr::lng_action_set_same_wallpaper_me + : tr::lng_action_set_wallpaper_me)( + tr::now, + Ui::Text::WithEntities)) : (same ? tr::lng_action_set_same_wallpaper : tr::lng_action_set_wallpaper)( tr::now, lt_user, - Ui::Text::Link(name, 1), // Link 1. + Ui::Text::Link(Ui::Text::Bold(name), 1), Ui::Text::WithEntities); return result; }; @@ -4681,7 +4688,10 @@ void HistoryItem::applyAction(const MTPMessageAction &action) { const auto session = &history()->session(); const auto &attached = data.vwallpaper(); if (const auto paper = WallPaper::Create(session, attached)) { - _media = std::make_unique(this, *paper); + _media = std::make_unique( + this, + *paper, + data.is_for_both()); } } }, [&](const MTPDmessageActionGiftCode &data) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp index b7758eafa..a1b60cb67 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.cpp @@ -77,10 +77,10 @@ TextWithEntities PremiumGift::subtitle() { return result; } -QString PremiumGift::button() { +rpl::producer PremiumGift::button() { return _data.slug.isEmpty() - ? tr::lng_sticker_premium_view(tr::now) - : tr::lng_prize_open(tr::now); + ? tr::lng_sticker_premium_view() + : tr::lng_prize_open(); } ClickHandlerPtr PremiumGift::createViewLink() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h index e43c5f937..b83c4e16b 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h +++ b/Telegram/SourceFiles/history/view/media/history_view_premium_gift.h @@ -28,7 +28,7 @@ public: QSize size() override; QString title() override; TextWithEntities subtitle() override; - QString button() override; + rpl::producer button() override; int buttonSkip() override; void draw( Painter &p, diff --git a/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp b/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp index a1d723e43..6bb085f1a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_service_box.cpp @@ -26,28 +26,7 @@ ServiceBox::ServiceBox( : Media(parent) , _parent(parent) , _content(std::move(content)) -, _button([&] { - auto result = Button(); - result.link = _content->createViewLink(); - - const auto text = _content->button(); - if (text.isEmpty()) { - return result; - } - result.repaint = [=] { repaint(); }; - result.text.setText(st::semiboldTextStyle, _content->button()); - - const auto height = st::msgServiceGiftBoxButtonHeight; - const auto &padding = st::msgServiceGiftBoxButtonPadding; - result.size = QSize( - result.text.maxWidth() - + height - + padding.left() - + padding.right(), - height); - - return result; -}()) +, _button({ .link = _content->createViewLink() }) , _maxWidth(st::msgServiceGiftBoxSize.width() - st::msgPadding.left() - st::msgPadding.right()) @@ -79,11 +58,29 @@ ServiceBox::ServiceBox( : (_title.countHeight(_maxWidth) + st::msgServiceGiftBoxTitlePadding.bottom())) + _subtitle.countHeight(_maxWidth) - + (_button.empty() + + (!_content->button() ? 0 - : (_content->buttonSkip() + _button.size.height())) + : (_content->buttonSkip() + st::msgServiceGiftBoxButtonHeight)) + st::msgServiceGiftBoxButtonMargins.bottom())) , _innerSize(_size - QSize(0, st::msgServiceGiftBoxTopSkip)) { + if (auto text = _content->button()) { + _button.repaint = [=] { repaint(); }; + std::move(text) | rpl::start_with_next([=](QString value) { + _button.text.setText(st::semiboldTextStyle, value); + const auto height = st::msgServiceGiftBoxButtonHeight; + const auto &padding = st::msgServiceGiftBoxButtonPadding; + const auto empty = _button.size.isEmpty(); + _button.size = QSize( + (_button.text.maxWidth() + + height + + padding.left() + + padding.right()), + height); + if (!empty) { + repaint(); + } + }, _lifetime); + } } ServiceBox::~ServiceBox() = default; diff --git a/Telegram/SourceFiles/history/view/media/history_view_service_box.h b/Telegram/SourceFiles/history/view/media/history_view_service_box.h index 1ae0c30ea..2b459e027 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_service_box.h +++ b/Telegram/SourceFiles/history/view/media/history_view_service_box.h @@ -26,7 +26,7 @@ public: [[nodiscard]] virtual int buttonSkip() { return top(); } - [[nodiscard]] virtual QString button() = 0; + [[nodiscard]] virtual rpl::producer button() = 0; virtual void draw( Painter &p, const PaintContext &context, @@ -110,6 +110,7 @@ private: Ui::Text::String _subtitle; const QSize _size; const QSize _innerSize; + rpl::lifetime _lifetime; }; diff --git a/Telegram/SourceFiles/history/view/media/history_view_story_mention.cpp b/Telegram/SourceFiles/history/view/media/history_view_story_mention.cpp index 07a469097..2d9089f37 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_story_mention.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_story_mention.cpp @@ -76,8 +76,8 @@ int StoryMention::buttonSkip() { return st::storyMentionButtonSkip; } -QString StoryMention::button() { - return tr::lng_action_story_mention_button(tr::now); +rpl::producer StoryMention::button() { + return tr::lng_action_story_mention_button(); } TextWithEntities StoryMention::subtitle() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_story_mention.h b/Telegram/SourceFiles/history/view/media/history_view_story_mention.h index 51704d440..376926f3b 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_story_mention.h +++ b/Telegram/SourceFiles/history/view/media/history_view_story_mention.h @@ -33,7 +33,7 @@ public: QString title() override; TextWithEntities subtitle() override; int buttonSkip() override; - QString button() override; + rpl::producer button() override; void draw( Painter &p, const PaintContext &context, diff --git a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp index 0fbc095f8..2496417c2 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp @@ -7,12 +7,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/media/history_view_theme_document.h" +#include "apiwrap.h" #include "boxes/background_preview_box.h" #include "history/history.h" #include "history/history_item.h" #include "history/view/history_view_element.h" #include "history/view/history_view_cursor_state.h" #include "history/view/media/history_view_sticker_player_abstract.h" +#include "data/data_changes.h" #include "data/data_document.h" #include "data/data_session.h" #include "data/data_document_media.h" @@ -23,7 +25,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/click_handler_types.h" #include "core/local_url_handlers.h" #include "lang/lang_keys.h" +#include "main/main_session.h" #include "ui/text/format_values.h" +#include "ui/boxes/confirm_box.h" #include "ui/chat/chat_style.h" #include "ui/chat/chat_theme.h" #include "ui/cached_round_corners.h" @@ -34,6 +38,40 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_chat.h" namespace HistoryView { +namespace { + +[[nodiscard]] bool HasThatWallPaperForBoth( + not_null peer, + const Data::WallPaper &paper) { + const auto now = peer->wallPaper(); + return now && now->equals(paper); +} + +[[nodiscard]] bool HasThatWallPaperForBoth(not_null item) { + const auto media = item->media(); + const auto paper = media ? media->paper() : nullptr; + return paper + && media->paperForBoth() + && HasThatWallPaperForBoth(item->history()->peer, *paper); +} + +[[nodiscard]] rpl::producer HasThatWallPaperForBothValue( + not_null item) { + const auto media = item->media(); + const auto paper = media ? media->paper() : nullptr; + if (!paper || !media->paperForBoth()) { + return rpl::single(false); + } + const auto peer = item->history()->peer; + return peer->session().changes().peerFlagsValue( + peer, + Data::PeerUpdate::Flag::ChatWallPaper + ) | rpl::map([peer, paper = *paper] { + return HasThatWallPaperForBoth(peer, paper); + }); +} + +} // namespace ThemeDocument::ThemeDocument( not_null parent, @@ -457,23 +495,49 @@ TextWithEntities ThemeDocumentBox::subtitle() { return _parent->data()->notificationText(); } -QString ThemeDocumentBox::button() { +rpl::producer ThemeDocumentBox::button() { return _parent->data()->out() - ? QString() - : tr::lng_action_set_wallpaper_button(tr::now); + ? nullptr + : rpl::conditional( + HasThatWallPaperForBothValue(_parent->data()), + tr::lng_action_set_wallpaper_remove(), + tr::lng_action_set_wallpaper_button()); } ClickHandlerPtr ThemeDocumentBox::createViewLink() { const auto out = _parent->data()->out(); const auto to = _parent->history()->peer; const auto media = _parent->data()->media(); + const auto weak = base::make_weak(_parent); const auto paper = media ? media->paper() : nullptr; const auto maybe = paper ? *paper : std::optional(); const auto itemId = _parent->data()->fullId(); return std::make_shared([=](ClickContext context) { const auto my = context.other.value(); if (const auto controller = my.sessionWindow.get()) { - if (out) { + const auto view = weak.get(); + if (view + && !view->data()->out() + && HasThatWallPaperForBoth(view->data())) { + const auto reset = crl::guard(weak, [=](Fn close) { + const auto api = &controller->session().api(); + api->request(MTPmessages_SetChatWallPaper( + MTP_flags(MTPmessages_SetChatWallPaper::Flag::f_revert), + view->data()->history()->peer->input, + MTPInputWallPaper(), + MTPWallPaperSettings(), + MTPint() + )).done([=](const MTPUpdates &result) { + api->applyUpdates(result); + }).send(); + close(); + }); + controller->show(Ui::MakeConfirmBox({ + .text = tr::lng_background_sure_reset_default(), + .confirmed = reset, + .confirmText = tr::lng_background_reset_default(), + })); + } else if (out) { controller->toggleChooseChatTheme(to); } else if (maybe) { controller->show(Box( diff --git a/Telegram/SourceFiles/history/view/media/history_view_theme_document.h b/Telegram/SourceFiles/history/view/media/history_view_theme_document.h index 7ed9bcf91..a9e2e6ecc 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.h +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.h @@ -99,7 +99,7 @@ public: QSize size() override; QString title() override; TextWithEntities subtitle() override; - QString button() override; + rpl::producer button() override; void draw( Painter &p, const PaintContext &context, diff --git a/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.cpp b/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.cpp index 5c37ccb04..79e42f482 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.cpp @@ -203,12 +203,12 @@ QString UserpicSuggestion::title() { return QString(); } -QString UserpicSuggestion::button() { +rpl::producer UserpicSuggestion::button() { return _photo.getPhoto()->hasVideo() ? (_photo.parent()->data()->out() - ? tr::lng_action_suggested_video_button(tr::now) - : tr::lng_profile_set_video_button(tr::now)) - : tr::lng_action_suggested_photo_button(tr::now); + ? tr::lng_action_suggested_video_button() + : tr::lng_profile_set_video_button()) + : tr::lng_action_suggested_photo_button(); } TextWithEntities UserpicSuggestion::subtitle() { diff --git a/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.h b/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.h index 42ad65f44..93aaca380 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.h +++ b/Telegram/SourceFiles/history/view/media/history_view_userpic_suggestion.h @@ -31,7 +31,7 @@ public: QSize size() override; QString title() override; TextWithEntities subtitle() override; - QString button() override; + rpl::producer button() override; void draw( Painter &p, const PaintContext &context,