Correctly show premium promo for custom reactions.

This commit is contained in:
John Preston 2022-08-30 10:53:07 +04:00
parent a3c110dafa
commit ebf6cea2f5
8 changed files with 75 additions and 47 deletions

View File

@ -996,7 +996,7 @@ void ReactionPreview::paintEffect(QPainter &p) {
Data::Reactions::Type::Active);
const auto count = ranges::count(list, true, &Data::Reaction::premium);
const auto rows = (count + kReactionsPerRow - 1) / kReactionsPerRow;
const auto inrowmax = (count + rows - 1) / rows;
const auto inrowmax = rows ? ((count + rows - 1) / rows) : 1;
const auto inrowless = (inrowmax * rows - count);
const auto inrowmore = rows - inrowless;
const auto inmaxrows = inrowmore * inrowmax;

View File

@ -455,9 +455,7 @@ void ReactionsSettingsBox(
button->setClickedCallback([=, id = r.id] {
if (premium && !controller->session().premium()) {
ShowPremiumPreviewBox(
controller,
PremiumPreview::Reactions);
ShowPremiumPreviewBox(controller, PremiumPreview::Reactions);
return;
}
checkButton(button);

View File

@ -826,8 +826,11 @@ void EmojiListWidget::paint(
const auto buttonSelected = selectedButton
? (selectedButton->section == info.section)
: false;
const auto titleLeft = (info.premiumRequired
? st().headerLockedLeft
: st().headerLeft) - st().margin.left();
const auto widthForTitle = emojiRight()
- (st().headerLeft - st().margin.left())
- titleLeft
- paintButtonGetWidth(p, info, buttonSelected, clip);
if (info.section > 0 && clip.top() < info.rowsTop) {
p.setFont(st::emojiPanHeaderFont);
@ -840,9 +843,6 @@ void EmojiListWidget::paint(
titleText = st::emojiPanHeaderFont->elided(titleText, widthForTitle);
titleWidth = st::emojiPanHeaderFont->width(titleText);
}
const auto left = (info.premiumRequired
? st().headerLockedLeft
: st().headerLeft) - st().margin.left();
const auto top = info.top + st().headerTop;
if (info.premiumRequired) {
st::emojiPremiumRequired.paint(
@ -851,10 +851,10 @@ void EmojiListWidget::paint(
top,
width());
}
const auto textTop = top + st::emojiPanHeaderFont->ascent;
const auto textBaseline = top + st::emojiPanHeaderFont->ascent;
p.setFont(st::emojiPanHeaderFont);
p.setPen(st::emojiPanHeaderFg);
p.drawText(left, textTop, titleText);
p.drawText(titleLeft, textBaseline, titleText);
}
if (clip.top() + clip.height() > info.rowsTop) {
ensureLoaded(info.section);
@ -1139,7 +1139,18 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
_localSetsManager->install(id);
} else if (_controller) {
_jumpedToPremium.fire({});
Settings::ShowPremium(_controller, u"animated_emoji"_q);
switch (_mode) {
case Mode::Full:
Settings::ShowPremium(_controller, u"animated_emoji"_q);
break;
case Mode::FullReactions:
case Mode::RecentReactions:
Settings::ShowPremium(_controller, u"unique_reactions"_q);
break;
case Mode::EmojiStatus:
Settings::ShowPremium(_controller, u"emoji_status"_q);
break;
}
}
}
}
@ -1679,7 +1690,7 @@ int EmojiListWidget::paintButtonGetWidth(
remove.topLeft() + st::stickerPanRemoveSet.iconPosition,
width());
}
return remove.width();
return emojiRight() - remove.x();
}
const auto canAdd = hasAddButton(info.section);
const auto &button = rightButton(info.section);
@ -1704,7 +1715,7 @@ int EmojiListWidget::paintButtonGetWidth(
+ st::emojiPanButton.textTop
+ st::emojiPanButton.font->ascent),
button.text);
return rect.width();
return emojiRight() - rect.x();
}
bool EmojiListWidget::eventHook(QEvent *e) {

View File

@ -184,18 +184,21 @@ Reactions::Reactions(not_null<Session*> owner)
_repaintItems.remove(item);
}, _lifetime);
rpl::single(rpl::empty) | rpl::then(
_owner->session().mtp().config().updates()
) | rpl::map([=] {
const auto &config = _owner->session().mtp().configValues();
return config.reactionDefaultCustom
? ReactionId{ DocumentId(config.reactionDefaultCustom) }
: ReactionId{ config.reactionDefaultEmoji };
}) | rpl::filter([=](const ReactionId &id) {
return !_saveFaveRequestId;
}) | rpl::start_with_next([=](ReactionId &&id) {
applyFavorite(id);
}, _lifetime);
crl::on_main(&owner->session(), [=] {
// applyFavorite accesses not yet constructed parts of session.
rpl::single(rpl::empty) | rpl::then(
_owner->session().mtp().config().updates()
) | rpl::map([=] {
const auto &config = _owner->session().mtp().configValues();
return config.reactionDefaultCustom
? ReactionId{ DocumentId(config.reactionDefaultCustom) }
: ReactionId{ config.reactionDefaultEmoji };
}) | rpl::filter([=](const ReactionId &id) {
return !_saveFaveRequestId;
}) | rpl::start_with_next([=](ReactionId &&id) {
applyFavorite(id);
}, _lifetime);
});
}
Reactions::~Reactions() = default;

