mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show outline for premium emoji packs.
This commit is contained in:
parent
3ccc567e04
commit
2524b9a4c6
4 changed files with 96 additions and 21 deletions
|
@ -1484,6 +1484,8 @@ void PreviewBox(
|
||||||
? tr::lng_premium_unlock_reactions()
|
? tr::lng_premium_unlock_reactions()
|
||||||
: (section == PremiumPreview::Stickers)
|
: (section == PremiumPreview::Stickers)
|
||||||
? tr::lng_premium_unlock_stickers()
|
? tr::lng_premium_unlock_stickers()
|
||||||
|
: (section == PremiumPreview::AnimatedEmoji)
|
||||||
|
? tr::lng_premium_unlock_emoji()
|
||||||
: tr::lng_premium_more_about();
|
: tr::lng_premium_more_about();
|
||||||
}) | rpl::flatten_latest();
|
}) | rpl::flatten_latest();
|
||||||
auto button = descriptor.fromSettings
|
auto button = descriptor.fromSettings
|
||||||
|
|
|
@ -181,6 +181,7 @@ emojiSwitchEmoji: icon {{ "emoji/emoji_switch-flip_horizontal", emojiSwitchColor
|
||||||
|
|
||||||
emojiIconPadding: 7px;
|
emojiIconPadding: 7px;
|
||||||
emojiIconSelectSkip: 3px;
|
emojiIconSelectSkip: 3px;
|
||||||
|
emojiPremiumRequired: icon{{ "emoji/premium_lock", windowSubTextFg }};
|
||||||
|
|
||||||
hashtagClose: IconButton {
|
hashtagClose: IconButton {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
|
|
|
@ -16,10 +16,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
#include "boxes/sticker_set_box.h"
|
#include "boxes/sticker_set_box.h"
|
||||||
|
#include "boxes/premium_preview_box.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "layout/layout_position.h"
|
#include "layout/layout_position.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_peer_values.h"
|
||||||
#include "data/stickers/data_stickers.h"
|
#include "data/stickers/data_stickers.h"
|
||||||
#include "data/stickers/data_custom_emoji.h"
|
#include "data/stickers/data_custom_emoji.h"
|
||||||
#include "chat_helpers/stickers_list_widget.h"
|
#include "chat_helpers/stickers_list_widget.h"
|
||||||
|
@ -455,6 +457,12 @@ EmojiListWidget::EmojiListWidget(
|
||||||
refreshCustom();
|
refreshCustom();
|
||||||
resizeToWidth(width());
|
resizeToWidth(width());
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
Data::AmPremiumValue(
|
||||||
|
&controller->session()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
update();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiListWidget::~EmojiListWidget() {
|
EmojiListWidget::~EmojiListWidget() {
|
||||||
|
@ -617,10 +625,19 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
||||||
|
|
||||||
auto i = 0;
|
auto i = 0;
|
||||||
auto info = SectionInfo();
|
auto info = SectionInfo();
|
||||||
|
const auto session = &controller()->session();
|
||||||
|
const auto premiumMayBeBought = !session->premium()
|
||||||
|
&& session->premiumPossible();
|
||||||
const auto next = [&] {
|
const auto next = [&] {
|
||||||
|
const auto shift = (info.premiumRequired ? st::emojiPanPadding : 0);
|
||||||
info.rowsCount = (info.count + _columnCount - 1) / _columnCount;
|
info.rowsCount = (info.count + _columnCount - 1) / _columnCount;
|
||||||
info.rowsTop = info.top + (i == 0 ? st::emojiPanPadding : st::emojiPanHeader);
|
info.rowsTop = info.top
|
||||||
info.rowsBottom = info.rowsTop + info.rowsCount * _singleSize.height();
|
+ (i == 0 ? st::emojiPanPadding : st::emojiPanHeader)
|
||||||
|
- shift;
|
||||||
|
info.rowsBottom = info.rowsTop
|
||||||
|
+ shift
|
||||||
|
+ (info.rowsCount * _singleSize.height())
|
||||||
|
+ st::roundRadiusSmall;
|
||||||
if (!callback(info)) {
|
if (!callback(info)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -636,6 +653,7 @@ bool EmojiListWidget::enumerateSections(Callback callback) const {
|
||||||
}
|
}
|
||||||
for (auto §ion : _custom) {
|
for (auto §ion : _custom) {
|
||||||
info.section = i++;
|
info.section = i++;
|
||||||
|
info.premiumRequired = section.premium && premiumMayBeBought;
|
||||||
info.count = int(section.list.size());
|
info.count = int(section.list.size());
|
||||||
if (!next()) {
|
if (!next()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -775,17 +793,17 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
} else if (r.top() + r.height() <= info.top) {
|
} else if (r.top() + r.height() <= info.top) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (info.section > 0 && r.top() < info.rowsTop) {
|
if (info.premiumRequired) {
|
||||||
p.setFont(st::emojiPanHeaderFont);
|
drawPremiumRect(p, info);
|
||||||
p.setPen(st::emojiPanHeaderFg);
|
}
|
||||||
auto titleText = (info.section < kEmojiSectionCount)
|
auto widthForTitle = emojiRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
||||||
? ChatHelpers::EmojiCategoryTitle(info.section)(tr::now)
|
const auto skip = st::roundRadiusSmall;
|
||||||
: _custom[info.section - kEmojiSectionCount].title;
|
if (hasRemoveButton(info.section)) {
|
||||||
auto titleWidth = st::stickersTrendingHeaderFont->width(titleText);
|
auto &custom = _custom[info.section - kEmojiSectionCount];
|
||||||
auto widthForTitle = emojiRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
auto remove = removeButtonRect(info.section);
|
||||||
if (hasRemoveButton(info.section)) {
|
auto expanded = remove.marginsAdded({ skip, 0, skip, 0 });
|
||||||
auto &custom = _custom[info.section - kEmojiSectionCount];
|
if (expanded.intersects(r)) {
|
||||||
auto remove = removeButtonRect(info.section);
|
p.fillRect(expanded, st::emojiPanBg);
|
||||||
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
||||||
if (custom.ripple) {
|
if (custom.ripple) {
|
||||||
custom.ripple->paint(p, remove.x() + st::stickerPanRemoveSet.rippleAreaPosition.x(), remove.y() + st::stickerPanRemoveSet.rippleAreaPosition.y(), width());
|
custom.ripple->paint(p, remove.x() + st::stickerPanRemoveSet.rippleAreaPosition.x(), remove.y() + st::stickerPanRemoveSet.rippleAreaPosition.y(), width());
|
||||||
|
@ -794,16 +812,35 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(selected ? st::stickerPanRemoveSet.iconOver : st::stickerPanRemoveSet.icon).paint(p, remove.topLeft() + st::stickerPanRemoveSet.iconPosition, width());
|
(selected ? st::stickerPanRemoveSet.iconOver : st::stickerPanRemoveSet.icon).paint(p, remove.topLeft() + st::stickerPanRemoveSet.iconPosition, width());
|
||||||
|
|
||||||
widthForTitle -= remove.width();
|
|
||||||
}
|
}
|
||||||
|
widthForTitle -= remove.width();
|
||||||
|
}
|
||||||
|
if (info.section > 0 && r.top() < info.rowsTop) {
|
||||||
|
p.setFont(st::emojiPanHeaderFont);
|
||||||
|
p.setPen(st::emojiPanHeaderFg);
|
||||||
|
auto titleText = (info.section < kEmojiSectionCount)
|
||||||
|
? ChatHelpers::EmojiCategoryTitle(info.section)(tr::now)
|
||||||
|
: _custom[info.section - kEmojiSectionCount].title;
|
||||||
|
auto titleWidth = st::emojiPanHeaderFont->width(titleText);
|
||||||
if (titleWidth > widthForTitle) {
|
if (titleWidth > widthForTitle) {
|
||||||
titleText = st::stickersTrendingHeaderFont->elided(titleText, widthForTitle);
|
titleText = st::emojiPanHeaderFont->elided(titleText, widthForTitle);
|
||||||
titleWidth = st::stickersTrendingHeaderFont->width(titleText);
|
titleWidth = st::emojiPanHeaderFont->width(titleText);
|
||||||
|
}
|
||||||
|
auto left = st::emojiPanHeaderLeft - st::roundRadiusSmall;
|
||||||
|
const auto top = info.top + st::emojiPanHeaderTop;
|
||||||
|
if (info.premiumRequired) {
|
||||||
|
p.fillRect(
|
||||||
|
left - skip,
|
||||||
|
top - skip,
|
||||||
|
titleWidth + st::emojiPremiumRequired.width() + skip,
|
||||||
|
st::emojiPanHeaderFont->height + 2 * skip,
|
||||||
|
st::emojiPanBg);
|
||||||
|
st::emojiPremiumRequired.paint(p, left - skip, top, width());
|
||||||
|
left += st::emojiPremiumRequired.width() - skip;
|
||||||
}
|
}
|
||||||
p.setFont(st::emojiPanHeaderFont);
|
p.setFont(st::emojiPanHeaderFont);
|
||||||
p.setPen(st::emojiPanHeaderFg);
|
p.setPen(st::emojiPanHeaderFg);
|
||||||
p.drawTextLeft(st::emojiPanHeaderLeft - st::roundRadiusSmall, info.top + st::emojiPanHeaderTop, width(), titleText, titleWidth);
|
p.drawTextLeft(left, top, width(), titleText, titleWidth);
|
||||||
}
|
}
|
||||||
if (r.top() + r.height() > info.rowsTop) {
|
if (r.top() + r.height() > info.rowsTop) {
|
||||||
ensureLoaded(info.section);
|
ensureLoaded(info.section);
|
||||||
|
@ -823,7 +860,7 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
&& state == _pickerSelected);
|
&& state == _pickerSelected);
|
||||||
|
|
||||||
auto w = QPoint(_rowsLeft + j * _singleSize.width(), info.rowsTop + i * _singleSize.height());
|
auto w = QPoint(_rowsLeft + j * _singleSize.width(), info.rowsTop + i * _singleSize.height());
|
||||||
if (selected) {
|
if (selected && !info.premiumRequired) {
|
||||||
auto tl = w;
|
auto tl = w;
|
||||||
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
if (rtl()) tl.setX(width() - tl.x() - _singleSize.width());
|
||||||
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
Ui::FillRoundRect(p, QRect(tl, _singleSize), st::emojiPanHover, Ui::StickerHoverCorners);
|
||||||
|
@ -843,6 +880,24 @@ void EmojiListWidget::paintEvent(QPaintEvent *e) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::drawPremiumRect(QPainter &p, const SectionInfo &info) {
|
||||||
|
auto pen = st::windowSubTextFg->p;
|
||||||
|
pen.setWidthF(style::ConvertScale(2.));
|
||||||
|
pen.setDashPattern({ 3, 5 });
|
||||||
|
pen.setDashOffset(2);
|
||||||
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
|
p.setPen(pen);
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
|
const auto radius = st::roundRadiusLarge;
|
||||||
|
const auto titleTop = info.top + st::emojiPanHeaderTop;
|
||||||
|
const auto left = _rowsLeft;
|
||||||
|
const auto top = titleTop + st::emojiPanHeaderFont->height / 2;
|
||||||
|
const auto width = _columnCount * _singleSize.width();
|
||||||
|
const auto height = info.rowsBottom - top - st::roundRadiusSmall;
|
||||||
|
p.drawRoundedRect(left, top, width, height, radius, radius);
|
||||||
|
}
|
||||||
|
|
||||||
void EmojiListWidget::drawRecent(
|
void EmojiListWidget::drawRecent(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
|
@ -1025,6 +1080,12 @@ void EmojiListWidget::selectEmoji(EmojiPtr emoji) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::selectCustom(not_null<DocumentData*> document) {
|
void EmojiListWidget::selectCustom(not_null<DocumentData*> document) {
|
||||||
|
if (document->isPremiumEmoji() && !document->session().premium()) {
|
||||||
|
ShowPremiumPreviewBox(
|
||||||
|
controller(),
|
||||||
|
PremiumPreview::AnimatedEmoji);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Core::App().settings().incrementRecentEmoji({ document->id });
|
Core::App().settings().incrementRecentEmoji({ document->id });
|
||||||
_customChosen.fire({ .document = document });
|
_customChosen.fire({ .document = document });
|
||||||
}
|
}
|
||||||
|
@ -1071,7 +1132,8 @@ bool EmojiListWidget::hasRemoveButton(int index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect EmojiListWidget::removeButtonRect(int index) const {
|
QRect EmojiListWidget::removeButtonRect(int index) const {
|
||||||
auto buttonw = st::stickerPanRemoveSet.width;
|
auto buttonw = st::stickerPanRemoveSet.rippleAreaPosition.x()
|
||||||
|
+ st::stickerPanRemoveSet.rippleAreaSize;
|
||||||
auto buttonh = st::stickerPanRemoveSet.height;
|
auto buttonh = st::stickerPanRemoveSet.height;
|
||||||
auto buttonx = emojiRight() - buttonw;
|
auto buttonx = emojiRight() - buttonw;
|
||||||
auto buttony = sectionInfo(index).top + (st::emojiPanHeader - buttonh) / 2;
|
auto buttony = sectionInfo(index).top + (st::emojiPanHeader - buttonh) / 2;
|
||||||
|
@ -1223,6 +1285,7 @@ void EmojiListWidget::refreshCustom() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
auto premium = false;
|
||||||
auto set = std::vector<CustomOne>();
|
auto set = std::vector<CustomOne>();
|
||||||
set.reserve(list.size());
|
set.reserve(list.size());
|
||||||
for (const auto document : list) {
|
for (const auto document : list) {
|
||||||
|
@ -1231,14 +1294,21 @@ void EmojiListWidget::refreshCustom() {
|
||||||
.instance = resolveCustomInstance(document, setId),
|
.instance = resolveCustomInstance(document, setId),
|
||||||
.document = document,
|
.document = document,
|
||||||
});
|
});
|
||||||
|
if (document->isPremiumEmoji()) {
|
||||||
|
premium = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (premium && !controller()->session().premiumPossible()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
_custom.push_back({
|
_custom.push_back({
|
||||||
.id = setId,
|
.id = setId,
|
||||||
.set = it->second.get(),
|
.set = it->second.get(),
|
||||||
.thumbnailDocument = it->second->lookupThumbnailDocument(),
|
.thumbnailDocument = it->second->lookupThumbnailDocument(),
|
||||||
.title = it->second->title,
|
.title = it->second->title,
|
||||||
.list = std::move(set),
|
.list = std::move(set),
|
||||||
|
.premium = premium,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_footer->refreshIcons(
|
_footer->refreshIcons(
|
||||||
|
@ -1552,7 +1622,6 @@ uint64 EmojiListWidget::sectionSetId(int section) const {
|
||||||
return (section < kEmojiSectionCount)
|
return (section < kEmojiSectionCount)
|
||||||
? EmojiSectionSetId(static_cast<Section>(section))
|
? EmojiSectionSetId(static_cast<Section>(section))
|
||||||
: _custom[section - kEmojiSectionCount].id;
|
: _custom[section - kEmojiSectionCount].id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tr::phrase<> EmojiCategoryTitle(int index) {
|
tr::phrase<> EmojiCategoryTitle(int index) {
|
||||||
|
|
|
@ -102,6 +102,7 @@ private:
|
||||||
int rowsCount = 0;
|
int rowsCount = 0;
|
||||||
int rowsTop = 0;
|
int rowsTop = 0;
|
||||||
int rowsBottom = 0;
|
int rowsBottom = 0;
|
||||||
|
bool premiumRequired = false;
|
||||||
};
|
};
|
||||||
struct CustomInstance;
|
struct CustomInstance;
|
||||||
struct CustomOne {
|
struct CustomOne {
|
||||||
|
@ -116,6 +117,7 @@ private:
|
||||||
std::vector<CustomOne> list;
|
std::vector<CustomOne> list;
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
bool painted = false;
|
bool painted = false;
|
||||||
|
bool premium = false;
|
||||||
};
|
};
|
||||||
struct RecentOne {
|
struct RecentOne {
|
||||||
not_null<CustomInstance*> instance;
|
not_null<CustomInstance*> instance;
|
||||||
|
@ -202,6 +204,7 @@ private:
|
||||||
bool paused,
|
bool paused,
|
||||||
int set,
|
int set,
|
||||||
int index);
|
int index);
|
||||||
|
void drawPremiumRect(QPainter &p, const SectionInfo &info);
|
||||||
[[nodiscard]] bool hasRemoveButton(int index) const;
|
[[nodiscard]] bool hasRemoveButton(int index) const;
|
||||||
[[nodiscard]] QRect removeButtonRect(int index) const;
|
[[nodiscard]] QRect removeButtonRect(int index) const;
|
||||||
[[nodiscard]] QRect emojiRect(int section, int index) const;
|
[[nodiscard]] QRect emojiRect(int section, int index) const;
|
||||||
|
|
Loading…
Add table
Reference in a new issue