Set gift as theme from gift view.

This commit is contained in:
John Preston
2025-08-29 15:25:15 +04:00
parent 50450de3e4
commit e876a0f6bd
7 changed files with 136 additions and 36 deletions
+2
View File
@@ -3787,6 +3787,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_gift_transfer_sure_for" = "Do you want to transfer ownership of {name} to {recipient} for {price}?";
"lng_gift_transfer_button" = "Transfer";
"lng_gift_transfer_button_for" = "Transfer for {price}";
"lng_gift_transfer_set_theme" = "Set as Theme in...";
"lng_gift_transfer_choose" = "Choose Chat";
"lng_gift_transfer_wear" = "Wear";
"lng_gift_transfer_take_off" = "Take Off";
"lng_gift_transfer_sell" = "Sell";
@@ -12,8 +12,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_cloud_password.h"
#include "base/unixtime.h"
#include "boxes/passcode_box.h"
#include "data/data_cloud_themes.h"
#include "data/data_session.h"
#include "data/data_star_gift.h"
#include "data/data_thread.h"
#include "data/data_user.h"
#include "boxes/filters/edit_filter_chats_list.h" // CreatePe...tionSubtitle.
#include "boxes/peer_list_box.h"
@@ -673,6 +675,107 @@ void ShowTransferGiftBox(
Ui::LayerOption::KeepOther);
}
void SetThemeFromUniqueGift(
not_null<Window::SessionController*> window,
std::shared_ptr<Data::UniqueGift> unique) {
class Controller final : public ChooseRecipientBoxController {
public:
Controller(
not_null<Window::SessionController*> window,
std::shared_ptr<Data::UniqueGift> unique)
: ChooseRecipientBoxController({
.session = &window->session(),
.callback = [=](not_null<Data::Thread*> thread) {
const auto weak = base::make_weak(window);
const auto peer = thread->peer();
SendPeerThemeChangeRequest(window, peer, QString(), unique);
if (weak) window->showPeerHistory(peer);
if (weak) window->hideLayer(anim::type::normal);
},
.filter = [=](not_null<Data::Thread*> thread) {
return thread->peer()->isUser();
},
.moneyRestrictionError = WriteMoneyRestrictionError,
}) {
}
private:
void prepareViewHook() override {
ChooseRecipientBoxController::prepareViewHook();
delegate()->peerListSetTitle(tr::lng_gift_transfer_choose());
}
};
window->show(
Box<PeerListBox>(
std::make_unique<Controller>(window, std::move(unique)),
[](not_null<PeerListBox*> box) {
box->addButton(tr::lng_cancel(), [=] {
box->closeBox();
});
}));
}
void SendPeerThemeChangeRequest(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
const QString &token,
const std::shared_ptr<Data::UniqueGift> &unique,
bool locallySet) {
const auto api = &peer->session().api();
api->request(MTPmessages_SetChatWallPaper(
MTP_flags(0),
peer->input,
MTPInputWallPaper(),
MTPWallPaperSettings(),
MTPint()
)).afterDelay(10).done([=](const MTPUpdates &result) {
api->applyUpdates(result);
}).send();
api->request(MTPmessages_SetChatTheme(
peer->input,
(unique
? MTP_inputChatThemeUniqueGift(MTP_string(unique->slug))
: MTP_inputChatTheme(MTP_string(token)))
)).done([=](const MTPUpdates &result) {
api->applyUpdates(result);
if (!locallySet) {
peer->updateFullForced();
}
}).send();
}
void SetPeerTheme(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
const QString &token,
const std::shared_ptr<Ui::ChatTheme> &theme) {
const auto giftTheme = token.startsWith(u"gift:"_q)
? peer->owner().cloudThemes().themeForToken(token)
: std::optional<Data::CloudTheme>();
peer->setThemeToken(token);
const auto dropWallPaper = (peer->wallPaper() != nullptr);
if (dropWallPaper) {
peer->setWallPaper({});
}
if (theme) {
// Remember while changes propagate through event loop.
controller->pushLastUsedChatTheme(theme);
}
SendPeerThemeChangeRequest(
controller,
peer,
token,
giftTheme ? giftTheme->unique : nullptr,
true);
}
void ShowBuyResaleGiftBox(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift,
@@ -20,6 +20,10 @@ struct UniqueGift;
class SavedStarGiftId;
} // namespace Data
namespace Ui {
class ChatTheme;
} // namespace Ui
void ShowTransferToBox(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
@@ -45,3 +49,18 @@ bool ShowResaleGiftLater(
bool ShowTransferGiftLater(
std::shared_ptr<ChatHelpers::Show> show,
std::shared_ptr<Data::UniqueGift> gift);
void SetThemeFromUniqueGift(
not_null<Window::SessionController*> window,
std::shared_ptr<Data::UniqueGift> unique);
void SendPeerThemeChangeRequest(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
const QString &token,
const std::shared_ptr<Data::UniqueGift> &unique,
bool locallySet = false);
void SetPeerTheme(
not_null<Window::SessionController*> controller,
not_null<PeerData*> peer,
const QString &token,
const std::shared_ptr<Ui::ChatTheme> &theme);
@@ -214,6 +214,7 @@ darkGiftCodeBox: Box(giveawayGiftCodeBox) {
}
darkGiftLink: icon {{ "menu/copy", groupCallMembersFg }};
darkGiftShare: icon {{ "menu/share", groupCallMembersFg }};
darkGiftTheme: icon {{ "menu/colors", groupCallMembersFg }};
darkGiftTransfer: icon {{ "chat/input_replace", groupCallMembersFg }};
darkGiftNftWear: icon {{ "menu/nft_wear", groupCallMembersFg }};
darkGiftNftTakeOff: icon {{ "menu/nft_takeoff", groupCallMembersFg }};
@@ -1094,6 +1094,13 @@ void FillUniqueGiftMenu(
if (!unique) {
return;
}
if (unique->canBeTheme) {
menu->addAction(tr::lng_gift_transfer_set_theme(tr::now), [=] {
if (const auto window = show->resolveWindow()) {
SetThemeFromUniqueGift(window, unique);
}
}, st.theme ? st.theme : &st::menuIconChangeColors);
}
const auto transfer = savedId
&& (savedId.isUser() ? e.in : savedId.chat()->canTransferGifts())
&& (unique->starsForTransfer >= 0);
@@ -1176,6 +1183,7 @@ CreditsEntryBoxStyleOverrides DarkCreditsEntryBoxStyle() {
.tableValueMessage = &st::darkGiftTableMessage,
.link = &st::darkGiftLink,
.share = &st::darkGiftShare,
.theme = &st::darkGiftTheme,
.transfer = &st::darkGiftTransfer,
.wear = &st::darkGiftNftWear,
.takeoff = &st::darkGiftNftTakeOff,
@@ -115,6 +115,7 @@ struct CreditsEntryBoxStyleOverrides {
const style::FlatLabel *tableValueMessage = nullptr;
const style::icon *link = nullptr;
const style::icon *share = nullptr;
const style::icon *theme = nullptr;
const style::icon *transfer = nullptr;
const style::icon *wear = nullptr;
const style::icon *takeoff = nullptr;
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/choose_theme_controller.h"
#include "boxes/background_box.h"
#include "boxes/transfer_gift_box.h"
#include "ui/dynamic_image.h"
#include "ui/dynamic_thumbnails.h"
#include "ui/rp_widget.h"
@@ -327,42 +328,7 @@ void ChooseThemeController::initButtons() {
const auto setTheme = crl::guard(apply, [=](
const QString &token,
const std::shared_ptr<Ui::ChatTheme> &theme) {
const auto giftTheme = token.startsWith(u"gift:"_q)
? _peer->owner().cloudThemes().themeForToken(token)
: std::optional<Data::CloudTheme>();
_peer->setThemeToken(token);
const auto dropWallPaper = (_peer->wallPaper() != nullptr);
if (dropWallPaper) {
_peer->setWallPaper({});
}
if (theme) {
// Remember while changes propagate through event loop.
_controller->pushLastUsedChatTheme(theme);
}
const auto api = &_peer->session().api();
api->request(MTPmessages_SetChatWallPaper(
MTP_flags(0),
_peer->input,
MTPInputWallPaper(),
MTPWallPaperSettings(),
MTPint()
)).afterDelay(10).done([=](const MTPUpdates &result) {
api->applyUpdates(result);
}).send();
api->request(MTPmessages_SetChatTheme(
_peer->input,
((giftTheme && giftTheme->unique)
? MTP_inputChatThemeUniqueGift(
MTP_string(giftTheme->unique->slug))
: MTP_inputChatTheme(MTP_string(token)))
)).done([=](const MTPUpdates &result) {
api->applyUpdates(result);
}).send();
SetPeerTheme(_controller, _peer, token, theme);
_controller->toggleChooseChatTheme(_peer);
});
const auto confirmTakeGiftTheme = crl::guard(apply, [=](