Update chat wallpaper from service message.

This commit is contained in:
John Preston 2023-04-17 16:36:13 +04:00
parent bf27185feb
commit 9b25973b49
4 changed files with 114 additions and 12 deletions

View File

@ -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<HistoryView::ElementDelegate*> delegate,
not_null<History*> 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<HistoryView::ElementDelegate*> delegate,
not_null<History*> history,
@ -136,19 +155,35 @@ constexpr auto kMaxWallPaperSlugLength = 255;
BackgroundPreviewBox::BackgroundPreviewBox(
QWidget*,
not_null<Window::SessionController*> 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<Ui::ChatStyle>())
, _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<HistoryView::ElementDelegate*> 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);

View File

@ -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<Window::SessionController*> controller,
const Data::WallPaper &paper);
const Data::WallPaper &paper,
BackgroundPreviewArgs args = {});
static bool Start(
not_null<Window::SessionController*> 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<Window::SessionController*> _controller;
PeerData * const _forPeer = nullptr;
FullMsgId _fromMessageId;
std::unique_ptr<Ui::ChatStyle> _chatStyle;
const not_null<History*> _serviceHistory;
AdminLog::OwnedItem _service;
AdminLog::OwnedItem _text1;
AdminLog::OwnedItem _text2;
Data::WallPaper _paper;

View File

@ -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> 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;
}

View File

@ -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<Data::WallPaper>();
const auto itemId = _parent->data()->fullId();
return std::make_shared<LambdaClickHandler>([=](ClickContext context) {
const auto my = context.other.value<ClickHandlerContext>();
if (const auto controller = my.sessionWindow.get()) {
if (out) {
controller->toggleChooseChatTheme(to);
} else if (maybe) {
controller->show(
Box<BackgroundPreviewBox>(
controller,
*maybe,
BackgroundPreviewArgs{ to, itemId }),
Ui::LayerOption::KeepOther);
}
}
});