View File

@ -464,11 +464,15 @@ HistoryInner::HistoryInner(
void HistoryInner::reactionChosen(const ChosenReaction &reaction) {
const auto item = session().data().message(reaction.context);
if (!item
|| Window::ShowReactPremiumError(
if (!item) {
return;
} else if (Window::ShowReactPremiumError(
_controller,
item,
reaction.id)) {
if (_menu) {
_menu->hideMenu();
}
return;
}
item->toggleReaction(reaction.id, HistoryItem::ReactionSource::Selector);
@ -1943,9 +1947,9 @@ void HistoryInner::toggleFavoriteReaction(not_null<Element*> view) const {
const auto item = view->data();
const auto favorite = session().data().reactions().favoriteId();
if (!ranges::contains(
Data::LookupPossibleReactions(item).recent,
favorite,
&Data::Reaction::id)
Data::LookupPossibleReactions(item).recent,
favorite,
&Data::Reaction::id)
|| Window::ShowReactPremiumError(_controller, item, favorite)) {
return;
} else if (!ranges::contains(item->chosenReactions(), favorite)) {

View File

@ -357,11 +357,15 @@ ListWidget::ListWidget(
_reactionsManager->updateButton({});
const auto item = session().data().message(reaction.context);
if (!item
|| Window::ShowReactPremiumError(
_controller,
item,
reaction.id)) {
if (!item) {
return;
} else if (Window::ShowReactPremiumError(
_controller,
item,
reaction.id)) {
if (_menu) {
_menu->hideMenu();
}
return;
}
item->toggleReaction(

View File

@ -19,7 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/emoji_list_widget.h"
#include "chat_helpers/stickers_list_footer.h"
#include "window/window_session_controller.h"
#include "settings/settings_premium.h"
#include "boxes/premium_preview_box.h"
#include "mainwidget.h"
#include "apiwrap.h"
#include "base/call_delayed.h"
@ -515,7 +515,14 @@ void Selector::expand() {
}
_expandScheduled = true;
const auto parent = parentWidget()->geometry();
const auto additionalBottom = parent.height() - y() - height();
const auto extents = extentsForShadow();
const auto heightLimit = _reactions.customAllowed
? st::emojiPanMaxHeight
: minimalHeight();
const auto willBeHeight = std::min(
parent.height() - y(),
extents.top() + heightLimit + extents.bottom());
const auto additionalBottom = willBeHeight - height();
const auto additional = _specialExpandTopSkip + additionalBottom;
const auto strong = _parentController.get();
if (additionalBottom < 0 || additional <= 0 || !strong) {
@ -627,9 +634,14 @@ void Selector::createList(not_null<Window::SessionController*> controller) {
})
).data();
_list->customChosen(
) | rpl::start_with_next([=](const TabbedSelector::FileChosen &chosen) {
const auto id = DocumentId{ chosen.document->id };
rpl::merge(
_list->customChosen(
) | rpl::map([=](const TabbedSelector::FileChosen &chosen) {
return chosen.document;
}),
_list->premiumChosen()
) | rpl::start_with_next([=](not_null<DocumentData*> document) {
const auto id = DocumentId{ document->id };
const auto i = defaultReactionIds.find(id);
if (i != end(defaultReactionIds)) {
_chosen.fire({ .id = { i->second } });
@ -638,12 +650,6 @@ void Selector::createList(not_null<Window::SessionController*> controller) {
}
}, _list->lifetime());
_list->premiumChosen(
) | rpl::start_with_next([=] {
_jumpedToPremium();
Settings::ShowPremium(controller, u"animated_emoji"_q);
}, _list->lifetime());
_list->jumpedToPremium(
) | rpl::start_with_next(_jumpedToPremium, _list->lifetime());

View File

@ -375,7 +375,9 @@ bool ShowReactPremiumError(
Data::Reactions::Type::Active);
const auto i = ranges::find(list, id, &Data::Reaction::id);
if (i == end(list) || !i->premium) {
return false;
if (!id.custom()) {
return false;
}
}
ShowPremiumPreviewBox(
controller,