Handle for_both chat wallpaper change.

This commit is contained in:
John Preston 2023-11-23 11:16:32 +04:00
parent f8825e8135
commit 324f2f68ba
16 changed files with 164 additions and 56 deletions

View file

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

View file

@ -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()))) {

View file

@ -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<HistoryView::Media> MediaGiftBox::createView(
MediaWallPaper::MediaWallPaper(
not_null<HistoryItem*> parent,
const WallPaper &paper)
const WallPaper &paper,
bool paperForBoth)
: Media(parent)
, _paper(paper) {
, _paper(paper)
, _paperForBoth(paperForBoth) {
}
MediaWallPaper::~MediaWallPaper() = default;
std::unique_ptr<Media> MediaWallPaper::clone(not_null<HistoryItem*> parent) {
return std::make_unique<MediaWallPaper>(parent, _paper);
std::unique_ptr<Media> MediaWallPaper::clone(
not_null<HistoryItem*> parent) {
return std::make_unique<MediaWallPaper>(parent, _paper, _paperForBoth);
}
const WallPaper *MediaWallPaper::paper() const {
return &_paper;
}
bool MediaWallPaper::paperForBoth() const {
return _paperForBoth;
}
TextWithEntities MediaWallPaper::notificationText() const {
return {};
}

View file

@ -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<HistoryItem*> parent, const WallPaper &paper);
MediaWallPaper(
not_null<HistoryItem*> parent,
const WallPaper &paper,
bool paperForBoth);
~MediaWallPaper();
std::unique_ptr<Media> clone(not_null<HistoryItem*> 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;
};

View file

@ -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) {

View file

@ -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<MediaWallPaper>(this, *paper);
_media = std::make_unique<MediaWallPaper>(
this,
*paper,
data.is_for_both());
}
}
}, [&](const MTPDmessageActionGiftCode &data) {

View file

@ -77,10 +77,10 @@ TextWithEntities PremiumGift::subtitle() {
return result;
}
QString PremiumGift::button() {
rpl::producer<QString> 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() {

View file

@ -28,7 +28,7 @@ public:
QSize size() override;
QString title() override;
TextWithEntities subtitle() override;
QString button() override;
rpl::producer<QString> button() override;
int buttonSkip() override;
void draw(
Painter &p,

View file

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

View file

@ -26,7 +26,7 @@ public:
[[nodiscard]] virtual int buttonSkip() {
return top();
}
[[nodiscard]] virtual QString button() = 0;
[[nodiscard]] virtual rpl::producer<QString> 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;
};

View file

@ -76,8 +76,8 @@ int StoryMention::buttonSkip() {
return st::storyMentionButtonSkip;
}
QString StoryMention::button() {
return tr::lng_action_story_mention_button(tr::now);
rpl::producer<QString> StoryMention::button() {
return tr::lng_action_story_mention_button();
}
TextWithEntities StoryMention::subtitle() {

View file

@ -33,7 +33,7 @@ public:
QString title() override;
TextWithEntities subtitle() override;
int buttonSkip() override;
QString button() override;
rpl::producer<QString> button() override;
void draw(
Painter &p,
const PaintContext &context,

View file

@ -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<PeerData*> peer,
const Data::WallPaper &paper) {
const auto now = peer->wallPaper();
return now && now->equals(paper);
}
[[nodiscard]] bool HasThatWallPaperForBoth(not_null<HistoryItem*> 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<bool> HasThatWallPaperForBothValue(
not_null<HistoryItem*> 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<Element*> parent,
@ -457,23 +495,49 @@ TextWithEntities ThemeDocumentBox::subtitle() {
return _parent->data()->notificationText();
}
QString ThemeDocumentBox::button() {
rpl::producer<QString> 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<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) {
const auto view = weak.get();
if (view
&& !view->data()->out()
&& HasThatWallPaperForBoth(view->data())) {
const auto reset = crl::guard(weak, [=](Fn<void()> 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<BackgroundPreviewBox>(

View file

@ -99,7 +99,7 @@ public:
QSize size() override;
QString title() override;
TextWithEntities subtitle() override;
QString button() override;
rpl::producer<QString> button() override;
void draw(
Painter &p,
const PaintContext &context,

View file

@ -203,12 +203,12 @@ QString UserpicSuggestion::title() {
return QString();
}
QString UserpicSuggestion::button() {
rpl::producer<QString> 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() {

View file

@ -31,7 +31,7 @@ public:
QSize size() override;
QString title() override;
TextWithEntities subtitle() override;
QString button() override;
rpl::producer<QString> button() override;
void draw(
Painter &p,
const PaintContext &context,