Show premium stickers lock icon.

This commit is contained in:
John Preston 2022-05-20 18:57:01 +04:00
parent 5cd065ef6b
commit 853cafe195
19 changed files with 137 additions and 41 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -345,7 +345,7 @@ void EditCaptionBox::setupEditEventHandler() {
}
return true;
};
const auto premium = _controller->session().user()->isPremium();
const auto premium = _controller->session().premium();
auto list = Storage::PreparedFileFromFilesDialog(
std::move(result),
checkResult,
@ -524,7 +524,7 @@ void EditCaptionBox::updateEmojiPanelGeometry() {
}
bool EditCaptionBox::fileFromClipboard(not_null<const QMimeData*> data) {
const auto premium = _controller->session().user()->isPremium();
const auto premium = _controller->session().premium();
return setPreparedList(ListFromMimeData(data, premium));
}

View File

@ -104,7 +104,7 @@ private:
}
[[nodiscard]] int Limit(not_null<Main::Session*> session) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
return Limit(session,
(premium
? "dialog_filters_chats_limit_premium"

View File

@ -454,7 +454,7 @@ void SimplePinsLimitBox(
int limitDefault,
const QString &keyPremium,
int limitPremium) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
const auto defaultLimit = Limit(session, keyDefault, limitDefault);
const auto premiumLimit = Limit(session, keyPremium, limitPremium);
@ -489,7 +489,7 @@ void SimplePinsLimitBox(
void ChannelsLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
const auto defaultLimit = Limit(session, "channels_limit_default", 500);
const auto premiumLimit = Limit(session, "channels_limit_premium", 1000);
@ -574,7 +574,7 @@ void PublicLinksLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Window::SessionNavigation*> navigation) {
const auto session = &navigation->session();
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
const auto defaultLimit = Limit(
session,
@ -639,7 +639,7 @@ void PublicLinksLimitBox(
void FilterChatsLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
const auto defaultLimit = Limit(
session,
@ -679,7 +679,7 @@ void FilterChatsLimitBox(
void FiltersLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
const auto defaultLimit = Limit(
session,
@ -754,7 +754,7 @@ void PinsLimitBox(
void CaptionLimitBox(
not_null<Ui::GenericBox*> box,
not_null<Main::Session*> session) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
const auto defaultLimit = Limit(
session,
@ -795,7 +795,7 @@ void CaptionLimitReachedBox(
.text = tr::lng_caption_limit_reached(tr::now, lt_count, remove),
.inform = true,
});
if (!session->user()->isPremium()) {
if (!session->premium()) {
box->addLeftButton(tr::lng_limits_increase(), [=] {
box->getDelegate()->showBox(
Box(CaptionLimitBox, session),
@ -821,7 +821,7 @@ int CurrentPremiumLimit(
int limitDefault,
const QString &keyPremium,
int limitPremium) {
const auto premium = session->user()->isPremium();
const auto premium = session->premium();
return AppConfigLimit(
session,
premium ? keyPremium : keyDefault,

View File

@ -447,7 +447,7 @@ void ReactionsSettingsBox(
&button->lifetime());
button->setClickedCallback([=, emoji = r.emoji] {
if (premium && !controller->session().user()->isPremium()) {
if (premium && !controller->session().premium()) {
Settings::ShowPremium(&controller->session());
return;
}

View File

@ -404,7 +404,7 @@ void SendFilesBox::openDialogToAddFileToAlbum() {
return true;
};
const auto callback = [=](FileDialog::OpenResult &&result) {
const auto premium = _controller->session().user()->isPremium();
const auto premium = _controller->session().premium();
FileDialogCallback(
std::move(result),
checkResult,
@ -575,7 +575,7 @@ void SendFilesBox::pushBlock(int from, int till) {
return true;
};
const auto callback = [=](FileDialog::OpenResult &&result) {
const auto premium = _controller->session().user()->isPremium();
const auto premium = _controller->session().premium();
FileDialogCallback(
std::move(result),
checkResult,
@ -773,7 +773,7 @@ bool SendFilesBox::canAddFiles(not_null<const QMimeData*> data) const {
}
bool SendFilesBox::addFiles(not_null<const QMimeData*> data) {
const auto premium = _controller->session().user()->isPremium();
const auto premium = _controller->session().premium();
auto list = [&] {
const auto urls = data->hasUrls() ? data->urls() : QList<QUrl>();
auto result = CanAddUrls(urls)

View File

@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "ui/chat/chat_theme.h"
#include "ui/layers/generic_box.h"
#include "ui/effects/premium_graphics.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/gradient_round_button.h"
#include "ui/wrap/padding_wrap.h"
@ -149,11 +150,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
[[nodiscard]] object_ptr<Ui::AbstractButton> CreatePremiumButton(
QWidget *parent) {
return CreateGradientButton(parent, {
{ 0., st::premiumButtonBg1->c },
{ 0.6, st::premiumButtonBg2->c },
{ 1., st::premiumButtonBg3->c },
});
return CreateGradientButton(parent, Ui::Premium::ButtonGradientStops());
}
[[nodiscard]] object_ptr<Ui::AbstractButton> CreateUnlockButton(
@ -167,6 +164,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
result.data(),
tr::lng_sticker_premium_button(),
st::premiumPreviewButtonLabel);
label->setAttribute(Qt::WA_TransparentForMouseEvents);
rpl::combine(
result->widthValue(),
label->widthValue()

View File

@ -298,3 +298,5 @@ premiumPreviewButtonLabel: FlatLabel(defaultFlatLabel) {
textFg: premiumButtonFg;
style: semiboldTextStyle;
}
stickersPremiumLock: icon{{ "emoji/premium_lock", premiumButtonFg }};

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "data/data_cloud_file.h"
#include "data/data_changes.h"
#include "data/data_peer_values.h"
#include "menu/menu_send.h" // SendMenu::FillSendMenu
#include "chat_helpers/stickers_lottie.h"
#include "ui/widgets/buttons.h"
@ -21,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h"
#include "ui/effects/ripple_animation.h"
#include "ui/effects/path_shift_gradient.h"
#include "ui/effects/premium_graphics.h"
#include "ui/image/image.h"
#include "ui/cached_round_corners.h"
#include "lottie/lottie_multi_player.h"
@ -56,6 +58,7 @@ constexpr auto kPreloadOfficialPages = 4;
constexpr auto kOfficialLoadLimit = 40;
constexpr auto kMinRepaintDelay = crl::time(33);
constexpr auto kMinAfterScrollDelay = crl::time(33);
constexpr auto kPremiumLockedOpacity = 0.5;
using Data::StickersSet;
using Data::StickersPack;
@ -1176,6 +1179,17 @@ StickersListWidget::StickersListWidget(
) | rpl::skip(1) | rpl::map_to(
TabbedSelector::Action::Update
) | rpl::start_to_stream(_choosingUpdated, lifetime());
style::PaletteChanged(
) | rpl::start_with_next([=] {
_premiumLock = QImage();
}, lifetime());
Data::AmPremiumValue(
&session()
) | rpl::start_with_next([=](bool premium) {
refreshStickers();
}, lifetime());
}
Main::Session &StickersListWidget::session() const {
@ -2276,6 +2290,7 @@ void StickersListWidget::paintSticker(
return;
}
const auto locked = document->isPremiumSticker() && !session().premium();
const auto isLottie = document->sticker()->isLottie();
const auto isWebm = document->sticker()->isWebm();
if (isLottie
@ -2302,6 +2317,9 @@ void StickersListWidget::paintSticker(
(_singleSize.width() - size.width()) / 2,
(_singleSize.height() - size.height()) / 2);
if (locked) {
p.setOpacity(kPremiumLockedOpacity);
}
if (sticker.lottie && sticker.lottie->ready()) {
auto request = Lottie::FrameRequest();
request.box = boundingBoxSize() * cIntRetinaFactor();
@ -2341,6 +2359,7 @@ void StickersListWidget::paintSticker(
sticker.savedFrameFor = _singleSize;
}
} else {
p.setOpacity(1.);
PaintStickerThumbnailPath(
p,
media.get(),
@ -2358,16 +2377,40 @@ void StickersListWidget::paintSticker(
p.setOpacity(1.);
}
if (document->isPremiumSticker()) {
if (locked) {
p.setOpacity(1.);
validatePremiumLock();
const auto factor = style::DevicePixelRatio();
const auto point = pos
+ QPoint(
_singleSize.width() - st::stickerPanDeleteIconBg.width(),
_singleSize.height() - st::stickerPanDeleteIconBg.height());
st::stickerPanDeleteIconBg.paint(p, point, width());
st::stickerPanDeleteIconFg.paint(p, point, width());
_singleSize.width() - (_premiumLock.width() / factor),
_singleSize.height() - (_premiumLock.height() / factor));
p.drawImage(point, _premiumLock);
}
}
void StickersListWidget::validatePremiumLock() {
if (!_premiumLock.isNull()) {
return;
}
const auto factor = style::DevicePixelRatio();
const auto size = st::stickersPremiumLock.size();
_premiumLock = QImage(
size * factor,
QImage::Format_ARGB32_Premultiplied);
_premiumLock.setDevicePixelRatio(factor);
auto p = QPainter(&_premiumLock);
auto gradient = QLinearGradient(
QPoint(0, size.height()),
QPoint(size.width(), 0));
gradient.setStops(Ui::Premium::LockGradientStops());
p.fillRect(QRect(QPoint(), size), gradient);
st::stickersPremiumLock.paint(p, 0, 0, size.width());
p.end();
_premiumLock = Images::Circle(std::move(_premiumLock));
}
int StickersListWidget::stickersRight() const {
return stickersLeft() + (_columnCount * _singleSize.width());
}
@ -2991,7 +3034,7 @@ bool StickersListWidget::appendSet(
PrepareStickers((set->stickers.empty() && externalLayout)
? set->covers
: set->stickers));
if (!externalLayout && _premiumsIndex >= 0) {
if (!externalLayout && _premiumsIndex >= 0 && session().premium()) {
for (const auto &sticker : to.back().stickers) {
const auto document = sticker.document;
if (document->isPremiumSticker()) {

View File

@ -330,6 +330,7 @@ private:
void addSearchRow(not_null<Data::StickersSet*> set);
void showPreview();
void validatePremiumLock();
Ui::MessageSendingAnimationFrom messageSentAnimationInfo(
int section,
@ -390,6 +391,8 @@ private:
base::Timer _previewTimer;
bool _previewShown = false;
QImage _premiumLock;
std::map<QString, std::vector<uint64>> _searchCache;
std::vector<std::pair<uint64, QStringList>> _searchIndex;
base::Timer _searchRequestTimer;

View File

@ -94,18 +94,25 @@ void EmojiInteractions::play(
void EmojiInteractions::playPremiumEffect(
not_null<const Element*> view,
Element *replacing) {
const auto already = ranges::contains(_plays, view, &Play::view);
if (replacing) {
const auto i = ranges::find(_plays, replacing, &Play::view);
if (i != end(_plays)) {
//if (i->premium) {
// replacing->externalLottieProgressing(false);
//}
i->view = view;
if (already) {
_plays.erase(i);
} else {
i->view = view;
}
//if (i->premium) {
// view->externalLottieProgressing(true);
//}
return;
}
} else if (already) {
return;
}
if (const auto media = view->media()) {
if (const auto document = media->getDocument()) {

View File

@ -255,6 +255,7 @@ void Sticker::paintLottie(
_lottieOncePlayed = true;
_parent->delegate()->elementStartStickerLoop(_parent);
}
checkPremiumEffectStart();
}
bool Sticker::paintPixmap(
@ -362,7 +363,16 @@ void Sticker::refreshLink() {
}
});
} else if (sticker && sticker->set) {
_link = ShowSetHandler(_data);
if (_data->isPremiumSticker()) {
const auto weak = base::make_weak(this);
_link = std::make_shared<LambdaClickHandler>([weak] {
if (const auto that = weak.get()) {
that->premiumStickerClicked();
}
});
} else {
_link = ShowSetHandler(_data);
}
} else if (sticker
&& (_data->dimensions.width() > kStickerSideSize
|| _data->dimensions.height() > kStickerSideSize)
@ -388,6 +398,11 @@ void Sticker::emojiStickerClicked() {
_parent->history()->owner().requestViewRepaint(_parent);
}
void Sticker::premiumStickerClicked() {
_premiumEffectPlayed = false;
_parent->history()->owner().requestViewRepaint(_parent);
}
void Sticker::ensureDataMediaCreated() const {
if (_dataMedia) {
return;
@ -423,12 +438,15 @@ void Sticker::setupLottie() {
ChatHelpers::StickerLottieSize::MessageHistory,
size() * style::DevicePixelRatio(),
Lottie::Quality::High);
if (_data->isPremiumSticker()
&& !_premiumEffectPlayed) {
checkPremiumEffectStart();
lottieCreated();
}
void Sticker::checkPremiumEffectStart() {
if (!_premiumEffectPlayed && _data->isPremiumSticker()) {
_premiumEffectPlayed = true;
_parent->delegate()->elementStartPremium(_parent, nullptr);
}
lottieCreated();
}
void Sticker::lottieCreated() {

View File

@ -100,6 +100,8 @@ private:
void lottieCreated();
void unloadLottie();
void emojiStickerClicked();
void premiumStickerClicked();
void checkPremiumEffectStart();
//bool markFramesTillExternal();
const not_null<Element*> _parent;

View File

@ -218,6 +218,10 @@ rpl::producer<> Session::downloaderTaskFinished() const {
return downloader().taskFinished();
}
bool Session::premium() const {
return _user->isPremium();
}
uint64 Session::uniqueId() const {
// See also Account::willHaveSessionUniqueId.
return userId().bare

View File

@ -80,6 +80,7 @@ public:
[[nodiscard]] Domain &domain() const;
[[nodiscard]] Storage::Domain &domainLocal() const;
[[nodiscard]] bool premium() const;
[[nodiscard]] uint64 uniqueId() const; // userId() with TestDC shift.
[[nodiscard]] UserId userId() const;
[[nodiscard]] PeerId userPeerId() const;

View File

@ -29,15 +29,6 @@ constexpr auto kStepBeforeDeflection = 0.75;
constexpr auto kStepAfterDeflection = kStepBeforeDeflection
+ (1. - kStepBeforeDeflection) / 2.;
[[nodiscard]] QGradientStops GradientStops() {
return QGradientStops{
QGradientStop(0.0, st::premiumButtonBg1->c),
QGradientStop(.25, st::premiumButtonBg1->c),
QGradientStop(.85, st::premiumButtonBg2->c),
QGradientStop(1.0, st::premiumButtonBg3->c),
};
}
[[nodiscard]] QLinearGradient ComputeGradient(
not_null<QWidget*> content,
int left,
@ -46,7 +37,7 @@ constexpr auto kStepAfterDeflection = kStepBeforeDeflection
// Take a full width of parent box without paddings.
const auto fullGradientWidth = content->parentWidget()->width();
auto fullGradient = QLinearGradient(0, 0, fullGradientWidth, 0);
fullGradient.setStops(GradientStops());
fullGradient.setStops(ButtonGradientStops());
auto gradient = QLinearGradient(0, 0, width, 0);
const auto fullFinal = float64(fullGradient.finalStop().x());
@ -506,5 +497,26 @@ void AddLimitRow(not_null<Ui::VerticalLayout*> parent, int max) {
st::boxRowPadding);
}
QGradientStops LimitGradientStops() {
return {
{ 0.0, st::premiumButtonBg1->c },
{ .25, st::premiumButtonBg1->c },
{ .85, st::premiumButtonBg2->c },
{ 1.0, st::premiumButtonBg3->c },
};
}
QGradientStops ButtonGradientStops() {
return {
{ 0., st::premiumButtonBg1->c },
{ 0.6, st::premiumButtonBg2->c },
{ 1., st::premiumButtonBg3->c },
};
}
QGradientStops LockGradientStops() {
return ButtonGradientStops();
}
} // namespace Premium
} // namespace Ui

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtGui/QBrush>
namespace tr {
template <typename ...>
struct phrase;
@ -31,5 +33,9 @@ void AddBubbleRow(
void AddLimitRow(not_null<Ui::VerticalLayout*> parent, int max);
[[nodiscard]] QGradientStops LimitGradientStops();
[[nodiscard]] QGradientStops ButtonGradientStops();
[[nodiscard]] QGradientStops LockGradientStops();
} // namespace Premium
} // namespace Ui