From 9b25973b491a110c4ee6cb0e5503278648fc9659 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 17 Apr 2023 16:36:13 +0400 Subject: [PATCH] Update chat wallpaper from service message. --- .../boxes/background_preview_box.cpp | 92 +++++++++++++++++-- .../boxes/background_preview_box.h | 14 ++- Telegram/SourceFiles/data/data_wall_paper.cpp | 8 +- .../media/history_view_theme_document.cpp | 12 +++ 4 files changed, 114 insertions(+), 12 deletions(-) diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index 1a2d3fe244..5040f870f9 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/ui_utility.h" #include "history/history.h" #include "history/history_item.h" +#include "history/history_item_helpers.h" #include "history/view/history_view_message.h" #include "main/main_session.h" #include "apiwrap.h" @@ -59,6 +60,24 @@ constexpr auto kMaxWallPaperSlugLength = 255; }); } +[[nodiscard]] AdminLog::OwnedItem GenerateServiceItem( + not_null delegate, + not_null history, + const QString &text, + bool out) { + Expects(history->peer->isUser()); + + const auto flags = MessageFlag::FakeHistoryItem + | MessageFlag::HasFromId + | (out ? MessageFlag::Outgoing : MessageFlag(0)); + const auto item = history->makeMessage( + history->owner().nextLocalMessageId(), + flags, + base::unixtime::now(), + PreparedServiceText{ { text } }); + return AdminLog::OwnedItem(delegate, item); +} + [[nodiscard]] AdminLog::OwnedItem GenerateTextItem( not_null delegate, not_null history, @@ -136,19 +155,35 @@ constexpr auto kMaxWallPaperSlugLength = 255; BackgroundPreviewBox::BackgroundPreviewBox( QWidget*, not_null controller, - const Data::WallPaper &paper) + const Data::WallPaper &paper, + BackgroundPreviewArgs args) : SimpleElementDelegate(controller, [=] { update(); }) , _controller(controller) +, _forPeer(args.forPeer) +, _fromMessageId(args.fromMessageId) , _chatStyle(std::make_unique()) +, _serviceHistory(_controller->session().data().history( + PeerData::kServiceNotificationsId)) +, _service((_forPeer && !_fromMessageId) + ? GenerateServiceItem( + delegate(), + _serviceHistory, + tr::lng_background_other_info(tr::now, lt_user, _forPeer->shortName()), + false) + : nullptr) , _text1(GenerateTextItem( delegate(), _controller->session().data().history(PeerData::kServiceNotificationsId), - tr::lng_background_text1(tr::now), + (_forPeer + ? tr::lng_background_apply1(tr::now) + : tr::lng_background_text1(tr::now)), false)) , _text2(GenerateTextItem( delegate(), _controller->session().data().history(PeerData::kServiceNotificationsId), - tr::lng_background_text2(tr::now), + (_forPeer + ? tr::lng_background_apply2(tr::now) + : tr::lng_background_text2(tr::now)), true)) , _paper(paper) , _media(_paper.document() ? _paper.document()->createMediaView() : nullptr) @@ -187,9 +222,11 @@ not_null BackgroundPreviewBox::delegate() { void BackgroundPreviewBox::prepare() { setTitle(tr::lng_background_header()); - addButton(tr::lng_background_apply(), [=] { apply(); }); + addButton(_forPeer + ? tr::lng_background_apply_button() + : tr::lng_background_apply(), [=] { apply(); }); addButton(tr::lng_cancel(), [=] { closeBox(); }); - if (_paper.hasShareUrl()) { + if (!_forPeer && _paper.hasShareUrl()) { addLeftButton(tr::lng_background_share(), [=] { share(); }); } updateServiceBg(_paper.backgroundColors()); @@ -207,7 +244,11 @@ void BackgroundPreviewBox::prepare() { setScaledFromThumb(); checkLoadedDocument(); - _text1->setDisplayDate(true); + if (_service) { + _service->initDimensions(); + _service->resizeGetHeight(st::boxWideWidth); + } + _text1->setDisplayDate(!_service); _text1->initDimensions(); _text1->resizeGetHeight(st::boxWideWidth); _text2->initDimensions(); @@ -244,6 +285,35 @@ void BackgroundPreviewBox::createBlurCheckbox() { } void BackgroundPreviewBox::apply() { + if (_forPeer) { + applyForPeer(); + } else { + applyForEveryone(); + } + closeBox(); +} + +void BackgroundPreviewBox::applyForPeer() { + Expects(_forPeer != nullptr); + + const auto api = &_controller->session().api(); + using Flag = MTPmessages_SetChatWallPaper::Flag; + api->request(MTPmessages_SetChatWallPaper( + MTP_flags((_fromMessageId ? Flag::f_id : Flag()) + | (_fromMessageId ? Flag() : Flag::f_wallpaper) + | Flag::f_settings), + _forPeer->input, + _paper.mtpInput(&_controller->session()), + _paper.mtpSettings(), + MTP_int(_fromMessageId.msg) + )).done([=](const MTPUpdates &result) { + api->applyUpdates(result); + }).send(); + + _forPeer->setWallPaper(_paper); +} + +void BackgroundPreviewBox::applyForEveryone() { const auto install = (_paper.id() != Window::Theme::Background()->id()) && Data::IsCloudWallPaper(_paper); _controller->content()->setChatBackground(_paper, std::move(_full)); @@ -253,7 +323,6 @@ void BackgroundPreviewBox::apply() { _paper.mtpSettings() )).send(); } - closeBox(); } void BackgroundPreviewBox::share() { @@ -339,6 +408,7 @@ int BackgroundPreviewBox::textsTop() const { const auto bottom = _blur ? _blur->y() : height(); return bottom - st::historyPaddingBottom + - (_service ? _service->height() : 0) - _text1->height() - _text2->height(); } @@ -353,6 +423,7 @@ QRect BackgroundPreviewBox::radialRect() const { } void BackgroundPreviewBox::paintTexts(Painter &p, crl::time ms) { + const auto heights = _service ? _service->height() : 0; const auto height1 = _text1->height(); const auto height2 = _text2->height(); auto context = _controller->defaultChatTheme()->preparePaintContext( @@ -361,7 +432,12 @@ void BackgroundPreviewBox::paintTexts(Painter &p, crl::time ms) { rect(), _controller->isGifPausedAtLeastFor(Window::GifPauseReason::Layer)); p.translate(0, textsTop()); - paintDate(p); + if (_service) { + _service->draw(p, context); + p.translate(0, heights); + } else { + paintDate(p); + } context.outbg = _text1->hasOutLayout(); _text1->draw(p, context); diff --git a/Telegram/SourceFiles/boxes/background_preview_box.h b/Telegram/SourceFiles/boxes/background_preview_box.h index 24554cd844..f758a77afa 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.h +++ b/Telegram/SourceFiles/boxes/background_preview_box.h @@ -28,6 +28,11 @@ class Checkbox; class ChatStyle; } // namespace Ui +struct BackgroundPreviewArgs { + PeerData *forPeer = nullptr; + FullMsgId fromMessageId; +}; + class BackgroundPreviewBox : public Ui::BoxContent , private HistoryView::SimpleElementDelegate { @@ -35,7 +40,8 @@ public: BackgroundPreviewBox( QWidget*, not_null controller, - const Data::WallPaper &paper); + const Data::WallPaper &paper, + BackgroundPreviewArgs args = {}); static bool Start( not_null controller, @@ -53,6 +59,8 @@ private: HistoryView::Context elementContext() override; void apply(); + void applyForPeer(); + void applyForEveryone(); void share(); void radialAnimationCallback(crl::time now); QRect radialRect() const; @@ -72,7 +80,11 @@ private: void checkBlurAnimationStart(); const not_null _controller; + PeerData * const _forPeer = nullptr; + FullMsgId _fromMessageId; std::unique_ptr _chatStyle; + const not_null _serviceHistory; + AdminLog::OwnedItem _service; AdminLog::OwnedItem _text1; AdminLog::OwnedItem _text2; Data::WallPaper _paper; diff --git a/Telegram/SourceFiles/data/data_wall_paper.cpp b/Telegram/SourceFiles/data/data_wall_paper.cpp index 468c05f87f..d1babb244a 100644 --- a/Telegram/SourceFiles/data/data_wall_paper.cpp +++ b/Telegram/SourceFiles/data/data_wall_paper.cpp @@ -357,6 +357,8 @@ MTPWallPaperSettings WallPaper::mtpSettings() const { }; return MTP_wallPaperSettings( MTP_flags((_blurred ? Flag::f_blur : Flag(0)) + | Flag::f_intensity + | Flag::f_rotation | flagForIndex(0) | flagForIndex(1) | flagForIndex(2) @@ -487,11 +489,11 @@ std::optional WallPaper::Create( if (const auto settings = data.vsettings()) { settings->match([&](const MTPDwallPaperSettings &data) { result._blurred = data.is_blur(); + if (const auto intensity = data.vintensity()) { + result._intensity = intensity->v; + } if (result.isPattern()) { result._backgroundColors = ColorsFromMTP(data); - if (const auto intensity = data.vintensity()) { - result._intensity = intensity->v; - } if (const auto rotation = data.vrotation()) { result._rotation = rotation->v; } 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 76024cea8d..0a5d63cf2a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_theme_document.cpp @@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/media/history_view_theme_document.h" +#include "boxes/background_preview_box.h" #include "history/history.h" #include "history/history_item.h" #include "history/view/history_view_element.h" @@ -443,11 +444,22 @@ QString ThemeDocumentBox::button() { ClickHandlerPtr ThemeDocumentBox::createViewLink() { const auto out = _parent->data()->out(); const auto to = _parent->history()->peer; + const auto media = _parent->data()->media(); + 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) { controller->toggleChooseChatTheme(to); + } else if (maybe) { + controller->show( + Box( + controller, + *maybe, + BackgroundPreviewArgs{ to, itemId }), + Ui::LayerOption::KeepOther); } } });