From 66e8f9865abc73d55874be6b14fd057d2870b2a3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 17 Jul 2025 17:31:38 +0400 Subject: [PATCH] Started gift collections. --- Telegram/CMakeLists.txt | 2 + Telegram/Resources/langs/lang.strings | 17 +++ .../chat_helpers/chat_helpers.style | 3 - Telegram/SourceFiles/info/info.style | 16 +++ .../info_peer_gifts_collections.cpp | 107 ++++++++++++++++++ .../peer_gifts/info_peer_gifts_collections.h | 30 +++++ .../peer_gifts/info_peer_gifts_widget.cpp | 19 +++- Telegram/SourceFiles/main/main_app_config.cpp | 8 ++ Telegram/SourceFiles/main/main_app_config.h | 2 + 9 files changed, 200 insertions(+), 4 deletions(-) create mode 100644 Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.cpp create mode 100644 Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 6e285ca175..a1f99fb31d 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1007,6 +1007,8 @@ PRIVATE info/media/info_media_widget.h info/members/info_members_widget.cpp info/members/info_members_widget.h + info/peer_gifts/info_peer_gifts_collections.cpp + info/peer_gifts/info_peer_gifts_collections.h info/peer_gifts/info_peer_gifts_common.cpp info/peer_gifts/info_peer_gifts_common.h info/peer_gifts/info_peer_gifts_widget.cpp diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 06857aae47..2e049a9692 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -3751,6 +3751,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_gift_resale_early" = "You will be able to resell this gift in {duration}."; "lng_gift_transfer_early" = "You will be able to transfer this gift in {duration}."; "lng_gift_resale_transfer_early_title" = "Try Later"; +"lng_gift_collection_add" = "Add Collection"; +"lng_gift_collection_new_title" = "Create a New Collection"; +"lng_gift_collection_new_button" = "New Collection"; +"lng_gift_collection_new_text" = "Choose a name for your collection and start adding your gifts there."; +"lng_gift_collection_new_ph" = "Title"; +"lng_gift_collection_new_create" = "Create"; +"lng_gift_collection_empty_title" = "Organize Your Gifts"; +"lng_gift_collection_empty_text" = "Add some of your gifts to this collection."; +"lng_gift_collection_empty_button" = "Add to Collection"; +"lng_gift_collection_all" = "All Gifts"; +"lng_gift_collection_add_title" = "Add Gifts"; +"lng_gift_collection_edit" = "Edit Name"; +"lng_gift_collection_limit_title" = "Limit Reached"; +"lng_gift_collection_limit_text" = "Please remove one of the existing collections to add a new one."; +"lng_gift_collection_delete" = "Delete Collection"; +"lng_gift_collection_add_to" = "Add to Collection"; +"lng_gift_collection_reorder" = "Reorder"; "lng_accounts_limit_title" = "Limit Reached"; "lng_accounts_limit1#one" = "You have reached the limit of **{count}** connected account."; diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index a2158bbe20..252a7dbc94 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -1487,9 +1487,6 @@ editTagField: InputField(defaultInputField) { heightMin: 36px; } -editTagLimit: FlatLabel(defaultFlatLabel) { - textFg: windowSubTextFg; -} editStickerSetNameField: InputField(defaultInputField) { textMargins: margins(0px, 8px, 26px, 4px); diff --git a/Telegram/SourceFiles/info/info.style b/Telegram/SourceFiles/info/info.style index 283fa1df9a..5e05950c2c 100644 --- a/Telegram/SourceFiles/info/info.style +++ b/Telegram/SourceFiles/info/info.style @@ -1227,3 +1227,19 @@ infoStarsRatingLearn: RoundButton(defaultActiveButton) { ripple: emptyRippleAnimation; } infoStarsRatingTooltip: defaultImportantTooltip; + +collectionAbout: FlatLabel(defaultFlatLabel) { + minWidth: 256px; +} +collectionNameField: InputField(defaultInputField) { + textBg: transparent; + textMargins: margins(2px, 10px, 32px, 2px); + + placeholderFg: placeholderFg; + placeholderFgActive: placeholderFgActive; + placeholderFgError: placeholderFgActive; + placeholderMargins: margins(2px, 0px, 2px, 0px); + placeholderScale: 0.; + + heightMin: 36px; +} diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.cpp new file mode 100644 index 0000000000..2b66c8a78b --- /dev/null +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.cpp @@ -0,0 +1,107 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "info/peer_gifts/info_peer_gifts_collections.h" + +#include "api/api_credits.h" // +#include "apiwrap.h" +#include "data/data_peer.h" +#include "data/data_star_gift.h" +#include "lang/lang_keys.h" +#include "main/main_session.h" +#include "ui/boxes/confirm_box.h" +#include "ui/layers/generic_box.h" +#include "ui/widgets/fields/input_field.h" +#include "window/window_session_controller.h" +#include "styles/style_layers.h" +#include "styles/style_info.h" + +namespace Info::PeerGifts { +namespace { + +constexpr auto kCollectionNameLimit = 12; + +} // namespace + +void NewCollectionBox( + not_null box, + not_null navigation, + not_null peer, + Data::SavedStarGiftId addId) { + box->setTitle(tr::lng_gift_collection_new_title()); + + box->addRow( + object_ptr( + box, + tr::lng_gift_collection_new_text(), + st::collectionAbout)); + const auto title = box->addRow( + object_ptr( + box, + st::collectionNameField, + tr::lng_gift_collection_new_ph())); + title->setMaxLength(kCollectionNameLimit * 2); + box->setFocusCallback([=] { + title->setFocusFast(); + }); + + Ui::AddLengthLimitLabel(title, kCollectionNameLimit); + + const auto show = navigation->uiShow(); + const auto session = &peer->session(); + + const auto creating = std::make_shared(false); + box->addButton(tr::lng_gift_collection_new_create(), [=] { + if (*creating) { + return; + } + const auto text = title->getLastText().trimmed(); + if (text.isEmpty()) { + title->showError(); + return; + } + + *creating = true; + auto ids = QVector(); + if (addId) { + ids.push_back(Api::InputSavedStarGiftId(addId)); + } + const auto weak = base::make_weak(box); + session->api().request(MTPpayments_CreateStarGiftCollection( + peer->input, + MTP_string(text), + MTP_vector(ids) + )).done([=](const MTPStarGiftCollection &result) { + *creating = false; + if (const auto strong = weak.get()) { + strong->closeBox(); + } + }).fail([=](const MTP::Error &error) { + *creating = false; + const auto &type = error.type(); + if (type == u""_q) { + show->show(Ui::MakeInformBox({ + .text = tr::lng_gift_collection_limit_text(), + .confirmText = tr::lng_box_ok(), + .title = tr::lng_gift_collection_limit_title(), + })); + if (const auto strong = weak.get()) { + strong->closeBox(); + } + } else { + show->showToast(error.type()); + } + }).send(); + }); + + box->addButton(tr::lng_cancel(), [=] { + box->closeBox(); + }); + +} + +} // namespace Info::PeerGifts diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.h b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.h new file mode 100644 index 0000000000..cbb18a28a8 --- /dev/null +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_collections.h @@ -0,0 +1,30 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Data { +class SavedStarGiftId; +} // namespace Data + +namespace Ui { +class GenericBox; +} // namespace Ui + +namespace Window { +class SessionNavigation; +} // namespace Window + +namespace Info::PeerGifts { + +void NewCollectionBox( + not_null box, + not_null navigation, + not_null peer, + Data::SavedStarGiftId addId); + +} // namespace Info::PeerGifts diff --git a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp index 68a79563f6..73bd98c99a 100644 --- a/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp +++ b/Telegram/SourceFiles/info/peer_gifts/info_peer_gifts_widget.cpp @@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_credits.h" #include "data/data_session.h" #include "data/data_user.h" +#include "info/peer_gifts/info_peer_gifts_collections.h" #include "info/peer_gifts/info_peer_gifts_common.h" #include "info/info_controller.h" #include "ui/layers/generic_box.h" @@ -807,6 +808,8 @@ void Widget::setupNotifyCheckbox(bool enabled) { } void Widget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) { + const auto peer = _inner->peer(); + const auto canManage = peer->canManageGifts(); const auto filter = _filter.current(); const auto change = [=](Fn update) { auto now = _filter.current(); @@ -824,6 +827,20 @@ void Widget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) { }, &st::menuIconEarn); } + if (canManage) { + const auto weak = base::make_weak( + (Window::SessionNavigation*)controller()); + addAction(tr::lng_gift_collection_add(tr::now), [=] { + if (const auto strong = weak.get()) { + strong->uiShow()->show(Box( + NewCollectionBox, + strong, + peer, + Data::SavedStarGiftId())); + } + }, &st::menuIconAddToFolder); + } + addAction({ .isSeparator = true }); addAction(tr::lng_peer_gifts_filter_unlimited(tr::now), [=] { @@ -857,7 +874,7 @@ void Widget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) { }); }, filter.skipUnique ? nullptr : &st::mediaPlayerMenuCheck); - if (_inner->peer()->canManageGifts()) { + if (canManage) { addAction({ .isSeparator = true }); addAction(tr::lng_peer_gifts_filter_saved(tr::now), [=] { diff --git a/Telegram/SourceFiles/main/main_app_config.cpp b/Telegram/SourceFiles/main/main_app_config.cpp index ea8561669e..32b1ae53d8 100644 --- a/Telegram/SourceFiles/main/main_app_config.cpp +++ b/Telegram/SourceFiles/main/main_app_config.cpp @@ -121,6 +121,14 @@ int AppConfig::pinnedGiftsLimit() const { return get(u"stargifts_pinned_to_top_limit"_q, 6); } +int AppConfig::giftCollectionsLimit() const { + return get(u"stargifts_collections_limit"_q, 10); +} + +int AppConfig::giftCollectionGiftsLimit() const { + return get(u"stargifts_collection_gifts_limit"_q, 500); +} + bool AppConfig::callsDisabledForSession() const { const auto authorizations = _account->sessionExists() ? &_account->session().api().authorizations() diff --git a/Telegram/SourceFiles/main/main_app_config.h b/Telegram/SourceFiles/main/main_app_config.h index c5ba22ee40..7dc2205d1a 100644 --- a/Telegram/SourceFiles/main/main_app_config.h +++ b/Telegram/SourceFiles/main/main_app_config.h @@ -78,6 +78,8 @@ public: [[nodiscard]] int paidMessageChannelStarsDefault() const; [[nodiscard]] int pinnedGiftsLimit() const; + [[nodiscard]] int giftCollectionsLimit() const; + [[nodiscard]] int giftCollectionGiftsLimit() const; [[nodiscard]] bool callsDisabledForSession() const; [[nodiscard]] int confcallSizeLimit() const;