mirror of https://github.com/procxx/kepka.git
Fix sticker set icons display.
This commit is contained in:
parent
803593cd8d
commit
ae9ed820ee
|
@ -1865,7 +1865,7 @@ void ApiWrap::saveStickerSets(
|
|||
auto &sets = _session->data().stickerSetsRef();
|
||||
|
||||
_stickersOrder = localOrder;
|
||||
for_const (auto removedSetId, localRemoved) {
|
||||
for (const auto removedSetId : localRemoved) {
|
||||
if (removedSetId == Stickers::CloudRecentSetId) {
|
||||
if (sets.remove(Stickers::CloudRecentSetId) != 0) {
|
||||
writeCloudRecent = true;
|
||||
|
@ -3348,8 +3348,8 @@ void ApiWrap::readFeaturedSets() {
|
|||
auto count = _session->data().featuredStickerSetsUnreadCount();
|
||||
QVector<MTPlong> wrappedIds;
|
||||
wrappedIds.reserve(_featuredSetsRead.size());
|
||||
for (auto setId : _featuredSetsRead) {
|
||||
auto it = sets.find(setId);
|
||||
for (const auto setId : _featuredSetsRead) {
|
||||
const auto it = sets.find(setId);
|
||||
if (it != sets.cend()) {
|
||||
it->second->flags &= ~MTPDstickerSet_ClientFlag::f_unread;
|
||||
wrappedIds.append(MTP_long(setId));
|
||||
|
|
|
@ -166,7 +166,7 @@ void StickersBox::showAttachedStickers() {
|
|||
});
|
||||
|
||||
if (const auto set = Stickers::FeedSet(*setData)) {
|
||||
if (_attached.widget()->appendSet(*set)) {
|
||||
if (_attached.widget()->appendSet(set)) {
|
||||
addedSet = true;
|
||||
if (set->stickers.isEmpty() || (set->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||
_session->api().scheduleStickerSetRequest(set->id, set->access);
|
||||
|
@ -221,8 +221,8 @@ void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedSti
|
|||
}
|
||||
if (!setData) continue;
|
||||
|
||||
if (auto set = Stickers::FeedSet(*setData)) {
|
||||
auto index = archived.indexOf(set->id);
|
||||
if (const auto set = Stickers::FeedSet(*setData)) {
|
||||
const auto index = archived.indexOf(set->id);
|
||||
if (archived.isEmpty() || index != archived.size() - 1) {
|
||||
changedSets = true;
|
||||
if (index < archived.size() - 1) {
|
||||
|
@ -230,7 +230,7 @@ void StickersBox::getArchivedDone(uint64 offsetId, const MTPmessages_ArchivedSti
|
|||
}
|
||||
archived.push_back(set->id);
|
||||
}
|
||||
if (_archived.widget()->appendSet(*set)) {
|
||||
if (_archived.widget()->appendSet(set)) {
|
||||
addedSet = true;
|
||||
if (set->stickers.isEmpty() || (set->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||
_session->api().scheduleStickerSetRequest(set->id, set->access);
|
||||
|
@ -635,9 +635,7 @@ void StickersBox::setInnerFocus() {
|
|||
StickersBox::~StickersBox() = default;
|
||||
|
||||
StickersBox::Inner::Row::Row(
|
||||
uint64 id,
|
||||
uint64 accessHash,
|
||||
ImagePtr thumbnail,
|
||||
not_null<Stickers::Set*> set,
|
||||
DocumentData *sticker,
|
||||
int32 count,
|
||||
const QString &title,
|
||||
|
@ -649,11 +647,8 @@ StickersBox::Inner::Row::Row(
|
|||
bool removed,
|
||||
int32 pixw,
|
||||
int32 pixh)
|
||||
: id(id)
|
||||
, accessHash(accessHash)
|
||||
, thumbnail(thumbnail)
|
||||
: set(set)
|
||||
, sticker(sticker)
|
||||
, stickerMedia(sticker ? sticker->createMediaView() : nullptr)
|
||||
, count(count)
|
||||
, title(title)
|
||||
, titleWidth(titleWidth)
|
||||
|
@ -669,7 +664,7 @@ StickersBox::Inner::Row::Row(
|
|||
StickersBox::Inner::Row::~Row() = default;
|
||||
|
||||
bool StickersBox::Inner::Row::isRecentSet() const {
|
||||
return (id == Stickers::CloudRecentSetId);
|
||||
return (set->id == Stickers::CloudRecentSetId);
|
||||
}
|
||||
|
||||
StickersBox::Inner::Inner(
|
||||
|
@ -820,8 +815,8 @@ QRect StickersBox::Inner::relativeButtonRect(bool removeButton) const {
|
|||
return QRect(buttonx, buttony, buttonw, buttonh);
|
||||
}
|
||||
|
||||
void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
|
||||
auto xadd = 0, yadd = qRound(set->yadd.current());
|
||||
void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> row, int index) {
|
||||
auto xadd = 0, yadd = qRound(row->yadd.current());
|
||||
if (xadd || yadd) p.translate(xadd, yadd);
|
||||
|
||||
if (_megagroupSet) {
|
||||
|
@ -833,8 +828,8 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
|
|||
}();
|
||||
if (index >= 0 && index == selectedIndex) {
|
||||
p.fillRect(0, 0, width(), _rowHeight, st::contactsBgOver);
|
||||
if (set->ripple) {
|
||||
set->ripple->paint(p, 0, 0, width());
|
||||
if (row->ripple) {
|
||||
row->ripple->paint(p, 0, 0, width());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -849,24 +844,24 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
|
|||
current = reachedOpacity;
|
||||
}
|
||||
}
|
||||
auto row = myrtlrect(st::contactsPadding.left() / 2, st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - st::contactsPadding.left() / 2, _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2));
|
||||
auto rect = myrtlrect(st::contactsPadding.left() / 2, st::contactsPadding.top() / 2, width() - (st::contactsPadding.left() / 2) - _scrollbar - st::contactsPadding.left() / 2, _rowHeight - ((st::contactsPadding.top() + st::contactsPadding.bottom()) / 2));
|
||||
p.setOpacity(current);
|
||||
Ui::Shadow::paint(p, row, width(), st::boxRoundShadow);
|
||||
Ui::Shadow::paint(p, rect, width(), st::boxRoundShadow);
|
||||
p.setOpacity(1);
|
||||
|
||||
App::roundRect(p, row, st::boxBg, BoxCorners);
|
||||
App::roundRect(p, rect, st::boxBg, BoxCorners);
|
||||
|
||||
p.setOpacity(1. - current);
|
||||
paintFakeButton(p, set, index);
|
||||
paintFakeButton(p, row, index);
|
||||
p.setOpacity(1.);
|
||||
} else if (!_megagroupSet) {
|
||||
paintFakeButton(p, set, index);
|
||||
paintFakeButton(p, row, index);
|
||||
}
|
||||
} else if (!_megagroupSet) {
|
||||
paintFakeButton(p, set, index);
|
||||
paintFakeButton(p, row, index);
|
||||
}
|
||||
|
||||
if (set->removed && _section == Section::Installed) {
|
||||
if (row->removed && _section == Section::Installed) {
|
||||
p.setOpacity(st::stickersRowDisabledOpacity);
|
||||
}
|
||||
|
||||
|
@ -874,13 +869,13 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
|
|||
|
||||
if (!_megagroupSet && _section == Section::Installed) {
|
||||
stickerx += st::stickersReorderIcon.width() + st::stickersReorderSkip;
|
||||
if (!set->isRecentSet()) {
|
||||
if (!row->isRecentSet()) {
|
||||
st::stickersReorderIcon.paint(p, st::contactsPadding.left(), (_rowHeight - st::stickersReorderIcon.height()) / 2, width());
|
||||
}
|
||||
}
|
||||
|
||||
if (set->sticker) {
|
||||
paintRowThumbnail(p, set, stickerx);
|
||||
if (row->sticker) {
|
||||
paintRowThumbnail(p, row, stickerx);
|
||||
}
|
||||
|
||||
int namex = stickerx + st::contactsPhotoSize + st::contactsPadding.left();
|
||||
|
@ -891,19 +886,19 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
|
|||
|
||||
p.setFont(st::contactsNameStyle.font);
|
||||
p.setPen(st::contactsNameFg);
|
||||
p.drawTextLeft(namex, namey, width(), set->title, set->titleWidth);
|
||||
p.drawTextLeft(namex, namey, width(), row->title, row->titleWidth);
|
||||
|
||||
if (set->unread) {
|
||||
if (row->unread) {
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::stickersFeaturedUnreadBg);
|
||||
|
||||
{
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.drawEllipse(style::rtlrect(namex + set->titleWidth + st::stickersFeaturedUnreadSkip, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
|
||||
p.drawEllipse(style::rtlrect(namex + row->titleWidth + st::stickersFeaturedUnreadSkip, namey + st::stickersFeaturedUnreadTop, st::stickersFeaturedUnreadSize, st::stickersFeaturedUnreadSize, width()));
|
||||
}
|
||||
}
|
||||
|
||||
auto statusText = (set->count > 0) ? tr::lng_stickers_count(tr::now, lt_count, set->count) : tr::lng_contacts_loading(tr::now);
|
||||
auto statusText = (row->count > 0) ? tr::lng_stickers_count(tr::now, lt_count, row->count) : tr::lng_contacts_loading(tr::now);
|
||||
|
||||
p.setFont(st::contactsStatusFont);
|
||||
p.setPen(st::contactsStatusFg);
|
||||
|
@ -915,30 +910,39 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> set, int index) {
|
|||
|
||||
void StickersBox::Inner::paintRowThumbnail(
|
||||
Painter &p,
|
||||
not_null<Row*> set,
|
||||
not_null<Row*> row,
|
||||
int left) {
|
||||
const auto origin = Data::FileOriginStickerSet(
|
||||
set->id,
|
||||
set->accessHash);
|
||||
const auto thumb = set->thumbnail
|
||||
? set->thumbnail.get()
|
||||
: set->stickerMedia->thumbnail();
|
||||
if (!thumb) {
|
||||
return;
|
||||
row->set->id,
|
||||
row->set->access);
|
||||
if (row->set->hasThumbnail()) {
|
||||
if (!row->thumbnailMedia) {
|
||||
row->thumbnailMedia = row->set->createThumbnailView();
|
||||
row->set->loadThumbnail();
|
||||
}
|
||||
} else if (row->sticker) {
|
||||
if (!row->stickerMedia) {
|
||||
row->stickerMedia = row->sticker->createMediaView();
|
||||
row->stickerMedia->thumbnailWanted(origin);
|
||||
}
|
||||
}
|
||||
thumb->load(origin);
|
||||
validateLottieAnimation(set);
|
||||
if (!set->lottie) {
|
||||
if (!thumb->loaded()) {
|
||||
validateLottieAnimation(row);
|
||||
if (!row->lottie) {
|
||||
const auto thumb = row->thumbnailMedia
|
||||
? row->thumbnailMedia->image()
|
||||
: row->stickerMedia
|
||||
? row->stickerMedia->thumbnail()
|
||||
: nullptr;
|
||||
if (!thumb) {
|
||||
return;
|
||||
}
|
||||
p.drawPixmapLeft(
|
||||
left + (st::contactsPhotoSize - set->pixw) / 2,
|
||||
st::contactsPadding.top() + (st::contactsPhotoSize - set->pixh) / 2,
|
||||
left + (st::contactsPhotoSize - row->pixw) / 2,
|
||||
st::contactsPadding.top() + (st::contactsPhotoSize - row->pixh) / 2,
|
||||
width(),
|
||||
thumb->pix(origin, set->pixw, set->pixh));
|
||||
} else if (set->lottie->ready()) {
|
||||
const auto frame = set->lottie->frame();
|
||||
thumb->pix(origin, row->pixw, row->pixh));
|
||||
} else if (row->lottie->ready()) {
|
||||
const auto frame = row->lottie->frame();
|
||||
const auto size = frame.size() / cIntRetinaFactor();
|
||||
p.drawImage(
|
||||
QRect(
|
||||
|
@ -951,21 +955,21 @@ void StickersBox::Inner::paintRowThumbnail(
|
|||
const auto paused = controller->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::Layer);
|
||||
if (!paused) {
|
||||
set->lottie->markFrameShown();
|
||||
row->lottie->markFrameShown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StickersBox::Inner::validateLottieAnimation(not_null<Row*> set) {
|
||||
if (set->lottie
|
||||
void StickersBox::Inner::validateLottieAnimation(not_null<Row*> row) {
|
||||
if (row->lottie
|
||||
|| !Stickers::HasLottieThumbnail(
|
||||
set->thumbnail,
|
||||
set->stickerMedia.get())) {
|
||||
row->thumbnailMedia.get(),
|
||||
row->stickerMedia.get())) {
|
||||
return;
|
||||
}
|
||||
auto player = Stickers::LottieThumbnail(
|
||||
set->thumbnail,
|
||||
set->stickerMedia.get(),
|
||||
row->thumbnailMedia.get(),
|
||||
row->stickerMedia.get(),
|
||||
Stickers::LottieSize::SetsListThumbnail,
|
||||
QSize(
|
||||
st::contactsPhotoSize,
|
||||
|
@ -973,21 +977,21 @@ void StickersBox::Inner::validateLottieAnimation(not_null<Row*> set) {
|
|||
if (!player) {
|
||||
return;
|
||||
}
|
||||
set->lottie = std::move(player);
|
||||
set->lottie->updates(
|
||||
row->lottie = std::move(player);
|
||||
row->lottie->updates(
|
||||
) | rpl::start_with_next([=] {
|
||||
updateRowThumbnail(set);
|
||||
updateRowThumbnail(row);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void StickersBox::Inner::updateRowThumbnail(not_null<Row*> set) {
|
||||
void StickersBox::Inner::updateRowThumbnail(not_null<Row*> row) {
|
||||
const auto rowTop = [&] {
|
||||
if (set == _megagroupSelectedSet.get()) {
|
||||
if (row == _megagroupSelectedSet.get()) {
|
||||
return _megagroupDivider->y() - _rowHeight;
|
||||
}
|
||||
auto top = _itemsTop;
|
||||
for (const auto &row : _rows) {
|
||||
if (row.get() == set) {
|
||||
for (const auto &entry : _rows) {
|
||||
if (entry.get() == row) {
|
||||
return top + qRound(row->yadd.current());
|
||||
}
|
||||
top += _rowHeight;
|
||||
|
@ -1005,10 +1009,10 @@ void StickersBox::Inner::updateRowThumbnail(not_null<Row*> set) {
|
|||
st::contactsPhotoSize);
|
||||
}
|
||||
|
||||
void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> set, int index) {
|
||||
auto removeButton = (_section == Section::Installed && !set->removed);
|
||||
void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> row, int index) {
|
||||
auto removeButton = (_section == Section::Installed && !row->removed);
|
||||
auto rect = relativeButtonRect(removeButton);
|
||||
if (_section != Section::Installed && set->installed && !set->archived && !set->removed) {
|
||||
if (_section != Section::Installed && row->installed && !row->archived && !row->removed) {
|
||||
// Checkbox after installed from Trending or Archived.
|
||||
int checkx = width() - (st::contactsPadding.right() + st::contactsCheckPosition.x() + (rect.width() + st::stickersFeaturedInstalled.width()) / 2);
|
||||
int checky = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersFeaturedInstalled.height()) / 2;
|
||||
|
@ -1017,10 +1021,10 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> set, int ind
|
|||
auto selected = (index == _actionSel && _actionDown < 0) || (index == _actionDown);
|
||||
if (removeButton) {
|
||||
// Trash icon button when not disabled in Installed.
|
||||
if (set->ripple) {
|
||||
set->ripple->paint(p, rect.x(), rect.y(), width());
|
||||
if (set->ripple->empty()) {
|
||||
set->ripple.reset();
|
||||
if (row->ripple) {
|
||||
row->ripple->paint(p, rect.x(), rect.y(), width());
|
||||
if (row->ripple->empty()) {
|
||||
row->ripple.reset();
|
||||
}
|
||||
}
|
||||
auto &icon = selected ? st::stickersRemove.iconOver : st::stickersRemove.icon;
|
||||
|
@ -1036,10 +1040,10 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> set, int ind
|
|||
auto &text = (_section == Section::Installed) ? _undoText : _addText;
|
||||
auto &textBg = selected ? st.textBgOver : st.textBg;
|
||||
App::roundRect(p, myrtlrect(rect), textBg, ImageRoundRadius::Small);
|
||||
if (set->ripple) {
|
||||
set->ripple->paint(p, rect.x(), rect.y(), width());
|
||||
if (set->ripple->empty()) {
|
||||
set->ripple.reset();
|
||||
if (row->ripple) {
|
||||
row->ripple->paint(p, rect.x(), rect.y(), width());
|
||||
if (row->ripple->empty()) {
|
||||
row->ripple.reset();
|
||||
}
|
||||
}
|
||||
p.setFont(st.font);
|
||||
|
@ -1072,19 +1076,19 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
|
|||
}
|
||||
if (_actionDown >= 0 && _actionDown < _rows.size()) {
|
||||
update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight);
|
||||
auto &set = _rows[_actionDown];
|
||||
if (set->ripple) {
|
||||
set->ripple->lastStop();
|
||||
const auto row = _rows[_actionDown].get();
|
||||
if (row->ripple) {
|
||||
row->ripple->lastStop();
|
||||
}
|
||||
}
|
||||
_actionDown = newActionDown;
|
||||
if (_actionDown >= 0 && _actionDown < _rows.size()) {
|
||||
update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight);
|
||||
auto &set = _rows[_actionDown];
|
||||
auto removeButton = (_section == Section::Installed && !set->removed);
|
||||
if (!set->ripple) {
|
||||
const auto row = _rows[_actionDown].get();
|
||||
auto removeButton = (_section == Section::Installed && !row->removed);
|
||||
if (!row->ripple) {
|
||||
if (_section == Section::Installed) {
|
||||
if (set->removed) {
|
||||
if (row->removed) {
|
||||
auto rippleSize = QSize(_undoWidth - st::stickersUndoRemove.width, st::stickersUndoRemove.height);
|
||||
auto rippleMask = Ui::RippleAnimation::roundRectMask(rippleSize, st::buttonRadius);
|
||||
ensureRipple(st::stickersUndoRemove.ripple, std::move(rippleMask), removeButton);
|
||||
|
@ -1093,15 +1097,15 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
|
|||
auto rippleMask = Ui::RippleAnimation::ellipseMask(QSize(rippleSize, rippleSize));
|
||||
ensureRipple(st::stickersRemove.ripple, std::move(rippleMask), removeButton);
|
||||
}
|
||||
} else if (!set->installed || set->archived || set->removed) {
|
||||
} else if (!row->installed || row->archived || row->removed) {
|
||||
auto rippleSize = QSize(_addWidth - st::stickersTrendingAdd.width, st::stickersTrendingAdd.height);
|
||||
auto rippleMask = Ui::RippleAnimation::roundRectMask(rippleSize, st::buttonRadius);
|
||||
ensureRipple(st::stickersTrendingAdd.ripple, std::move(rippleMask), removeButton);
|
||||
}
|
||||
}
|
||||
if (set->ripple) {
|
||||
if (row->ripple) {
|
||||
auto rect = relativeButtonRect(removeButton);
|
||||
set->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(myrtlrect(rect).x(), _itemsTop + _actionDown * _rowHeight + rect.y()));
|
||||
row->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(myrtlrect(rect).x(), _itemsTop + _actionDown * _rowHeight + rect.y()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1110,14 +1114,6 @@ void StickersBox::Inner::setSelected(SelectedRow selected) {
|
|||
if (_selected == selected) {
|
||||
return;
|
||||
}
|
||||
if ((_megagroupSet || _section != Section::Installed)
|
||||
&& ((_selected.has_value() || _pressed.has_value()) != (selected.has_value() || _pressed.has_value()))) {
|
||||
if (!_inDragArea) {
|
||||
setCursor((selected.has_value() || _pressed.has_value())
|
||||
? style::cur_pointer
|
||||
: style::cur_default);
|
||||
}
|
||||
}
|
||||
auto countSelectedIndex = [&] {
|
||||
if (auto index = base::get_if<int>(&_selected)) {
|
||||
return *index;
|
||||
|
@ -1129,6 +1125,7 @@ void StickersBox::Inner::setSelected(SelectedRow selected) {
|
|||
update(0, _itemsTop + selectedIndex * _rowHeight, width(), _rowHeight);
|
||||
}
|
||||
_selected = selected;
|
||||
updateCursor();
|
||||
selectedIndex = countSelectedIndex();
|
||||
if (_megagroupSet && selectedIndex >= 0 && selectedIndex < _rows.size()) {
|
||||
update(0, _itemsTop + selectedIndex * _rowHeight, width(), _rowHeight);
|
||||
|
@ -1148,9 +1145,9 @@ void StickersBox::Inner::setPressed(SelectedRow pressed) {
|
|||
auto pressedIndex = countPressedIndex();
|
||||
if (_megagroupSet && pressedIndex >= 0 && pressedIndex < _rows.size()) {
|
||||
update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight);
|
||||
auto &set = _rows[pressedIndex];
|
||||
if (set->ripple) {
|
||||
set->ripple->lastStop();
|
||||
const auto row = _rows[pressedIndex].get();
|
||||
if (row->ripple) {
|
||||
row->ripple->lastStop();
|
||||
}
|
||||
}
|
||||
_pressed = pressed;
|
||||
|
@ -1234,15 +1231,15 @@ void StickersBox::Inner::onUpdateSelected() {
|
|||
auto selectedIndex = floorclamp(local.y() - _itemsTop, _rowHeight, 0, _rows.size() - 1);
|
||||
selected = selectedIndex;
|
||||
local.setY(local.y() - _itemsTop - selectedIndex * _rowHeight);
|
||||
auto &set = _rows[selectedIndex];
|
||||
if (!_megagroupSet && (_section == Section::Installed || !set->installed || set->archived || set->removed)) {
|
||||
auto removeButton = (_section == Section::Installed && !set->removed);
|
||||
const auto row = _rows[selectedIndex].get();
|
||||
if (!_megagroupSet && (_section == Section::Installed || !row->installed || row->archived || row->removed)) {
|
||||
auto removeButton = (_section == Section::Installed && !row->removed);
|
||||
auto rect = myrtlrect(relativeButtonRect(removeButton));
|
||||
actionSel = rect.contains(local) ? selectedIndex : -1;
|
||||
} else {
|
||||
actionSel = -1;
|
||||
}
|
||||
if (!_megagroupSet && _section == Section::Installed && !set->isRecentSet()) {
|
||||
if (!_megagroupSet && _section == Section::Installed && !row->isRecentSet()) {
|
||||
auto dragAreaWidth = st::contactsPadding.left() + st::stickersReorderIcon.width() + st::stickersReorderSkip;
|
||||
auto dragArea = myrtlrect(0, 0, dragAreaWidth, _rowHeight);
|
||||
inDragArea = dragArea.contains(local);
|
||||
|
@ -1256,17 +1253,25 @@ void StickersBox::Inner::onUpdateSelected() {
|
|||
setSelected(selected);
|
||||
if (_inDragArea != inDragArea) {
|
||||
_inDragArea = inDragArea;
|
||||
setCursor(_inDragArea
|
||||
? style::cur_sizeall
|
||||
: ((_selected.has_value() || _pressed.has_value())
|
||||
? style::cur_pointer
|
||||
: style::cur_default));
|
||||
updateCursor();
|
||||
}
|
||||
setActionSel(actionSel);
|
||||
emit draggingScrollDelta(0);
|
||||
}
|
||||
}
|
||||
|
||||
void StickersBox::Inner::updateCursor() {
|
||||
setCursor(_inDragArea
|
||||
? style::cur_sizeall
|
||||
: (!_megagroupSet && _section == Section::Installed)
|
||||
? ((_actionSel >= 0 && (_actionDown < 0 || _actionDown == _actionSel))
|
||||
? style::cur_pointer
|
||||
: style::cur_default)
|
||||
: (_selected.has_value() || _pressed.has_value())
|
||||
? style::cur_pointer
|
||||
: style::cur_default);
|
||||
}
|
||||
|
||||
float64 StickersBox::Inner::aboveShadowOpacity() const {
|
||||
if (_above < 0) return 0;
|
||||
|
||||
|
@ -1278,9 +1283,7 @@ float64 StickersBox::Inner::aboveShadowOpacity() const {
|
|||
void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||
auto pressed = std::exchange(_pressed, SelectedRow());
|
||||
|
||||
if (_section != Section::Installed && !_selected.has_value() && pressed.has_value()) {
|
||||
setCursor(style::cur_default);
|
||||
}
|
||||
updateCursor();
|
||||
|
||||
_mouse = e->globalPos();
|
||||
onUpdateSelected();
|
||||
|
@ -1288,7 +1291,7 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
|||
if (_section == Section::Installed) {
|
||||
setRowRemoved(_actionDown, !_rows[_actionDown]->removed);
|
||||
} else if (_installSetCallback) {
|
||||
_installSetCallback(_rows[_actionDown]->id);
|
||||
_installSetCallback(_rows[_actionDown]->set->id);
|
||||
}
|
||||
} else if (_dragging >= 0) {
|
||||
QPoint local(mapFromGlobal(_mouse));
|
||||
|
@ -1301,42 +1304,28 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
|||
|
||||
_dragging = _started = -1;
|
||||
} else if (pressed == _selected && _actionSel < 0 && _actionDown < 0) {
|
||||
auto selectedIndex = [&] {
|
||||
const auto selectedIndex = [&] {
|
||||
if (auto index = base::get_if<int>(&_selected)) {
|
||||
return *index;
|
||||
}
|
||||
return -1;
|
||||
}();
|
||||
auto getSetByRow = [&](const Row &row) -> const Stickers::Set* {
|
||||
auto &sets = _session->data().stickerSetsRef();
|
||||
if (!row.isRecentSet()) {
|
||||
auto it = sets.find(row.id);
|
||||
if (it != sets.cend()) {
|
||||
return it->second.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
auto showSetByRow = [&](const Row &row) {
|
||||
if (auto set = getSetByRow(row)) {
|
||||
setSelected(SelectedRow());
|
||||
Ui::show(
|
||||
Box<StickerSetBox>(
|
||||
App::wnd()->sessionController(),
|
||||
set->mtpInput()),
|
||||
Ui::LayerOption::KeepOther);
|
||||
}
|
||||
const auto showSetByRow = [&](const Row &row) {
|
||||
setSelected(SelectedRow());
|
||||
Ui::show(
|
||||
Box<StickerSetBox>(
|
||||
App::wnd()->sessionController(),
|
||||
row.set->mtpInput()),
|
||||
Ui::LayerOption::KeepOther);
|
||||
};
|
||||
if (selectedIndex >= 0 && !_inDragArea) {
|
||||
auto &row = *_rows[selectedIndex];
|
||||
if (_megagroupSet) {
|
||||
if (auto set = getSetByRow(row)) {
|
||||
setMegagroupSelectedSet(MTP_inputStickerSetID(
|
||||
MTP_long(set->id),
|
||||
MTP_long(set->access)));
|
||||
const auto row = _rows[selectedIndex].get();
|
||||
if (!row->isRecentSet()) {
|
||||
if (_megagroupSet) {
|
||||
setMegagroupSelectedSet(row->set->mtpInput());
|
||||
} else {
|
||||
showSetByRow(*row);
|
||||
}
|
||||
} else {
|
||||
showSetByRow(row);
|
||||
}
|
||||
} else if (_megagroupSelectedSet && _selected.is<MegagroupSet>()) {
|
||||
showSetByRow(*_megagroupSelectedSet);
|
||||
|
@ -1447,9 +1436,7 @@ void StickersBox::Inner::setActionSel(int32 actionSel) {
|
|||
if (_actionSel >= 0) update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
|
||||
_actionSel = actionSel;
|
||||
if (_actionSel >= 0) update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight);
|
||||
if (_section == Section::Installed) {
|
||||
setCursor((_actionSel >= 0 && (_actionDown < 0 || _actionDown == _actionSel)) ? style::cur_pointer : style::cur_default);
|
||||
}
|
||||
updateCursor();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1485,7 +1472,7 @@ void StickersBox::Inner::handleMegagroupSetAddressChange() {
|
|||
if (text.isEmpty()) {
|
||||
if (_megagroupSelectedSet) {
|
||||
const auto &sets = _session->data().stickerSets();
|
||||
const auto it = sets.find(_megagroupSelectedSet->id);
|
||||
const auto it = sets.find(_megagroupSelectedSet->set->id);
|
||||
if (it != sets.cend() && !it->second->shortName.isEmpty()) {
|
||||
setMegagroupSelectedSet(MTP_inputStickerSetEmpty());
|
||||
}
|
||||
|
@ -1522,7 +1509,7 @@ void StickersBox::Inner::rebuildMegagroupSet() {
|
|||
}
|
||||
auto &inputId = _megagroupSetInput.c_inputStickerSetID();
|
||||
auto setId = inputId.vid().v;
|
||||
auto &sets = _session->data().stickerSets();
|
||||
const auto &sets = _session->data().stickerSets();
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.cend()
|
||||
|| (it->second->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||
|
@ -1535,21 +1522,18 @@ void StickersBox::Inner::rebuildMegagroupSet() {
|
|||
const auto set = it->second.get();
|
||||
auto maxNameWidth = countMaxNameWidth();
|
||||
auto titleWidth = 0;
|
||||
auto title = fillSetTitle(*set, maxNameWidth, &titleWidth);
|
||||
auto count = fillSetCount(*set);
|
||||
auto thumbnail = ImagePtr();
|
||||
auto title = fillSetTitle(set, maxNameWidth, &titleWidth);
|
||||
auto count = fillSetCount(set);
|
||||
auto sticker = (DocumentData*)nullptr;
|
||||
auto pixw = 0, pixh = 0;
|
||||
fillSetCover(*set, &thumbnail, &sticker, &pixw, &pixh);
|
||||
fillSetCover(set, &sticker, &pixw, &pixh);
|
||||
auto installed = true, official = false, unread = false, archived = false, removed = false;
|
||||
if (!_megagroupSelectedSet || _megagroupSelectedSet->id != set->id) {
|
||||
if (!_megagroupSelectedSet || _megagroupSelectedSet->set->id != set->id) {
|
||||
_megagroupSetField->setText(set->shortName);
|
||||
_megagroupSetField->finishAnimating();
|
||||
}
|
||||
_megagroupSelectedSet = std::make_unique<Row>(
|
||||
set->id,
|
||||
set->access,
|
||||
thumbnail,
|
||||
set,
|
||||
sticker,
|
||||
count,
|
||||
title,
|
||||
|
@ -1601,7 +1585,7 @@ void StickersBox::Inner::rebuild() {
|
|||
_rows.reserve(order.size() + 1);
|
||||
_shiftingStartTimes.reserve(order.size() + 1);
|
||||
|
||||
auto &sets = _session->data().stickerSets();
|
||||
const auto &sets = _session->data().stickerSets();
|
||||
if (_megagroupSet) {
|
||||
auto usingFeatured = _session->data().stickerSetsOrder().empty();
|
||||
_megagroupSubTitle->setText(usingFeatured
|
||||
|
@ -1611,7 +1595,7 @@ void StickersBox::Inner::rebuild() {
|
|||
} else if (_section == Section::Installed) {
|
||||
auto cloudIt = sets.find(Stickers::CloudRecentSetId);
|
||||
if (cloudIt != sets.cend() && !cloudIt->second->stickers.isEmpty()) {
|
||||
rebuildAppendSet(*cloudIt->second, maxNameWidth);
|
||||
rebuildAppendSet(cloudIt->second.get(), maxNameWidth);
|
||||
}
|
||||
}
|
||||
for (const auto setId : order) {
|
||||
|
@ -1621,7 +1605,7 @@ void StickersBox::Inner::rebuild() {
|
|||
}
|
||||
|
||||
const auto set = it->second.get();
|
||||
rebuildAppendSet(*set, maxNameWidth);
|
||||
rebuildAppendSet(set, maxNameWidth);
|
||||
|
||||
if (set->stickers.isEmpty()
|
||||
|| (set->flags & MTPDstickerSet_ClientFlag::f_not_loaded)) {
|
||||
|
@ -1653,28 +1637,23 @@ void StickersBox::Inner::updateSize(int newWidth) {
|
|||
|
||||
void StickersBox::Inner::updateRows() {
|
||||
int maxNameWidth = countMaxNameWidth();
|
||||
auto &sets = _session->data().stickerSets();
|
||||
const auto &sets = _session->data().stickerSets();
|
||||
for (const auto &row : _rows) {
|
||||
const auto it = sets.find(row->id);
|
||||
const auto it = sets.find(row->set->id);
|
||||
if (it == sets.cend()) {
|
||||
continue;
|
||||
}
|
||||
const auto set = it->second.get();
|
||||
if (!row->sticker) {
|
||||
auto thumbnail = ImagePtr();
|
||||
auto sticker = (DocumentData*)nullptr;
|
||||
auto pixw = 0, pixh = 0;
|
||||
fillSetCover(*set, &thumbnail, &sticker, &pixw, &pixh);
|
||||
fillSetCover(set, &sticker, &pixw, &pixh);
|
||||
if (sticker) {
|
||||
if ((row->thumbnail.get() != thumbnail.get())
|
||||
|| (!thumbnail && row->sticker != sticker)) {
|
||||
if (row->sticker != sticker && !row->thumbnailMedia) {
|
||||
row->lottie = nullptr;
|
||||
row->stickerMedia = nullptr;
|
||||
}
|
||||
row->thumbnail = thumbnail;
|
||||
row->sticker = sticker;
|
||||
row->stickerMedia = sticker->createMediaView();
|
||||
row->stickerMedia->thumbnailWanted(
|
||||
Data::FileOriginStickerSet(row->id, row->accessHash));
|
||||
row->pixw = pixw;
|
||||
row->pixh = pixh;
|
||||
}
|
||||
|
@ -1682,7 +1661,7 @@ void StickersBox::Inner::updateRows() {
|
|||
if (!row->isRecentSet()) {
|
||||
auto wasInstalled = row->installed;
|
||||
auto wasArchived = row->archived;
|
||||
fillSetFlags(*set, &row->installed, &row->official, &row->unread, &row->archived);
|
||||
fillSetFlags(set, &row->installed, &row->official, &row->unread, &row->archived);
|
||||
if (_section == Section::Installed) {
|
||||
row->archived = false;
|
||||
}
|
||||
|
@ -1690,15 +1669,15 @@ void StickersBox::Inner::updateRows() {
|
|||
row->ripple.reset();
|
||||
}
|
||||
}
|
||||
row->title = fillSetTitle(*set, maxNameWidth, &row->titleWidth);
|
||||
row->count = fillSetCount(*set);
|
||||
row->title = fillSetTitle(set, maxNameWidth, &row->titleWidth);
|
||||
row->count = fillSetCount(set);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
bool StickersBox::Inner::appendSet(const Stickers::Set &set) {
|
||||
for_const (auto &row, _rows) {
|
||||
if (row->id == set.id) {
|
||||
bool StickersBox::Inner::appendSet(not_null<Stickers::Set*> set) {
|
||||
for (const auto &row : _rows) {
|
||||
if (row->set == set) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1725,28 +1704,27 @@ int StickersBox::Inner::countMaxNameWidth() const {
|
|||
return namew;
|
||||
}
|
||||
|
||||
void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameWidth) {
|
||||
void StickersBox::Inner::rebuildAppendSet(
|
||||
not_null<Stickers::Set*> set,
|
||||
int maxNameWidth) {
|
||||
bool installed = true, official = true, unread = false, archived = false, removed = false;
|
||||
if (set.id != Stickers::CloudRecentSetId) {
|
||||
if (set->id != Stickers::CloudRecentSetId) {
|
||||
fillSetFlags(set, &installed, &official, &unread, &archived);
|
||||
}
|
||||
if (_section == Section::Installed && archived) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImagePtr thumbnail;
|
||||
DocumentData *sticker = nullptr;
|
||||
int pixw = 0, pixh = 0;
|
||||
fillSetCover(set, &thumbnail, &sticker, &pixw, &pixh);
|
||||
fillSetCover(set, &sticker, &pixw, &pixh);
|
||||
|
||||
int titleWidth = 0;
|
||||
QString title = fillSetTitle(set, maxNameWidth, &titleWidth);
|
||||
int count = fillSetCount(set);
|
||||
|
||||
_rows.push_back(std::make_unique<Row>(
|
||||
set.id,
|
||||
set.access,
|
||||
thumbnail,
|
||||
set,
|
||||
sticker,
|
||||
count,
|
||||
title,
|
||||
|
@ -1761,19 +1739,22 @@ void StickersBox::Inner::rebuildAppendSet(const Stickers::Set &set, int maxNameW
|
|||
_shiftingStartTimes.push_back(0);
|
||||
}
|
||||
|
||||
void StickersBox::Inner::fillSetCover(const Stickers::Set &set, ImagePtr *thumbnail, DocumentData **outSticker, int *outWidth, int *outHeight) const {
|
||||
//*thumbnail = set.thumbnail; // #TODO optimize stickers
|
||||
if (set.stickers.isEmpty()) {
|
||||
void StickersBox::Inner::fillSetCover(
|
||||
not_null<Stickers::Set*> set,
|
||||
DocumentData **outSticker,
|
||||
int *outWidth,
|
||||
int *outHeight) const {
|
||||
if (set->stickers.isEmpty()) {
|
||||
*outSticker = nullptr;
|
||||
*outWidth = *outHeight = 0;
|
||||
return;
|
||||
}
|
||||
auto sticker = *outSticker = set.stickers.front();
|
||||
auto sticker = *outSticker = set->stickers.front();
|
||||
|
||||
const auto size = set.hasThumbnail()
|
||||
const auto size = set->hasThumbnail()
|
||||
? QSize(
|
||||
set.thumbnailLocation().width(),
|
||||
set.thumbnailLocation().height())
|
||||
set->thumbnailLocation().width(),
|
||||
set->thumbnailLocation().height())
|
||||
: sticker->hasThumbnail()
|
||||
? QSize(
|
||||
sticker->thumbnailLocation().width(),
|
||||
|
@ -1797,9 +1778,12 @@ void StickersBox::Inner::fillSetCover(const Stickers::Set &set, ImagePtr *thumbn
|
|||
*outHeight = pixh;
|
||||
}
|
||||
|
||||
int StickersBox::Inner::fillSetCount(const Stickers::Set &set) const {
|
||||
int result = set.stickers.isEmpty() ? set.count : set.stickers.size(), added = 0;
|
||||
if (set.id == Stickers::CloudRecentSetId) {
|
||||
int StickersBox::Inner::fillSetCount(not_null<Stickers::Set*> set) const {
|
||||
int result = set->stickers.isEmpty()
|
||||
? set->count
|
||||
: set->stickers.size();
|
||||
auto added = 0;
|
||||
if (set->id == Stickers::CloudRecentSetId) {
|
||||
const auto &sets = _session->data().stickerSets();
|
||||
auto customIt = sets.find(Stickers::CustomSetId);
|
||||
if (customIt != sets.cend()) {
|
||||
|
@ -1817,8 +1801,11 @@ int StickersBox::Inner::fillSetCount(const Stickers::Set &set) const {
|
|||
return result + added;
|
||||
}
|
||||
|
||||
QString StickersBox::Inner::fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const {
|
||||
auto result = set.title;
|
||||
QString StickersBox::Inner::fillSetTitle(
|
||||
not_null<Stickers::Set*> set,
|
||||
int maxNameWidth,
|
||||
int *outTitleWidth) const {
|
||||
auto result = set->title;
|
||||
int titleWidth = st::contactsNameStyle.font->width(result);
|
||||
if (titleWidth > maxNameWidth) {
|
||||
result = st::contactsNameStyle.font->elided(result, maxNameWidth);
|
||||
|
@ -1831,16 +1818,16 @@ QString StickersBox::Inner::fillSetTitle(const Stickers::Set &set, int maxNameWi
|
|||
}
|
||||
|
||||
void StickersBox::Inner::fillSetFlags(
|
||||
const Stickers::Set &set,
|
||||
not_null<Stickers::Set*> set,
|
||||
bool *outInstalled,
|
||||
bool *outOfficial,
|
||||
bool *outUnread,
|
||||
bool *outArchived) {
|
||||
*outInstalled = (set.flags & MTPDstickerSet::Flag::f_installed_date);
|
||||
*outOfficial = (set.flags & MTPDstickerSet::Flag::f_official);
|
||||
*outArchived = (set.flags & MTPDstickerSet::Flag::f_archived);
|
||||
*outInstalled = (set->flags & MTPDstickerSet::Flag::f_installed_date);
|
||||
*outOfficial = (set->flags & MTPDstickerSet::Flag::f_official);
|
||||
*outArchived = (set->flags & MTPDstickerSet::Flag::f_archived);
|
||||
if (_section == Section::Featured) {
|
||||
*outUnread = (set.flags & MTPDstickerSet_ClientFlag::f_unread);
|
||||
*outUnread = (set->flags & MTPDstickerSet_ClientFlag::f_unread);
|
||||
} else {
|
||||
*outUnread = false;
|
||||
}
|
||||
|
@ -1852,7 +1839,7 @@ Stickers::Order StickersBox::Inner::collectSets(Check check) const {
|
|||
result.reserve(_rows.size());
|
||||
for_const (auto &row, _rows) {
|
||||
if (check(row.get())) {
|
||||
result.push_back(row->id);
|
||||
result.push_back(row->set->id);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -1879,7 +1866,7 @@ Stickers::Order StickersBox::Inner::getRemovedSets() const {
|
|||
int StickersBox::Inner::getRowIndex(uint64 setId) const {
|
||||
for (auto i = 0, count = int(_rows.size()); i != count; ++i) {
|
||||
auto &row = _rows[i];
|
||||
if (row->id == setId) {
|
||||
if (row->set->id == setId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -1902,7 +1889,7 @@ void StickersBox::Inner::setFullOrder(const Stickers::Order &order) {
|
|||
|
||||
void StickersBox::Inner::setRemovedSets(const Stickers::Order &removed) {
|
||||
for (auto i = 0, count = int(_rows.size()); i != count; ++i) {
|
||||
setRowRemoved(i, removed.contains(_rows[i]->id));
|
||||
setRowRemoved(i, removed.contains(_rows[i]->set->id));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1940,22 +1927,14 @@ void StickersBox::Inner::readVisibleSets() {
|
|||
if (i * _rowHeight < itemsVisibleTop || (i + 1) * _rowHeight > itemsVisibleBottom) {
|
||||
continue;
|
||||
}
|
||||
const auto thumbnail = !_rows[i]->sticker
|
||||
? nullptr
|
||||
: _rows[i]->thumbnail
|
||||
? _rows[i]->thumbnail.get()
|
||||
: _rows[i]->stickerMedia
|
||||
? _rows[i]->stickerMedia->thumbnail()
|
||||
: nullptr;
|
||||
const auto thumbnailLoading = !_rows[i]->sticker
|
||||
? false
|
||||
: _rows[i]->thumbnail
|
||||
? !thumbnail->loaded()
|
||||
: _rows[i]->stickerMedia
|
||||
? _rows[i]->sticker->thumbnailLoading()
|
||||
const auto thumbnailLoading = _rows[i]->set->hasThumbnail()
|
||||
? _rows[i]->set->thumbnailLoading()
|
||||
: _rows[i]->sticker
|
||||
? ((_rows[i]->stickerMedia && _rows[i]->stickerMedia->loaded())
|
||||
|| _rows[i]->sticker->thumbnailLoading())
|
||||
: false;
|
||||
if (!thumbnailLoading || _rows[i]->stickerMedia->loaded()) {
|
||||
_session->api().readFeaturedSetDelayed(_rows[i]->id);
|
||||
_session->api().readFeaturedSetDelayed(_rows[i]->set->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@ namespace Lottie {
|
|||
class SinglePlayer;
|
||||
} // namespace Lottie
|
||||
|
||||
namespace Stickers {
|
||||
class Set;
|
||||
} // namespace Stickers
|
||||
|
||||
class StickersBox final
|
||||
: public Ui::BoxContent
|
||||
, public RPCSender
|
||||
|
@ -181,7 +185,7 @@ public:
|
|||
void rebuild();
|
||||
void updateSize(int newWidth = 0);
|
||||
void updateRows(); // refresh only pack cover stickers
|
||||
bool appendSet(const Stickers::Set &set);
|
||||
bool appendSet(not_null<Stickers::Set*> set);
|
||||
|
||||
Stickers::Order getOrder() const;
|
||||
Stickers::Order getFullOrder() const;
|
||||
|
@ -227,9 +231,7 @@ public slots:
|
|||
private:
|
||||
struct Row {
|
||||
Row(
|
||||
uint64 id,
|
||||
uint64 accessHash,
|
||||
ImagePtr thumbnail,
|
||||
not_null<Stickers::Set*> set,
|
||||
DocumentData *sticker,
|
||||
int32 count,
|
||||
const QString &title,
|
||||
|
@ -245,11 +247,10 @@ private:
|
|||
|
||||
bool isRecentSet() const;
|
||||
|
||||
uint64 id = 0;
|
||||
uint64 accessHash = 0;
|
||||
ImagePtr thumbnail;
|
||||
const not_null<Stickers::Set*> set;
|
||||
DocumentData *sticker = nullptr;
|
||||
std::shared_ptr<Data::DocumentMedia> stickerMedia;
|
||||
std::shared_ptr<Stickers::SetThumbnailView> thumbnailMedia;
|
||||
int32 count = 0;
|
||||
QString title;
|
||||
int titleWidth = 0;
|
||||
|
@ -302,23 +303,24 @@ private:
|
|||
void ensureRipple(const style::RippleAnimation &st, QImage mask, bool removeButton);
|
||||
|
||||
bool shiftingAnimationCallback(crl::time now);
|
||||
void paintRow(Painter &p, not_null<Row*> set, int index);
|
||||
void paintRowThumbnail(Painter &p, not_null<Row*> set, int left);
|
||||
void paintFakeButton(Painter &p, not_null<Row*> set, int index);
|
||||
void paintRow(Painter &p, not_null<Row*> row, int index);
|
||||
void paintRowThumbnail(Painter &p, not_null<Row*> row, int left);
|
||||
void paintFakeButton(Painter &p, not_null<Row*> row, int index);
|
||||
void clear();
|
||||
void updateCursor();
|
||||
void setActionSel(int32 actionSel);
|
||||
float64 aboveShadowOpacity() const;
|
||||
void validateLottieAnimation(not_null<Row*> set);
|
||||
void updateRowThumbnail(not_null<Row*> set);
|
||||
void validateLottieAnimation(not_null<Row*> row);
|
||||
void updateRowThumbnail(not_null<Row*> row);
|
||||
|
||||
void readVisibleSets();
|
||||
|
||||
void updateControlsGeometry();
|
||||
void rebuildAppendSet(const Stickers::Set &set, int maxNameWidth);
|
||||
void fillSetCover(const Stickers::Set &set, ImagePtr *thumbnail, DocumentData **outSticker, int *outWidth, int *outHeight) const;
|
||||
int fillSetCount(const Stickers::Set &set) const;
|
||||
QString fillSetTitle(const Stickers::Set &set, int maxNameWidth, int *outTitleWidth) const;
|
||||
void fillSetFlags(const Stickers::Set &set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived);
|
||||
void rebuildAppendSet(not_null<Stickers::Set*> set, int maxNameWidth);
|
||||
void fillSetCover(not_null<Stickers::Set*> set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
|
||||
int fillSetCount(not_null<Stickers::Set*> set) const;
|
||||
QString fillSetTitle(not_null<Stickers::Set*> set, int maxNameWidth, int *outTitleWidth) const;
|
||||
void fillSetFlags(not_null<Stickers::Set*> set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived);
|
||||
void rebuildMegagroupSet();
|
||||
void fixupMegagroupSetAddress();
|
||||
void handleMegagroupSetAddressChange();
|
||||
|
|
|
@ -93,7 +93,7 @@ void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d) {
|
|||
// For testing: Just apply random subset or your sticker sets as archived.
|
||||
bool ApplyArchivedResultFake() {
|
||||
auto sets = QVector<MTPStickerSetCovered>();
|
||||
for (const auto &[id, set] : Auth().data().stickerSetsRef()) {
|
||||
for (const auto &[id, set] : Auth().data().stickerSets()) {
|
||||
const auto raw = set.get();
|
||||
if ((raw->flags & MTPDstickerSet::Flag::f_installed_date)
|
||||
&& !(raw->flags & MTPDstickerSet_ClientFlag::f_special)) {
|
||||
|
@ -884,7 +884,7 @@ std::optional<std::vector<not_null<EmojiPtr>>> GetEmojiListFromSet(
|
|||
if (inputSet.type() != mtpc_inputStickerSetID) {
|
||||
return std::nullopt;
|
||||
}
|
||||
auto &sets = Auth().data().stickerSets();
|
||||
const auto &sets = Auth().data().stickerSets();
|
||||
auto it = sets.find(inputSet.c_inputStickerSetID().vid().v);
|
||||
if (it == sets.cend()) {
|
||||
return std::nullopt;
|
||||
|
@ -1231,19 +1231,15 @@ not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
|||
}
|
||||
|
||||
bool HasLottieThumbnail(
|
||||
ImagePtr thumbnail,
|
||||
not_null<Data::DocumentMedia*> media) {
|
||||
SetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media) {
|
||||
if (thumb) {
|
||||
return !thumb->content().isEmpty();
|
||||
} else if (!media) {
|
||||
return false;
|
||||
}
|
||||
const auto document = media->owner();
|
||||
if (thumbnail) {
|
||||
if (!thumbnail->loaded()) {
|
||||
return false;
|
||||
}
|
||||
const auto &location = thumbnail->location();
|
||||
const auto &bytes = thumbnail->bytesForCache();
|
||||
return location.valid()
|
||||
&& location.type() == StorageFileLocation::Type::StickerSetThumb
|
||||
&& !bytes.isEmpty();
|
||||
} else if (const auto info = document->sticker()) {
|
||||
if (const auto info = document->sticker()) {
|
||||
if (!info->animated) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1257,21 +1253,22 @@ bool HasLottieThumbnail(
|
|||
}
|
||||
|
||||
std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
|
||||
ImagePtr thumbnail,
|
||||
not_null<Data::DocumentMedia*> media,
|
||||
SetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media,
|
||||
LottieSize sizeTag,
|
||||
QSize box,
|
||||
std::shared_ptr<Lottie::FrameRenderer> renderer) {
|
||||
const auto document = media->owner();
|
||||
const auto baseKey = thumbnail
|
||||
? thumbnail->location().file().bigFileBaseCacheKey()
|
||||
: document->bigFileBaseCacheKey();
|
||||
const auto baseKey = thumb
|
||||
? thumb->owner()->thumbnailLocation().file().bigFileBaseCacheKey()
|
||||
: media
|
||||
? media->owner()->bigFileBaseCacheKey()
|
||||
: Storage::Cache::Key();
|
||||
if (!baseKey) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto content = (thumbnail
|
||||
? thumbnail->bytesForCache()
|
||||
: Lottie::ReadContent(media->bytes(), document->filepath()));
|
||||
const auto content = thumb
|
||||
? thumb->content()
|
||||
: Lottie::ReadContent(media->bytes(), media->owner()->filepath());
|
||||
if (content.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1279,11 +1276,16 @@ std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
|
|||
return std::make_unique<Lottie::SinglePlayer>(
|
||||
std::forward<decltype(args)>(args)...);
|
||||
};
|
||||
const auto session = thumb
|
||||
? &thumb->owner()->session()
|
||||
: media
|
||||
? &media->owner()->session()
|
||||
: nullptr;
|
||||
return LottieCachedFromContent(
|
||||
method,
|
||||
baseKey,
|
||||
uint8(sizeTag),
|
||||
&document->session(),
|
||||
session,
|
||||
content,
|
||||
box);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ constexpr auto FavedSetId = 0xFFFFFFFFFFFFFFFAULL; // for cloud-stored faved sti
|
|||
constexpr auto MegagroupSetId = 0xFFFFFFFFFFFFFFEFULL; // for setting up megagroup sticker set
|
||||
|
||||
class Set;
|
||||
class SetThumbnailView;
|
||||
|
||||
void ApplyArchivedResult(const MTPDmessages_stickerSetInstallResultArchive &d);
|
||||
bool ApplyArchivedResultFake(); // For testing.
|
||||
|
@ -112,11 +113,11 @@ enum class LottieSize : uchar {
|
|||
QSize box);
|
||||
|
||||
[[nodiscard]] bool HasLottieThumbnail(
|
||||
ImagePtr thumbnail,
|
||||
not_null<Data::DocumentMedia*> media);
|
||||
SetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media);
|
||||
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
|
||||
ImagePtr thumbnail,
|
||||
not_null<Data::DocumentMedia*> media,
|
||||
SetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media,
|
||||
LottieSize sizeTag,
|
||||
QSize box,
|
||||
std::shared_ptr<Lottie::FrameRenderer> renderer = nullptr);
|
||||
|
|
|
@ -59,31 +59,37 @@ struct StickerIcon {
|
|||
StickerIcon(uint64 setId) : setId(setId) {
|
||||
}
|
||||
StickerIcon(
|
||||
uint64 setId,
|
||||
ImagePtr thumbnail,
|
||||
not_null<Stickers::Set*> set,
|
||||
DocumentData *sticker,
|
||||
int pixw,
|
||||
int pixh)
|
||||
: setId(setId)
|
||||
, thumbnail(thumbnail)
|
||||
: setId(set->id)
|
||||
, set(set)
|
||||
, sticker(sticker)
|
||||
, pixw(pixw)
|
||||
, pixh(pixh) {
|
||||
}
|
||||
|
||||
void ensureMediaCreated() const {
|
||||
if (stickerMedia || !sticker) {
|
||||
if (!sticker) {
|
||||
return;
|
||||
} else if (set->hasThumbnail()) {
|
||||
if (!thumbnailMedia) {
|
||||
thumbnailMedia = set->createThumbnailView();
|
||||
set->loadThumbnail();
|
||||
}
|
||||
} else if (!stickerMedia) {
|
||||
stickerMedia = sticker->createMediaView();
|
||||
stickerMedia->thumbnailWanted(sticker->stickerSetOrigin());
|
||||
}
|
||||
stickerMedia = sticker->createMediaView();
|
||||
stickerMedia->thumbnailWanted(sticker->stickerSetOrigin());
|
||||
}
|
||||
|
||||
uint64 setId = 0;
|
||||
ImagePtr thumbnail;
|
||||
Stickers::Set *set = nullptr;
|
||||
mutable std::unique_ptr<Lottie::SinglePlayer> lottie;
|
||||
mutable QPixmap savedFrame;
|
||||
DocumentData *sticker = nullptr;
|
||||
mutable std::shared_ptr<Stickers::SetThumbnailView> thumbnailMedia;
|
||||
mutable std::shared_ptr<Data::DocumentMedia> stickerMedia;
|
||||
ChannelData *megagroup = nullptr;
|
||||
int pixw = 0;
|
||||
|
@ -196,18 +202,18 @@ auto StickersListWidget::PrepareStickers(
|
|||
|
||||
StickersListWidget::Set::Set(
|
||||
uint64 id,
|
||||
Stickers::Set *set,
|
||||
MTPDstickerSet::Flags flags,
|
||||
const QString &title,
|
||||
const QString &shortName,
|
||||
ImagePtr thumbnail,
|
||||
int count,
|
||||
bool externalLayout,
|
||||
std::vector<Sticker> &&stickers)
|
||||
: id(id)
|
||||
, set(set)
|
||||
, flags(flags)
|
||||
, title(title)
|
||||
, shortName(shortName)
|
||||
, thumbnail(thumbnail)
|
||||
, stickers(std::move(stickers))
|
||||
, count(count)
|
||||
, externalLayout(externalLayout) {
|
||||
|
@ -343,11 +349,11 @@ void StickersListWidget::Footer::enumerateVisibleIcons(Callback callback) {
|
|||
void StickersListWidget::Footer::preloadImages() {
|
||||
enumerateVisibleIcons([](const StickerIcon &icon, int x) {
|
||||
if (const auto sticker = icon.sticker) {
|
||||
const auto origin = sticker->stickerSetOrigin();
|
||||
if (icon.thumbnail) {
|
||||
icon.thumbnail->load(origin);
|
||||
Assert(icon.set != nullptr);
|
||||
if (icon.set->hasThumbnail()) {
|
||||
icon.set->loadThumbnail();
|
||||
} else {
|
||||
sticker->loadThumbnail(origin);
|
||||
sticker->loadThumbnail(sticker->stickerSetOrigin());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -679,8 +685,7 @@ void StickersListWidget::Footer::refreshIcons(
|
|||
for (auto &now : icons) {
|
||||
if (const auto i = indices.find(now.setId); i != end(indices)) {
|
||||
auto &was = _icons[i->second];
|
||||
if (now.sticker == was.sticker
|
||||
&& now.thumbnail.get() == was.thumbnail.get()) {
|
||||
if (now.sticker == was.sticker) {
|
||||
now.lottie = std::move(was.lottie);
|
||||
now.lifetime = std::move(was.lifetime);
|
||||
now.savedFrame = std::move(was.savedFrame);
|
||||
|
@ -728,13 +733,14 @@ void StickersListWidget::Footer::validateIconLottieAnimation(
|
|||
const StickerIcon &icon) {
|
||||
icon.ensureMediaCreated();
|
||||
if (icon.lottie
|
||||
|| !icon.sticker
|
||||
|| !Stickers::HasLottieThumbnail(
|
||||
icon.thumbnail,
|
||||
icon.thumbnailMedia.get(),
|
||||
icon.stickerMedia.get())) {
|
||||
return;
|
||||
}
|
||||
auto player = Stickers::LottieThumbnail(
|
||||
icon.thumbnail,
|
||||
icon.thumbnailMedia.get(),
|
||||
icon.stickerMedia.get(),
|
||||
Stickers::LottieSize::StickersFooter,
|
||||
QSize(
|
||||
|
@ -769,14 +775,13 @@ void StickersListWidget::Footer::paintSetIcon(
|
|||
int x) const {
|
||||
if (icon.sticker) {
|
||||
icon.ensureMediaCreated();
|
||||
const auto origin = icon.sticker->stickerSetOrigin();
|
||||
const auto thumb = icon.thumbnail
|
||||
? icon.thumbnail.get()
|
||||
: icon.stickerMedia->thumbnail();
|
||||
if (thumb) {
|
||||
thumb->load(origin);
|
||||
}
|
||||
const_cast<Footer*>(this)->validateIconLottieAnimation(icon);
|
||||
const auto origin = icon.sticker->stickerSetOrigin();
|
||||
const auto thumb = icon.thumbnailMedia
|
||||
? icon.thumbnailMedia->image()
|
||||
: icon.stickerMedia
|
||||
? icon.stickerMedia->thumbnail()
|
||||
: nullptr;
|
||||
if (!icon.lottie
|
||||
|| (!icon.lottie->ready() && !icon.savedFrame.isNull())) {
|
||||
const auto pixmap = !icon.savedFrame.isNull()
|
||||
|
@ -1305,13 +1310,13 @@ void StickersListWidget::fillCloudSearchRows(
|
|||
}
|
||||
}
|
||||
|
||||
void StickersListWidget::addSearchRow(not_null<const Stickers::Set*> set) {
|
||||
void StickersListWidget::addSearchRow(not_null<Stickers::Set*> set) {
|
||||
_searchSets.emplace_back(
|
||||
set->id,
|
||||
set,
|
||||
set->flags,
|
||||
set->title,
|
||||
set->shortName,
|
||||
ImagePtr(),// set->thumbnail, #TODO optimize stickers
|
||||
set->count,
|
||||
!SetInMyList(set->flags),
|
||||
PrepareStickers(set->stickers.empty()
|
||||
|
@ -2292,7 +2297,7 @@ void StickersListWidget::refreshFeaturedSets() {
|
|||
}
|
||||
_featuredSetsCount = _officialSets.size();
|
||||
if (wereOfficial.size() > wasFeaturedSetsCount) {
|
||||
auto &sets = session().data().stickerSets();
|
||||
const auto &sets = session().data().stickerSets();
|
||||
const auto from = begin(wereOfficial) + wasFeaturedSetsCount;
|
||||
const auto till = end(wereOfficial);
|
||||
for (auto i = from; i != till; ++i) {
|
||||
|
@ -2375,7 +2380,7 @@ bool StickersListWidget::appendSet(
|
|||
uint64 setId,
|
||||
bool externalLayout,
|
||||
AppendSkip skip) {
|
||||
auto &sets = session().data().stickerSets();
|
||||
const auto &sets = session().data().stickerSets();
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.cend()
|
||||
|| (!externalLayout && it->second->stickers.isEmpty())) {
|
||||
|
@ -2395,10 +2400,10 @@ bool StickersListWidget::appendSet(
|
|||
}
|
||||
to.emplace_back(
|
||||
set->id,
|
||||
set,
|
||||
set->flags,
|
||||
set->title,
|
||||
set->shortName,
|
||||
ImagePtr(), // set->thumbnail, #TODO optimize stickers
|
||||
set->count,
|
||||
externalLayout,
|
||||
PrepareStickers((set->stickers.empty() && externalLayout)
|
||||
|
@ -2477,15 +2482,14 @@ void StickersListWidget::refreshRecentStickers(bool performResize) {
|
|||
});
|
||||
if (!recentPack.empty()) {
|
||||
const auto shortName = QString();
|
||||
const auto thumbnail = ImagePtr();
|
||||
const auto externalLayout = false;
|
||||
auto set = Set(
|
||||
Stickers::RecentSetId,
|
||||
nullptr,
|
||||
(MTPDstickerSet::Flag::f_official
|
||||
| MTPDstickerSet_ClientFlag::f_special),
|
||||
tr::lng_recent_stickers(tr::now),
|
||||
shortName,
|
||||
thumbnail,
|
||||
recentPack.size(),
|
||||
externalLayout,
|
||||
std::move(recentPack));
|
||||
|
@ -2515,14 +2519,13 @@ void StickersListWidget::refreshFavedStickers() {
|
|||
const auto set = it->second.get();
|
||||
const auto externalLayout = false;
|
||||
const auto shortName = QString();
|
||||
const auto thumbnail = ImagePtr();
|
||||
_mySets.emplace_back(
|
||||
Stickers::FavedSetId,
|
||||
nullptr,
|
||||
(MTPDstickerSet::Flag::f_official
|
||||
| MTPDstickerSet_ClientFlag::f_special),
|
||||
Lang::Hard::FavedSetTitle(),
|
||||
shortName,
|
||||
thumbnail,
|
||||
set->count,
|
||||
externalLayout,
|
||||
PrepareStickers(set->stickers));
|
||||
|
@ -2542,18 +2545,18 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
|
|||
};
|
||||
if (_megagroupSet->mgInfo->stickerSet.type() == mtpc_inputStickerSetEmpty) {
|
||||
if (canEdit) {
|
||||
auto hidden = session().settings().isGroupStickersSectionHidden(_megagroupSet->id);
|
||||
auto hidden = session().settings().isGroupStickersSectionHidden(
|
||||
_megagroupSet->id);
|
||||
if (isShownHere(hidden)) {
|
||||
const auto shortName = QString();
|
||||
const auto thumbnail = ImagePtr();
|
||||
const auto externalLayout = false;
|
||||
const auto count = 0;
|
||||
_mySets.emplace_back(
|
||||
Stickers::MegagroupSetId,
|
||||
nullptr,
|
||||
MTPDstickerSet_ClientFlag::f_special | 0,
|
||||
tr::lng_group_stickers(tr::now),
|
||||
shortName,
|
||||
thumbnail,
|
||||
count,
|
||||
externalLayout);
|
||||
}
|
||||
|
@ -2585,14 +2588,13 @@ void StickersListWidget::refreshMegagroupStickers(GroupStickersPlace place) {
|
|||
removeHiddenForGroup();
|
||||
} else if (isShownHere(hidden)) {
|
||||
const auto shortName = QString();
|
||||
const auto thumbnail = ImagePtr();
|
||||
const auto externalLayout = false;
|
||||
_mySets.emplace_back(
|
||||
Stickers::MegagroupSetId,
|
||||
set,
|
||||
MTPDstickerSet_ClientFlag::f_special | 0,
|
||||
tr::lng_group_stickers(tr::now),
|
||||
shortName,
|
||||
thumbnail,
|
||||
set->count,
|
||||
externalLayout,
|
||||
PrepareStickers(set->stickers));
|
||||
|
@ -2635,18 +2637,22 @@ std::vector<StickerIcon> StickersListWidget::fillIcons() {
|
|||
result.emplace_back(Stickers::RecentSetId);
|
||||
}
|
||||
}
|
||||
const auto &sets = session().data().stickerSets();
|
||||
for (auto l = _mySets.size(); i != l; ++i) {
|
||||
if (_mySets[i].id == Stickers::MegagroupSetId) {
|
||||
result.emplace_back(Stickers::MegagroupSetId);
|
||||
result.back().megagroup = _megagroupSet;
|
||||
continue;
|
||||
}
|
||||
const auto thumbnail = _mySets[i].thumbnail;
|
||||
const auto set = _mySets[i].set;
|
||||
Assert(set != nullptr);
|
||||
const auto s = _mySets[i].stickers[0].document;
|
||||
const auto availw = st::stickerIconWidth - 2 * st::stickerIconPadding;
|
||||
const auto availh = st::emojiFooterHeight - 2 * st::stickerIconPadding;
|
||||
const auto size = thumbnail
|
||||
? thumbnail->size()
|
||||
const auto size = set->hasThumbnail()
|
||||
? QSize(
|
||||
set->thumbnailLocation().width(),
|
||||
set->thumbnailLocation().height())
|
||||
: s->hasThumbnail()
|
||||
? QSize(
|
||||
s->thumbnailLocation().width(),
|
||||
|
@ -2662,12 +2668,7 @@ std::vector<StickerIcon> StickersListWidget::fillIcons() {
|
|||
}
|
||||
if (pixw < 1) pixw = 1;
|
||||
if (pixh < 1) pixh = 1;
|
||||
result.emplace_back(
|
||||
_mySets[i].id,
|
||||
thumbnail,
|
||||
s,
|
||||
pixw,
|
||||
pixh);
|
||||
result.emplace_back(set, s, pixw, pixh);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -2915,7 +2916,7 @@ void StickersListWidget::displaySet(uint64 setId) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
auto &sets = session().data().stickerSets();
|
||||
const auto &sets = session().data().stickerSets();
|
||||
auto it = sets.find(setId);
|
||||
if (it != sets.cend()) {
|
||||
_displayingSet = true;
|
||||
|
@ -3006,7 +3007,7 @@ void StickersListWidget::removeSet(uint64 setId) {
|
|||
auto text = tr::lng_stickers_remove_pack(tr::now, lt_sticker_pack, set->title);
|
||||
Ui::show(Box<ConfirmBox>(text, tr::lng_stickers_remove_pack_confirm(tr::now), crl::guard(this, [=] {
|
||||
Ui::hideLayer();
|
||||
const auto &sets = session().data().stickerSetsRef();
|
||||
const auto &sets = session().data().stickerSets();
|
||||
const auto it = sets.find(_removingSetId);
|
||||
if (it != sets.cend()) {
|
||||
const auto set = it->second.get();
|
||||
|
|
|
@ -36,6 +36,10 @@ namespace Data {
|
|||
class DocumentMedia;
|
||||
} // namespace Data
|
||||
|
||||
namespace Stickers {
|
||||
class Set;
|
||||
} // namespace Stickers
|
||||
|
||||
namespace ChatHelpers {
|
||||
|
||||
struct StickerIcon;
|
||||
|
@ -165,10 +169,10 @@ private:
|
|||
struct Set {
|
||||
Set(
|
||||
uint64 id,
|
||||
Stickers::Set *set,
|
||||
MTPDstickerSet::Flags flags,
|
||||
const QString &title,
|
||||
const QString &shortName,
|
||||
ImagePtr thumbnail,
|
||||
int count,
|
||||
bool externalLayout,
|
||||
std::vector<Sticker> &&stickers = {});
|
||||
|
@ -177,10 +181,10 @@ private:
|
|||
~Set();
|
||||
|
||||
uint64 id = 0;
|
||||
Stickers::Set *set = nullptr;
|
||||
MTPDstickerSet::Flags flags = MTPDstickerSet::Flags();
|
||||
QString title;
|
||||
QString shortName;
|
||||
ImagePtr thumbnail;
|
||||
std::vector<Sticker> stickers;
|
||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||
|
||||
|
@ -304,7 +308,7 @@ private:
|
|||
void refreshSearchRows(const std::vector<uint64> *cloudSets);
|
||||
void fillLocalSearchRows(const QString &query);
|
||||
void fillCloudSearchRows(const std::vector<uint64> &cloudSets);
|
||||
void addSearchRow(not_null<const Stickers::Set*> set);
|
||||
void addSearchRow(not_null<Stickers::Set*> set);
|
||||
|
||||
void showPreview();
|
||||
|
||||
|
|
|
@ -16,6 +16,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Stickers {
|
||||
|
||||
SetThumbnailView::SetThumbnailView(not_null<Set*> owner) : _owner(owner) {
|
||||
}
|
||||
|
||||
not_null<Set*> SetThumbnailView::owner() const {
|
||||
return _owner;
|
||||
}
|
||||
|
||||
void SetThumbnailView::set(
|
||||
not_null<Main::Session*> session,
|
||||
QByteArray content) {
|
||||
|
@ -58,6 +65,14 @@ Set::Set(
|
|||
, _owner(owner) {
|
||||
}
|
||||
|
||||
Data::Session &Set::owner() const {
|
||||
return *_owner;
|
||||
}
|
||||
|
||||
Main::Session &Set::session() const {
|
||||
return _owner->session();
|
||||
}
|
||||
|
||||
MTPInputStickerSet Set::mtpInput() const {
|
||||
return (id && access)
|
||||
? MTP_inputStickerSetID(MTP_long(id), MTP_long(access))
|
||||
|
@ -70,7 +85,7 @@ void Set::setThumbnail(const ImageWithLocation &data) {
|
|||
data,
|
||||
_owner->cache(),
|
||||
Data::kImageCacheTag,
|
||||
[=](Data::FileOrigin origin) { loadThumbnail(origin); });
|
||||
[=](Data::FileOrigin origin) { loadThumbnail(); });
|
||||
if (!data.bytes.isEmpty()) {
|
||||
if (_thumbnail.loader) {
|
||||
_thumbnail.loader->cancel();
|
||||
|
@ -93,8 +108,9 @@ bool Set::thumbnailFailed() const {
|
|||
return (_thumbnail.flags & Data::CloudFile::Flag::Failed);
|
||||
}
|
||||
|
||||
void Set::loadThumbnail(Data::FileOrigin origin) {
|
||||
void Set::loadThumbnail() {
|
||||
auto &file = _thumbnail;
|
||||
const auto origin = Data::FileOriginStickerSet(id, access);
|
||||
const auto fromCloud = LoadFromCloudOrLocal;
|
||||
const auto cacheTag = Data::kImageCacheTag;
|
||||
const auto autoLoading = false;
|
||||
|
@ -122,7 +138,7 @@ std::shared_ptr<SetThumbnailView> Set::createThumbnailView() {
|
|||
if (auto active = activeThumbnailView()) {
|
||||
return active;
|
||||
}
|
||||
auto view = std::make_shared<SetThumbnailView>();
|
||||
auto view = std::make_shared<SetThumbnailView>(this);
|
||||
_thumbnailView = view;
|
||||
return view;
|
||||
}
|
||||
|
|
|
@ -31,12 +31,17 @@ using Sets = base::flat_map<uint64, std::unique_ptr<Set>>;
|
|||
|
||||
class SetThumbnailView final {
|
||||
public:
|
||||
explicit SetThumbnailView(not_null<Set*> owner);
|
||||
|
||||
[[nodiscard]] not_null<Set*> owner() const;
|
||||
|
||||
void set(not_null<Main::Session*> session, QByteArray content);
|
||||
|
||||
[[nodiscard]] Image *image() const;
|
||||
[[nodiscard]] QByteArray content() const;
|
||||
|
||||
private:
|
||||
const not_null<Set*> _owner;
|
||||
std::unique_ptr<Image> _image;
|
||||
QByteArray _content;
|
||||
|
||||
|
@ -55,6 +60,9 @@ public:
|
|||
MTPDstickerSet::Flags flags,
|
||||
TimeId installDate);
|
||||
|
||||
[[nodiscard]] Data::Session &owner() const;
|
||||
[[nodiscard]] Main::Session &session() const;
|
||||
|
||||
[[nodiscard]] MTPInputStickerSet mtpInput() const;
|
||||
|
||||
void setThumbnail(const ImageWithLocation &data);
|
||||
|
@ -62,7 +70,7 @@ public:
|
|||
[[nodiscard]] bool hasThumbnail() const;
|
||||
[[nodiscard]] bool thumbnailLoading() const;
|
||||
[[nodiscard]] bool thumbnailFailed() const;
|
||||
void loadThumbnail(Data::FileOrigin origin);
|
||||
void loadThumbnail();
|
||||
[[nodiscard]] const ImageLocation &thumbnailLocation() const;
|
||||
[[nodiscard]] int thumbnailByteSize() const;
|
||||
|
||||
|
|
|
@ -3360,16 +3360,18 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
|
|||
auto it = sets.find(Stickers::CloudRecentSetId);
|
||||
if (it == sets.cend()) {
|
||||
if (it == sets.cend()) {
|
||||
it = sets.emplace(Stickers::CloudRecentSetId, std::make_unique<Stickers::Set>(
|
||||
&session().data(),
|
||||
it = sets.emplace(
|
||||
Stickers::CloudRecentSetId,
|
||||
uint64(0),
|
||||
tr::lng_recent_stickers(tr::now),
|
||||
QString(),
|
||||
0, // count
|
||||
0, // hash
|
||||
MTPDstickerSet_ClientFlag::f_special | 0,
|
||||
TimeId(0))).first;
|
||||
std::make_unique<Stickers::Set>(
|
||||
&session().data(),
|
||||
Stickers::CloudRecentSetId,
|
||||
uint64(0),
|
||||
tr::lng_recent_stickers(tr::now),
|
||||
QString(),
|
||||
0, // count
|
||||
0, // hash
|
||||
MTPDstickerSet_ClientFlag::f_special | 0,
|
||||
TimeId(0))).first;
|
||||
} else {
|
||||
it->second->title = tr::lng_recent_stickers(tr::now);
|
||||
}
|
||||
|
@ -4518,8 +4520,8 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||
case mtpc_updateStickerSetsOrder: {
|
||||
auto &d = update.c_updateStickerSetsOrder();
|
||||
if (!d.is_masks()) {
|
||||
auto &order = d.vorder().v;
|
||||
auto &sets = session().data().stickerSets();
|
||||
const auto &order = d.vorder().v;
|
||||
const auto &sets = session().data().stickerSets();
|
||||
Stickers::Order result;
|
||||
for (const auto &item : order) {
|
||||
if (sets.find(item.v) == sets.cend()) {
|
||||
|
|
|
@ -220,9 +220,9 @@ inline std::optional<QString> RestrictionToSendStickers() {
|
|||
|
||||
QString TitleRecentlyUsed() {
|
||||
const auto &sets = Auth().data().stickerSets();
|
||||
const auto it = sets.constFind(Stickers::CloudRecentSetId);
|
||||
const auto it = sets.find(Stickers::CloudRecentSetId);
|
||||
if (it != sets.cend()) {
|
||||
return it->title;
|
||||
return it->second->title;
|
||||
}
|
||||
return tr::lng_recent_stickers(tr::now);
|
||||
}
|
||||
|
@ -328,37 +328,37 @@ void SendKeyEvent(int command) {
|
|||
}
|
||||
|
||||
void AppendStickerSet(std::vector<PickerScrubberItem> &to, uint64 setId) {
|
||||
auto &sets = Auth().data().stickerSets();
|
||||
auto it = sets.constFind(setId);
|
||||
if (it == sets.cend() || it->stickers.isEmpty()) {
|
||||
const auto &sets = Auth().data().stickerSets();
|
||||
const auto it = sets.find(setId);
|
||||
if (it == sets.cend() || it->second->stickers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (it->flags & MTPDstickerSet::Flag::f_archived) {
|
||||
const auto set = it->second.get();
|
||||
if (set->flags & MTPDstickerSet::Flag::f_archived) {
|
||||
return;
|
||||
}
|
||||
if (!(it->flags & MTPDstickerSet::Flag::f_installed_date)) {
|
||||
if (!(set->flags & MTPDstickerSet::Flag::f_installed_date)) {
|
||||
return;
|
||||
}
|
||||
|
||||
to.emplace_back(PickerScrubberItem(it->title.isEmpty()
|
||||
? it->shortName
|
||||
: it->title));
|
||||
for (const auto sticker : it->stickers) {
|
||||
to.emplace_back(PickerScrubberItem(set->title.isEmpty()
|
||||
? set->shortName
|
||||
: set->title));
|
||||
for (const auto sticker : set->stickers) {
|
||||
to.emplace_back(PickerScrubberItem(sticker));
|
||||
}
|
||||
}
|
||||
|
||||
void AppendRecentStickers(std::vector<PickerScrubberItem> &to) {
|
||||
const auto &sets = Auth().data().stickerSets();
|
||||
const auto cloudIt = sets.constFind(Stickers::CloudRecentSetId);
|
||||
const auto favedIt = sets.constFind(Stickers::FavedSetId);
|
||||
const auto cloudIt = sets.find(Stickers::CloudRecentSetId);
|
||||
const auto cloudCount = (cloudIt != sets.cend())
|
||||
? cloudIt->stickers.size()
|
||||
? cloudIt->second->stickers.size()
|
||||
: 0;
|
||||
if (cloudCount > 0) {
|
||||
to.emplace_back(PickerScrubberItem(cloudIt->title));
|
||||
to.emplace_back(PickerScrubberItem(cloudIt->second->title));
|
||||
auto count = 0;
|
||||
for (const auto document : cloudIt->stickers) {
|
||||
for (const auto document : cloudIt->second->stickers) {
|
||||
if (Stickers::IsFaved(document)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -372,16 +372,16 @@ void AppendRecentStickers(std::vector<PickerScrubberItem> &to) {
|
|||
|
||||
void AppendFavedStickers(std::vector<PickerScrubberItem> &to) {
|
||||
const auto &sets = Auth().data().stickerSets();
|
||||
const auto it = sets.constFind(Stickers::FavedSetId);
|
||||
const auto it = sets.find(Stickers::FavedSetId);
|
||||
const auto count = (it != sets.cend())
|
||||
? it->stickers.size()
|
||||
? it->second->stickers.size()
|
||||
: 0;
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
to.emplace_back(PickerScrubberItem(
|
||||
tr::lng_mac_touchbar_favorite_stickers(tr::now)));
|
||||
for (const auto document : it->stickers) {
|
||||
for (const auto document : it->second->stickers) {
|
||||
to.emplace_back(PickerScrubberItem(document));
|
||||
}
|
||||
}
|
||||
|
@ -1060,7 +1060,7 @@ void AppendEmojiPacks(std::vector<PickerScrubberItem> &to) {
|
|||
) | rpl::start_with_next([=] {
|
||||
if (const auto window = App::wnd()) {
|
||||
if (const auto controller = window->sessionController()) {
|
||||
if (!Auth().data().stickerSets().size()) {
|
||||
if (Auth().data().stickerSets().empty()) {
|
||||
Auth().api().updateStickers();
|
||||
}
|
||||
_lifetimeSessionControllerChecker.destroy();
|
||||
|
|
|
@ -3887,29 +3887,33 @@ void importOldRecentStickers() {
|
|||
auto &recent = cRefRecentStickers();
|
||||
recent.clear();
|
||||
|
||||
const auto def = sets.emplace(Stickers::DefaultSetId, std::make_unique<Stickers::Set>(
|
||||
&Auth().data(),
|
||||
const auto def = sets.emplace(
|
||||
Stickers::DefaultSetId,
|
||||
uint64(0),
|
||||
tr::lng_stickers_default_set(tr::now),
|
||||
QString(),
|
||||
0, // count
|
||||
0, // hash
|
||||
(MTPDstickerSet::Flag::f_official
|
||||
| MTPDstickerSet::Flag::f_installed_date
|
||||
| MTPDstickerSet_ClientFlag::f_special),
|
||||
kDefaultStickerInstallDate)).first->second.get();
|
||||
const auto custom = sets.emplace(Stickers::CustomSetId, std::make_unique<Stickers::Set>(
|
||||
&Auth().data(),
|
||||
std::make_unique<Stickers::Set>(
|
||||
&Auth().data(),
|
||||
Stickers::DefaultSetId,
|
||||
uint64(0),
|
||||
tr::lng_stickers_default_set(tr::now),
|
||||
QString(),
|
||||
0, // count
|
||||
0, // hash
|
||||
(MTPDstickerSet::Flag::f_official
|
||||
| MTPDstickerSet::Flag::f_installed_date
|
||||
| MTPDstickerSet_ClientFlag::f_special),
|
||||
kDefaultStickerInstallDate)).first->second.get();
|
||||
const auto custom = sets.emplace(
|
||||
Stickers::CustomSetId,
|
||||
uint64(0),
|
||||
qsl("Custom stickers"),
|
||||
QString(),
|
||||
0, // count
|
||||
0, // hash
|
||||
(MTPDstickerSet::Flag::f_installed_date
|
||||
| MTPDstickerSet_ClientFlag::f_special),
|
||||
kDefaultStickerInstallDate)).first->second.get();
|
||||
std::make_unique<Stickers::Set>(
|
||||
&Auth().data(),
|
||||
Stickers::CustomSetId,
|
||||
uint64(0),
|
||||
qsl("Custom stickers"),
|
||||
QString(),
|
||||
0, // count
|
||||
0, // hash
|
||||
(MTPDstickerSet::Flag::f_installed_date
|
||||
| MTPDstickerSet_ClientFlag::f_special),
|
||||
kDefaultStickerInstallDate)).first->second.get();
|
||||
|
||||
QMap<uint64, bool> read;
|
||||
while (!stickers.stream.atEnd()) {
|
||||
|
@ -4035,8 +4039,8 @@ int32 countDocumentVectorHash(const QVector<DocumentData*> vector) {
|
|||
}
|
||||
|
||||
int32 countSpecialStickerSetHash(uint64 setId) {
|
||||
auto &sets = Auth().data().stickerSets();
|
||||
auto it = sets.find(setId);
|
||||
const auto &sets = Auth().data().stickerSets();
|
||||
const auto it = sets.find(setId);
|
||||
if (it != sets.cend()) {
|
||||
return countDocumentVectorHash(it->second->stickers);
|
||||
}
|
||||
|
|
|
@ -24,9 +24,7 @@ namespace {
|
|||
// After 128 MB of unpacked images we try to clear some memory.
|
||||
constexpr auto kMemoryForCache = 128 * 1024 * 1024;
|
||||
|
||||
std::map<QString, std::unique_ptr<Image>> WebUrlImages;
|
||||
std::unordered_map<InMemoryKey, std::unique_ptr<Image>> StorageImages;
|
||||
std::unordered_map<InMemoryKey, std::unique_ptr<Image>> WebCachedImages;
|
||||
std::unordered_map<InMemoryKey, std::unique_ptr<Image>> GeoPointImages;
|
||||
|
||||
int64 ComputeUsage(QSize size) {
|
||||
|
@ -115,8 +113,6 @@ QImage FromInlineBytes(const QByteArray &bytes) {
|
|||
|
||||
void ClearRemote() {
|
||||
base::take(StorageImages);
|
||||
base::take(WebUrlImages);
|
||||
base::take(WebCachedImages);
|
||||
base::take(GeoPointImages);
|
||||
}
|
||||
|
||||
|
@ -125,18 +121,6 @@ void ClearAll() {
|
|||
ClearRemote();
|
||||
}
|
||||
|
||||
ImagePtr Create(const QString &url, QSize box) {
|
||||
const auto key = qsl("//:%1//:%2//:").arg(box.width()).arg(box.height()) + url;
|
||||
const auto i = WebUrlImages.find(key);
|
||||
const auto image = (i != end(WebUrlImages))
|
||||
? i->second.get()
|
||||
: WebUrlImages.emplace(
|
||||
key,
|
||||
std::make_unique<Image>(std::make_unique<WebUrlSource>(url, box))
|
||||
).first->second.get();
|
||||
return ImagePtr(image);
|
||||
}
|
||||
|
||||
ImagePtr Create(QImage &&image, QByteArray format) {
|
||||
return ImagePtr(new Image(std::make_unique<ImageSource>(
|
||||
std::move(image),
|
||||
|
@ -185,60 +169,6 @@ QSize GetSizeForDocument(const QVector<MTPDocumentAttribute> &attributes) {
|
|||
return QSize();
|
||||
}
|
||||
|
||||
ImagePtr Create(const MTPDwebDocument &document, QSize box) {
|
||||
//const auto size = GetSizeForDocument(document.vattributes().v);
|
||||
//if (size.isEmpty()) {
|
||||
// return ImagePtr();
|
||||
//}
|
||||
|
||||
// We don't use size from WebDocument, because it is not reliable.
|
||||
// It can be > 0 and different from the real size that we get in upload.WebFile result.
|
||||
auto filesize = 0; // document.vsize().v;
|
||||
return Create(
|
||||
WebFileLocation(
|
||||
document.vurl().v,
|
||||
document.vaccess_hash().v),
|
||||
box,
|
||||
filesize);
|
||||
}
|
||||
|
||||
ImagePtr Create(const MTPDwebDocumentNoProxy &document, QSize box) {
|
||||
//const auto size = GetSizeForDocument(document.vattributes().v);
|
||||
//if (size.isEmpty()) {
|
||||
// return ImagePtr();
|
||||
//}
|
||||
|
||||
return Create(qs(document.vurl()), box);
|
||||
}
|
||||
|
||||
ImagePtr Create(const MTPWebDocument &document, QSize box) {
|
||||
switch (document.type()) {
|
||||
case mtpc_webDocument:
|
||||
return Create(document.c_webDocument(), box);
|
||||
case mtpc_webDocumentNoProxy:
|
||||
return Create(document.c_webDocumentNoProxy(), box);
|
||||
}
|
||||
Unexpected("Type in getImage(MTPWebDocument).");
|
||||
}
|
||||
|
||||
ImagePtr Create(
|
||||
const WebFileLocation &location,
|
||||
QSize box,
|
||||
int size) {
|
||||
const auto key = inMemoryKey(location);
|
||||
const auto i = WebCachedImages.find(key);
|
||||
const auto image = (i != end(WebCachedImages))
|
||||
? i->second.get()
|
||||
: WebCachedImages.emplace(
|
||||
key,
|
||||
std::make_unique<Image>(std::make_unique<WebCachedSource>(
|
||||
location,
|
||||
box,
|
||||
size))
|
||||
).first->second.get();
|
||||
return ImagePtr(image);
|
||||
}
|
||||
|
||||
ImagePtr Create(const GeoPointLocation &location) {
|
||||
const auto key = inMemoryKey(location);
|
||||
const auto i = GeoPointImages.find(key);
|
||||
|
|
|
@ -22,16 +22,8 @@ void ClearAll();
|
|||
[[nodiscard]] QSize GetSizeForDocument(
|
||||
const QVector<MTPDocumentAttribute> &attributes);
|
||||
|
||||
ImagePtr Create(const QString &url, QSize box);
|
||||
ImagePtr Create(QImage &&data, QByteArray format);
|
||||
ImagePtr Create(const StorageImageLocation &location, int size = 0);
|
||||
ImagePtr CreateStickerSetThumbnail(const StorageImageLocation &location);
|
||||
ImagePtr Create(const MTPDstickerSet &set, const MTPPhotoSize &size);
|
||||
ImagePtr Create(const MTPWebDocument &location, QSize box);
|
||||
ImagePtr Create(
|
||||
const WebFileLocation &location,
|
||||
QSize box,
|
||||
int size = 0);
|
||||
ImagePtr Create(const GeoPointLocation &location);
|
||||
|
||||
class Source {
|
||||
|
|
|
@ -776,7 +776,7 @@ DownloadLocation DownloadLocation::convertToModern(
|
|||
if (!data.is<StorageFileLocation>()) {
|
||||
return *this;
|
||||
}
|
||||
auto &file = this->data.get_unchecked<StorageFileLocation>();
|
||||
auto &file = data.get_unchecked<StorageFileLocation>();
|
||||
return DownloadLocation{ file.convertToModern(type, id, accessHash) };
|
||||
}
|
||||
|
||||
|
@ -800,6 +800,12 @@ Storage::Cache::Key DownloadLocation::cacheKey() const {
|
|||
});
|
||||
}
|
||||
|
||||
Storage::Cache::Key DownloadLocation::bigFileBaseCacheKey() const {
|
||||
return data.is<StorageFileLocation>()
|
||||
? data.get_unchecked<StorageFileLocation>().bigFileBaseCacheKey()
|
||||
: Storage::Cache::Key();
|
||||
}
|
||||
|
||||
bool DownloadLocation::valid() const {
|
||||
return data.match([](const GeoPointLocation &data) {
|
||||
return true;
|
||||
|
|
|
@ -416,6 +416,7 @@ public:
|
|||
uint64 accessHash) const;
|
||||
|
||||
[[nodiscard]] Storage::Cache::Key cacheKey() const;
|
||||
[[nodiscard]] Storage::Cache::Key bigFileBaseCacheKey() const;
|
||||
[[nodiscard]] bool valid() const;
|
||||
[[nodiscard]] bool isLegacy() const;
|
||||
[[nodiscard]] QByteArray fileReference() const;
|
||||
|
|
Loading…
Reference in New Issue