diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 655a29f76..29f186057 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1986,6 +1986,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_group_stickers" = "Group stickers"; "lng_group_stickers_description" = "You can choose a sticker set which will be available for every member while in the group chat."; "lng_group_stickers_add" = "Choose sticker set"; +"lng_group_emoji" = "Group emoji pack"; +"lng_group_emoji_description" = "Choose an emoji pack that will be available to all members within the group."; "lng_premium" = "Premium"; "lng_premium_free" = "Free"; @@ -2230,15 +2232,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_boost_channel_title_wallpaper" = "Enable wallpapers"; "lng_boost_channel_needs_level_wallpaper#one" = "Your channel needs to reach **Level {count}** to change channel wallpaper."; "lng_boost_channel_needs_level_wallpaper#other" = "Your channel needs to reach **Level {count}** to change channel wallpaper."; +"lng_boost_group_needs_level_wallpaper#one" = "Your group needs to reach **Level {count}** to change group wallpaper."; +"lng_boost_group_needs_level_wallpaper#other" = "Your group needs to reach **Level {count}** to change group wallpaper."; "lng_boost_channel_title_status" = "Enable emoji status"; "lng_boost_channel_needs_level_status#one" = "Your channel needs to reach **Level {count}** to set emoji status."; "lng_boost_channel_needs_level_status#other" = "Your channel needs to reach **Level {count}** to set emoji status."; +"lng_boost_group_needs_level_status#one" = "Your group needs to reach **Level {count}** to set emoji status."; +"lng_boost_group_needs_level_status#other" = "Your group needs to reach **Level {count}** to set emoji status."; "lng_boost_channel_title_reactions" = "Custom reactions"; "lng_boost_channel_needs_level_reactions#one" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as a reaction."; "lng_boost_channel_needs_level_reactions#other" = "Your channel needs to reach **Level {count}** to add **{same_count}** custom emoji as reactions."; +"lng_boost_group_title_emoji" = "Enable emoji pack"; +"lng_boost_group_needs_level_emoji#one" = "Your group needs to reach **Level {count}** to set emoji pack."; +"lng_boost_group_needs_level_emoji#other" = "Your group needs to reach **Level {count}** to set emoji pack."; + "lng_boost_channel_ask" = "Ask your **Premium** subscribers to boost your channel with this link:"; "lng_boost_channel_ask_button" = "Copy Link"; "lng_boost_channel_or" = "or"; @@ -2518,6 +2528,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_stickers_remove_pack_confirm" = "Remove"; "lng_stickers_archive_pack" = "Archive Stickers"; "lng_stickers_has_been_archived" = "Sticker pack has been archived."; +"lng_emoji_group_set" = "Group emoji set"; +"lng_emoji_remove_group_set" = "Remove group emoji set?"; +"lng_emoji_group_from_your" = "Choose from your emoji"; +"lng_emoji_group_from_featured" = "Choose from trending emoji"; "lng_masks_archive_pack" = "Archive Masks"; "lng_masks_has_been_archived" = "Mask pack has been archived."; "lng_masks_installed" = "Mask pack has been installed."; @@ -3028,8 +3042,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_edit_channel_level_min" = "Level 1+"; "lng_edit_channel_wallpaper" = "Channel wallpaper"; "lng_edit_channel_wallpaper_about" = "Set a wallpaper that will be visible for everyone reading your channel."; +"lng_edit_channel_wallpaper_group" = "Group wallpaper"; +"lng_edit_channel_wallpaper_about_group" = "Set a wallpaper that will be visible for everyone participating in your group."; "lng_edit_channel_status" = "Channel emoji status"; "lng_edit_channel_status_about" = "Choose a status that will be shown next to the channel's name."; +"lng_edit_channel_status_group" = "Group emoji status"; +"lng_edit_channel_status_about_group" = "Choose a status that will be shown next to the group's name."; "lng_edit_self_title" = "Edit your name"; "lng_confirm_contact_data" = "New Contact"; "lng_add_contact" = "Create"; diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 73026cc88..c9141d065 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -2606,6 +2606,19 @@ void ApiWrap::setGroupStickerSet( _session->data().stickers().notifyUpdated(Data::StickersType::Stickers); } +void ApiWrap::setGroupEmojiSet( + not_null megagroup, + const StickerSetIdentifier &set) { + Expects(megagroup->mgInfo != nullptr); + + megagroup->mgInfo->emojiSet = set; + request(MTPchannels_SetEmojiStickers( + megagroup->inputChannel, + Data::InputStickerSet(set) + )).send(); + _session->data().stickers().notifyUpdated(Data::StickersType::Emoji); +} + std::vector> *ApiWrap::stickersByEmoji( const QString &key) { const auto it = _stickersByEmoji.find(key); diff --git a/Telegram/SourceFiles/apiwrap.h b/Telegram/SourceFiles/apiwrap.h index 192e14f28..615960126 100644 --- a/Telegram/SourceFiles/apiwrap.h +++ b/Telegram/SourceFiles/apiwrap.h @@ -246,6 +246,9 @@ public: void setGroupStickerSet( not_null megagroup, const StickerSetIdentifier &set); + void setGroupEmojiSet( + not_null megagroup, + const StickerSetIdentifier &set); [[nodiscard]] std::vector> *stickersByEmoji( const QString &key); diff --git a/Telegram/SourceFiles/boxes/background_preview_box.cpp b/Telegram/SourceFiles/boxes/background_preview_box.cpp index db72d5690..cae929641 100644 --- a/Telegram/SourceFiles/boxes/background_preview_box.cpp +++ b/Telegram/SourceFiles/boxes/background_preview_box.cpp @@ -708,7 +708,7 @@ void BackgroundPreviewBox::checkLevelForChannel() { return std::optional(); } return std::make_optional(Ui::AskBoostReason{ - Ui::AskBoostWallpaper{ required } + Ui::AskBoostWallpaper{ required, _forPeer->isMegagroup()} }); }, [=] { _forPeerLevelCheck = false; }); } diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp index 15e30cba2..0ab69bf3b 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp @@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/unixtime.h" #include "boxes/peers/replace_boost_box.h" #include "boxes/background_box.h" +#include "boxes/stickers_box.h" #include "chat_helpers/compose/compose_show.h" #include "data/data_changes.h" #include "data/data_channel.h" @@ -557,7 +558,10 @@ void Apply( } const auto reason = [&]() -> Ui::AskBoostReason { if (level < statusRequired) { - return { Ui::AskBoostEmojiStatus{ statusRequired } }; + return { Ui::AskBoostEmojiStatus{ + statusRequired, + peer->isMegagroup() + } }; } else if (level < iconRequired) { return { Ui::AskBoostChannelColor{ iconRequired } }; } @@ -795,7 +799,8 @@ int ColorSelector::resizeGetHeight(int newWidth) { not_null parent, std::shared_ptr show, rpl::producer statusIdValue, - Fn statusIdChosen) { + Fn statusIdChosen, + bool group) { const auto &basicSt = st::settingsButtonNoIcon; const auto ratio = style::DevicePixelRatio(); const auto added = st::normalFont->spacew; @@ -810,7 +815,9 @@ int ColorSelector::resizeGetHeight(int newWidth) { st->padding.setRight(rightPadding); auto result = object_ptr( parent, - tr::lng_edit_channel_status(), + (group + ? tr::lng_edit_channel_status_group() + : tr::lng_edit_channel_status()), *st); const auto raw = result.data(); @@ -901,7 +908,12 @@ void EditPeerColorBox( not_null peer, std::shared_ptr style, std::shared_ptr theme) { - box->setTitle(tr::lng_settings_color_title()); + const auto group = peer->isMegagroup(); + const auto container = box->verticalLayout(); + + box->setTitle(peer->isSelf() + ? tr::lng_settings_color_title() + : tr::lng_edit_channel_color()); box->setWidth(st::boxWideWidth); struct State { @@ -918,52 +930,55 @@ void EditPeerColorBox( state->emojiId = peer->backgroundEmojiId(); state->statusId = peer->emojiStatusId(); - box->addRow(object_ptr( - box, - style, - theme, - peer, - state->index.value(), - state->emojiId.value() - ), {}); - - auto indices = peer->session().api().peerColors().suggestedValue(); - const auto margin = st::settingsColorRadioMargin; - const auto skip = st::settingsColorRadioSkip; - box->addRow( - object_ptr( + if (!group) { + box->addRow(object_ptr( box, style, - std::move(indices), - state->index.current(), - [=](uint8 index) { state->index = index; }), - { margin, skip, margin, skip }); + theme, + peer, + state->index.value(), + state->emojiId.value() + ), {}); - const auto container = box->verticalLayout(); - Ui::AddDividerText(container, peer->isSelf() - ? tr::lng_settings_color_about() - : tr::lng_settings_color_about_channel()); + auto indices = peer->session().api().peerColors().suggestedValue(); + const auto margin = st::settingsColorRadioMargin; + const auto skip = st::settingsColorRadioSkip; + box->addRow( + object_ptr( + box, + style, + std::move(indices), + state->index.current(), + [=](uint8 index) { state->index = index; }), + { margin, skip, margin, skip }); - Ui::AddSkip(container, st::settingsColorSampleSkip); + Ui::AddDividerText(container, peer->isSelf() + ? tr::lng_settings_color_about() + : tr::lng_settings_color_about_channel()); - container->add(CreateEmojiIconButton( - container, - show, - style, - state->index.value(), - state->emojiId.value(), - [=](DocumentId id) { state->emojiId = id; })); + Ui::AddSkip(container, st::settingsColorSampleSkip); - Ui::AddSkip(container, st::settingsColorSampleSkip); - Ui::AddDividerText(container, peer->isSelf() - ? tr::lng_settings_color_emoji_about() - : tr::lng_settings_color_emoji_about_channel()); + container->add(CreateEmojiIconButton( + container, + show, + style, + state->index.value(), + state->emojiId.value(), + [=](DocumentId id) { state->emojiId = id; })); + + Ui::AddSkip(container, st::settingsColorSampleSkip); + Ui::AddDividerText(container, peer->isSelf() + ? tr::lng_settings_color_emoji_about() + : tr::lng_settings_color_emoji_about_channel()); + } if (const auto channel = peer->asChannel()) { Ui::AddSkip(container, st::settingsColorSampleSkip); container->add(object_ptr( container, - tr::lng_edit_channel_wallpaper(), + (group + ? tr::lng_edit_channel_wallpaper_group() + : tr::lng_edit_channel_wallpaper()), st::settingsButtonNoIcon) )->setClickedCallback([=] { const auto usage = ChatHelpers::WindowUsage::PremiumPromo; @@ -973,9 +988,25 @@ void EditPeerColorBox( }); Ui::AddSkip(container, st::settingsColorSampleSkip); - Ui::AddDividerText( - container, - tr::lng_edit_channel_wallpaper_about()); + Ui::AddDividerText(container, group + ? tr::lng_edit_channel_wallpaper_about_group() + : tr::lng_edit_channel_wallpaper_about()); + + if (group) { + Ui::AddSkip(container, st::settingsColorSampleSkip); + + container->add(object_ptr( + container, + tr::lng_group_emoji(), + st::settingsButtonNoIcon) + )->setClickedCallback([=] { + const auto isEmoji = true; + show->showBox(Box(show, channel, isEmoji)); + }); + + Ui::AddSkip(container, st::settingsColorSampleSkip); + Ui::AddDividerText(container, tr::lng_group_emoji_description()); + } // Preload exceptions list. const auto peerPhoto = &channel->session().api().peerPhoto(); @@ -996,10 +1027,13 @@ void EditPeerColorBox( state->statusId = id; state->statusUntil = until; state->statusChanged = true; - })); + }, + group)); Ui::AddSkip(container, st::settingsColorSampleSkip); - Ui::AddDividerText(container, tr::lng_edit_channel_status_about()); + Ui::AddDividerText(container, group + ? tr::lng_edit_channel_status_about_group() + : tr::lng_edit_channel_status_about()); } box->addButton(tr::lng_settings_apply(), [=] { @@ -1024,19 +1058,11 @@ void EditPeerColorBox( }); } -void AddPeerColorButton( - not_null container, - std::shared_ptr show, - not_null peer) { - auto label = peer->isSelf() - ? tr::lng_settings_theme_name_color() - : tr::lng_edit_channel_color(); - const auto button = AddButtonWithIcon( - container, - rpl::duplicate(label), - st::settingsColorButton, - { &st::menuIconChangeColors }); - +void SetupPeerColorSample( + not_null button, + not_null peer, + rpl::producer label, + std::shared_ptr style) { auto colorIndexValue = peer->session().changes().peerFlagsValue( peer, Data::PeerUpdate::Flag::Color @@ -1045,12 +1071,6 @@ void AddPeerColorButton( }); const auto name = peer->shortName(); - const auto style = std::make_shared( - peer->session().colorIndicesValue()); - const auto theme = std::shared_ptr( - Window::Theme::DefaultChatThemeOn(button->lifetime())); - style->apply(theme.get()); - const auto sample = Ui::CreateChild( button.get(), style, @@ -1102,6 +1122,30 @@ void AddPeerColorButton( }, sample->lifetime()); sample->setAttribute(Qt::WA_TransparentForMouseEvents); +} + +void AddPeerColorButton( + not_null container, + std::shared_ptr show, + not_null peer) { + auto label = peer->isSelf() + ? tr::lng_settings_theme_name_color() + : tr::lng_edit_channel_color(); + const auto button = AddButtonWithIcon( + container, + rpl::duplicate(label), + st::settingsColorButton, + { &st::menuIconChangeColors }); + + const auto style = std::make_shared( + peer->session().colorIndicesValue()); + const auto theme = std::shared_ptr( + Window::Theme::DefaultChatThemeOn(button->lifetime())); + style->apply(theme.get()); + + if (!peer->isMegagroup()) { + SetupPeerColorSample(button, peer, rpl::duplicate(label), style); + } button->setClickedCallback([=] { show->show(Box(EditPeerColorBox, show, peer, style, theme)); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 8ae5907e6..7b9abb4c1 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -631,8 +631,9 @@ object_ptr Controller::createStickersEdit() { tr::lng_group_stickers_add(), rpl::single(QString()), //Empty count. [=, controller = _navigation->parentController()] { + const auto isEmoji = false; controller->show( - Box(controller->uiShow(), channel)); + Box(controller->uiShow(), channel, isEmoji)); }, { &st::menuIconStickers }); @@ -1094,8 +1095,8 @@ void Controller::fillManageSection() { const auto canEditStickers = isChannel && channel->canEditStickers(); const auto canDeleteChannel = isChannel && channel->canDelete(); const auto canEditColorIndex = isChannel - && !channel->isMegagroup() - && channel->canEditInformation(); + && (channel->amCreator() + || (channel->adminRights() & ChatAdminRight::ChangeInfo)); const auto canViewOrEditLinkedChat = isChannel && (channel->linkedChat() || (channel->isBroadcast() && channel->canEditInformation())); diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 3f35e9591..2426906e5 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -17,7 +17,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "lang/lang_keys.h" #include "mainwidget.h" #include "mainwindow.h" +#include "ui/boxes/boost_box.h" #include "ui/boxes/confirm_box.h" +#include "boxes/peers/edit_peer_color_box.h" #include "boxes/sticker_set_box.h" #include "apiwrap.h" #include "storage/storage_account.h" @@ -38,6 +40,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/painter.h" #include "ui/unread_badge_paint.h" #include "media/clip/media_clip_reader.h" +#include "main/main_account.h" +#include "main/main_app_config.h" #include "main/main_session.h" #include "styles/style_layers.h" #include "styles/style_boxes.h" @@ -99,7 +103,8 @@ public: Inner( QWidget *parent, std::shared_ptr show, - not_null megagroup); + not_null megagroup, + bool isEmoji); [[nodiscard]] Main::Session &session() const; @@ -108,7 +113,7 @@ public: } void setInnerFocus(); - void saveGroupSet(); + void saveGroupSet(Fn done); void rebuild(bool masks); void updateSize(int newWidth = 0); @@ -221,6 +226,7 @@ private: StickersSetsOrder collectSets(Check check) const; void updateSelected(); + void checkGroupLevel(Fn done); void checkLoadMore(); void updateScrollbarWidth(); @@ -323,6 +329,8 @@ private: int _scrollbar = 0; ChannelData *_megagroupSet = nullptr; + bool _megagroupSetEmoji = false; + bool _checkingGroupLevel = false; StickerSetIdentifier _megagroupSetInput; std::unique_ptr _megagroupSelectedSet; object_ptr _megagroupSetField = { nullptr }; @@ -429,15 +437,16 @@ StickersBox::StickersBox( StickersBox::StickersBox( QWidget*, std::shared_ptr show, - not_null megagroup) + not_null megagroup, + bool isEmoji) : _st(st::stickersRowItem) , _show(std::move(show)) , _session(&_show->session()) , _api(&_session->mtp()) , _section(Section::Installed) , _isMasks(false) -, _isEmoji(false) -, _installed(0, this, _show, megagroup) +, _isEmoji(isEmoji) +, _installed(0, this, _show, megagroup, isEmoji) , _megagroupSet(megagroup) { _installed.widget()->scrollsToY( ) | rpl::start_with_next([=](int y) { @@ -581,7 +590,9 @@ void StickersBox::prepare() { session().local().readArchivedStickers(); } } else { - setTitle(tr::lng_stickers_group_set()); + setTitle(_isEmoji + ? tr::lng_emoji_group_set() + : tr::lng_stickers_group_set()); } } else if (_section == Section::Archived) { requestArchivedSets(); @@ -659,9 +670,11 @@ void StickersBox::prepare() { } if (_megagroupSet) { - addButton( - tr::lng_settings_save(), - [=] { _installed.widget()->saveGroupSet(); closeBox(); }); + addButton(tr::lng_settings_save(), [=] { + _installed.widget()->saveGroupSet(crl::guard(this, [=] { + closeBox(); + })); + }); addButton(tr::lng_cancel(), [=] { closeBox(); }); } else { const auto close = _section == Section::Attached; @@ -1220,7 +1233,8 @@ StickersBox::Inner::Inner( StickersBox::Inner::Inner( QWidget *parent, std::shared_ptr show, - not_null megagroup) + not_null megagroup, + bool isEmoji) : RpWidget(parent) , _st(st::stickersRowItem) , _show(std::move(show)) @@ -1248,19 +1262,30 @@ StickersBox::Inner::Inner( }) , _itemsTop(st::lineWidth) , _megagroupSet(megagroup) -, _megagroupSetInput(_megagroupSet->mgInfo->stickerSet) +, _megagroupSetEmoji(isEmoji) +, _megagroupSetInput(isEmoji + ? _megagroupSet->mgInfo->emojiSet + : _megagroupSet->mgInfo->stickerSet) , _megagroupSetField( this, st::groupStickersField, - rpl::single(u"stickerset"_q), + rpl::single(isEmoji ? u"emojipack"_q : u"stickerset"_q), QString(), _session->createInternalLink(QString())) , _megagroupDivider(this) -, _megagroupSubTitle(this, tr::lng_stickers_group_from_your(tr::now), st::boxTitle) { +, _megagroupSubTitle( + this, + (isEmoji + ? tr::lng_emoji_group_from_your + : tr::lng_stickers_group_from_your)(tr::now), + st::boxTitle) { _megagroupSetField->setLinkPlaceholder( - _session->createInternalLink(u"addstickers/"_q)); + _session->createInternalLink( + isEmoji ? u"addemoji/"_q : u"addstickers/"_q)); _megagroupSetField->setPlaceholderHidden(false); - _megagroupSetAddressChangedTimer.setCallback([this] { handleMegagroupSetAddressChange(); }); + _megagroupSetAddressChangedTimer.setCallback([this] { + handleMegagroupSetAddressChange(); + }); connect( _megagroupSetField, &Ui::MaskedInputField::changed, @@ -1689,7 +1714,9 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null row, int ind } void StickersBox::Inner::mousePressEvent(QMouseEvent *e) { - if (_dragging >= 0) mouseReleaseEvent(e); + if (_dragging >= 0) { + mouseReleaseEvent(e); + } _mouse = e->globalPos(); updateSelected(); @@ -1979,18 +2006,63 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) { setActionDown(-1); } -void StickersBox::Inner::saveGroupSet() { +void StickersBox::Inner::saveGroupSet(Fn done) { Expects(_megagroupSet != nullptr); - auto oldId = _megagroupSet->mgInfo->stickerSet.id; + auto oldId = _megagroupSetEmoji + ? _megagroupSet->mgInfo->emojiSet.id + : _megagroupSet->mgInfo->stickerSet.id; auto newId = _megagroupSetInput.id; - if (newId != oldId) { + if (newId == oldId) { + done(); + } else if (_megagroupSetEmoji) { + checkGroupLevel(done); + } else { session().api().setGroupStickerSet(_megagroupSet, _megagroupSetInput); session().data().stickers().notifyStickerSetInstalled( Data::Stickers::MegagroupSetId); } } +void StickersBox::Inner::checkGroupLevel(Fn done) { + Expects(_megagroupSet != nullptr); + Expects(_megagroupSetEmoji); + + const auto peer = _megagroupSet; + const auto save = [=] { + session().api().setGroupEmojiSet(peer, _megagroupSetInput); + session().data().stickers().notifyEmojiSetInstalled( + Data::Stickers::MegagroupSetId); + done(); + }; + + if (!_megagroupSetInput) { + save(); + } else if (_checkingGroupLevel) { + return; + } + _checkingGroupLevel = true; + + const auto weak = Ui::MakeWeak(this); + CheckBoostLevel(_show, peer, [=](int level) { + if (!weak) { + return std::optional(); + } + _checkingGroupLevel = false; + const auto appConfig = &peer->session().account().appConfig(); + const auto required = appConfig->get( + "group_emoji_stickers_level_min", + 4); + if (level >= required) { + save(); + return std::optional(); + } + return std::make_optional(Ui::AskBoostReason{ + Ui::AskBoostEmojiPack{ required } + }); + }, [=] { _checkingGroupLevel = false; }); +} + void StickersBox::Inner::setRowRemovedBySetId(uint64 setId, bool removed) { const auto index = getRowIndex(setId); if (index >= 0) { @@ -2233,9 +2305,13 @@ void StickersBox::Inner::rebuild(bool masks) { clear(); const auto &order = ([&]() -> const StickersSetsOrder & { if (_section == Section::Installed) { - auto &result = session().data().stickers().setsOrder(); + auto &result = _megagroupSetEmoji + ? session().data().stickers().emojiSetsOrder() + : session().data().stickers().setsOrder(); if (_megagroupSet && result.empty()) { - return session().data().stickers().featuredSetsOrder(); + return _megagroupSetEmoji + ? session().data().stickers().featuredEmojiSetsOrder() + : session().data().stickers().featuredSetsOrder(); } return result; } else if (_section == Section::Masks) { @@ -2252,9 +2328,15 @@ void StickersBox::Inner::rebuild(bool masks) { const auto &sets = session().data().stickers().sets(); if (_megagroupSet) { - auto usingFeatured = session().data().stickers().setsOrder().empty(); + auto usingFeatured = _megagroupSetEmoji + ? session().data().stickers().emojiSetsOrder().empty() + : session().data().stickers().setsOrder().empty(); _megagroupSubTitle->setText(usingFeatured - ? tr::lng_stickers_group_from_featured(tr::now) + ? (_megagroupSetEmoji + ? tr::lng_stickers_group_from_featured(tr::now) + : tr::lng_emoji_group_from_featured(tr::now)) + : _megagroupSetEmoji + ? tr::lng_emoji_group_from_your(tr::now) : tr::lng_stickers_group_from_your(tr::now)); updateControlsGeometry(); } else if (_isInstalledTab) { diff --git a/Telegram/SourceFiles/boxes/stickers_box.h b/Telegram/SourceFiles/boxes/stickers_box.h index 255ed3936..89b31ccf5 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.h +++ b/Telegram/SourceFiles/boxes/stickers_box.h @@ -66,7 +66,8 @@ public: StickersBox( QWidget*, std::shared_ptr show, - not_null megagroup); + not_null megagroup, + bool isEmoji); StickersBox( QWidget*, std::shared_ptr show, diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp index 3675c0483..543ce497d 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.cpp @@ -1767,7 +1767,8 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) { removeSet(sets[button->section].id); } } else if (std::get_if(&pressed)) { - _show->showBox(Box(_show, _megagroupSet)); + const auto isEmoji = false; + _show->showBox(Box(_show, _megagroupSet, isEmoji)); } } } @@ -2617,7 +2618,8 @@ void StickersListWidget::setupSearch() { void StickersListWidget::displaySet(uint64 setId) { if (setId == Data::Stickers::MegagroupSetId) { if (_megagroupSet->canEditStickers()) { - checkHideWithBox(Box(_show, _megagroupSet)); + const auto isEmoji = false; + checkHideWithBox(Box(_show, _megagroupSet, isEmoji)); return; } else if (_megagroupSet->mgInfo->stickerSet.id) { setId = _megagroupSet->mgInfo->stickerSet.id; diff --git a/Telegram/SourceFiles/data/data_changes.h b/Telegram/SourceFiles/data/data_changes.h index 9de11be5b..2c29ef8fc 100644 --- a/Telegram/SourceFiles/data/data_changes.h +++ b/Telegram/SourceFiles/data/data_changes.h @@ -101,13 +101,14 @@ struct PeerUpdate { // For channels ChannelAmIn = (1ULL << 36), StickersSet = (1ULL << 37), - ChannelLinkedChat = (1ULL << 38), - ChannelLocation = (1ULL << 39), - Slowmode = (1ULL << 40), - GroupCall = (1ULL << 41), + EmojiSet = (1ULL << 38), + ChannelLinkedChat = (1ULL << 39), + ChannelLocation = (1ULL << 40), + Slowmode = (1ULL << 41), + GroupCall = (1ULL << 42), // For iteration - LastUsedBit = (1ULL << 41), + LastUsedBit = (1ULL << 42), }; using Flags = base::flags; friend inline constexpr auto is_flag_type(Flag) { return true; } diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index cf9048a5b..831709a18 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -1163,20 +1163,34 @@ void ApplyChannelUpdate( channel->owner().botCommandsChanged(channel); } const auto stickerSet = update.vstickerset(); - const auto set = stickerSet ? &stickerSet->c_stickerSet() : nullptr; - const auto newSetId = (set ? set->vid().v : 0); - const auto oldSetId = channel->mgInfo->stickerSet.id; + const auto sset = stickerSet ? &stickerSet->c_stickerSet() : nullptr; + const auto newStickerSetId = (sset ? sset->vid().v : 0); + const auto oldStickerSetId = channel->mgInfo->stickerSet.id; const auto stickersChanged = (canEditStickers != channel->canEditStickers()) - || (oldSetId != newSetId); - if (oldSetId != newSetId) { + || (oldStickerSetId != newStickerSetId); + if (oldStickerSetId != newStickerSetId) { channel->mgInfo->stickerSet = StickerSetIdentifier{ - .id = set ? set->vid().v : 0, - .accessHash = set ? set->vaccess_hash().v : 0, + .id = sset ? sset->vid().v : 0, + .accessHash = sset ? sset->vaccess_hash().v : 0, }; } if (stickersChanged) { session->changes().peerUpdated(channel, UpdateFlag::StickersSet); } + const auto emojiSet = update.vemojiset(); + const auto eset = emojiSet ? &emojiSet->c_stickerSet() : nullptr; + const auto newEmojiSetId = (eset ? eset->vid().v : 0); + const auto oldEmojiSetId = channel->mgInfo->emojiSet.id; + const auto emojiChanged = (oldEmojiSetId != newEmojiSetId); + if (oldEmojiSetId != newEmojiSetId) { + channel->mgInfo->emojiSet = StickerSetIdentifier{ + .id = eset ? eset->vid().v : 0, + .accessHash = eset ? eset->vaccess_hash().v : 0, + }; + } + if (emojiChanged) { + session->changes().peerUpdated(channel, UpdateFlag::EmojiSet); + } channel->setBoostsUnrestrict( update.vboosts_applied().value_or_empty(), update.vboosts_unrestrict().value_or_empty()); diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index b822edda5..9cdebf5c4 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -125,6 +125,7 @@ public: bool joinedMessageFound = false; bool adminsLoaded = false; StickerSetIdentifier stickerSet; + StickerSetIdentifier emojiSet; enum LastParticipantsStatus { LastParticipantsUpToDate = 0x00, diff --git a/Telegram/SourceFiles/ui/boxes/boost_box.cpp b/Telegram/SourceFiles/ui/boxes/boost_box.cpp index fc374dc30..25cfd75e5 100644 --- a/Telegram/SourceFiles/ui/boxes/boost_box.cpp +++ b/Telegram/SourceFiles/ui/boxes/boost_box.cpp @@ -684,6 +684,8 @@ void AskBoostBox( return tr::lng_boost_channel_title_wallpaper(); }, [&](AskBoostEmojiStatus data) { return tr::lng_boost_channel_title_status(); + }, [&](AskBoostEmojiPack data) { + return tr::lng_boost_group_title_emoji(); }, [&](AskBoostCustomReactions data) { return tr::lng_boost_channel_title_reactions(); }); @@ -694,12 +696,21 @@ void AskBoostBox( rpl::single(float64(data.requiredLevel)), Ui::Text::RichLangValue); }, [&](AskBoostWallpaper data) { - return tr::lng_boost_channel_needs_level_wallpaper( - lt_count, - rpl::single(float64(data.requiredLevel)), - Ui::Text::RichLangValue); + return (data.group + ? tr::lng_boost_group_needs_level_wallpaper + : tr::lng_boost_channel_needs_level_wallpaper)( + lt_count, + rpl::single(float64(data.requiredLevel)), + Ui::Text::RichLangValue); }, [&](AskBoostEmojiStatus data) { - return tr::lng_boost_channel_needs_level_status( + return (data.group + ? tr::lng_boost_group_needs_level_status + : tr::lng_boost_channel_needs_level_status)( + lt_count, + rpl::single(float64(data.requiredLevel)), + Ui::Text::RichLangValue); + }, [&](AskBoostEmojiPack data) { + return tr::lng_boost_group_needs_level_emoji( lt_count, rpl::single(float64(data.requiredLevel)), Ui::Text::RichLangValue); diff --git a/Telegram/SourceFiles/ui/boxes/boost_box.h b/Telegram/SourceFiles/ui/boxes/boost_box.h index 064e697ef..78e046cba 100644 --- a/Telegram/SourceFiles/ui/boxes/boost_box.h +++ b/Telegram/SourceFiles/ui/boxes/boost_box.h @@ -73,10 +73,16 @@ struct AskBoostChannelColor { struct AskBoostWallpaper { int requiredLevel = 0; + bool group = false; }; struct AskBoostEmojiStatus { int requiredLevel = 0; + bool group = false; +}; + +struct AskBoostEmojiPack { + int requiredLevel = 0; }; struct AskBoostCustomReactions { @@ -88,6 +94,7 @@ struct AskBoostReason { AskBoostChannelColor, AskBoostWallpaper, AskBoostEmojiStatus, + AskBoostEmojiPack, AskBoostCustomReactions> data; };