From b42f2784ab629f569f7d1b00c1c58444d078fdf6 Mon Sep 17 00:00:00 2001 From: John Preston Date: Mon, 1 Aug 2022 16:24:51 +0300 Subject: [PATCH] Allow sending premium emoji to Saved Messages. --- .../SourceFiles/boxes/edit_caption_box.cpp | 6 +++- Telegram/SourceFiles/boxes/send_files_box.cpp | 10 ++++-- Telegram/SourceFiles/boxes/send_files_box.h | 3 +- .../SourceFiles/boxes/sticker_set_box.cpp | 7 ++-- .../chat_helpers/emoji_list_widget.cpp | 19 ++++++++-- .../chat_helpers/emoji_list_widget.h | 2 ++ .../chat_helpers/message_field.cpp | 36 +++++++++---------- .../SourceFiles/chat_helpers/message_field.h | 6 ++-- .../chat_helpers/tabbed_selector.cpp | 12 +++++++ .../chat_helpers/tabbed_selector.h | 1 + .../data/stickers/data_custom_emoji.cpp | 5 +++ .../data/stickers/data_custom_emoji.h | 2 ++ .../SourceFiles/history/history_message.cpp | 1 - .../SourceFiles/history/history_widget.cpp | 6 +++- .../history_view_compose_controls.cpp | 10 +++++- .../view/history_view_replies_section.cpp | 2 +- .../view/history_view_replies_section.h | 2 -- .../view/history_view_scheduled_section.cpp | 2 +- 18 files changed, 93 insertions(+), 39 deletions(-) diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 703448e477..73c777cef8 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "editor/photo_editor_layer_widget.h" #include "history/history_drag_area.h" #include "history/history_item.h" +#include "history/history.h" #include "lang/lang_keys.h" #include "main/main_session.h" #include "main/main_session_settings.h" @@ -242,10 +243,12 @@ void EditCaptionBox::rebuildPreview() { } void EditCaptionBox::setupField() { + const auto peer = _historyItem->history()->peer; InitMessageFieldHandlers( _controller, _field.get(), - Window::GifPauseReason::Layer); + Window::GifPauseReason::Layer, + [=](const auto&) { return Data::AllowEmojiWithoutPremium(peer); }); Ui::Emoji::SuggestionsController::Init( getDelegate()->outerContainer(), _field, @@ -488,6 +491,7 @@ void EditCaptionBox::setupEmojiPanel() { st::emojiPanMinHeight / 2, st::emojiPanMinHeight); _emojiPanel->hide(); + _emojiPanel->selector()->setCurrentPeer(_historyItem->history()->peer); _emojiPanel->selector()->emojiChosen( ) | rpl::start_with_next([=](EmojiPtr emoji) { Ui::InsertEmojiAtCursor(_field->textCursor(), emoji); diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index b612f5da2f..046705365c 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -250,15 +250,16 @@ SendFilesBox::SendFilesBox( not_null controller, Ui::PreparedList &&list, const TextWithTags &caption, - SendLimit limit, + not_null peer, Api::SendType sendType, SendMenu::Type sendMenuType) : _controller(controller) , _sendType(sendType) , _titleHeight(st::boxTitleHeight) , _list(std::move(list)) -, _sendLimit(limit) +, _sendLimit(peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many) , _sendMenuType(sendMenuType) +, _allowEmojiWithoutPremium(Data::AllowEmojiWithoutPremium(peer)) , _caption( this, st::confirmCaptionArea, @@ -676,7 +677,8 @@ void SendFilesBox::setupCaption() { InitMessageFieldHandlers( _controller, _caption.data(), - Window::GifPauseReason::Layer); + Window::GifPauseReason::Layer, + [=](const auto&) { return _allowEmojiWithoutPremium; }); Ui::Emoji::SuggestionsController::Init( getDelegate()->outerContainer(), _caption, @@ -730,6 +732,8 @@ void SendFilesBox::setupEmojiPanel() { st::emojiPanMinHeight / 2, st::emojiPanMinHeight); _emojiPanel->hide(); + _emojiPanel->selector()->setAllowEmojiWithoutPremium( + _allowEmojiWithoutPremium); _emojiPanel->selector()->emojiChosen( ) | rpl::start_with_next([=](EmojiPtr emoji) { Ui::InsertEmojiAtCursor(_caption->textCursor(), emoji); diff --git a/Telegram/SourceFiles/boxes/send_files_box.h b/Telegram/SourceFiles/boxes/send_files_box.h index add87e2a90..978e2d34bb 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.h +++ b/Telegram/SourceFiles/boxes/send_files_box.h @@ -57,7 +57,7 @@ public: not_null controller, Ui::PreparedList &&list, const TextWithTags &caption, - SendLimit limit, + not_null peer, Api::SendType sendType, SendMenu::Type sendMenuType); @@ -168,6 +168,7 @@ private: SendLimit _sendLimit = SendLimit::Many; SendMenu::Type _sendMenuType = SendMenu::Type(); + bool _allowEmojiWithoutPremium = false; Fnsession().premium() && _controller->session().premiumPossible() && _inner->premiumEmojiSet()) { - setStyle(st::premiumPreviewBox); + const auto &st = st::premiumPreviewDoubledLimitsBox; + setStyle(st); auto button = CreateUnlockButton( this, tr::lng_premium_unlock_emoji()); button->resizeToWidth(st::boxWideWidth - - st::premiumPreviewBox.buttonPadding.left() - - st::premiumPreviewBox.buttonPadding.left()); + - st.buttonPadding.left() + - st.buttonPadding.left()); button->setClickedCallback([=] { Settings::ShowPremium(_controller, u"animated_emoji"_q); }); diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp index 6c5bade447..08ef573f08 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.cpp @@ -776,7 +776,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) { drawCollapsedBadge(p, w - _areaPosition, info.count); continue; } - if (selected && !info.premiumRequired) { + if (selected) { auto tl = w; if (rtl()) { tl.setX(width() - tl.x() - st::emojiPanArea.width()); @@ -1023,7 +1023,9 @@ void EmojiListWidget::selectEmoji(EmojiPtr emoji) { } void EmojiListWidget::selectCustom(not_null document) { - if (document->isPremiumEmoji() && !document->session().premium()) { + if (document->isPremiumEmoji() + && !document->session().premium() + && !_allowWithoutPremium) { ShowPremiumPreviewBox( controller(), PremiumPreview::AnimatedEmoji, @@ -1231,6 +1233,15 @@ uint64 EmojiListWidget::currentSet(int yOffset) const { return sectionSetId(sectionInfoByOffset(yOffset).section); } +void EmojiListWidget::setAllowWithoutPremium(bool allow) { + if (_allowWithoutPremium == allow) { + return; + } + _allowWithoutPremium = allow; + refreshCustom(); + resizeToWidth(width()); +} + QString EmojiListWidget::tooltipText() const { const auto &replacements = Ui::Emoji::internal::GetAllReplacements(); const auto over = std::get_if(&_selected); @@ -1285,7 +1296,9 @@ void EmojiListWidget::refreshCustom() { auto old = base::take(_custom); const auto session = &controller()->session(); const auto premiumPossible = session->premiumPossible(); - const auto premiumMayBeBought = premiumPossible && !session->premium(); + const auto premiumMayBeBought = premiumPossible + && !session->premium() + && !_allowWithoutPremium; const auto owner = &session->data(); const auto &sets = owner->stickers().sets(); const auto push = [&](uint64 setId, bool installed) { diff --git a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h index 6a32ca0108..42a3414fb2 100644 --- a/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/emoji_list_widget.h @@ -70,6 +70,7 @@ public: void showSet(uint64 setId); [[nodiscard]] uint64 currentSet(int yOffset) const; + void setAllowWithoutPremium(bool allow); // Ui::AbstractTooltipShower interface. QString tooltipText() const override; @@ -274,6 +275,7 @@ private: QVector _emoji[kEmojiSectionCount]; std::vector _custom; base::flat_map _customEmoji; + bool _allowWithoutPremium = false; int _rowsLeft = 0; int _columnCount = 1; diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index 772736a795..73f1c2d1b7 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -56,21 +56,21 @@ class FieldTagMimeProcessor final { public: FieldTagMimeProcessor( not_null _session, - Fn)> unavailableEmojiPasted); + Fn)> allowPremiumEmoji); QString operator()(QStringView mimeTag); private: const not_null _session; - const Fn)> _unavailableEmojiPasted; + const Fn)> _allowPremiumEmoji; }; FieldTagMimeProcessor::FieldTagMimeProcessor( not_null session, - Fn)> unavailableEmojiPasted) + Fn)> allowPremiumEmoji) : _session(session) -, _unavailableEmojiPasted(unavailableEmojiPasted) { +, _allowPremiumEmoji(allowPremiumEmoji) { } QString FieldTagMimeProcessor::operator()(QStringView mimeTag) { @@ -93,19 +93,19 @@ QString FieldTagMimeProcessor::operator()(QStringView mimeTag) { if (!_session->premium()) { const auto document = _session->data().document(emoji.id); if (document->isPremiumEmoji()) { - premiumSkipped = document; - i = all.erase(i); - continue; + if (!_allowPremiumEmoji + || premiumSkipped + || !_session->premiumPossible() + || !_allowPremiumEmoji(document)) { + premiumSkipped = document; + i = all.erase(i); + continue; + } } } } ++i; } - if (premiumSkipped - && _session->premiumPossible() - && _unavailableEmojiPasted) { - _unavailableEmojiPasted(premiumSkipped); - } return TextUtilities::JoinTag(all); } @@ -313,10 +313,10 @@ void InitMessageFieldHandlers( std::shared_ptr show, not_null field, Fn customEmojiPaused, - Fn)> unavailableEmojiPasted, + Fn)> allowPremiumEmoji, const style::InputField *fieldStyle) { field->setTagMimeProcessor( - FieldTagMimeProcessor(session, unavailableEmojiPasted)); + FieldTagMimeProcessor(session, allowPremiumEmoji)); field->setCustomEmojiFactory([=](QStringView data, Fn update) { return session->data().customEmojiManager().create( data, @@ -337,13 +337,13 @@ void InitMessageFieldHandlers( not_null controller, not_null field, Window::GifPauseReason pauseReasonLevel, - Fn)> unavailableEmojiPasted) { + Fn)> allowPremiumEmoji) { InitMessageFieldHandlers( &controller->session(), std::make_shared(controller), field, [=] { return controller->isGifPausedAtLeastFor(pauseReasonLevel); }, - unavailableEmojiPasted); + allowPremiumEmoji); } void InitMessageFieldGeometry(not_null field) { @@ -358,12 +358,12 @@ void InitMessageFieldGeometry(not_null field) { void InitMessageField( not_null controller, not_null field, - Fn)> unavailableEmojiPasted) { + Fn)> allowPremiumEmoji) { InitMessageFieldHandlers( controller, field, Window::GifPauseReason::Any, - unavailableEmojiPasted); + allowPremiumEmoji); InitMessageFieldGeometry(field); field->customTab(true); } diff --git a/Telegram/SourceFiles/chat_helpers/message_field.h b/Telegram/SourceFiles/chat_helpers/message_field.h index 0c0bbb8654..e91257a857 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.h +++ b/Telegram/SourceFiles/chat_helpers/message_field.h @@ -49,17 +49,17 @@ void InitMessageFieldHandlers( std::shared_ptr show, not_null field, Fn customEmojiPaused, - Fn)> unavailableEmojiPasted = nullptr, + Fn)> allowPremiumEmoji = nullptr, const style::InputField *fieldStyle = nullptr); void InitMessageFieldHandlers( not_null controller, not_null field, Window::GifPauseReason pauseReasonLevel, - Fn)> unavailableEmojiPasted = nullptr); + Fn)> allowPremiumEmoji = nullptr); void InitMessageField( not_null controller, not_null field, - Fn)> unavailableEmojiPasted); + Fn)> allowPremiumEmoji); void InitSpellchecker( std::shared_ptr show, diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp index 5718f195fb..bb93c68fe0 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_session.h" #include "data/data_changes.h" #include "data/stickers/data_stickers.h" +#include "data/stickers/data_custom_emoji.h" // AllowEmojiWithoutPremium. #include "lang/lang_keys.h" #include "mainwindow.h" #include "apiwrap.h" @@ -839,6 +840,8 @@ void TabbedSelector::setCurrentPeer(PeerData *peer) { if (hasStickersTab()) { stickers()->showMegagroupSet(peer ? peer->asMegagroup() : nullptr); } + setAllowEmojiWithoutPremium( + peer && Data::AllowEmojiWithoutPremium(peer)); } void TabbedSelector::checkRestrictedPeer() { @@ -924,6 +927,15 @@ void TabbedSelector::setRoundRadius(int radius) { } } +void TabbedSelector::setAllowEmojiWithoutPremium(bool allow) { + for (const auto &tab : _tabs) { + if (tab.type() == SelectorTab::Emoji) { + const auto emoji = static_cast(tab.widget()); + emoji->setAllowWithoutPremium(allow); + } + } +} + void TabbedSelector::createTabsSlider() { _tabsSlider.create(this, st::emojiTabs); diff --git a/Telegram/SourceFiles/chat_helpers/tabbed_selector.h b/Telegram/SourceFiles/chat_helpers/tabbed_selector.h index 5b7eedd019..7086a69f33 100644 --- a/Telegram/SourceFiles/chat_helpers/tabbed_selector.h +++ b/Telegram/SourceFiles/chat_helpers/tabbed_selector.h @@ -98,6 +98,7 @@ public: rpl::producer<> contextMenuRequested() const; rpl::producer choosingStickerUpdated() const; + void setAllowEmojiWithoutPremium(bool allow); void setRoundRadius(int radius); void refreshStickers(); void setCurrentPeer(PeerData *peer); diff --git a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp index 05663becfc..4f7977db5a 100644 --- a/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp +++ b/Telegram/SourceFiles/data/stickers/data_custom_emoji.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_document.h" #include "data/data_document_media.h" #include "data/data_file_origin.h" +#include "data/data_peer.h" #include "lottie/lottie_common.h" #include "lottie/lottie_emoji.h" #include "ffmpeg/ffmpeg_emoji.h" @@ -646,6 +647,10 @@ CustomEmojiId ParseCustomEmojiData(QStringView data) { }; } +bool AllowEmojiWithoutPremium(not_null peer) { + return peer->isSelf(); +} + void InsertCustomEmoji( not_null field, not_null document) { diff --git a/Telegram/SourceFiles/data/stickers/data_custom_emoji.h b/Telegram/SourceFiles/data/stickers/data_custom_emoji.h index 74666add13..516fd3331d 100644 --- a/Telegram/SourceFiles/data/stickers/data_custom_emoji.h +++ b/Telegram/SourceFiles/data/stickers/data_custom_emoji.h @@ -122,6 +122,8 @@ private: not_null document); [[nodiscard]] CustomEmojiId ParseCustomEmojiData(QStringView data); +[[nodiscard]] bool AllowEmojiWithoutPremium(not_null peer); + void InsertCustomEmoji( not_null field, not_null document); diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index c0d6693671..94b65d2cd9 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -404,7 +404,6 @@ HistoryMessage::HistoryMessage( const auto dropForwardInfo = (originalMedia && originalMedia->dropForwardedInfo()) || (original->history()->peer->isSelf() - && !history->peer->isSelf() && !original->Has() && (!originalMedia || !originalMedia->forceForwardedInfo())); if (!dropForwardInfo) { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c66e77db94..b7e3433fb5 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -396,7 +396,11 @@ HistoryWidget::HistoryWidget( InitMessageField(controller, _field, [=]( not_null document) { + if (_peer && Data::AllowEmojiWithoutPremium(_peer)) { + return true; + } showPremiumToast(document); + return false; }); _keyboard->sendCommandRequests( @@ -5001,7 +5005,7 @@ bool HistoryWidget::confirmSendingFiles( controller(), std::move(list), text, - _peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many, + _peer, Api::SendType::Normal, sendMenuType()); _field->setTextWithTags({}); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 9f237f7d12..02e76bc61b 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -1422,7 +1422,15 @@ void ComposeControls::initField() { Ui::Connect(_field, &Ui::InputField::resized, [=] { updateHeight(); }); //Ui::Connect(_field, &Ui::InputField::focused, [=] { fieldFocused(); }); Ui::Connect(_field, &Ui::InputField::changed, [=] { fieldChanged(); }); - InitMessageField(_window, _field, _unavailableEmojiPasted); + InitMessageField(_window, _field, [=](not_null emoji) { + if (_history && Data::AllowEmojiWithoutPremium(_history->peer)) { + return true; + } + if (_unavailableEmojiPasted) { + _unavailableEmojiPasted(emoji); + } + return false; + }); initAutocomplete(); const auto suggestions = Ui::Emoji::SuggestionsController::Init( _parent, diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 4e5cc64be7..003bba20e3 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -747,7 +747,7 @@ bool RepliesWidget::confirmSendingFiles( controller(), std::move(list), _composeControls->getTextWithAppliedMarkdown(), - _history->peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many, + _history->peer, Api::SendType::Normal, SendMenu::Type::SilentOnly); // #TODO replies schedule diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index 31296bce5f..82ea5d6523 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -195,8 +195,6 @@ private: void clearSelected(); void setPinnedVisibility(bool shown); - void showPremiumToast(not_null document); - [[nodiscard]] Api::SendAction prepareSendAction( Api::SendOptions options) const; void send(); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 264ad9b5cf..3b7de57edb 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -405,7 +405,7 @@ bool ScheduledWidget::confirmSendingFiles( controller(), std::move(list), _composeControls->getTextWithAppliedMarkdown(), - _history->peer->slowmodeApplied() ? SendLimit::One : SendLimit::Many, + _history->peer, CanScheduleUntilOnline(_history->peer) ? Api::SendType::ScheduledToUser : Api::SendType::Scheduled,