mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show featured custom sets in the panel.
This commit is contained in:
parent
ff55918da0
commit
b0fab8c987
11 changed files with 478 additions and 193 deletions
|
@ -1061,11 +1061,11 @@ bool StickersBox::Inner::Row::isRecentSet() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersBox::Inner::Row::isMasksSet() const {
|
bool StickersBox::Inner::Row::isMasksSet() const {
|
||||||
return (set->flags & SetFlag::Masks);
|
return (set->type() == Data::StickersType::Masks);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersBox::Inner::Row::isEmojiSet() const {
|
bool StickersBox::Inner::Row::isEmojiSet() const {
|
||||||
return (set->flags & SetFlag::Emoji);
|
return (set->type() == Data::StickersType::Emoji);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersBox::Inner::Row::isWebm() const {
|
bool StickersBox::Inner::Row::isWebm() const {
|
||||||
|
|
|
@ -31,6 +31,14 @@ stickersTrendingSubheaderFont: normalFont;
|
||||||
stickersTrendingSubheaderFg: windowSubTextFg;
|
stickersTrendingSubheaderFg: windowSubTextFg;
|
||||||
stickersTrendingSubheaderTop: 31px;
|
stickersTrendingSubheaderTop: 31px;
|
||||||
|
|
||||||
|
emojiPanButtonRight: 7px;
|
||||||
|
emojiPanButtonTop: 10px;
|
||||||
|
emojiPanButton: RoundButton(defaultActiveButton) {
|
||||||
|
width: -24px;
|
||||||
|
height: 23px;
|
||||||
|
textTop: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
stickersTrendingAddTop: 14px;
|
stickersTrendingAddTop: 14px;
|
||||||
stickersTrendingAdd: RoundButton(defaultActiveButton) {
|
stickersTrendingAdd: RoundButton(defaultActiveButton) {
|
||||||
width: -16px;
|
width: -16px;
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/text/custom_emoji_instance.h"
|
#include "ui/text/custom_emoji_instance.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
|
#include "ui/effects/premium_graphics.h"
|
||||||
#include "ui/emoji_config.h"
|
#include "ui/emoji_config.h"
|
||||||
#include "ui/ui_utility.h"
|
#include "ui/ui_utility.h"
|
||||||
#include "ui/cached_round_corners.h"
|
#include "ui/cached_round_corners.h"
|
||||||
|
@ -31,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
|
#include "settings/settings_premium.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "facades.h"
|
#include "facades.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
@ -363,6 +365,8 @@ EmojiListWidget::EmojiListWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::SessionController*> controller)
|
not_null<Window::SessionController*> controller)
|
||||||
: Inner(parent, controller)
|
: Inner(parent, controller)
|
||||||
|
, _localSetsManager(
|
||||||
|
std::make_unique<LocalStickersManager>(&controller->session()))
|
||||||
, _picker(this)
|
, _picker(this)
|
||||||
, _showPickerTimer([=] { showPicker(); })
|
, _showPickerTimer([=] { showPicker(); })
|
||||||
, _repaintTimer([=] { invokeRepaints(); }) {
|
, _repaintTimer([=] { invokeRepaints(); }) {
|
||||||
|
@ -399,6 +403,16 @@ EmojiListWidget::EmojiListWidget(
|
||||||
refreshCustom();
|
refreshCustom();
|
||||||
resizeToWidth(width());
|
resizeToWidth(width());
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
rpl::single(
|
||||||
|
rpl::empty
|
||||||
|
) | rpl::then(
|
||||||
|
style::PaletteChanged()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
initButton(_add, tr::lng_stickers_featured_add(tr::now), false);
|
||||||
|
initButton(_unlock, tr::lng_emoji_featured_unlock(tr::now), true);
|
||||||
|
initButton(_restore, tr::lng_emoji_premium_restore(tr::now), true);
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiListWidget::~EmojiListWidget() {
|
EmojiListWidget::~EmojiListWidget() {
|
||||||
|
@ -581,8 +595,6 @@ 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 session = &controller()->session();
|
||||||
const auto premiumMayBeBought = !session->premium()
|
|
||||||
&& session->premiumPossible();
|
|
||||||
const auto next = [&] {
|
const auto next = [&] {
|
||||||
info.rowsCount = (info.count + _columnCount - 1) / _columnCount;
|
info.rowsCount = (info.count + _columnCount - 1) / _columnCount;
|
||||||
info.rowsTop = info.top
|
info.rowsTop = info.top
|
||||||
|
@ -605,7 +617,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.premiumRequired = section.premiumRequired;
|
||||||
info.count = int(section.list.size());
|
info.count = int(section.list.size());
|
||||||
if (!next()) {
|
if (!next()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -763,23 +775,13 @@ 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;
|
||||||
}
|
}
|
||||||
auto widthForTitle = emojiRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
const auto buttonSelected = selectedButton
|
||||||
|
? (selectedButton->section == info.section)
|
||||||
|
: false;
|
||||||
|
const auto widthForTitle = emojiRight()
|
||||||
|
- (st::emojiPanHeaderLeft - st::roundRadiusSmall)
|
||||||
|
- paintButtonGetWidth(p, info, buttonSelected, r);
|
||||||
const auto skip = st::roundRadiusSmall;
|
const auto skip = st::roundRadiusSmall;
|
||||||
if (hasRemoveButton(info.section)) {
|
|
||||||
auto &custom = _custom[info.section - kEmojiSectionCount];
|
|
||||||
auto remove = removeButtonRect(info.section);
|
|
||||||
if (remove.intersects(r)) {
|
|
||||||
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
|
||||||
if (custom.ripple) {
|
|
||||||
custom.ripple->paint(p, remove.x() + st::stickerPanRemoveSet.rippleAreaPosition.x(), remove.y() + st::stickerPanRemoveSet.rippleAreaPosition.y(), width());
|
|
||||||
if (custom.ripple->empty()) {
|
|
||||||
custom.ripple.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(selected ? st::stickerPanRemoveSet.iconOver : st::stickerPanRemoveSet.icon).paint(p, remove.topLeft() + st::stickerPanRemoveSet.iconPosition, width());
|
|
||||||
}
|
|
||||||
widthForTitle -= remove.width();
|
|
||||||
}
|
|
||||||
if (info.section > 0 && r.top() < info.rowsTop) {
|
if (info.section > 0 && r.top() < info.rowsTop) {
|
||||||
p.setFont(st::emojiPanHeaderFont);
|
p.setFont(st::emojiPanHeaderFont);
|
||||||
p.setPen(st::emojiPanHeaderFg);
|
p.setPen(st::emojiPanHeaderFg);
|
||||||
|
@ -1010,7 +1012,14 @@ void EmojiListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
||||||
Assert(button->section >= kEmojiSectionCount
|
Assert(button->section >= kEmojiSectionCount
|
||||||
&& button->section < kEmojiSectionCount + _custom.size());
|
&& button->section < kEmojiSectionCount + _custom.size());
|
||||||
removeSet(_custom[button->section - kEmojiSectionCount].id);
|
const auto id = _custom[button->section - kEmojiSectionCount].id;
|
||||||
|
if (hasRemoveButton(button->section)) {
|
||||||
|
removeSet(id);
|
||||||
|
} else if (hasAddButton(button->section)) {
|
||||||
|
_localSetsManager->install(id);
|
||||||
|
} else {
|
||||||
|
Settings::ShowPremium(controller(), u"animated_emoji"_q);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1089,18 +1098,88 @@ bool EmojiListWidget::hasRemoveButton(int index) const {
|
||||||
|| index >= kEmojiSectionCount + _custom.size()) {
|
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
const auto &set = _custom[index - kEmojiSectionCount];
|
||||||
|
return set.canRemove && !set.premiumRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect EmojiListWidget::removeButtonRect(int index) const {
|
QRect EmojiListWidget::removeButtonRect(int index) const {
|
||||||
auto buttonw = st::stickerPanRemoveSet.rippleAreaPosition.x()
|
return removeButtonRect(sectionInfo(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::removeButtonRect(const SectionInfo &info) const {
|
||||||
|
const auto buttonw = st::stickerPanRemoveSet.rippleAreaPosition.x()
|
||||||
+ st::stickerPanRemoveSet.rippleAreaSize;
|
+ st::stickerPanRemoveSet.rippleAreaSize;
|
||||||
auto buttonh = st::stickerPanRemoveSet.height;
|
const auto buttonh = st::stickerPanRemoveSet.height;
|
||||||
auto buttonx = emojiRight() - st::emojiPanRemoveSkip - buttonw;
|
const auto buttonx = emojiRight() - st::emojiPanRemoveSkip - buttonw;
|
||||||
auto buttony = sectionInfo(index).top + (st::emojiPanHeader - buttonh) / 2;
|
const auto buttony = info.top + (st::emojiPanHeader - buttonh) / 2;
|
||||||
return QRect(buttonx, buttony, buttonw, buttonh);
|
return QRect(buttonx, buttony, buttonw, buttonh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EmojiListWidget::hasAddButton(int index) const {
|
||||||
|
if (index < kEmojiSectionCount
|
||||||
|
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto &set = _custom[index - kEmojiSectionCount];
|
||||||
|
return !set.canRemove && !set.premiumRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::addButtonRect(int index) const {
|
||||||
|
return buttonRect(sectionInfo(index), _add);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmojiListWidget::hasUnlockButton(int index) const {
|
||||||
|
if (index < kEmojiSectionCount
|
||||||
|
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto &set = _custom[index - kEmojiSectionCount];
|
||||||
|
return set.premiumRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::unlockButtonRect(int index) const {
|
||||||
|
Expects(index >= kEmojiSectionCount
|
||||||
|
&& index < kEmojiSectionCount + _custom.size());
|
||||||
|
|
||||||
|
return buttonRect(sectionInfo(index), rightButton(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmojiListWidget::hasButton(int index) const {
|
||||||
|
if (index < kEmojiSectionCount
|
||||||
|
|| index >= kEmojiSectionCount + _custom.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::buttonRect(int index) const {
|
||||||
|
return hasRemoveButton(index)
|
||||||
|
? removeButtonRect(index)
|
||||||
|
: hasAddButton(index)
|
||||||
|
? addButtonRect(index)
|
||||||
|
: unlockButtonRect(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect EmojiListWidget::buttonRect(
|
||||||
|
const SectionInfo &info,
|
||||||
|
const RightButton &button) const {
|
||||||
|
const auto buttonw = button.textWidth - st::emojiPanButton.width;
|
||||||
|
const auto buttonh = st::emojiPanButton.height;
|
||||||
|
const auto buttonx = emojiRight() - buttonw - st::emojiPanButtonRight;
|
||||||
|
const auto buttony = info.top + st::emojiPanButtonTop;
|
||||||
|
return QRect(buttonx, buttony, buttonw, buttonh);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto EmojiListWidget::rightButton(int index) const -> const RightButton & {
|
||||||
|
Expects(index >= kEmojiSectionCount
|
||||||
|
&& index < kEmojiSectionCount + _custom.size());
|
||||||
|
return hasAddButton(index)
|
||||||
|
? _add
|
||||||
|
: _custom[index - kEmojiSectionCount].canRemove
|
||||||
|
? _restore
|
||||||
|
: _unlock;
|
||||||
|
}
|
||||||
|
|
||||||
int EmojiListWidget::emojiRight() const {
|
int EmojiListWidget::emojiRight() const {
|
||||||
return emojiLeft() + (_columnCount * _singleSize.width());
|
return emojiLeft() + (_columnCount * _singleSize.width());
|
||||||
}
|
}
|
||||||
|
@ -1221,15 +1300,22 @@ void EmojiListWidget::refreshRecent() {
|
||||||
|
|
||||||
void EmojiListWidget::refreshCustom() {
|
void EmojiListWidget::refreshCustom() {
|
||||||
auto old = base::take(_custom);
|
auto old = base::take(_custom);
|
||||||
const auto owner = &controller()->session().data();
|
const auto session = &controller()->session();
|
||||||
const auto &order = owner->stickers().emojiSetsOrder();
|
const auto premiumPossible = session->premiumPossible();
|
||||||
const auto &featured = owner->stickers().featuredEmojiSetsOrder();
|
const auto premiumMayBeBought = premiumPossible && !session->premium();
|
||||||
|
const auto owner = &session->data();
|
||||||
const auto &sets = owner->stickers().sets();
|
const auto &sets = owner->stickers().sets();
|
||||||
for (const auto setId : ranges::views::concat(order, featured)) {
|
const auto push = [&](uint64 setId, bool installed) {
|
||||||
auto it = sets.find(setId);
|
auto it = sets.find(setId);
|
||||||
if (it == sets.cend() || it->second->stickers.isEmpty()) {
|
if (it == sets.cend() || it->second->stickers.isEmpty()) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
const auto canRemove = !!(it->second->flags
|
||||||
|
& Data::StickersSetFlag::Installed);
|
||||||
|
if (canRemove != installed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto premium = false;
|
||||||
const auto &list = it->second->stickers;
|
const auto &list = it->second->stickers;
|
||||||
const auto i = ranges::find(old, setId, &CustomSet::id);
|
const auto i = ranges::find(old, setId, &CustomSet::id);
|
||||||
if (i != end(old)) {
|
if (i != end(old)) {
|
||||||
|
@ -1239,19 +1325,26 @@ void EmojiListWidget::refreshCustom() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (auto k = 0; k != count; ++k) {
|
for (auto k = 0; k != count; ++k) {
|
||||||
|
if (!premium && list[k]->isPremiumEmoji()) {
|
||||||
|
premium = true;
|
||||||
|
}
|
||||||
if (i->list[k].document != list[k]) {
|
if (i->list[k].document != list[k]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}();
|
}();
|
||||||
if (valid) {
|
if (premium && !premiumPossible) {
|
||||||
|
return;
|
||||||
|
} else if (valid) {
|
||||||
i->thumbnailDocument = it->second->lookupThumbnailDocument();
|
i->thumbnailDocument = it->second->lookupThumbnailDocument();
|
||||||
|
i->canRemove = canRemove;
|
||||||
|
i->premiumRequired = premium && premiumMayBeBought;
|
||||||
|
i->ripple.reset();
|
||||||
_custom.push_back(std::move(*i));
|
_custom.push_back(std::move(*i));
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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) {
|
||||||
|
@ -1260,13 +1353,13 @@ void EmojiListWidget::refreshCustom() {
|
||||||
.instance = resolveCustomInstance(document, setId),
|
.instance = resolveCustomInstance(document, setId),
|
||||||
.document = document,
|
.document = document,
|
||||||
});
|
});
|
||||||
if (document->isPremiumEmoji()) {
|
if (!premium && document->isPremiumEmoji()) {
|
||||||
premium = true;
|
premium = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (premium && !controller()->session().premiumPossible()) {
|
if (premium && !premiumPossible) {
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
_custom.push_back({
|
_custom.push_back({
|
||||||
.id = setId,
|
.id = setId,
|
||||||
|
@ -1274,13 +1367,22 @@ void EmojiListWidget::refreshCustom() {
|
||||||
.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,
|
.canRemove = canRemove,
|
||||||
|
.premiumRequired = premium && premiumMayBeBought,
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
for (const auto setId : owner->stickers().emojiSetsOrder()) {
|
||||||
|
push(setId, true);
|
||||||
}
|
}
|
||||||
|
for (const auto setId : owner->stickers().featuredEmojiSetsOrder()) {
|
||||||
|
push(setId, false);
|
||||||
|
}
|
||||||
|
|
||||||
_footer->refreshIcons(
|
_footer->refreshIcons(
|
||||||
fillIcons(),
|
fillIcons(),
|
||||||
nullptr,
|
nullptr,
|
||||||
ValidateIconAnimations::None);
|
ValidateIconAnimations::None);
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EmojiListWidget::customInstanceWithLoader(
|
auto EmojiListWidget::customInstanceWithLoader(
|
||||||
|
@ -1419,6 +1521,64 @@ std::vector<StickerIcon> EmojiListWidget::fillIcons() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EmojiListWidget::paintButtonGetWidth(
|
||||||
|
QPainter &p,
|
||||||
|
const SectionInfo &info,
|
||||||
|
bool selected,
|
||||||
|
QRect clip) const {
|
||||||
|
if (info.section < kEmojiSectionCount
|
||||||
|
|| info.section >= kEmojiSectionCount + _custom.size()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
auto &custom = _custom[info.section - kEmojiSectionCount];
|
||||||
|
if (hasRemoveButton(info.section)) {
|
||||||
|
const auto remove = removeButtonRect(info);
|
||||||
|
if (remove.intersects(clip)) {
|
||||||
|
if (custom.ripple) {
|
||||||
|
custom.ripple->paint(
|
||||||
|
p,
|
||||||
|
remove.x() + st::stickerPanRemoveSet.rippleAreaPosition.x(),
|
||||||
|
remove.y() + st::stickerPanRemoveSet.rippleAreaPosition.y(),
|
||||||
|
width());
|
||||||
|
if (custom.ripple->empty()) {
|
||||||
|
custom.ripple.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(selected
|
||||||
|
? st::stickerPanRemoveSet.iconOver
|
||||||
|
: st::stickerPanRemoveSet.icon).paint(
|
||||||
|
p,
|
||||||
|
remove.topLeft() + st::stickerPanRemoveSet.iconPosition,
|
||||||
|
width());
|
||||||
|
}
|
||||||
|
return remove.width();
|
||||||
|
}
|
||||||
|
const auto canAdd = hasAddButton(info.section);
|
||||||
|
const auto &button = rightButton(info.section);
|
||||||
|
const auto rect = buttonRect(info, button);
|
||||||
|
p.drawImage(rect.topLeft(), selected ? button.backOver : button.back);
|
||||||
|
if (custom.ripple) {
|
||||||
|
const auto ripple = QColor(0, 0, 0, 36);
|
||||||
|
custom.ripple->paint(p, rect.x(), rect.y(), width(), &ripple);
|
||||||
|
if (custom.ripple->empty()) {
|
||||||
|
custom.ripple.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.setPen(!canAdd
|
||||||
|
? st::premiumButtonFg
|
||||||
|
: selected
|
||||||
|
? st::emojiPanButton.textFgOver
|
||||||
|
: st::emojiPanButton.textFg);
|
||||||
|
p.setFont(st::emojiPanButton.font);
|
||||||
|
p.drawText(
|
||||||
|
rect.x() - (st::emojiPanButton.width / 2),
|
||||||
|
(rect.y()
|
||||||
|
+ st::emojiPanButton.textTop
|
||||||
|
+ st::emojiPanButton.font->ascent),
|
||||||
|
button.text);
|
||||||
|
return rect.width();
|
||||||
|
}
|
||||||
|
|
||||||
bool EmojiListWidget::eventHook(QEvent *e) {
|
bool EmojiListWidget::eventHook(QEvent *e) {
|
||||||
if (e->type() == QEvent::ParentChange) {
|
if (e->type() == QEvent::ParentChange) {
|
||||||
if (_picker->parentWidget() != parentWidget()) {
|
if (_picker->parentWidget() != parentWidget()) {
|
||||||
|
@ -1439,9 +1599,8 @@ void EmojiListWidget::updateSelected() {
|
||||||
auto info = sectionInfoByOffset(p.y());
|
auto info = sectionInfoByOffset(p.y());
|
||||||
auto section = info.section;
|
auto section = info.section;
|
||||||
if (p.y() >= info.top && p.y() < info.rowsTop) {
|
if (p.y() >= info.top && p.y() < info.rowsTop) {
|
||||||
if (hasRemoveButton(section)
|
if (hasButton(section)
|
||||||
&& myrtlrect(
|
&& myrtlrect(buttonRect(section)).contains(p.x(), p.y())) {
|
||||||
removeButtonRect(section)).contains(p.x(), p.y())) {
|
|
||||||
newSelected = OverButton{ section };
|
newSelected = OverButton{ section };
|
||||||
} else if (section >= kEmojiSectionCount) {
|
} else if (section >= kEmojiSectionCount) {
|
||||||
newSelected = OverSet{ section };
|
newSelected = OverSet{ section };
|
||||||
|
@ -1470,7 +1629,7 @@ void EmojiListWidget::setSelected(OverState newSelected) {
|
||||||
if (const auto sticker = std::get_if<OverEmoji>(&_selected)) {
|
if (const auto sticker = std::get_if<OverEmoji>(&_selected)) {
|
||||||
rtlupdate(emojiRect(sticker->section, sticker->index));
|
rtlupdate(emojiRect(sticker->section, sticker->index));
|
||||||
} else if (const auto button = std::get_if<OverButton>(&_selected)) {
|
} else if (const auto button = std::get_if<OverButton>(&_selected)) {
|
||||||
rtlupdate(removeButtonRect(button->section));
|
rtlupdate(buttonRect(button->section));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -1513,27 +1672,72 @@ void EmojiListWidget::setPressed(OverState newPressed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmojiListWidget::initButton(
|
||||||
|
RightButton &button,
|
||||||
|
const QString &text,
|
||||||
|
bool gradient) {
|
||||||
|
button.text = text;
|
||||||
|
button.textWidth = st::emojiPanButton.font->width(text);
|
||||||
|
const auto width = button.textWidth - st::emojiPanButton.width;
|
||||||
|
const auto height = st::emojiPanButton.height;
|
||||||
|
const auto factor = style::DevicePixelRatio();
|
||||||
|
auto prepare = [&](QColor bg, QBrush fg) {
|
||||||
|
auto image = QImage(
|
||||||
|
QSize(width, height) * factor,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
image.setDevicePixelRatio(factor);
|
||||||
|
image.fill(Qt::transparent);
|
||||||
|
auto p = QPainter(&image);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(fg);
|
||||||
|
const auto radius = height / 2.;
|
||||||
|
p.drawRoundedRect(QRect(0, 0, width, height), radius, radius);
|
||||||
|
p.end();
|
||||||
|
return image;
|
||||||
|
};
|
||||||
|
button.back = prepare(Qt::transparent, [&]() -> QBrush {
|
||||||
|
if (gradient) {
|
||||||
|
auto result = QLinearGradient(QPointF(0, 0), QPointF(width, 0));
|
||||||
|
result.setStops(Ui::Premium::ButtonGradientStops());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return st::emojiPanButton.textBg;
|
||||||
|
}());
|
||||||
|
button.backOver = gradient
|
||||||
|
? button.back
|
||||||
|
: prepare(Qt::transparent, st::emojiPanButton.textBgOver);
|
||||||
|
button.rippleMask = prepare(Qt::black, Qt::white);
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
|
||||||
int section) {
|
int section) {
|
||||||
Expects(section >= kEmojiSectionCount
|
Expects(section >= kEmojiSectionCount
|
||||||
&& section < kEmojiSectionCount + _custom.size());
|
&& section < kEmojiSectionCount + _custom.size());
|
||||||
|
|
||||||
auto maskSize = QSize(
|
const auto remove = hasRemoveButton(section);
|
||||||
st::stickerPanRemoveSet.rippleAreaSize,
|
const auto &st = remove
|
||||||
st::stickerPanRemoveSet.rippleAreaSize);
|
? st::stickerPanRemoveSet.ripple
|
||||||
auto mask = Ui::RippleAnimation::ellipseMask(maskSize);
|
: st::emojiPanButton.ripple;
|
||||||
|
auto mask = remove
|
||||||
|
? Ui::RippleAnimation::ellipseMask(QSize(
|
||||||
|
st::stickerPanRemoveSet.rippleAreaSize,
|
||||||
|
st::stickerPanRemoveSet.rippleAreaSize))
|
||||||
|
: rightButton(section).rippleMask;
|
||||||
return std::make_unique<Ui::RippleAnimation>(
|
return std::make_unique<Ui::RippleAnimation>(
|
||||||
st::stickerPanRemoveSet.ripple,
|
st,
|
||||||
std::move(mask),
|
std::move(mask),
|
||||||
[this, section] { rtlupdate(removeButtonRect(section)); });
|
[this, section] { rtlupdate(buttonRect(section)); });
|
||||||
}
|
}
|
||||||
|
|
||||||
QPoint EmojiListWidget::buttonRippleTopLeft(int section) const {
|
QPoint EmojiListWidget::buttonRippleTopLeft(int section) const {
|
||||||
Expects(section >= kEmojiSectionCount
|
Expects(section >= kEmojiSectionCount
|
||||||
&& section < kEmojiSectionCount + _custom.size());
|
&& section < kEmojiSectionCount + _custom.size());
|
||||||
|
|
||||||
return myrtlrect(removeButtonRect(section)).topLeft()
|
return myrtlrect(buttonRect(section)).topLeft()
|
||||||
+ st::stickerPanRemoveSet.rippleAreaPosition;
|
+ (hasRemoveButton(section)
|
||||||
|
? st::stickerPanRemoveSet.rippleAreaPosition
|
||||||
|
: QPoint());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiListWidget::showEmojiSection(Section section) {
|
void EmojiListWidget::showEmojiSection(Section section) {
|
||||||
|
|
|
@ -49,6 +49,7 @@ inline constexpr auto kEmojiSectionCount = 8;
|
||||||
struct StickerIcon;
|
struct StickerIcon;
|
||||||
class EmojiColorPicker;
|
class EmojiColorPicker;
|
||||||
class StickersListFooter;
|
class StickersListFooter;
|
||||||
|
class LocalStickersManager;
|
||||||
|
|
||||||
class EmojiListWidget
|
class EmojiListWidget
|
||||||
: public TabbedSelector::Inner
|
: public TabbedSelector::Inner
|
||||||
|
@ -120,9 +121,17 @@ private:
|
||||||
DocumentData *thumbnailDocument = nullptr;
|
DocumentData *thumbnailDocument = nullptr;
|
||||||
QString title;
|
QString title;
|
||||||
std::vector<CustomOne> list;
|
std::vector<CustomOne> list;
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
bool painted = false;
|
bool painted = false;
|
||||||
bool premium = false;
|
bool canRemove = false;
|
||||||
|
bool premiumRequired = false;
|
||||||
|
};
|
||||||
|
struct RightButton {
|
||||||
|
QImage back;
|
||||||
|
QImage backOver;
|
||||||
|
QImage rippleMask;
|
||||||
|
QString text;
|
||||||
|
int textWidth = 0;
|
||||||
};
|
};
|
||||||
struct RecentOne;
|
struct RecentOne;
|
||||||
struct RepaintSet {
|
struct RepaintSet {
|
||||||
|
@ -210,15 +219,32 @@ private:
|
||||||
int index);
|
int index);
|
||||||
[[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 removeButtonRect(const SectionInfo &info) const;
|
||||||
|
[[nodiscard]] bool hasAddButton(int index) const;
|
||||||
|
[[nodiscard]] QRect addButtonRect(int index) const;
|
||||||
|
[[nodiscard]] bool hasUnlockButton(int index) const;
|
||||||
|
[[nodiscard]] QRect unlockButtonRect(int index) const;
|
||||||
|
[[nodiscard]] bool hasButton(int index) const;
|
||||||
|
[[nodiscard]] QRect buttonRect(int index) const;
|
||||||
|
[[nodiscard]] QRect buttonRect(
|
||||||
|
const SectionInfo &info,
|
||||||
|
const RightButton &button) const;
|
||||||
|
[[nodiscard]] const RightButton &rightButton(int index) const;
|
||||||
[[nodiscard]] QRect emojiRect(int section, int index) const;
|
[[nodiscard]] QRect emojiRect(int section, int index) const;
|
||||||
[[nodiscard]] int emojiRight() const;
|
[[nodiscard]] int emojiRight() const;
|
||||||
[[nodiscard]] int emojiLeft() const;
|
[[nodiscard]] int emojiLeft() const;
|
||||||
[[nodiscard]] uint64 sectionSetId(int section) const;
|
[[nodiscard]] uint64 sectionSetId(int section) const;
|
||||||
[[nodiscard]] std::vector<StickerIcon> fillIcons();
|
[[nodiscard]] std::vector<StickerIcon> fillIcons();
|
||||||
|
int paintButtonGetWidth(
|
||||||
|
QPainter &p,
|
||||||
|
const SectionInfo &info,
|
||||||
|
bool selected,
|
||||||
|
QRect clip) const;
|
||||||
|
|
||||||
void displaySet(uint64 setId);
|
void displaySet(uint64 setId);
|
||||||
void removeSet(uint64 setId);
|
void removeSet(uint64 setId);
|
||||||
|
|
||||||
|
void initButton(RightButton &button, const QString &text, bool gradient);
|
||||||
[[nodiscard]] std::unique_ptr<Ui::RippleAnimation> createButtonRipple(
|
[[nodiscard]] std::unique_ptr<Ui::RippleAnimation> createButtonRipple(
|
||||||
int section);
|
int section);
|
||||||
[[nodiscard]] QPoint buttonRippleTopLeft(int section) const;
|
[[nodiscard]] QPoint buttonRippleTopLeft(int section) const;
|
||||||
|
@ -246,6 +272,7 @@ private:
|
||||||
uint64 setId);
|
uint64 setId);
|
||||||
|
|
||||||
StickersListFooter *_footer = nullptr;
|
StickersListFooter *_footer = nullptr;
|
||||||
|
std::unique_ptr<LocalStickersManager> _localSetsManager;
|
||||||
|
|
||||||
int _counts[kEmojiSectionCount];
|
int _counts[kEmojiSectionCount];
|
||||||
std::vector<RecentOne> _recent;
|
std::vector<RecentOne> _recent;
|
||||||
|
@ -261,6 +288,10 @@ private:
|
||||||
QPoint _areaPosition;
|
QPoint _areaPosition;
|
||||||
QPoint _innerPosition;
|
QPoint _innerPosition;
|
||||||
|
|
||||||
|
RightButton _add;
|
||||||
|
RightButton _unlock;
|
||||||
|
RightButton _restore;
|
||||||
|
|
||||||
OverState _selected;
|
OverState _selected;
|
||||||
OverState _pressed;
|
OverState _pressed;
|
||||||
OverState _pickerSelected;
|
OverState _pickerSelected;
|
||||||
|
|
|
@ -1275,4 +1275,79 @@ void StickersListFooter::paintSetIcon(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalStickersManager::LocalStickersManager(not_null<Main::Session*> session)
|
||||||
|
: _session(session)
|
||||||
|
, _api(&session->mtp()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalStickersManager::install(uint64 setId) {
|
||||||
|
const auto &sets = _session->data().stickers().sets();
|
||||||
|
const auto it = sets.find(setId);
|
||||||
|
if (it == sets.cend()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto set = it->second.get();
|
||||||
|
const auto input = set->mtpInput();
|
||||||
|
if (!(set->flags & Data::StickersSetFlag::NotLoaded)
|
||||||
|
&& !set->stickers.empty()) {
|
||||||
|
sendInstallRequest(setId, input);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_api.request(MTPmessages_GetStickerSet(
|
||||||
|
input,
|
||||||
|
MTP_int(0) // hash
|
||||||
|
)).done([=](const MTPmessages_StickerSet &result) {
|
||||||
|
result.match([&](const MTPDmessages_stickerSet &data) {
|
||||||
|
_session->data().stickers().feedSetFull(data);
|
||||||
|
}, [](const MTPDmessages_stickerSetNotModified &) {
|
||||||
|
LOG(("API Error: Unexpected messages.stickerSetNotModified."));
|
||||||
|
});
|
||||||
|
sendInstallRequest(setId, input);
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalStickersManager::isInstalledLocally(uint64 setId) const {
|
||||||
|
return _installedLocallySets.contains(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalStickersManager::sendInstallRequest(
|
||||||
|
uint64 setId,
|
||||||
|
const MTPInputStickerSet &input) {
|
||||||
|
_api.request(MTPmessages_InstallStickerSet(
|
||||||
|
input,
|
||||||
|
MTP_bool(false)
|
||||||
|
)).done([=](const MTPmessages_StickerSetInstallResult &result) {
|
||||||
|
if (result.type() == mtpc_messages_stickerSetInstallResultArchive) {
|
||||||
|
_session->data().stickers().applyArchivedResult(
|
||||||
|
result.c_messages_stickerSetInstallResultArchive());
|
||||||
|
}
|
||||||
|
}).fail([=] {
|
||||||
|
notInstalledLocally(setId);
|
||||||
|
_session->data().stickers().undoInstallLocally(setId);
|
||||||
|
}).send();
|
||||||
|
|
||||||
|
installedLocally(setId);
|
||||||
|
_session->data().stickers().installLocally(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalStickersManager::installedLocally(uint64 setId) {
|
||||||
|
_installedLocallySets.insert(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalStickersManager::notInstalledLocally(uint64 setId) {
|
||||||
|
_installedLocallySets.remove(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalStickersManager::removeInstalledLocally(uint64 setId) {
|
||||||
|
_installedLocallySets.remove(setId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalStickersManager::clearInstalledLocally() {
|
||||||
|
if (_installedLocallySets.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_installedLocallySets.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "media/clip/media_clip_reader.h"
|
#include "media/clip/media_clip_reader.h"
|
||||||
#include "chat_helpers/tabbed_selector.h"
|
#include "chat_helpers/tabbed_selector.h"
|
||||||
|
#include "mtproto/sender.h"
|
||||||
#include "ui/round_rect.h"
|
#include "ui/round_rect.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
@ -251,4 +252,27 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LocalStickersManager final {
|
||||||
|
public:
|
||||||
|
explicit LocalStickersManager(not_null<Main::Session*> session);
|
||||||
|
|
||||||
|
void install(uint64 setId);
|
||||||
|
[[nodiscard]] bool isInstalledLocally(uint64 setId) const;
|
||||||
|
void removeInstalledLocally(uint64 setId);
|
||||||
|
bool clearInstalledLocally();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void sendInstallRequest(
|
||||||
|
uint64 setId,
|
||||||
|
const MTPInputStickerSet &input);
|
||||||
|
void installedLocally(uint64 setId);
|
||||||
|
void notInstalledLocally(uint64 setId);
|
||||||
|
|
||||||
|
const not_null<Main::Session*> _session;
|
||||||
|
MTP::Sender _api;
|
||||||
|
|
||||||
|
base::flat_set<uint64> _installedLocallySets;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace ChatHelpers
|
} // namespace ChatHelpers
|
||||||
|
|
|
@ -165,6 +165,8 @@ StickersListWidget::StickersListWidget(
|
||||||
bool masks)
|
bool masks)
|
||||||
: Inner(parent, controller)
|
: Inner(parent, controller)
|
||||||
, _api(&controller->session().mtp())
|
, _api(&controller->session().mtp())
|
||||||
|
, _localSetsManager(
|
||||||
|
std::make_unique<LocalStickersManager>(&controller->session()))
|
||||||
, _section(Section::Stickers)
|
, _section(Section::Stickers)
|
||||||
, _isMasks(masks)
|
, _isMasks(masks)
|
||||||
, _updateItemsTimer([=] { updateItems(); })
|
, _updateItemsTimer([=] { updateItems(); })
|
||||||
|
@ -495,21 +497,6 @@ int StickersListWidget::countDesiredHeight(int newWidth) {
|
||||||
+ st::stickerPanPadding;
|
+ st::stickerPanPadding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::installedLocally(uint64 setId) {
|
|
||||||
_installedLocallySets.insert(setId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickersListWidget::notInstalledLocally(uint64 setId) {
|
|
||||||
_installedLocallySets.remove(setId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickersListWidget::clearInstalledLocally() {
|
|
||||||
if (!_installedLocallySets.empty()) {
|
|
||||||
_installedLocallySets.clear();
|
|
||||||
refreshStickers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickersListWidget::sendSearchRequest() {
|
void StickersListWidget::sendSearchRequest() {
|
||||||
if (_searchRequestId || _searchNextQuery.isEmpty()) {
|
if (_searchRequestId || _searchNextQuery.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -851,7 +838,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
|
|
||||||
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
||||||
if (featuredHasAddButton(info.section)) {
|
if (featuredHasAddButton(info.section)) {
|
||||||
auto add = featuredAddRect(info.section);
|
auto add = featuredAddRect(info);
|
||||||
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
||||||
auto &textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
|
auto &textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
|
||||||
|
|
||||||
|
@ -868,7 +855,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
|
|
||||||
widthForTitle -= add.width() - (st::stickersTrendingAdd.width / 2);
|
widthForTitle -= add.width() - (st::stickersTrendingAdd.width / 2);
|
||||||
} else {
|
} else {
|
||||||
auto add = featuredAddRect(info.section);
|
auto add = featuredAddRect(info);
|
||||||
int checkx = add.left() + (add.width() - st::stickersFeaturedInstalled.width()) / 2;
|
int checkx = add.left() + (add.width() - st::stickersFeaturedInstalled.width()) / 2;
|
||||||
int checky = add.top() + (add.height() - st::stickersFeaturedInstalled.height()) / 2;
|
int checky = add.top() + (add.height() - st::stickersFeaturedInstalled.height()) / 2;
|
||||||
st::stickersFeaturedInstalled.paint(p, QPoint(checkx, checky), width());
|
st::stickersFeaturedInstalled.paint(p, QPoint(checkx, checky), width());
|
||||||
|
@ -924,7 +911,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
auto titleWidth = st::stickersTrendingHeaderFont->width(titleText);
|
auto titleWidth = st::stickersTrendingHeaderFont->width(titleText);
|
||||||
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::roundRadiusSmall);
|
||||||
if (hasRemoveButton(info.section)) {
|
if (hasRemoveButton(info.section)) {
|
||||||
auto remove = removeButtonRect(info.section);
|
auto remove = removeButtonRect(info);
|
||||||
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
|
||||||
if (set.ripple) {
|
if (set.ripple) {
|
||||||
set.ripple->paint(p, remove.x() + st::stickerPanRemoveSet.rippleAreaPosition.x(), remove.y() + st::stickerPanRemoveSet.rippleAreaPosition.y(), width());
|
set.ripple->paint(p, remove.x() + st::stickerPanRemoveSet.rippleAreaPosition.x(), remove.y() + st::stickerPanRemoveSet.rippleAreaPosition.y(), width());
|
||||||
|
@ -1430,10 +1417,14 @@ bool StickersListWidget::featuredHasAddButton(int index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect StickersListWidget::featuredAddRect(int index) const {
|
QRect StickersListWidget::featuredAddRect(int index) const {
|
||||||
|
return featuredAddRect(sectionInfo(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect StickersListWidget::featuredAddRect(const SectionInfo &info) const {
|
||||||
auto addw = _addWidth - st::stickersTrendingAdd.width;
|
auto addw = _addWidth - st::stickersTrendingAdd.width;
|
||||||
auto addh = st::stickersTrendingAdd.height;
|
auto addh = st::stickersTrendingAdd.height;
|
||||||
auto addx = stickersRight() - addw;
|
auto addx = stickersRight() - addw;
|
||||||
auto addy = sectionInfo(index).top + st::stickersTrendingAddTop;
|
auto addy = info.top + st::stickersTrendingAddTop;
|
||||||
return QRect(addx, addy, addw, addh);
|
return QRect(addx, addy, addw, addh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1460,10 +1451,14 @@ bool StickersListWidget::hasRemoveButton(int index) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect StickersListWidget::removeButtonRect(int index) const {
|
QRect StickersListWidget::removeButtonRect(int index) const {
|
||||||
|
return removeButtonRect(sectionInfo(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect StickersListWidget::removeButtonRect(const SectionInfo &info) const {
|
||||||
auto buttonw = st::stickerPanRemoveSet.width;
|
auto buttonw = st::stickerPanRemoveSet.width;
|
||||||
auto buttonh = st::stickerPanRemoveSet.height;
|
auto buttonh = st::stickerPanRemoveSet.height;
|
||||||
auto buttonx = stickersRight() - buttonw;
|
auto buttonx = stickersRight() - buttonw;
|
||||||
auto buttony = sectionInfo(index).top + (st::emojiPanHeader - buttonh) / 2;
|
auto buttony = info.top + (st::emojiPanHeader - buttonh) / 2;
|
||||||
return QRect(buttonx, buttony, buttonw, buttonh);
|
return QRect(buttonx, buttony, buttonw, buttonh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1692,7 +1687,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
} else if (auto button = std::get_if<OverButton>(&pressed)) {
|
||||||
Assert(button->section >= 0 && button->section < sets.size());
|
Assert(button->section >= 0 && button->section < sets.size());
|
||||||
if (sets[button->section].externalLayout) {
|
if (sets[button->section].externalLayout) {
|
||||||
installSet(sets[button->section].id);
|
_localSetsManager->install(sets[button->section].id);
|
||||||
} else if (sets[button->section].id == Data::Stickers::MegagroupSetId) {
|
} else if (sets[button->section].id == Data::Stickers::MegagroupSetId) {
|
||||||
auto removeLocally = sets[button->section].stickers.empty()
|
auto removeLocally = sets[button->section].stickers.empty()
|
||||||
|| !_megagroupSet->canEditStickers();
|
|| !_megagroupSet->canEditStickers();
|
||||||
|
@ -1823,7 +1818,9 @@ void StickersListWidget::processHideFinished() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::processPanelHideFinished() {
|
void StickersListWidget::processPanelHideFinished() {
|
||||||
clearInstalledLocally();
|
if (_localSetsManager->clearInstalledLocally()) {
|
||||||
|
refreshStickers();
|
||||||
|
}
|
||||||
clearHeavyData();
|
clearHeavyData();
|
||||||
if (_footer) {
|
if (_footer) {
|
||||||
_footer->clearHeavyData();
|
_footer->clearHeavyData();
|
||||||
|
@ -1925,7 +1922,7 @@ void StickersListWidget::refreshFeaturedSets() {
|
||||||
if (it == sets.cend()
|
if (it == sets.cend()
|
||||||
|| ((it->second->flags & SetFlag::Installed)
|
|| ((it->second->flags & SetFlag::Installed)
|
||||||
&& !(it->second->flags & SetFlag::Archived)
|
&& !(it->second->flags & SetFlag::Archived)
|
||||||
&& !_installedLocallySets.contains(set.id))) {
|
&& !_localSetsManager->isInstalledLocally(set.id))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
set.flags = it->second->flags;
|
set.flags = it->second->flags;
|
||||||
|
@ -1949,7 +1946,7 @@ void StickersListWidget::refreshSearchSets() {
|
||||||
entry.stickers = std::move(elements);
|
entry.stickers = std::move(elements);
|
||||||
}
|
}
|
||||||
if (!SetInMyList(entry.flags)) {
|
if (!SetInMyList(entry.flags)) {
|
||||||
_installedLocallySets.remove(entry.id);
|
_localSetsManager->removeInstalledLocally(entry.id);
|
||||||
entry.externalLayout = true;
|
entry.externalLayout = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2017,7 +2014,7 @@ bool StickersListWidget::appendSet(
|
||||||
if ((skip == AppendSkip::Installed)
|
if ((skip == AppendSkip::Installed)
|
||||||
&& (set->flags & SetFlag::Installed)
|
&& (set->flags & SetFlag::Installed)
|
||||||
&& !(set->flags & SetFlag::Archived)) {
|
&& !(set->flags & SetFlag::Archived)) {
|
||||||
if (!_installedLocallySets.contains(setId)) {
|
if (!_localSetsManager->isInstalledLocally(setId)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2379,22 +2376,22 @@ void StickersListWidget::updateSelected() {
|
||||||
auto info = sectionInfoByOffset(p.y());
|
auto info = sectionInfoByOffset(p.y());
|
||||||
auto section = info.section;
|
auto section = info.section;
|
||||||
if (p.y() >= info.top && p.y() < info.rowsTop) {
|
if (p.y() >= info.top && p.y() < info.rowsTop) {
|
||||||
if (hasRemoveButton(section) && myrtlrect(removeButtonRect(section)).contains(p.x(), p.y())) {
|
if (hasRemoveButton(section) && myrtlrect(removeButtonRect(info)).contains(p.x(), p.y())) {
|
||||||
newSelected = OverButton { section };
|
newSelected = OverButton{ section };
|
||||||
} else if (featuredHasAddButton(section) && myrtlrect(featuredAddRect(section)).contains(p.x(), p.y())) {
|
} else if (featuredHasAddButton(section) && myrtlrect(featuredAddRect(info)).contains(p.x(), p.y())) {
|
||||||
newSelected = OverButton{ section };
|
newSelected = OverButton{ section };
|
||||||
} else if (!(sets[section].flags & SetFlag::Special)) {
|
} else if (!(sets[section].flags & SetFlag::Special)) {
|
||||||
newSelected = OverSet { section };
|
newSelected = OverSet{ section };
|
||||||
} else if (sets[section].id == Data::Stickers::MegagroupSetId
|
} else if (sets[section].id == Data::Stickers::MegagroupSetId
|
||||||
&& (_megagroupSet->canEditStickers() || !sets[section].stickers.empty())) {
|
&& (_megagroupSet->canEditStickers() || !sets[section].stickers.empty())) {
|
||||||
newSelected = OverSet { section };
|
newSelected = OverSet{ section };
|
||||||
}
|
}
|
||||||
} else if (p.y() >= info.rowsTop && p.y() < info.rowsBottom && sx >= 0) {
|
} else if (p.y() >= info.rowsTop && p.y() < info.rowsBottom && sx >= 0) {
|
||||||
auto yOffset = p.y() - info.rowsTop;
|
auto yOffset = p.y() - info.rowsTop;
|
||||||
auto &set = sets[section];
|
auto &set = sets[section];
|
||||||
if (set.id == Data::Stickers::MegagroupSetId && set.stickers.empty()) {
|
if (set.id == Data::Stickers::MegagroupSetId && set.stickers.empty()) {
|
||||||
if (_megagroupSetButtonRect.contains(stickersLeft() + sx, yOffset)) {
|
if (_megagroupSetButtonRect.contains(stickersLeft() + sx, yOffset)) {
|
||||||
newSelected = OverGroupAdd {};
|
newSelected = OverGroupAdd{};
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto rowIndex = qFloor(yOffset / _singleSize.height());
|
auto rowIndex = qFloor(yOffset / _singleSize.height());
|
||||||
|
@ -2616,50 +2613,6 @@ void StickersListWidget::displaySet(uint64 setId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::installSet(uint64 setId) {
|
|
||||||
const auto &sets = session().data().stickers().sets();
|
|
||||||
const auto it = sets.find(setId);
|
|
||||||
if (it != sets.cend()) {
|
|
||||||
const auto set = it->second.get();
|
|
||||||
const auto input = set->mtpInput();
|
|
||||||
if ((set->flags & SetFlag::NotLoaded) || set->stickers.empty()) {
|
|
||||||
_api.request(MTPmessages_GetStickerSet(
|
|
||||||
input,
|
|
||||||
MTP_int(0) // hash
|
|
||||||
)).done([=](const MTPmessages_StickerSet &result) {
|
|
||||||
result.match([&](const MTPDmessages_stickerSet &data) {
|
|
||||||
session().data().stickers().feedSetFull(data);
|
|
||||||
}, [](const MTPDmessages_stickerSetNotModified &) {
|
|
||||||
LOG(("API Error: Unexpected messages.stickerSetNotModified."));
|
|
||||||
});
|
|
||||||
sendInstallRequest(setId, input);
|
|
||||||
}).send();
|
|
||||||
} else {
|
|
||||||
sendInstallRequest(setId, input);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickersListWidget::sendInstallRequest(
|
|
||||||
uint64 setId,
|
|
||||||
const MTPInputStickerSet &input) {
|
|
||||||
_api.request(MTPmessages_InstallStickerSet(
|
|
||||||
input,
|
|
||||||
MTP_bool(false)
|
|
||||||
)).done([=](const MTPmessages_StickerSetInstallResult &result) {
|
|
||||||
if (result.type() == mtpc_messages_stickerSetInstallResultArchive) {
|
|
||||||
session().data().stickers().applyArchivedResult(
|
|
||||||
result.c_messages_stickerSetInstallResultArchive());
|
|
||||||
}
|
|
||||||
}).fail([=] {
|
|
||||||
notInstalledLocally(setId);
|
|
||||||
session().data().stickers().undoInstallLocally(setId);
|
|
||||||
}).send();
|
|
||||||
|
|
||||||
installedLocally(setId);
|
|
||||||
session().data().stickers().installLocally(setId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StickersListWidget::removeMegagroupSet(bool locally) {
|
void StickersListWidget::removeMegagroupSet(bool locally) {
|
||||||
if (locally) {
|
if (locally) {
|
||||||
session().settings().setGroupStickersSectionHidden(_megagroupSet->id);
|
session().settings().setGroupStickersSectionHidden(_megagroupSet->id);
|
||||||
|
@ -2693,15 +2646,15 @@ void StickersListWidget::removeSet(uint64 setId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Data::StickersSetsOrder &StickersListWidget::defaultSetsOrder() const {
|
const Data::StickersSetsOrder &StickersListWidget::defaultSetsOrder() const {
|
||||||
return !_isMasks
|
return _isMasks
|
||||||
? session().data().stickers().setsOrder()
|
? session().data().stickers().maskSetsOrder()
|
||||||
: session().data().stickers().maskSetsOrder();
|
: session().data().stickers().setsOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::StickersSetsOrder &StickersListWidget::defaultSetsOrderRef() {
|
Data::StickersSetsOrder &StickersListWidget::defaultSetsOrderRef() {
|
||||||
return !_isMasks
|
return _isMasks
|
||||||
? session().data().stickers().setsOrderRef()
|
? session().data().stickers().maskSetsOrderRef()
|
||||||
: session().data().stickers().maskSetsOrderRef();
|
: session().data().stickers().setsOrderRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickersListWidget::mySetsEmpty() const {
|
bool StickersListWidget::mySetsEmpty() const {
|
||||||
|
@ -2762,9 +2715,9 @@ object_ptr<Ui::BoxContent> MakeConfirmRemoveSetBox(
|
||||||
// && !(set->flags & SetFlag::Special)) {
|
// && !(set->flags & SetFlag::Special)) {
|
||||||
// sets.erase(it);
|
// sets.erase(it);
|
||||||
//}
|
//}
|
||||||
auto &orderRef = (set->flags & SetFlag::Emoji)
|
auto &orderRef = (set->type() == Data::StickersType::Emoji)
|
||||||
? session->data().stickers().emojiSetsOrderRef()
|
? session->data().stickers().emojiSetsOrderRef()
|
||||||
: (set->flags & SetFlag::Masks)
|
: (set->type() == Data::StickersType::Masks)
|
||||||
? session->data().stickers().maskSetsOrderRef()
|
? session->data().stickers().maskSetsOrderRef()
|
||||||
: session->data().stickers().setsOrderRef();
|
: session->data().stickers().setsOrderRef();
|
||||||
const auto removeIndex = orderRef.indexOf(setId);
|
const auto removeIndex = orderRef.indexOf(setId);
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace ChatHelpers {
|
||||||
struct StickerIcon;
|
struct StickerIcon;
|
||||||
enum class ValidateIconAnimations;
|
enum class ValidateIconAnimations;
|
||||||
class StickersListFooter;
|
class StickersListFooter;
|
||||||
|
class LocalStickersManager;
|
||||||
|
|
||||||
class StickersListWidget final : public TabbedSelector::Inner {
|
class StickersListWidget final : public TabbedSelector::Inner {
|
||||||
public:
|
public:
|
||||||
|
@ -78,10 +79,6 @@ public:
|
||||||
|
|
||||||
uint64 currentSet(int yOffset) const;
|
uint64 currentSet(int yOffset) const;
|
||||||
|
|
||||||
void installedLocally(uint64 setId);
|
|
||||||
void notInstalledLocally(uint64 setId);
|
|
||||||
void clearInstalledLocally();
|
|
||||||
|
|
||||||
void sendSearchRequest();
|
void sendSearchRequest();
|
||||||
void searchForSets(const QString &query);
|
void searchForSets(const QString &query);
|
||||||
|
|
||||||
|
@ -202,12 +199,8 @@ private:
|
||||||
|
|
||||||
void setSection(Section section);
|
void setSection(Section section);
|
||||||
void displaySet(uint64 setId);
|
void displaySet(uint64 setId);
|
||||||
void installSet(uint64 setId);
|
|
||||||
void removeMegagroupSet(bool locally);
|
void removeMegagroupSet(bool locally);
|
||||||
void removeSet(uint64 setId);
|
void removeSet(uint64 setId);
|
||||||
void sendInstallRequest(
|
|
||||||
uint64 setId,
|
|
||||||
const MTPInputStickerSet &input);
|
|
||||||
void refreshMySets();
|
void refreshMySets();
|
||||||
void refreshFeaturedSets();
|
void refreshFeaturedSets();
|
||||||
void refreshSearchSets();
|
void refreshSearchSets();
|
||||||
|
@ -277,14 +270,16 @@ private:
|
||||||
const SectionInfo &info,
|
const SectionInfo &info,
|
||||||
crl::time now);
|
crl::time now);
|
||||||
|
|
||||||
int stickersRight() const;
|
[[nodiscard]] int stickersRight() const;
|
||||||
bool featuredHasAddButton(int index) const;
|
[[nodiscard]] bool featuredHasAddButton(int index) const;
|
||||||
QRect featuredAddRect(int index) const;
|
[[nodiscard]] QRect featuredAddRect(int index) const;
|
||||||
bool hasRemoveButton(int index) const;
|
[[nodiscard]] QRect featuredAddRect(const SectionInfo &info) const;
|
||||||
QRect removeButtonRect(int index) const;
|
[[nodiscard]] bool hasRemoveButton(int index) const;
|
||||||
int megagroupSetInfoLeft() const;
|
[[nodiscard]] QRect removeButtonRect(int index) const;
|
||||||
|
[[nodiscard]] QRect removeButtonRect(const SectionInfo &info) const;
|
||||||
|
[[nodiscard]] int megagroupSetInfoLeft() const;
|
||||||
void refreshMegagroupSetGeometry();
|
void refreshMegagroupSetGeometry();
|
||||||
QRect megagroupSetButtonRectFinal() const;
|
[[nodiscard]] QRect megagroupSetButtonRectFinal() const;
|
||||||
|
|
||||||
[[nodiscard]] const Data::StickersSetsOrder &defaultSetsOrder() const;
|
[[nodiscard]] const Data::StickersSetsOrder &defaultSetsOrder() const;
|
||||||
[[nodiscard]] Data::StickersSetsOrder &defaultSetsOrderRef();
|
[[nodiscard]] Data::StickersSetsOrder &defaultSetsOrderRef();
|
||||||
|
@ -332,6 +327,7 @@ private:
|
||||||
not_null<DocumentData*> document);
|
not_null<DocumentData*> document);
|
||||||
|
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
|
std::unique_ptr<LocalStickersManager> _localSetsManager;
|
||||||
ChannelData *_megagroupSet = nullptr;
|
ChannelData *_megagroupSet = nullptr;
|
||||||
uint64 _megagroupSetIdRequested = 0;
|
uint64 _megagroupSetIdRequested = 0;
|
||||||
std::vector<Set> _mySets;
|
std::vector<Set> _mySets;
|
||||||
|
@ -339,7 +335,6 @@ private:
|
||||||
std::vector<Set> _searchSets;
|
std::vector<Set> _searchSets;
|
||||||
int _premiumsIndex = -1;
|
int _premiumsIndex = -1;
|
||||||
int _featuredSetsCount = 0;
|
int _featuredSetsCount = 0;
|
||||||
base::flat_set<uint64> _installedLocallySets;
|
|
||||||
std::vector<bool> _custom;
|
std::vector<bool> _custom;
|
||||||
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
base::flat_set<not_null<DocumentData*>> _favedStickersMap;
|
||||||
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
|
std::weak_ptr<Lottie::FrameRenderer> _lottieRenderer;
|
||||||
|
|
|
@ -356,9 +356,12 @@ void Stickers::applyArchivedResult(
|
||||||
if (set->flags & SetFlag::NotLoaded) {
|
if (set->flags & SetFlag::NotLoaded) {
|
||||||
setsToRequest.insert(set->id, set->accessHash);
|
setsToRequest.insert(set->id, set->accessHash);
|
||||||
}
|
}
|
||||||
const auto masks = !!(set->flags & SetFlag::Masks);
|
if (set->type() == StickersType::Emoji) {
|
||||||
(masks ? masksCount : stickersCount)++;
|
continue;
|
||||||
auto &order = masks ? maskSetsOrderRef() : setsOrderRef();
|
}
|
||||||
|
const auto isMasks = (set->type() == StickersType::Masks);
|
||||||
|
(isMasks ? masksCount : stickersCount)++;
|
||||||
|
auto &order = isMasks ? maskSetsOrderRef() : setsOrderRef();
|
||||||
const auto index = order.indexOf(set->id);
|
const auto index = order.indexOf(set->id);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
order.removeAt(index);
|
order.removeAt(index);
|
||||||
|
@ -692,12 +695,7 @@ void Stickers::somethingReceived(
|
||||||
QMap<uint64, uint64> setsToRequest;
|
QMap<uint64, uint64> setsToRequest;
|
||||||
for (auto &[id, set] : sets) {
|
for (auto &[id, set] : sets) {
|
||||||
const auto archived = !!(set->flags & SetFlag::Archived);
|
const auto archived = !!(set->flags & SetFlag::Archived);
|
||||||
const auto setType = !!(set->flags & SetFlag::Emoji)
|
if (!archived && (type == set->type())) {
|
||||||
? StickersType::Emoji
|
|
||||||
: !!(set->flags & SetFlag::Masks)
|
|
||||||
? StickersType::Masks
|
|
||||||
: StickersType::Stickers;
|
|
||||||
if (!archived && (type == setType)) {
|
|
||||||
// Mark for removing.
|
// Mark for removing.
|
||||||
set->flags &= ~SetFlag::Installed;
|
set->flags &= ~SetFlag::Installed;
|
||||||
set->installDate = 0;
|
set->installDate = 0;
|
||||||
|
@ -964,10 +962,10 @@ void Stickers::featuredReceived(
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto isEmoji = (type == StickersType::Emoji);
|
const auto isEmoji = (type == StickersType::Emoji);
|
||||||
auto &setsOrder = isEmoji
|
auto &featuredOrder = isEmoji
|
||||||
? featuredEmojiSetsOrderRef()
|
? featuredEmojiSetsOrderRef()
|
||||||
: featuredSetsOrderRef();
|
: featuredSetsOrderRef();
|
||||||
setsOrder.clear();
|
featuredOrder.clear();
|
||||||
|
|
||||||
auto &sets = setsRef();
|
auto &sets = setsRef();
|
||||||
auto setsToRequest = base::flat_map<uint64, uint64>();
|
auto setsToRequest = base::flat_map<uint64, uint64>();
|
||||||
|
@ -1000,15 +998,14 @@ void Stickers::featuredReceived(
|
||||||
}
|
}
|
||||||
return ImageWithLocation();
|
return ImageWithLocation();
|
||||||
}();
|
}();
|
||||||
|
const auto setId = data->vid().v;
|
||||||
const auto flags = SetFlag::Featured
|
const auto flags = SetFlag::Featured
|
||||||
| (unreadMap.contains(data->vid().v)
|
| (unreadMap.contains(setId) ? SetFlag::Unread : SetFlag())
|
||||||
? SetFlag::Unread
|
|
||||||
: SetFlag())
|
|
||||||
| ParseStickersSetFlags(*data);
|
| ParseStickersSetFlags(*data);
|
||||||
if (it == sets.cend()) {
|
if (it == sets.cend()) {
|
||||||
it = sets.emplace(data->vid().v, std::make_unique<StickersSet>(
|
it = sets.emplace(data->vid().v, std::make_unique<StickersSet>(
|
||||||
&owner(),
|
&owner(),
|
||||||
data->vid().v,
|
setId,
|
||||||
data->vaccess_hash().v,
|
data->vaccess_hash().v,
|
||||||
data->vhash().v,
|
data->vhash().v,
|
||||||
title,
|
title,
|
||||||
|
@ -1032,7 +1029,7 @@ void Stickers::featuredReceived(
|
||||||
}
|
}
|
||||||
it->second->setThumbnail(thumbnail);
|
it->second->setThumbnail(thumbnail);
|
||||||
it->second->thumbnailDocumentId = data->vthumb_document_id().value_or_empty();
|
it->second->thumbnailDocumentId = data->vthumb_document_id().value_or_empty();
|
||||||
setsOrder.push_back(data->vid().v);
|
featuredOrder.push_back(data->vid().v);
|
||||||
if (it->second->stickers.isEmpty()
|
if (it->second->stickers.isEmpty()
|
||||||
|| (it->second->flags & SetFlag::NotLoaded)) {
|
|| (it->second->flags & SetFlag::NotLoaded)) {
|
||||||
setsToRequest.emplace(data->vid().v, data->vaccess_hash().v);
|
setsToRequest.emplace(data->vid().v, data->vaccess_hash().v);
|
||||||
|
@ -1361,8 +1358,8 @@ not_null<StickersSet*> Stickers::feedSet(const MTPStickerSet &info) {
|
||||||
set->thumbnailDocumentId = data.vthumb_document_id().value_or_empty();
|
set->thumbnailDocumentId = data.vthumb_document_id().value_or_empty();
|
||||||
auto changedFlags = (oldFlags ^ set->flags);
|
auto changedFlags = (oldFlags ^ set->flags);
|
||||||
if (changedFlags & SetFlag::Archived) {
|
if (changedFlags & SetFlag::Archived) {
|
||||||
const auto masks = !!(set->flags & SetFlag::Masks);
|
const auto isMasks = (set->type() == StickersType::Masks);
|
||||||
auto &archivedOrder = masks
|
auto &archivedOrder = isMasks
|
||||||
? archivedMaskSetsOrderRef()
|
? archivedMaskSetsOrderRef()
|
||||||
: archivedSetsOrderRef();
|
: archivedSetsOrderRef();
|
||||||
const auto index = archivedOrder.indexOf(set->id);
|
const auto index = archivedOrder.indexOf(set->id);
|
||||||
|
|
|
@ -403,7 +403,7 @@ void Form::processDetails(const MTPDpayments_paymentForm &data) {
|
||||||
_invoice.cover.title = qs(data.vtitle());
|
_invoice.cover.title = qs(data.vtitle());
|
||||||
_invoice.cover.description = TextUtilities::ParseEntities(
|
_invoice.cover.description = TextUtilities::ParseEntities(
|
||||||
qs(data.vdescription()),
|
qs(data.vdescription()),
|
||||||
TextParseLinks | TextParseMultiline)
|
TextParseLinks | TextParseMultiline);
|
||||||
if (_invoice.cover.thumbnail.isNull() && !_thumbnailLoadProcess) {
|
if (_invoice.cover.thumbnail.isNull() && !_thumbnailLoadProcess) {
|
||||||
if (const auto photo = data.vphoto()) {
|
if (const auto photo = data.vphoto()) {
|
||||||
loadThumbnail(
|
loadThumbnail(
|
||||||
|
@ -435,7 +435,7 @@ void Form::processDetails(const MTPDpayments_paymentReceipt &data) {
|
||||||
.providerId = data.vprovider_id().v,
|
.providerId = data.vprovider_id().v,
|
||||||
};
|
};
|
||||||
if (_invoice.cover.title.isEmpty()
|
if (_invoice.cover.title.isEmpty()
|
||||||
&& _invoice.cover.description.isEmpty()
|
&& _invoice.cover.description.empty()
|
||||||
&& _invoice.cover.thumbnail.isNull()
|
&& _invoice.cover.thumbnail.isNull()
|
||||||
&& !_thumbnailLoadProcess) {
|
&& !_thumbnailLoadProcess) {
|
||||||
_invoice.cover = Ui::Cover{
|
_invoice.cover = Ui::Cover{
|
||||||
|
|
|
@ -2019,9 +2019,8 @@ void Account::writeInstalledStickers() {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
}
|
}
|
||||||
} else if (!(set.flags & SetFlag::Installed)
|
} else if (!(set.flags & SetFlag::Installed)
|
||||||
|| (set.flags & SetFlag::Archived)) {
|
|| (set.flags & SetFlag::Archived)
|
||||||
return StickerSetCheckResult::Skip;
|
|| (set.type() != Data::StickersType::Stickers)) {
|
||||||
} else if (set.flags & (SetFlag::Masks | SetFlag::Emoji)) {
|
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
} else if (set.flags & SetFlag::NotLoaded) {
|
} else if (set.flags & SetFlag::NotLoaded) {
|
||||||
// waiting to receive
|
// waiting to receive
|
||||||
|
@ -2042,9 +2041,9 @@ void Account::writeFeaturedStickers() {
|
||||||
|| set.id == Data::Stickers::CloudRecentAttachedSetId) {
|
|| set.id == Data::Stickers::CloudRecentAttachedSetId) {
|
||||||
// separate files for them
|
// separate files for them
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
} else if (set.flags & (SetFlag::Special | SetFlag::Emoji)) {
|
} else if ((set.flags & SetFlag::Special)
|
||||||
return StickerSetCheckResult::Skip;
|
|| !(set.flags & SetFlag::Featured)
|
||||||
} else if (!(set.flags & SetFlag::Featured)) {
|
|| (set.type() != Data::StickersType::Stickers)) {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
} else if (set.flags & SetFlag::NotLoaded) { // waiting to receive
|
} else if (set.flags & SetFlag::NotLoaded) { // waiting to receive
|
||||||
return StickerSetCheckResult::Abort;
|
return StickerSetCheckResult::Abort;
|
||||||
|
@ -2059,9 +2058,8 @@ void Account::writeFeaturedCustomEmoji() {
|
||||||
using SetFlag = Data::StickersSetFlag;
|
using SetFlag = Data::StickersSetFlag;
|
||||||
|
|
||||||
writeStickerSets(_featuredCustomEmojiKey, [](const Data::StickersSet &set) {
|
writeStickerSets(_featuredCustomEmojiKey, [](const Data::StickersSet &set) {
|
||||||
if (!(set.flags & SetFlag::Emoji)) {
|
if (!(set.flags & SetFlag::Featured)
|
||||||
return StickerSetCheckResult::Skip;
|
|| (set.type() != Data::StickersType::Emoji)) {
|
||||||
} else if (!(set.flags & SetFlag::Featured)) {
|
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
} else if (set.flags & SetFlag::NotLoaded) { // waiting to receive
|
} else if (set.flags & SetFlag::NotLoaded) { // waiting to receive
|
||||||
return StickerSetCheckResult::Abort;
|
return StickerSetCheckResult::Abort;
|
||||||
|
@ -2095,10 +2093,8 @@ void Account::writeArchivedStickers() {
|
||||||
using SetFlag = Data::StickersSetFlag;
|
using SetFlag = Data::StickersSetFlag;
|
||||||
|
|
||||||
writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) {
|
writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) {
|
||||||
if (set.flags & (SetFlag::Masks | SetFlag::Emoji)) {
|
|
||||||
return StickerSetCheckResult::Skip;
|
|
||||||
}
|
|
||||||
if (!(set.flags & SetFlag::Archived)
|
if (!(set.flags & SetFlag::Archived)
|
||||||
|
|| (set.type() != Data::StickersType::Stickers)
|
||||||
|| set.stickers.isEmpty()) {
|
|| set.stickers.isEmpty()) {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
}
|
}
|
||||||
|
@ -2110,10 +2106,9 @@ void Account::writeArchivedMasks() {
|
||||||
using SetFlag = Data::StickersSetFlag;
|
using SetFlag = Data::StickersSetFlag;
|
||||||
|
|
||||||
writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) {
|
writeStickerSets(_archivedStickersKey, [](const Data::StickersSet &set) {
|
||||||
if (!(set.flags & SetFlag::Masks)) {
|
if (!(set.flags & SetFlag::Archived)
|
||||||
return StickerSetCheckResult::Skip;
|
|| (set.type() != Data::StickersType::Masks)
|
||||||
}
|
|| set.stickers.isEmpty()) {
|
||||||
if (!(set.flags & SetFlag::Archived) || set.stickers.isEmpty()) {
|
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
}
|
}
|
||||||
return StickerSetCheckResult::Write;
|
return StickerSetCheckResult::Write;
|
||||||
|
@ -2124,7 +2119,10 @@ void Account::writeInstalledMasks() {
|
||||||
using SetFlag = Data::StickersSetFlag;
|
using SetFlag = Data::StickersSetFlag;
|
||||||
|
|
||||||
writeStickerSets(_installedMasksKey, [](const Data::StickersSet &set) {
|
writeStickerSets(_installedMasksKey, [](const Data::StickersSet &set) {
|
||||||
if (!(set.flags & SetFlag::Masks) || set.stickers.isEmpty()) {
|
if (!(set.flags & SetFlag::Installed)
|
||||||
|
|| (set.flags & SetFlag::Archived)
|
||||||
|
|| (set.type() != Data::StickersType::Masks)
|
||||||
|
|| set.stickers.isEmpty()) {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
}
|
}
|
||||||
return StickerSetCheckResult::Write;
|
return StickerSetCheckResult::Write;
|
||||||
|
@ -2145,14 +2143,14 @@ void Account::writeInstalledCustomEmoji() {
|
||||||
using SetFlag = Data::StickersSetFlag;
|
using SetFlag = Data::StickersSetFlag;
|
||||||
|
|
||||||
writeStickerSets(_installedCustomEmojiKey, [](const Data::StickersSet &set) {
|
writeStickerSets(_installedCustomEmojiKey, [](const Data::StickersSet &set) {
|
||||||
if (!(set.flags & SetFlag::Emoji)) {
|
if (!(set.flags & SetFlag::Installed)
|
||||||
|
|| (set.flags & SetFlag::Archived)
|
||||||
|
|| (set.type() != Data::StickersType::Emoji)) {
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
} else if (set.flags & SetFlag::NotLoaded) {
|
} else if (set.flags & SetFlag::NotLoaded) {
|
||||||
// waiting to receive
|
// waiting to receive
|
||||||
return StickerSetCheckResult::Abort;
|
return StickerSetCheckResult::Abort;
|
||||||
} else if (!(set.flags & SetFlag::Installed)
|
} else if (set.stickers.isEmpty()) {
|
||||||
|| (set.flags & SetFlag::Archived)
|
|
||||||
|| set.stickers.isEmpty()) {
|
|
||||||
return StickerSetCheckResult::Skip;
|
return StickerSetCheckResult::Skip;
|
||||||
}
|
}
|
||||||
return StickerSetCheckResult::Write;
|
return StickerSetCheckResult::Write;
|
||||||
|
|
Loading…
Add table
Reference in a new issue