diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b87b38d0f..64d657908 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2302,7 +2302,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_chat_intro_title" = "Intro"; "lng_chat_intro_subtitle" = "Customize your intro"; "lng_chat_intro_default_title" = "No messages here yet..."; -"lng_chat_intro_default_message" = "Send a message or tap on the greeting below"; +"lng_chat_intro_default_message" = "Send a message or click on the greeting below"; "lng_chat_intro_enter_title" = "Enter Title"; "lng_chat_intro_enter_message" = "Enter Message"; "lng_chat_intro_choose_sticker" = "Choose Sticker"; diff --git a/Telegram/SourceFiles/data/business/data_business_common.cpp b/Telegram/SourceFiles/data/business/data_business_common.cpp index bdc8ffe7d..52c545bc4 100644 --- a/Telegram/SourceFiles/data/business/data_business_common.cpp +++ b/Telegram/SourceFiles/data/business/data_business_common.cpp @@ -153,8 +153,10 @@ BusinessRecipients FromMTP( } BusinessDetails FromMTP( + not_null owner, const tl::conditional &hours, - const tl::conditional &location) { + const tl::conditional &location, + const tl::conditional &intro) { auto result = BusinessDetails(); if (hours) { const auto &data = hours->data(); @@ -179,6 +181,17 @@ BusinessDetails FromMTP( }); } } + if (intro) { + const auto &data = intro->data(); + result.intro.title = qs(data.vtitle()); + result.intro.description = qs(data.vdescription()); + if (const auto document = data.vsticker()) { + result.intro.sticker = owner->processDocument(*document); + if (!result.intro.sticker->sticker()) { + result.intro.sticker = nullptr; + } + } + } return result; } @@ -334,22 +347,4 @@ WorkingIntervals ReplaceDayIntervals( return result.normalized(); } -ChatIntro FromMTP( - not_null owner, - const tl::conditional &intro) { - auto result = ChatIntro(); - if (intro) { - const auto &data = intro->data(); - result.title = qs(data.vtitle()); - result.description = qs(data.vdescription()); - if (const auto document = data.vsticker()) { - result.sticker = owner->processDocument(*document); - if (!result.sticker->sticker()) { - result.sticker = nullptr; - } - } - } - return result; -} - } // namespace Data diff --git a/Telegram/SourceFiles/data/business/data_business_common.h b/Telegram/SourceFiles/data/business/data_business_common.h index 86754c56f..dc9f65256 100644 --- a/Telegram/SourceFiles/data/business/data_business_common.h +++ b/Telegram/SourceFiles/data/business/data_business_common.h @@ -182,12 +182,27 @@ struct BusinessLocation { const BusinessLocation &b) = default; }; +struct ChatIntro { + QString title; + QString description; + DocumentData *sticker = nullptr; + + explicit operator bool() const { + return !title.isEmpty() || !description.isEmpty(); + } + + friend inline bool operator==( + const ChatIntro &a, + const ChatIntro &b) = default; +}; + struct BusinessDetails { WorkingHours hours; BusinessLocation location; + ChatIntro intro; explicit operator bool() const { - return hours || location; + return hours || location || intro; } friend inline bool operator==( @@ -196,8 +211,10 @@ struct BusinessDetails { }; [[nodiscard]] BusinessDetails FromMTP( + not_null owner, const tl::conditional &hours, - const tl::conditional &location); + const tl::conditional &location, + const tl::conditional &intro); enum class AwayScheduleType : uchar { Never = 0, @@ -252,22 +269,4 @@ struct GreetingSettings { not_null owner, const tl::conditional &message); -struct ChatIntro { - QString title; - QString description; - DocumentData *sticker = nullptr; - - explicit operator bool() const { - return !title.isEmpty() || !description.isEmpty(); - } - - friend inline bool operator==( - const ChatIntro &a, - const ChatIntro &b) = default; -}; - -[[nodiscard]] ChatIntro FromMTP( - not_null owner, - const tl::conditional &intro); - } // namespace Data diff --git a/Telegram/SourceFiles/data/business/data_business_info.cpp b/Telegram/SourceFiles/data/business/data_business_info.cpp index 66c7e0be9..e158c7a3a 100644 --- a/Telegram/SourceFiles/data/business/data_business_info.cpp +++ b/Telegram/SourceFiles/data/business/data_business_info.cpp @@ -96,6 +96,40 @@ void BusinessInfo::saveWorkingHours( session->user()->setBusinessDetails(std::move(details)); } +void BusinessInfo::saveChatIntro(ChatIntro data, Fn fail) { + const auto session = &_owner->session(); + auto details = session->user()->businessDetails(); + const auto &was = details.intro; + if (was == data) { + return; + } else { + const auto session = &_owner->session(); + using Flag = MTPaccount_UpdateBusinessIntro::Flag; + session->api().request(MTPaccount_UpdateBusinessIntro( + MTP_flags(data ? Flag::f_intro : Flag()), + MTP_inputBusinessIntro( + MTP_flags(data.sticker + ? MTPDinputBusinessIntro::Flag::f_sticker + : MTPDinputBusinessIntro::Flag()), + MTP_string(data.title), + MTP_string(data.description), + (data.sticker + ? data.sticker->mtpInput() + : MTP_inputDocumentEmpty())) + )).fail([=](const MTP::Error &error) { + auto details = session->user()->businessDetails(); + details.intro = was; + session->user()->setBusinessDetails(std::move(details)); + if (fail) { + fail(error.type()); + } + }).send(); + } + + details.intro = std::move(data); + session->user()->setBusinessDetails(std::move(details)); +} + void BusinessInfo::applyAwaySettings(AwaySettings data) { if (_awaySettings == data) { return; @@ -184,54 +218,6 @@ rpl::producer<> BusinessInfo::greetingSettingsChanged() const { return _greetingSettingsChanged.events(); } -void BusinessInfo::saveChatIntro(ChatIntro data, Fn fail) { - const auto &was = _chatIntro; - if (was == data) { - return; - } else { - const auto session = &_owner->session(); - using Flag = MTPaccount_UpdateBusinessIntro::Flag; - session->api().request(MTPaccount_UpdateBusinessIntro( - MTP_flags(data ? Flag::f_intro : Flag()), - MTP_inputBusinessIntro( - MTP_flags(data.sticker ? MTPDinputBusinessIntro::Flag::f_sticker : MTPDinputBusinessIntro::Flag()), - MTP_string(data.title), - MTP_string(data.description), - (data.sticker - ? data.sticker->mtpInput() - : MTP_inputDocumentEmpty())) - )).fail([=](const MTP::Error &error) { - _chatIntro = was; - _chatIntroChanged.fire({}); - if (fail) { - fail(error.type()); - } - }).send(); - } - _chatIntro = std::move(data); - _chatIntroChanged.fire({}); -} - -void BusinessInfo::applyChatIntro(ChatIntro data) { - if (_chatIntro == data) { - return; - } - _chatIntro = data; - _chatIntroChanged.fire({}); -} - -ChatIntro BusinessInfo::chatIntro() const { - return _chatIntro.value_or(ChatIntro()); -} - -bool BusinessInfo::chatIntroLoaded() const { - return _chatIntro.has_value(); -} - -rpl::producer<> BusinessInfo::chatIntroChanged() const { - return _chatIntroChanged.events(); -} - void BusinessInfo::preload() { preloadTimezones(); } diff --git a/Telegram/SourceFiles/data/business/data_business_info.h b/Telegram/SourceFiles/data/business/data_business_info.h index bdae99e35..7b99e4c8f 100644 --- a/Telegram/SourceFiles/data/business/data_business_info.h +++ b/Telegram/SourceFiles/data/business/data_business_info.h @@ -21,6 +21,7 @@ public: void preload(); void saveWorkingHours(WorkingHours data, Fn fail); + void saveChatIntro(ChatIntro data, Fn fail); void saveAwaySettings(AwaySettings data, Fn fail); void applyAwaySettings(AwaySettings data); @@ -36,12 +37,6 @@ public: [[nodiscard]] bool greetingSettingsLoaded() const; [[nodiscard]] rpl::producer<> greetingSettingsChanged() const; - void saveChatIntro(ChatIntro data, Fn fail); - void applyChatIntro(ChatIntro data); - [[nodiscard]] ChatIntro chatIntro() const; - [[nodiscard]] bool chatIntroLoaded() const; - [[nodiscard]] rpl::producer<> chatIntroChanged() const; - void preloadTimezones(); [[nodiscard]] bool timezonesLoaded() const; [[nodiscard]] rpl::producer timezonesValue() const; @@ -57,9 +52,6 @@ private: std::optional _greetingSettings; rpl::event_stream<> _greetingSettingsChanged; - std::optional _chatIntro; - rpl::event_stream<> _chatIntroChanged; - mtpRequestId _timezonesRequestId = 0; int32 _timezonesHash = 0; diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index a1219380c..ebe681ac3 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -594,15 +594,15 @@ void ApplyUserUpdate(not_null user, const MTPDuserFull &update) { } user->setBusinessDetails(FromMTP( + &user->owner(), update.vbusiness_work_hours(), - update.vbusiness_location())); + update.vbusiness_location(), + update.vbusiness_intro())); if (user->isSelf()) { user->owner().businessInfo().applyAwaySettings( FromMTP(&user->owner(), update.vbusiness_away_message())); user->owner().businessInfo().applyGreetingSettings( FromMTP(&user->owner(), update.vbusiness_greeting_message())); - user->owner().businessInfo().applyChatIntro( - FromMTP(&user->owner(), update.vbusiness_intro())); } user->owner().stories().apply(user, update.vstories()); diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index 11c410da3..5981e5258 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -502,7 +502,7 @@ void Stickers::undoInstallLocally(uint64 setId) { Ui::LayerOption::KeepOther); } -bool Stickers::isFaved(not_null document) { +bool Stickers::isFaved(not_null document) const { const auto &sets = this->sets(); const auto it = sets.find(FavedSetId); if (it == sets.cend()) { diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.h b/Telegram/SourceFiles/data/stickers/data_stickers.h index 7b8937846..d5a192b4b 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.h +++ b/Telegram/SourceFiles/data/stickers/data_stickers.h @@ -80,13 +80,13 @@ public: void incrementSticker(not_null document); - bool updateNeeded(crl::time now) const { + [[nodiscard]] bool updateNeeded(crl::time now) const { return updateNeeded(_lastUpdate, now); } void setLastUpdate(crl::time update) { _lastUpdate = update; } - bool recentUpdateNeeded(crl::time now) const { + [[nodiscard]] bool recentUpdateNeeded(crl::time now) const { return updateNeeded(_lastRecentUpdate, now); } void setLastRecentUpdate(crl::time update) { @@ -95,19 +95,19 @@ public: } _lastRecentUpdate = update; } - bool masksUpdateNeeded(crl::time now) const { + [[nodiscard]] bool masksUpdateNeeded(crl::time now) const { return updateNeeded(_lastMasksUpdate, now); } void setLastMasksUpdate(crl::time update) { _lastMasksUpdate = update; } - bool emojiUpdateNeeded(crl::time now) const { + [[nodiscard]] bool emojiUpdateNeeded(crl::time now) const { return updateNeeded(_lastEmojiUpdate, now); } void setLastEmojiUpdate(crl::time update) { _lastEmojiUpdate = update; } - bool recentAttachedUpdateNeeded(crl::time now) const { + [[nodiscard]] bool recentAttachedUpdateNeeded(crl::time now) const { return updateNeeded(_lastRecentAttachedUpdate, now); } void setLastRecentAttachedUpdate(crl::time update) { @@ -116,31 +116,31 @@ public: } _lastRecentAttachedUpdate = update; } - bool favedUpdateNeeded(crl::time now) const { + [[nodiscard]] bool favedUpdateNeeded(crl::time now) const { return updateNeeded(_lastFavedUpdate, now); } void setLastFavedUpdate(crl::time update) { _lastFavedUpdate = update; } - bool featuredUpdateNeeded(crl::time now) const { + [[nodiscard]] bool featuredUpdateNeeded(crl::time now) const { return updateNeeded(_lastFeaturedUpdate, now); } void setLastFeaturedUpdate(crl::time update) { _lastFeaturedUpdate = update; } - bool featuredEmojiUpdateNeeded(crl::time now) const { + [[nodiscard]] bool featuredEmojiUpdateNeeded(crl::time now) const { return updateNeeded(_lastFeaturedEmojiUpdate, now); } void setLastFeaturedEmojiUpdate(crl::time update) { _lastFeaturedEmojiUpdate = update; } - bool savedGifsUpdateNeeded(crl::time now) const { + [[nodiscard]] bool savedGifsUpdateNeeded(crl::time now) const { return updateNeeded(_lastSavedGifsUpdate, now); } void setLastSavedGifsUpdate(crl::time update) { _lastSavedGifsUpdate = update; } - int featuredSetsUnreadCount() const { + [[nodiscard]] int featuredSetsUnreadCount() const { return _featuredSetsUnreadCount.current(); } void setFeaturedSetsUnreadCount(int count) { @@ -149,58 +149,58 @@ public: [[nodiscard]] rpl::producer featuredSetsUnreadCountValue() const { return _featuredSetsUnreadCount.value(); } - const StickersSets &sets() const { + [[nodiscard]] const StickersSets &sets() const { return _sets; } - StickersSets &setsRef() { + [[nodiscard]] StickersSets &setsRef() { return _sets; } - const StickersSetsOrder &setsOrder() const { + [[nodiscard]] const StickersSetsOrder &setsOrder() const { return _setsOrder; } - StickersSetsOrder &setsOrderRef() { + [[nodiscard]] StickersSetsOrder &setsOrderRef() { return _setsOrder; } - const StickersSetsOrder &maskSetsOrder() const { + [[nodiscard]] const StickersSetsOrder &maskSetsOrder() const { return _maskSetsOrder; } - StickersSetsOrder &maskSetsOrderRef() { + [[nodiscard]] StickersSetsOrder &maskSetsOrderRef() { return _maskSetsOrder; } - const StickersSetsOrder &emojiSetsOrder() const { + [[nodiscard]] const StickersSetsOrder &emojiSetsOrder() const { return _emojiSetsOrder; } - StickersSetsOrder &emojiSetsOrderRef() { + [[nodiscard]] StickersSetsOrder &emojiSetsOrderRef() { return _emojiSetsOrder; } - const StickersSetsOrder &featuredSetsOrder() const { + [[nodiscard]] const StickersSetsOrder &featuredSetsOrder() const { return _featuredSetsOrder; } - StickersSetsOrder &featuredSetsOrderRef() { + [[nodiscard]] StickersSetsOrder &featuredSetsOrderRef() { return _featuredSetsOrder; } - const StickersSetsOrder &featuredEmojiSetsOrder() const { + [[nodiscard]] const StickersSetsOrder &featuredEmojiSetsOrder() const { return _featuredEmojiSetsOrder; } - StickersSetsOrder &featuredEmojiSetsOrderRef() { + [[nodiscard]] StickersSetsOrder &featuredEmojiSetsOrderRef() { return _featuredEmojiSetsOrder; } - const StickersSetsOrder &archivedSetsOrder() const { + [[nodiscard]] const StickersSetsOrder &archivedSetsOrder() const { return _archivedSetsOrder; } - StickersSetsOrder &archivedSetsOrderRef() { + [[nodiscard]] StickersSetsOrder &archivedSetsOrderRef() { return _archivedSetsOrder; } - const StickersSetsOrder &archivedMaskSetsOrder() const { + [[nodiscard]] const StickersSetsOrder &archivedMaskSetsOrder() const { return _archivedMaskSetsOrder; } - StickersSetsOrder &archivedMaskSetsOrderRef() { + [[nodiscard]] StickersSetsOrder &archivedMaskSetsOrderRef() { return _archivedMaskSetsOrder; } - const SavedGifs &savedGifs() const { + [[nodiscard]] const SavedGifs &savedGifs() const { return _savedGifs; } - SavedGifs &savedGifsRef() { + [[nodiscard]] SavedGifs &savedGifsRef() { return _savedGifs; } void removeFromRecentSet(not_null document); @@ -214,7 +214,7 @@ public: const MTPDmessages_stickerSetInstallResultArchive &d); void installLocally(uint64 setId); void undoInstallLocally(uint64 setId); - bool isFaved(not_null document); + [[nodiscard]] bool isFaved(not_null document) const; void setFaved( std::shared_ptr show, not_null document, @@ -235,12 +235,12 @@ public: const MTPmessages_FeaturedStickers &result); void gifsReceived(const QVector &items, uint64 hash); - std::vector> getListByEmoji( + [[nodiscard]] std::vector> getListByEmoji( std::vector emoji, uint64 seed, bool forceAllResults = false); - std::optional>> getEmojiListFromSet( - not_null document); + [[nodiscard]] auto getEmojiListFromSet(not_null document) + -> std::optional>>; not_null feedSet(const MTPStickerSet &data); not_null feedSet(const MTPStickerSetCovered &data); @@ -254,15 +254,14 @@ public: const QVector &documents); void newSetReceived(const MTPDmessages_stickerSet &set); - QString getSetTitle(const MTPDstickerSet &s); + [[nodiscard]] QString getSetTitle(const MTPDstickerSet &s); - RecentStickerPack &getRecentPack() const; + [[nodiscard]] RecentStickerPack &getRecentPack() const; private: - bool updateNeeded(crl::time lastUpdate, crl::time now) const { + [[nodiscard]] bool updateNeeded(crl::time last, crl::time now) const { constexpr auto kUpdateTimeout = crl::time(3600'000); - return (lastUpdate == 0) - || (now >= lastUpdate + kUpdateTimeout); + return (last == 0) || (now >= last + kUpdateTimeout); } void checkFavedLimit( StickersSet &set, diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 5a8f09ffd..3b3dd87d9 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -4072,7 +4072,7 @@ void HistoryInner::refreshAboutView() { _history->delegateMixin()->delegate()); } if (!info->inited) { - session().api().requestFullPeer(_peer); + session().api().requestFullPeer(user); } } else if (user->meRequiresPremiumToWrite() && !user->session().premium() @@ -4082,8 +4082,15 @@ void HistoryInner::refreshAboutView() { _history, _history->delegateMixin()->delegate()); } - } else { - _aboutView = nullptr; + } else if (!historyHeight()) { + if (!_aboutView) { + _aboutView = std::make_unique( + _history, + _history->delegateMixin()->delegate()); + } + if (!user->isFullLoaded()) { + session().api().requestFullPeer(user); + } } } } diff --git a/Telegram/SourceFiles/history/view/history_view_about_view.cpp b/Telegram/SourceFiles/history/view/history_view_about_view.cpp index 6fe6bba3d..461dfd49a 100644 --- a/Telegram/SourceFiles/history/view/history_view_about_view.cpp +++ b/Telegram/SourceFiles/history/view/history_view_about_view.cpp @@ -7,6 +7,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #include "history/view/history_view_about_view.h" +#include "api/api_premium.h" +#include "apiwrap.h" +#include "base/random.h" #include "chat_helpers/stickers_lottie.h" #include "core/click_handler_types.h" #include "data/business/data_business_common.h" @@ -70,47 +73,11 @@ private: }; -class ChatIntroBox final : public ServiceBoxContent { -public: - ChatIntroBox(not_null parent, Data::ChatIntro data); - ~ChatIntroBox(); - - int width() override; - int top() override; - QSize size() override; - QString title() override; - TextWithEntities subtitle() override; - int buttonSkip() override; - rpl::producer button() override; - void draw( - Painter &p, - const PaintContext &context, - const QRect &geometry) override; - ClickHandlerPtr createViewLink() override; - - bool hideServiceText() override { - return true; - } - - void stickerClearLoopPlayed() override; - std::unique_ptr stickerTakePlayer( - not_null data, - const Lottie::ColorReplacements *replacements) override; - - bool hasHeavyPart() override; - void unloadHeavyPart() override; - -private: - const not_null _parent; - const Data::ChatIntro _data; - mutable std::optional _sticker; - -}; - auto GenerateChatIntro( not_null parent, Element *replacing, - const Data::ChatIntro &data) + const Data::ChatIntro &data, + Fn)> helloChosen) -> Fn)>)> { return [=](Fn)> push) { auto pushText = [&]( @@ -137,8 +104,19 @@ auto GenerateChatIntro( : st::chatIntroMargin); const auto sticker = [=] { using Tag = ChatHelpers::StickerLottieSize; + auto sticker = data.sticker; + if (!sticker) { + const auto api = &parent->history()->session().api(); + const auto &list = api->premium().helloStickers(); + if (!list.empty()) { + sticker = list[base::RandomIndex(list.size())]; + if (helloChosen) { + helloChosen(sticker); + } + } + } return StickerInBubblePart::Data{ - .sticker = data.sticker, + .sticker = sticker, .size = st::chatIntroStickerSize, .cacheTag = Tag::ChatIntroHelloSticker, }; @@ -220,96 +198,6 @@ bool PremiumRequiredBox::hasHeavyPart() { void PremiumRequiredBox::unloadHeavyPart() { } -ChatIntroBox::ChatIntroBox(not_null parent, Data::ChatIntro data) -: _parent(parent) -, _data(data) { - if (const auto document = data.sticker) { - if (const auto sticker = document->sticker()) { - const auto skipPremiumEffect = true; - _sticker.emplace(_parent, document, skipPremiumEffect, _parent); - _sticker->initSize(st::chatIntroStickerSize); - _sticker->setCustomCachingTag( - ChatHelpers::StickerLottieSize::ChatIntroHelloSticker); - } - } -} - -ChatIntroBox::~ChatIntroBox() = default; - -int ChatIntroBox::width() { - return st::chatIntroWidth; -} - -int ChatIntroBox::top() { - return st::msgServiceGiftBoxButtonMargins.top(); -} - -QSize ChatIntroBox::size() { - return { st::msgServicePhotoWidth, st::msgServicePhotoWidth }; -} - -QString ChatIntroBox::title() { - return _data ? _data.title : tr::lng_chat_intro_default_title(tr::now); -} - -int ChatIntroBox::buttonSkip() { - return st::storyMentionButtonSkip; -} - -rpl::producer ChatIntroBox::button() { - return nullptr; -} - -TextWithEntities ChatIntroBox::subtitle() { - return { - (_data - ? _data.description - : tr::lng_chat_intro_default_message(tr::now)) - }; -} - -ClickHandlerPtr ChatIntroBox::createViewLink() { - return std::make_shared([=](ClickContext context) { - const auto my = context.other.value(); - if (const auto controller = my.sessionWindow.get()) { - Settings::ShowPremium(controller, u"require_premium"_q); - } - }); -} - -void ChatIntroBox::draw( - Painter &p, - const PaintContext &context, - const QRect &geometry) { - if (_sticker) { - _sticker->draw(p, context, geometry); - } -} - -void ChatIntroBox::stickerClearLoopPlayed() { - if (_sticker) { - _sticker->stickerClearLoopPlayed(); - } -} - -std::unique_ptr ChatIntroBox::stickerTakePlayer( - not_null data, - const Lottie::ColorReplacements *replacements) { - return _sticker - ? _sticker->stickerTakePlayer(data, replacements) - : nullptr; -} - -bool ChatIntroBox::hasHeavyPart() { - return _sticker && _sticker->hasHeavyPart(); -} - -void ChatIntroBox::unloadHeavyPart() { - if (_sticker) { - _sticker->unloadHeavyPart(); - } -} - } // namespace AboutView::AboutView( @@ -339,21 +227,22 @@ HistoryItem *AboutView::item() const { } bool AboutView::refresh() { - const auto bot = _history->peer->asUser(); - const auto info = bot ? bot->botInfo.get() : nullptr; + const auto user = _history->peer->asUser(); + const auto info = user ? user->botInfo.get() : nullptr; if (!info) { - if (bot - && bot->meRequiresPremiumToWrite() - && !bot->session().premium() - && _history->isDisplayedEmpty()) { + if (user && _history->isDisplayedEmpty()) { if (_item) { return false; + } else if (user->meRequiresPremiumToWrite() + && !user->session().premium()) { + setItem(makePremiumRequired(), nullptr); + } else { + makeIntro(user); } - _item = makePremiumRequired(); return true; } if (_item) { - _item = {}; + setItem({}, nullptr); return true; } _version = 0; @@ -364,10 +253,14 @@ bool AboutView::refresh() { return false; } _version = version; - _item = makeAboutBot(info); + setItem(makeAboutBot(info), nullptr); return true; } +void AboutView::makeIntro(not_null user) { + make(user->businessDetails().intro); +} + void AboutView::make(Data::ChatIntro data) { const auto item = _history->makeMessage({ .id = _history->nextNonHistoryEntryId(), @@ -377,31 +270,58 @@ void AboutView::make(Data::ChatIntro data) { .from = _history->peer->id, }, PreparedServiceText{ { } }); + if (data.sticker) { + _helloChosen = nullptr; + } else if (_helloChosen) { + data.sticker = _helloChosen; + } + auto owned = AdminLog::OwnedItem(_delegate, item); + const auto helloChosen = [=](not_null sticker) { + setHelloChosen(sticker); + }; owned->overrideMedia(std::make_unique( owned.get(), - GenerateChatIntro(owned.get(), _item.get(), data), + GenerateChatIntro(owned.get(), _item.get(), data, helloChosen), HistoryView::MediaInBubbleDescriptor{ .maxWidth = st::chatIntroWidth, .service = true, .hideServiceText = true, })); + if (!data.sticker && _helloChosen) { + data.sticker = _helloChosen; + } setItem(std::move(owned), data.sticker); } -void AboutView::setItem(AdminLog::OwnedItem item, DocumentData *sticker) { - if (const auto was = _item ? _item->data().get() : nullptr) { +void AboutView::toggleStickerRegistered(bool registered) { + if (const auto item = _item ? _item->data().get() : nullptr) { if (_sticker) { - was->history()->owner().unregisterDocumentItem(_sticker, was); + const auto owner = &item->history()->owner(); + if (registered) { + owner->registerDocumentItem(_sticker, item); + } else { + owner->unregisterDocumentItem(_sticker, item); + } } } + if (!registered) { + _sticker = nullptr; + } +} + +void AboutView::setHelloChosen(not_null sticker) { + _helloChosen = sticker; + toggleStickerRegistered(false); + _sticker = sticker; + toggleStickerRegistered(true); +} + +void AboutView::setItem(AdminLog::OwnedItem item, DocumentData *sticker) { + toggleStickerRegistered(false); _item = std::move(item); _sticker = sticker; - if (const auto now = _item ? _item->data().get() : nullptr) { - if (_sticker) { - now->history()->owner().registerDocumentItem(_sticker, now); - } - } + toggleStickerRegistered(true); } AdminLog::OwnedItem AboutView::makeAboutBot(not_null info) { diff --git a/Telegram/SourceFiles/history/view/history_view_about_view.h b/Telegram/SourceFiles/history/view/history_view_about_view.h index cd1528b75..681b93e7f 100644 --- a/Telegram/SourceFiles/history/view/history_view_about_view.h +++ b/Telegram/SourceFiles/history/view/history_view_about_view.h @@ -36,11 +36,15 @@ public: private: [[nodiscard]] AdminLog::OwnedItem makeAboutBot(not_null info); [[nodiscard]] AdminLog::OwnedItem makePremiumRequired(); + void makeIntro(not_null user); void setItem(AdminLog::OwnedItem item, DocumentData *sticker); + void setHelloChosen(not_null sticker); + void toggleStickerRegistered(bool registered); const not_null _history; const not_null _delegate; AdminLog::OwnedItem _item; + DocumentData *_helloChosen = nullptr; DocumentData *_sticker = nullptr; int _version = 0; diff --git a/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp b/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp index 2e84f4d45..175538428 100644 --- a/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp +++ b/Telegram/SourceFiles/settings/business/settings_chat_intro.cpp @@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document.h" #include "data/data_document_media.h" #include "data/data_session.h" +#include "data/data_user.h" #include "history/view/media/history_view_media_common.h" #include "history/view/media/history_view_sticker_player.h" #include "history/view/history_view_about_view.h" @@ -564,10 +565,8 @@ void ChatIntro::setupContent( const auto content = Ui::CreateChild(this); const auto session = &controller->session(); - const auto info = &session->data().businessInfo(); - const auto current = info->chatIntro(); + _intro = controller->session().user()->businessDetails().intro; - _intro = info->chatIntro(); const auto change = [=](Fn modify) { auto intro = _intro.current(); modify(intro); @@ -584,12 +583,12 @@ void ChatIntro::setupContent( const auto title = AddPartInput( content, tr::lng_chat_intro_enter_title(), - current.title, + _intro.current().title, PartLimit(session, u"intro_title_length_limit"_q, 32)); const auto description = AddPartInput( content, tr::lng_chat_intro_enter_message(), - current.description, + _intro.current().description, PartLimit(session, u"intro_description_length_limit"_q, 70)); content->add(CreateIntroStickerButton( content,