mirror of https://github.com/procxx/kepka.git
Show animated stickers in the panel.
This commit is contained in:
parent
040cae6a9a
commit
0d6ee3929d
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
#include "ui/effects/ripple_animation.h"
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
#include "lottie/lottie_animation.h"
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
#include "chat_helpers/stickers.h"
|
#include "chat_helpers/stickers.h"
|
||||||
|
@ -24,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/sticker_set_box.h"
|
#include "boxes/sticker_set_box.h"
|
||||||
#include "boxes/stickers_box.h"
|
#include "boxes/stickers_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
#include "window/window_session_controller.h" // GifPauseReason.
|
||||||
#include "auth_session.h"
|
#include "auth_session.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
@ -155,6 +157,15 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto StickersListWidget::PrepareStickers(const Stickers::Pack &pack)
|
||||||
|
-> std::vector<Sticker> {
|
||||||
|
return ranges::view::all(
|
||||||
|
pack
|
||||||
|
) | ranges::view::transform([](DocumentData *document) {
|
||||||
|
return Sticker{ document };
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
}
|
||||||
|
|
||||||
StickersListWidget::Set::Set(
|
StickersListWidget::Set::Set(
|
||||||
uint64 id,
|
uint64 id,
|
||||||
MTPDstickerSet::Flags flags,
|
MTPDstickerSet::Flags flags,
|
||||||
|
@ -163,13 +174,13 @@ StickersListWidget::Set::Set(
|
||||||
ImagePtr thumbnail,
|
ImagePtr thumbnail,
|
||||||
bool externalLayout,
|
bool externalLayout,
|
||||||
int count,
|
int count,
|
||||||
const Stickers::Pack &pack)
|
std::vector<Sticker> &&stickers)
|
||||||
: id(id)
|
: id(id)
|
||||||
, flags(flags)
|
, flags(flags)
|
||||||
, title(title)
|
, title(title)
|
||||||
, shortName(shortName)
|
, shortName(shortName)
|
||||||
, thumbnail(thumbnail)
|
, thumbnail(thumbnail)
|
||||||
, pack(pack)
|
, stickers(std::move(stickers))
|
||||||
, externalLayout(externalLayout)
|
, externalLayout(externalLayout)
|
||||||
, count(count) {
|
, count(count) {
|
||||||
}
|
}
|
||||||
|
@ -773,12 +784,12 @@ void StickersListWidget::readVisibleSets() {
|
||||||
if (i * rowHeight < itemsVisibleTop || (i + 1) * rowHeight > itemsVisibleBottom) {
|
if (i * rowHeight < itemsVisibleTop || (i + 1) * rowHeight > itemsVisibleBottom) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int count = qMin(set.pack.size(), _columnCount);
|
int count = qMin(int(set.stickers.size()), _columnCount);
|
||||||
int loaded = 0;
|
int loaded = 0;
|
||||||
for (int j = 0; j < count; ++j) {
|
for (int j = 0; j < count; ++j) {
|
||||||
if (!set.pack[j]->hasThumbnail()
|
if (!set.stickers[j].document->hasThumbnail()
|
||||||
|| set.pack[j]->thumbnail()->loaded()
|
|| set.stickers[j].document->thumbnail()->loaded()
|
||||||
|| set.pack[j]->loaded()) {
|
|| set.stickers[j].document->loaded()) {
|
||||||
++loaded;
|
++loaded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -801,7 +812,7 @@ bool StickersListWidget::enumerateSections(Callback callback) const {
|
||||||
for (auto i = 0; i != sets.size(); ++i) {
|
for (auto i = 0; i != sets.size(); ++i) {
|
||||||
auto &set = sets[i];
|
auto &set = sets[i];
|
||||||
info.section = i;
|
info.section = i;
|
||||||
info.count = set.pack.size();
|
info.count = set.stickers.size();
|
||||||
const auto titleSkip = set.externalLayout
|
const auto titleSkip = set.externalLayout
|
||||||
? st::stickersTrendingHeader
|
? st::stickersTrendingHeader
|
||||||
: setHasTitle(set)
|
: setHasTitle(set)
|
||||||
|
@ -1061,7 +1072,9 @@ void StickersListWidget::addSearchRow(not_null<const Stickers::Set*> set) {
|
||||||
set->thumbnail,
|
set->thumbnail,
|
||||||
!SetInMyList(set->flags),
|
!SetInMyList(set->flags),
|
||||||
set->count,
|
set->count,
|
||||||
set->stickers.empty() ? set->covers : set->stickers);
|
PrepareStickers(set->stickers.empty()
|
||||||
|
? set->covers
|
||||||
|
: set->stickers));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto StickersListWidget::shownSets() const -> const std::vector<Set> & {
|
auto StickersListWidget::shownSets() const -> const std::vector<Set> & {
|
||||||
|
@ -1102,7 +1115,7 @@ void StickersListWidget::searchResultsDone(
|
||||||
std::vector<uint64>()).first;
|
std::vector<uint64>()).first;
|
||||||
}
|
}
|
||||||
auto &d = result.c_messages_foundStickerSets();
|
auto &d = result.c_messages_foundStickerSets();
|
||||||
for_const (const auto &stickerSet, d.vsets.v) {
|
for (const auto &stickerSet : d.vsets.v) {
|
||||||
const MTPDstickerSet *setData = nullptr;
|
const MTPDstickerSet *setData = nullptr;
|
||||||
Stickers::Pack covers;
|
Stickers::Pack covers;
|
||||||
switch (stickerSet.type()) {
|
switch (stickerSet.type()) {
|
||||||
|
@ -1146,8 +1159,8 @@ int StickersListWidget::stickersLeft() const {
|
||||||
|
|
||||||
QRect StickersListWidget::stickerRect(int section, int sel) {
|
QRect StickersListWidget::stickerRect(int section, int sel) {
|
||||||
auto info = sectionInfo(section);
|
auto info = sectionInfo(section);
|
||||||
if (sel >= shownSets()[section].pack.size()) {
|
if (sel >= shownSets()[section].stickers.size()) {
|
||||||
sel -= shownSets()[section].pack.size();
|
sel -= shownSets()[section].stickers.size();
|
||||||
}
|
}
|
||||||
auto countTillItem = (sel - (sel % _columnCount));
|
auto countTillItem = (sel - (sel % _columnCount));
|
||||||
auto rowsToSkip = (countTillItem / _columnCount) + ((countTillItem % _columnCount) ? 1 : 0);
|
auto rowsToSkip = (countTillItem / _columnCount) + ((countTillItem % _columnCount) ? 1 : 0);
|
||||||
|
@ -1191,7 +1204,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
const auto size = (set.flags
|
const auto size = (set.flags
|
||||||
& MTPDstickerSet_ClientFlag::f_not_loaded)
|
& MTPDstickerSet_ClientFlag::f_not_loaded)
|
||||||
? set.count
|
? set.count
|
||||||
: int(set.pack.size());
|
: int(set.stickers.size());
|
||||||
|
|
||||||
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::buttonRadius);
|
auto widthForTitle = stickersRight() - (st::emojiPanHeaderLeft - st::buttonRadius);
|
||||||
if (featuredHasAddButton(info.section)) {
|
if (featuredHasAddButton(info.section)) {
|
||||||
|
@ -1256,7 +1269,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
|
|
||||||
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
||||||
auto deleteSelected = false;
|
auto deleteSelected = false;
|
||||||
paintSticker(p, set, info.rowsTop, index, selected, deleteSelected);
|
paintSticker(p, set, info.rowsTop, info.section, index, selected, deleteSelected);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1286,7 +1299,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
p.drawTextLeft(st::emojiPanHeaderLeft - st::buttonRadius, info.top + st::emojiPanHeaderTop, width(), titleText, titleWidth);
|
p.drawTextLeft(st::emojiPanHeaderLeft - st::buttonRadius, info.top + st::emojiPanHeaderTop, width(), titleText, titleWidth);
|
||||||
}
|
}
|
||||||
if (clip.top() + clip.height() > info.rowsTop) {
|
if (clip.top() + clip.height() > info.rowsTop) {
|
||||||
if (set.id == Stickers::MegagroupSetId && set.pack.empty()) {
|
if (set.id == Stickers::MegagroupSetId && set.stickers.empty()) {
|
||||||
auto buttonSelected = (base::get_if<OverGroupAdd>(&_selected) != nullptr);
|
auto buttonSelected = (base::get_if<OverGroupAdd>(&_selected) != nullptr);
|
||||||
paintMegagroupEmptySet(p, info.rowsTop, buttonSelected);
|
paintMegagroupEmptySet(p, info.rowsTop, buttonSelected);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1300,7 +1313,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
|
||||||
|
|
||||||
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
auto selected = selectedSticker ? (selectedSticker->section == info.section && selectedSticker->index == index) : false;
|
||||||
auto deleteSelected = selected && selectedSticker->overDelete;
|
auto deleteSelected = selected && selectedSticker->overDelete;
|
||||||
paintSticker(p, set, info.rowsTop, index, selected, deleteSelected);
|
paintSticker(p, set, info.rowsTop, info.section, index, selected, deleteSelected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1351,9 +1364,34 @@ void StickersListWidget::paintMegagroupEmptySet(Painter &p, int y, bool buttonSe
|
||||||
p.drawTextLeft(button.x() - (st::stickerGroupCategoryAdd.width / 2), button.y() + st::stickerGroupCategoryAdd.textTop, width(), _megagroupSetButtonText, _megagroupSetButtonTextWidth);
|
p.drawTextLeft(button.x() - (st::stickerGroupCategoryAdd.width / 2), button.y() + st::stickerGroupCategoryAdd.textTop, width(), _megagroupSetButtonText, _megagroupSetButtonTextWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bool selected, bool deleteSelected) {
|
void StickersListWidget::setupLottie(Set &set, int section, int index) {
|
||||||
auto document = set.pack[index];
|
auto &sticker = set.stickers[index];
|
||||||
if (!document->sticker()) return;
|
const auto document = sticker.document;
|
||||||
|
|
||||||
|
sticker.animated = document->data().isEmpty()
|
||||||
|
? Lottie::FromFile(document->filepath())
|
||||||
|
: Lottie::FromData(document->data());
|
||||||
|
const auto animation = sticker.animated.get();
|
||||||
|
|
||||||
|
animation->updates(
|
||||||
|
) | rpl::start_with_next_error([=](Lottie::Update update) {
|
||||||
|
rtlupdate(stickerRect(section, index));
|
||||||
|
}, [=](Lottie::Error error) {
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int section, int index, bool selected, bool deleteSelected) {
|
||||||
|
auto &sticker = set.stickers[index];
|
||||||
|
const auto document = sticker.document;
|
||||||
|
if (!document->sticker()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document->sticker()->animated
|
||||||
|
&& !sticker.animated
|
||||||
|
&& document->loaded()) {
|
||||||
|
setupLottie(set, section, index);
|
||||||
|
}
|
||||||
|
|
||||||
int row = (index / _columnCount), col = (index % _columnCount);
|
int row = (index / _columnCount), col = (index % _columnCount);
|
||||||
|
|
||||||
|
@ -1371,7 +1409,19 @@ void StickersListWidget::paintSticker(Painter &p, Set &set, int y, int index, bo
|
||||||
auto w = qMax(qRound(coef * document->dimensions.width()), 1);
|
auto w = qMax(qRound(coef * document->dimensions.width()), 1);
|
||||||
auto h = qMax(qRound(coef * document->dimensions.height()), 1);
|
auto h = qMax(qRound(coef * document->dimensions.height()), 1);
|
||||||
auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2);
|
auto ppos = pos + QPoint((_singleSize.width() - w) / 2, (_singleSize.height() - h) / 2);
|
||||||
if (const auto image = document->getStickerSmall()) {
|
if (sticker.animated && sticker.animated->ready()) {
|
||||||
|
const auto size = QSize(w, h);
|
||||||
|
auto request = Lottie::FrameRequest();
|
||||||
|
request.resize = size * cIntRetinaFactor();
|
||||||
|
const auto paused = controller()->isGifPausedAtLeastFor(
|
||||||
|
Window::GifPauseReason::SavedGifs);
|
||||||
|
if (!paused) {
|
||||||
|
sticker.animated->markFrameShown();
|
||||||
|
}
|
||||||
|
p.drawImage(
|
||||||
|
QRect(ppos, size),
|
||||||
|
sticker.animated->frame(request));
|
||||||
|
} else if (const auto image = document->getStickerSmall()) {
|
||||||
if (image->loaded()) {
|
if (image->loaded()) {
|
||||||
p.drawPixmapLeft(
|
p.drawPixmapLeft(
|
||||||
ppos,
|
ppos,
|
||||||
|
@ -1435,7 +1485,7 @@ bool StickersListWidget::hasRemoveButton(int index) const {
|
||||||
if (index + 1 != shownSets().size()) {
|
if (index + 1 != shownSets().size()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return !set.pack.empty() && _megagroupSet->canEditStickers();
|
return !set.stickers.empty() && _megagroupSet->canEditStickers();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1559,7 +1609,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
if (auto sticker = base::get_if<OverSticker>(&pressed)) {
|
if (auto sticker = base::get_if<OverSticker>(&pressed)) {
|
||||||
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
||||||
auto &set = sets[sticker->section];
|
auto &set = sets[sticker->section];
|
||||||
Assert(sticker->index >= 0 && sticker->index < set.pack.size());
|
Assert(sticker->index >= 0 && sticker->index < set.stickers.size());
|
||||||
if (stickerHasDeleteButton(set, sticker->index) && sticker->overDelete) {
|
if (stickerHasDeleteButton(set, sticker->index) && sticker->overDelete) {
|
||||||
if (set.id == Stickers::RecentSetId) {
|
if (set.id == Stickers::RecentSetId) {
|
||||||
removeRecentSticker(sticker->section, sticker->index);
|
removeRecentSticker(sticker->section, sticker->index);
|
||||||
|
@ -1570,7 +1620,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_chosen.fire_copy(set.pack[sticker->index]);
|
_chosen.fire_copy(set.stickers[sticker->index].document);
|
||||||
} else if (auto set = base::get_if<OverSet>(&pressed)) {
|
} else if (auto set = base::get_if<OverSet>(&pressed)) {
|
||||||
Assert(set->section >= 0 && set->section < sets.size());
|
Assert(set->section >= 0 && set->section < sets.size());
|
||||||
displaySet(sets[set->section].id);
|
displaySet(sets[set->section].id);
|
||||||
|
@ -1579,7 +1629,7 @@ void StickersListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
if (sets[button->section].externalLayout) {
|
if (sets[button->section].externalLayout) {
|
||||||
installSet(sets[button->section].id);
|
installSet(sets[button->section].id);
|
||||||
} else if (sets[button->section].id == Stickers::MegagroupSetId) {
|
} else if (sets[button->section].id == Stickers::MegagroupSetId) {
|
||||||
auto removeLocally = sets[button->section].pack.empty()
|
auto removeLocally = sets[button->section].stickers.empty()
|
||||||
|| !_megagroupSet->canEditStickers();
|
|| !_megagroupSet->canEditStickers();
|
||||||
removeMegagroupSet(removeLocally);
|
removeMegagroupSet(removeLocally);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1609,10 +1659,11 @@ void StickersListWidget::removeRecentSticker(int section, int index) {
|
||||||
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
bool refresh = false;
|
bool refresh = false;
|
||||||
auto sticker = _mySets[section].pack[index];
|
auto &sticker = _mySets[section].stickers[index];
|
||||||
|
const auto document = sticker.document;
|
||||||
auto &recent = Stickers::GetRecentPack();
|
auto &recent = Stickers::GetRecentPack();
|
||||||
for (int32 i = 0, l = recent.size(); i < l; ++i) {
|
for (int32 i = 0, l = recent.size(); i < l; ++i) {
|
||||||
if (recent.at(i).first == sticker) {
|
if (recent.at(i).first == document) {
|
||||||
recent.removeAt(i);
|
recent.removeAt(i);
|
||||||
Local::writeUserSettings();
|
Local::writeUserSettings();
|
||||||
refresh = true;
|
refresh = true;
|
||||||
|
@ -1623,7 +1674,7 @@ void StickersListWidget::removeRecentSticker(int section, int index) {
|
||||||
auto it = sets.find(Stickers::CustomSetId);
|
auto it = sets.find(Stickers::CustomSetId);
|
||||||
if (it != sets.cend()) {
|
if (it != sets.cend()) {
|
||||||
for (int i = 0, l = it->stickers.size(); i < l; ++i) {
|
for (int i = 0, l = it->stickers.size(); i < l; ++i) {
|
||||||
if (it->stickers.at(i) == sticker) {
|
if (it->stickers.at(i) == document) {
|
||||||
it->stickers.removeAt(i);
|
it->stickers.removeAt(i);
|
||||||
if (it->stickers.isEmpty()) {
|
if (it->stickers.isEmpty()) {
|
||||||
sets.erase(it);
|
sets.erase(it);
|
||||||
|
@ -1649,10 +1700,11 @@ void StickersListWidget::removeFavedSticker(int section, int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
clearSelection();
|
clearSelection();
|
||||||
auto sticker = _mySets[section].pack[index];
|
auto &sticker = _mySets[section].stickers[index];
|
||||||
Stickers::SetFaved(sticker, false);
|
const auto document = sticker.document;
|
||||||
|
Stickers::SetFaved(document, false);
|
||||||
Auth().api().toggleFavedSticker(
|
Auth().api().toggleFavedSticker(
|
||||||
sticker,
|
document,
|
||||||
Data::FileOriginStickerSet(Stickers::FavedSetId, 0),
|
Data::FileOriginStickerSet(Stickers::FavedSetId, 0),
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
@ -1764,7 +1816,8 @@ void StickersListWidget::refreshSearchSets() {
|
||||||
if (const auto it = sets.find(set.id); it != sets.end()) {
|
if (const auto it = sets.find(set.id); it != sets.end()) {
|
||||||
set.flags = it->flags;
|
set.flags = it->flags;
|
||||||
if (!it->stickers.empty()) {
|
if (!it->stickers.empty()) {
|
||||||
set.pack = it->stickers;
|
// #TODO stickers preserve lottie etc.
|
||||||
|
set.stickers = PrepareStickers(it->stickers);
|
||||||
}
|
}
|
||||||
if (!SetInMyList(set.flags)) {
|
if (!SetInMyList(set.flags)) {
|
||||||
_installedLocallySets.remove(set.id);
|
_installedLocallySets.remove(set.id);
|
||||||
|
@ -1801,14 +1854,14 @@ void StickersListWidget::refreshFooterIcons() {
|
||||||
void StickersListWidget::preloadImages() {
|
void StickersListWidget::preloadImages() {
|
||||||
auto &sets = shownSets();
|
auto &sets = shownSets();
|
||||||
for (int i = 0, l = sets.size(), k = 0; i < l; ++i) {
|
for (int i = 0, l = sets.size(), k = 0; i < l; ++i) {
|
||||||
int count = sets[i].pack.size();
|
int count = sets[i].stickers.size();
|
||||||
if (sets[i].externalLayout) {
|
if (sets[i].externalLayout) {
|
||||||
accumulate_min(count, _columnCount);
|
accumulate_min(count, _columnCount);
|
||||||
}
|
}
|
||||||
for (int j = 0; j != count; ++j) {
|
for (int j = 0; j != count; ++j) {
|
||||||
if (++k > _columnCount * (_columnCount + 1)) break;
|
if (++k > _columnCount * (_columnCount + 1)) break;
|
||||||
|
|
||||||
const auto document = sets[i].pack[j];
|
const auto document = sets[i].stickers[j].document;
|
||||||
if (!document || !document->sticker()) continue;
|
if (!document || !document->sticker()) continue;
|
||||||
|
|
||||||
document->checkStickerSmall();
|
document->checkStickerSmall();
|
||||||
|
@ -1860,7 +1913,7 @@ void StickersListWidget::appendSet(
|
||||||
it->thumbnail,
|
it->thumbnail,
|
||||||
externalLayout,
|
externalLayout,
|
||||||
it->count,
|
it->count,
|
||||||
it->stickers);
|
PrepareStickers(it->stickers));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickersListWidget::refreshRecent() {
|
void StickersListWidget::refreshRecent() {
|
||||||
|
@ -1872,14 +1925,14 @@ void StickersListWidget::refreshRecent() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Stickers::Pack StickersListWidget::collectRecentStickers() {
|
auto StickersListWidget::collectRecentStickers() -> std::vector<Sticker> {
|
||||||
_custom.clear();
|
_custom.clear();
|
||||||
auto result = Stickers::Pack();
|
auto result = std::vector<Sticker>();
|
||||||
|
|
||||||
auto &sets = Auth().data().stickerSets();
|
const auto &sets = Auth().data().stickerSets();
|
||||||
auto &recent = Stickers::GetRecentPack();
|
const auto &recent = Stickers::GetRecentPack();
|
||||||
auto customIt = sets.constFind(Stickers::CustomSetId);
|
const auto customIt = sets.constFind(Stickers::CustomSetId);
|
||||||
auto cloudIt = sets.constFind(Stickers::CloudRecentSetId);
|
const auto cloudIt = sets.constFind(Stickers::CloudRecentSetId);
|
||||||
const auto customCount = (customIt != sets.cend())
|
const auto customCount = (customIt != sets.cend())
|
||||||
? customIt->stickers.size()
|
? customIt->stickers.size()
|
||||||
: 0;
|
: 0;
|
||||||
|
@ -1893,28 +1946,29 @@ Stickers::Pack StickersListWidget::collectRecentStickers() {
|
||||||
if (result.size() >= kRecentDisplayLimit) {
|
if (result.size() >= kRecentDisplayLimit) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto index = result.indexOf(document);
|
const auto i = ranges::find(result, document, &Sticker::document);
|
||||||
if (index >= 0) {
|
if (i != end(result)) {
|
||||||
|
const auto index = (i - begin(result));
|
||||||
if (index >= cloudCount && custom) {
|
if (index >= cloudCount && custom) {
|
||||||
// Mark stickers from local recent as custom.
|
// Mark stickers from local recent as custom.
|
||||||
_custom[index] = true;
|
_custom[index] = true;
|
||||||
}
|
}
|
||||||
} else if (!_favedStickersMap.contains(document)) {
|
} else if (!_favedStickersMap.contains(document)) {
|
||||||
result.push_back(document);
|
result.push_back(Sticker{ document });
|
||||||
_custom.push_back(custom);
|
_custom.push_back(custom);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (cloudCount > 0) {
|
if (cloudCount > 0) {
|
||||||
for_const (auto document, cloudIt->stickers) {
|
for (const auto document : cloudIt->stickers) {
|
||||||
add(document, false);
|
add(document, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for_const (auto &recentSticker, recent) {
|
for (const auto &recentSticker : recent) {
|
||||||
add(recentSticker.first, false);
|
add(recentSticker.first, false);
|
||||||
}
|
}
|
||||||
if (customCount > 0) {
|
if (customCount > 0) {
|
||||||
for_const (auto document, customIt->stickers) {
|
for (const auto document : customIt->stickers) {
|
||||||
add(document, true);
|
add(document, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1942,9 +1996,9 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
|
||||||
thumbnail,
|
thumbnail,
|
||||||
externalLayout,
|
externalLayout,
|
||||||
recentPack.size(),
|
recentPack.size(),
|
||||||
recentPack);
|
std::move(recentPack));
|
||||||
} else {
|
} else {
|
||||||
recentIt->pack = recentPack;
|
recentIt->stickers = std::move(recentPack);
|
||||||
}
|
}
|
||||||
} else if (recentIt != _mySets.end()) {
|
} else if (recentIt != _mySets.end()) {
|
||||||
_mySets.erase(recentIt);
|
_mySets.erase(recentIt);
|
||||||
|
@ -1975,7 +2029,7 @@ void StickersListWidget::refreshFavedStickers() {
|
||||||
thumbnail,
|
thumbnail,
|
||||||
externalLayout,
|
externalLayout,
|
||||||
it->count,
|
it->count,
|
||||||
it->stickers);
|
PrepareStickers(it->stickers));
|
||||||
_favedStickersMap = base::flat_set<not_null<DocumentData*>> { it->stickers.begin(), it->stickers.end() };
|
_favedStickersMap = base::flat_set<not_null<DocumentData*>> { it->stickers.begin(), it->stickers.end() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2041,7 +2095,7 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
|
||||||
thumbnail,
|
thumbnail,
|
||||||
externalLayout,
|
externalLayout,
|
||||||
it->count,
|
it->count,
|
||||||
it->stickers);
|
PrepareStickers(it->stickers));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else if (!isShownHere(hidden)
|
} else if (!isShownHere(hidden)
|
||||||
|
@ -2089,7 +2143,7 @@ void StickersListWidget::fillIcons(QList<StickerIcon> &icons) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const auto thumbnail = _mySets[i].thumbnail;
|
const auto thumbnail = _mySets[i].thumbnail;
|
||||||
const auto s = _mySets[i].pack[0];
|
const auto s = _mySets[i].stickers[0].document;
|
||||||
const auto availw = st::stickerIconWidth - 2 * st::stickerIconPadding;
|
const auto availw = st::stickerIconWidth - 2 * st::stickerIconPadding;
|
||||||
const auto availh = st::emojiFooterHeight - 2 * st::stickerIconPadding;
|
const auto availh = st::emojiFooterHeight - 2 * st::stickerIconPadding;
|
||||||
const auto size = thumbnail
|
const auto size = thumbnail
|
||||||
|
@ -2151,13 +2205,13 @@ void StickersListWidget::updateSelected() {
|
||||||
} else if (!(sets[section].flags & MTPDstickerSet_ClientFlag::f_special)) {
|
} else if (!(sets[section].flags & MTPDstickerSet_ClientFlag::f_special)) {
|
||||||
newSelected = OverSet { section };
|
newSelected = OverSet { section };
|
||||||
} else if (sets[section].id == Stickers::MegagroupSetId
|
} else if (sets[section].id == Stickers::MegagroupSetId
|
||||||
&& (_megagroupSet->canEditStickers() || !sets[section].pack.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 == Stickers::MegagroupSetId && set.pack.empty()) {
|
if (set.id == Stickers::MegagroupSetId && set.stickers.empty()) {
|
||||||
if (_megagroupSetButtonRect.contains(stickersLeft() + sx, yOffset)) {
|
if (_megagroupSetButtonRect.contains(stickersLeft() + sx, yOffset)) {
|
||||||
newSelected = OverGroupAdd {};
|
newSelected = OverGroupAdd {};
|
||||||
}
|
}
|
||||||
|
@ -2166,7 +2220,7 @@ void StickersListWidget::updateSelected() {
|
||||||
auto rowIndex = qFloor(yOffset / _singleSize.height());
|
auto rowIndex = qFloor(yOffset / _singleSize.height());
|
||||||
auto columnIndex = qFloor(sx / _singleSize.width());
|
auto columnIndex = qFloor(sx / _singleSize.width());
|
||||||
auto index = rowIndex * _columnCount + columnIndex;
|
auto index = rowIndex * _columnCount + columnIndex;
|
||||||
if (index >= 0 && index < set.pack.size()) {
|
if (index >= 0 && index < set.stickers.size()) {
|
||||||
auto overDelete = false;
|
auto overDelete = false;
|
||||||
if (stickerHasDeleteButton(set, index)) {
|
if (stickerHasDeleteButton(set, index)) {
|
||||||
auto inx = sx - (columnIndex * _singleSize.width());
|
auto inx = sx - (columnIndex * _singleSize.width());
|
||||||
|
@ -2226,14 +2280,13 @@ void StickersListWidget::setSelected(OverState newSelected) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
if (_previewShown && _pressed != _selected) {
|
if (_previewShown && _pressed != _selected) {
|
||||||
if (auto sticker = base::get_if<OverSticker>(&_selected)) {
|
if (const auto sticker = base::get_if<OverSticker>(&_selected)) {
|
||||||
_pressed = _selected;
|
_pressed = _selected;
|
||||||
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
||||||
auto &set = sets[sticker->section];
|
const auto &set = sets[sticker->section];
|
||||||
Assert(sticker->index >= 0 && sticker->index < set.pack.size());
|
Assert(sticker->index >= 0 && sticker->index < set.stickers.size());
|
||||||
Ui::showMediaPreview(
|
const auto document = set.stickers[sticker->index].document;
|
||||||
set.pack[sticker->index]->stickerSetOrigin(),
|
Ui::showMediaPreview(document->stickerSetOrigin(), document);
|
||||||
set.pack[sticker->index]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2244,10 +2297,9 @@ void StickersListWidget::showPreview() {
|
||||||
const auto &sets = shownSets();
|
const auto &sets = shownSets();
|
||||||
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
Assert(sticker->section >= 0 && sticker->section < sets.size());
|
||||||
const auto &set = sets[sticker->section];
|
const auto &set = sets[sticker->section];
|
||||||
Assert(sticker->index >= 0 && sticker->index < set.pack.size());
|
Assert(sticker->index >= 0 && sticker->index < set.stickers.size());
|
||||||
Ui::showMediaPreview(
|
const auto document = set.stickers[sticker->index].document;
|
||||||
set.pack[sticker->index]->stickerSetOrigin(),
|
Ui::showMediaPreview(document->stickerSetOrigin(), document);
|
||||||
set.pack[sticker->index]);
|
|
||||||
_previewShown = true;
|
_previewShown = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@ class LinkButton;
|
||||||
class RippleAnimation;
|
class RippleAnimation;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Lottie {
|
||||||
|
class Animation;
|
||||||
|
} // namespace Lottie
|
||||||
|
|
||||||
namespace ChatHelpers {
|
namespace ChatHelpers {
|
||||||
|
|
||||||
struct StickerIcon;
|
struct StickerIcon;
|
||||||
|
@ -129,6 +133,11 @@ private:
|
||||||
int rowsBottom = 0;
|
int rowsBottom = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Sticker {
|
||||||
|
not_null<DocumentData*> document;
|
||||||
|
std::unique_ptr<Lottie::Animation> animated;
|
||||||
|
};
|
||||||
|
|
||||||
struct Set {
|
struct Set {
|
||||||
Set(
|
Set(
|
||||||
uint64 id,
|
uint64 id,
|
||||||
|
@ -138,7 +147,7 @@ private:
|
||||||
ImagePtr thumbnail,
|
ImagePtr thumbnail,
|
||||||
bool externalLayout,
|
bool externalLayout,
|
||||||
int count,
|
int count,
|
||||||
const Stickers::Pack &pack = Stickers::Pack());
|
std::vector<Sticker> &&stickers = {});
|
||||||
Set(Set &&other);
|
Set(Set &&other);
|
||||||
Set &operator=(Set &&other);
|
Set &operator=(Set &&other);
|
||||||
~Set();
|
~Set();
|
||||||
|
@ -148,12 +157,14 @@ private:
|
||||||
QString title;
|
QString title;
|
||||||
QString shortName;
|
QString shortName;
|
||||||
ImagePtr thumbnail;
|
ImagePtr thumbnail;
|
||||||
Stickers::Pack pack;
|
std::vector<Sticker> stickers;
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
bool externalLayout = false;
|
bool externalLayout = false;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static std::vector<Sticker> PrepareStickers(const Stickers::Pack &pack);
|
||||||
|
|
||||||
template <typename Callback>
|
template <typename Callback>
|
||||||
bool enumerateSections(Callback callback) const;
|
bool enumerateSections(Callback callback) const;
|
||||||
SectionInfo sectionInfo(int section) const;
|
SectionInfo sectionInfo(int section) const;
|
||||||
|
@ -171,7 +182,7 @@ private:
|
||||||
|
|
||||||
bool setHasTitle(const Set &set) const;
|
bool setHasTitle(const Set &set) const;
|
||||||
bool stickerHasDeleteButton(const Set &set, int index) const;
|
bool stickerHasDeleteButton(const Set &set, int index) const;
|
||||||
Stickers::Pack collectRecentStickers();
|
std::vector<Sticker> collectRecentStickers();
|
||||||
void refreshRecentStickers(bool resize = true);
|
void refreshRecentStickers(bool resize = true);
|
||||||
void refreshFavedStickers();
|
void refreshFavedStickers();
|
||||||
enum class GroupStickersPlace {
|
enum class GroupStickersPlace {
|
||||||
|
@ -202,8 +213,9 @@ private:
|
||||||
void paintFeaturedStickers(Painter &p, QRect clip);
|
void paintFeaturedStickers(Painter &p, QRect clip);
|
||||||
void paintStickers(Painter &p, QRect clip);
|
void paintStickers(Painter &p, QRect clip);
|
||||||
void paintMegagroupEmptySet(Painter &p, int y, bool buttonSelected);
|
void paintMegagroupEmptySet(Painter &p, int y, bool buttonSelected);
|
||||||
void paintSticker(Painter &p, Set &set, int y, int index, bool selected, bool deleteSelected);
|
void paintSticker(Painter &p, Set &set, int y, int section, int index, bool selected, bool deleteSelected);
|
||||||
void paintEmptySearchResults(Painter &p);
|
void paintEmptySearchResults(Painter &p);
|
||||||
|
void setupLottie(Set &set, int section, int index);
|
||||||
|
|
||||||
int stickersRight() const;
|
int stickersRight() const;
|
||||||
bool featuredHasAddButton(int index) const;
|
bool featuredHasAddButton(int index) const;
|
||||||
|
|
Loading…
Reference in New Issue