2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 14:38:15 +00:00

Init webm player for sticker set thumbnails.

This commit is contained in:
John Preston
2022-01-24 15:33:31 +03:00
parent 10ff71e8f6
commit 20dbf18106
13 changed files with 251 additions and 117 deletions

View File

@@ -35,6 +35,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image.h"
#include "ui/cached_round_corners.h"
#include "window/window_session_controller.h"
#include "media/clip/media_clip_reader.h"
#include "main/main_session.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@@ -143,10 +144,7 @@ private:
int32 count,
const QString &title,
int titleWidth,
bool installed,
bool official,
bool unread,
bool archived,
Data::StickersSetFlags flagsOverride,
bool removed,
int32 pixw,
int32 pixh);
@@ -154,6 +152,10 @@ private:
bool isRecentSet() const;
bool isMasksSet() const;
bool isWebm() const;
bool isInstalled() const;
bool isUnread() const;
bool isArchived() const;
const not_null<StickersSet*> set;
DocumentData *sticker = nullptr;
@@ -162,16 +164,14 @@ private:
int32 count = 0;
QString title;
int titleWidth = 0;
bool installed = false;
bool official = false;
bool unread = false;
bool archived = false;
Data::StickersSetFlags flagsOverride;
bool removed = false;
int32 pixw = 0;
int32 pixh = 0;
anim::value yadd;
std::unique_ptr<Ui::RippleAnimation> ripple;
std::unique_ptr<Lottie::SinglePlayer> lottie;
Media::Clip::ReaderPointer webm;
};
struct MegagroupSet {
inline bool operator==(const MegagroupSet &other) const {
@@ -221,6 +221,8 @@ private:
void setActionSel(int32 actionSel);
float64 aboveShadowOpacity() const;
void validateLottieAnimation(not_null<Row*> row);
void validateWebmAnimation(not_null<Row*> row);
void validateAnimation(not_null<Row*> row);
void updateRowThumbnail(not_null<Row*> row);
void readVisibleSets();
@@ -229,8 +231,12 @@ private:
void rebuildAppendSet(not_null<StickersSet*> set, int maxNameWidth);
void fillSetCover(not_null<StickersSet*> set, DocumentData **outSticker, int *outWidth, int *outHeight) const;
int fillSetCount(not_null<StickersSet*> set) const;
QString fillSetTitle(not_null<StickersSet*> set, int maxNameWidth, int *outTitleWidth) const;
void fillSetFlags(not_null<StickersSet*> set, bool *outInstalled, bool *outOfficial, bool *outUnread, bool *outArchived);
[[nodiscard]] QString fillSetTitle(
not_null<StickersSet*> set,
int maxNameWidth,
int *outTitleWidth) const;
[[nodiscard]] Data::StickersSetFlags fillSetFlags(
not_null<StickersSet*> set) const;
void rebuildMegagroupSet();
void fixupMegagroupSetAddress();
void handleMegagroupSetAddressChange();
@@ -1030,10 +1036,7 @@ StickersBox::Inner::Row::Row(
int32 count,
const QString &title,
int titleWidth,
bool installed,
bool official,
bool unread,
bool archived,
Data::StickersSetFlags flagsOverride,
bool removed,
int32 pixw,
int32 pixh)
@@ -1042,10 +1045,7 @@ StickersBox::Inner::Row::Row(
, count(count)
, title(title)
, titleWidth(titleWidth)
, installed(installed)
, official(official)
, unread(unread)
, archived(archived)
, flagsOverride(flagsOverride)
, removed(removed)
, pixw(pixw)
, pixh(pixh) {
@@ -1062,6 +1062,22 @@ bool StickersBox::Inner::Row::isMasksSet() const {
return (set->flags & SetFlag::Masks);
}
bool StickersBox::Inner::Row::isWebm() const {
return (set->flags & SetFlag::Webm);
}
bool StickersBox::Inner::Row::isInstalled() const {
return (flagsOverride & SetFlag::Installed);
}
bool StickersBox::Inner::Row::isUnread() const {
return (flagsOverride & SetFlag::Unread);
}
bool StickersBox::Inner::Row::isArchived() const {
return (flagsOverride & SetFlag::Archived);
}
StickersBox::Inner::Inner(
QWidget *parent,
not_null<Window::SessionController*> controller,
@@ -1302,7 +1318,7 @@ void StickersBox::Inner::paintRow(Painter &p, not_null<Row*> row, int index) {
p.setPen(st::contactsNameFg);
p.drawTextLeft(namex, namey, width(), row->title, row->titleWidth);
if (row->unread) {
if (row->isUnread()) {
p.setPen(Qt::NoPen);
p.setBrush(st::stickersFeaturedUnreadBg);
@@ -1344,7 +1360,7 @@ void StickersBox::Inner::paintRowThumbnail(
row->stickerMedia->thumbnailWanted(origin);
}
}
validateLottieAnimation(row);
validateAnimation(row);
if (!row->lottie) {
const auto thumb = row->thumbnailMedia
? row->thumbnailMedia->image()
@@ -1380,6 +1396,7 @@ void StickersBox::Inner::paintRowThumbnail(
void StickersBox::Inner::validateLottieAnimation(not_null<Row*> row) {
if (row->lottie
|| !ChatHelpers::HasLottieThumbnail(
row->set->flags,
row->thumbnailMedia.get(),
row->stickerMedia.get())) {
return;
@@ -1401,6 +1418,25 @@ void StickersBox::Inner::validateLottieAnimation(not_null<Row*> row) {
}, lifetime());
}
void StickersBox::Inner::validateWebmAnimation(not_null<Row*> row) {
if (row->webm
|| !ChatHelpers::HasWebmThumbnail(
row->set->flags,
row->thumbnailMedia.get(),
row->stickerMedia.get())) {
return;
}
row->webm = ChatHelpers::WebmThumbnail(
row->thumbnailMedia.get(),
row->stickerMedia.get(),
[=](Media::Clip::Notification) { updateRowThumbnail(row); });
}
void StickersBox::Inner::validateAnimation(not_null<Row*> row) {
validateWebmAnimation(row);
validateLottieAnimation(row);
}
void StickersBox::Inner::updateRowThumbnail(not_null<Row*> row) {
const auto rowTop = [&] {
if (row == _megagroupSelectedSet.get()) {
@@ -1429,7 +1465,7 @@ void StickersBox::Inner::updateRowThumbnail(not_null<Row*> row) {
void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> row, int index) {
auto removeButton = (_isInstalled && !row->removed);
auto rect = relativeButtonRect(removeButton);
if (!_isInstalled && row->installed && !row->archived && !row->removed) {
if (!_isInstalled && row->isInstalled() && !row->isArchived() && !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;
@@ -1516,7 +1552,7 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
auto rippleMask = Ui::RippleAnimation::ellipseMask(QSize(rippleSize, rippleSize));
ensureRipple(st::stickersRemove.ripple, std::move(rippleMask), removeButton);
}
} else if (!row->installed || row->archived || row->removed) {
} else if (!row->isInstalled() || row->isArchived() || row->removed) {
auto rippleSize = QSize(_addWidth - st::stickersTrendingAdd.width, st::stickersTrendingAdd.height);
auto rippleMask = Ui::RippleAnimation::roundRectMask(rippleSize, st::roundRadiusSmall);
ensureRipple(st::stickersTrendingAdd.ripple, std::move(rippleMask), removeButton);
@@ -1649,7 +1685,7 @@ void StickersBox::Inner::updateSelected() {
selected = selectedIndex;
local.setY(local.y() - _itemsTop - selectedIndex * _rowHeight);
const auto row = _rows[selectedIndex].get();
if (!_megagroupSet && (_isInstalled || !row->installed || row->archived || row->removed)) {
if (!_megagroupSet && (_isInstalled || !row->isInstalled() || row->isArchived() || row->removed)) {
auto removeButton = (_isInstalled && !row->removed);
auto rect = myrtlrect(relativeButtonRect(removeButton));
actionSel = rect.contains(local) ? selectedIndex : -1;
@@ -1952,8 +1988,10 @@ void StickersBox::Inner::rebuildMegagroupSet() {
auto sticker = (DocumentData*)nullptr;
auto pixw = 0, pixh = 0;
fillSetCover(set, &sticker, &pixw, &pixh);
auto installed = true, official = false, unread = false, archived = false, removed = false;
if (!_megagroupSelectedSet || _megagroupSelectedSet->set->id != set->id) {
auto flagsOverride = SetFlag::Installed;
auto removed = false;
if (!_megagroupSelectedSet
|| _megagroupSelectedSet->set->id != set->id) {
_megagroupSetField->setText(set->shortName);
_megagroupSetField->finishAnimating();
}
@@ -1963,10 +2001,7 @@ void StickersBox::Inner::rebuildMegagroupSet() {
count,
title,
titleWidth,
installed,
official,
unread,
archived,
flagsOverride,
removed,
pixw,
pixh);
@@ -2095,13 +2130,14 @@ 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);
auto wasInstalled = row->isInstalled();
auto wasArchived = row->isArchived();
row->flagsOverride = fillSetFlags(set);
if (_isInstalled) {
row->archived = false;
row->flagsOverride &= ~SetFlag::Archived;
}
if (row->installed != wasInstalled || row->archived != wasArchived) {
if (row->isInstalled() != wasInstalled
|| row->isArchived() != wasArchived) {
row->ripple.reset();
}
}
@@ -2143,11 +2179,11 @@ int StickersBox::Inner::countMaxNameWidth() const {
void StickersBox::Inner::rebuildAppendSet(
not_null<StickersSet*> set,
int maxNameWidth) {
bool installed = true, official = true, unread = false, archived = false, removed = false;
if (set->id != Data::Stickers::CloudRecentSetId) {
fillSetFlags(set, &installed, &official, &unread, &archived);
}
if (_isInstalled && archived) {
auto flagsOverride = (set->id != Data::Stickers::CloudRecentSetId)
? fillSetFlags(set)
: SetFlag::Installed;
auto removed = false;
if (_isInstalled && (flagsOverride & SetFlag::Archived)) {
return;
}
@@ -2176,10 +2212,7 @@ void StickersBox::Inner::rebuildAppendSet(
raw->count = count;
raw->title = title;
raw->titleWidth = titleWidth;
raw->installed = installed;
raw->official = official;
raw->unread = unread;
raw->archived = archived;
raw->flagsOverride = flagsOverride;
raw->removed = removed;
raw->pixw = pixw;
raw->pixh = pixh;
@@ -2200,10 +2233,7 @@ void StickersBox::Inner::rebuildAppendSet(
count,
title,
titleWidth,
installed,
official,
unread,
archived,
flagsOverride,
removed,
pixw,
pixh));
@@ -2289,20 +2319,12 @@ QString StickersBox::Inner::fillSetTitle(
return result;
}
void StickersBox::Inner::fillSetFlags(
not_null<StickersSet*> set,
bool *outInstalled,
bool *outOfficial,
bool *outUnread,
bool *outArchived) {
*outInstalled = (set->flags & SetFlag::Installed);
*outOfficial = (set->flags & SetFlag::Official);
*outArchived = (set->flags & SetFlag::Archived);
if (_section == Section::Featured) {
*outUnread = (set->flags & SetFlag::Unread);
} else {
*outUnread = false;
}
Data::StickersSetFlags StickersBox::Inner::fillSetFlags(
not_null<StickersSet*> set) const {
const auto result = set->flags;
return (_section == Section::Featured)
? result
: (result & ~SetFlag::Unread);
}
template <typename Check>
@@ -2319,7 +2341,7 @@ StickersSetsOrder StickersBox::Inner::collectSets(Check check) const {
StickersSetsOrder StickersBox::Inner::getOrder() const {
return collectSets([](Row *row) {
return !row->archived && !row->removed && !row->isRecentSet();
return !row->isArchived() && !row->removed && !row->isRecentSet();
});
}
@@ -2394,7 +2416,7 @@ void StickersBox::Inner::readVisibleSets() {
int rowTo = ceilclamp(itemsVisibleBottom, _rowHeight, 0, _rows.size());
for (int i = rowFrom; i < rowTo; ++i) {
const auto row = _rows[i].get();
if (!row->unread) {
if (!row->isUnread()) {
continue;
}
if ((i * _rowHeight < itemsVisibleTop)