mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Improve mixed stickerpacks support.
This commit is contained in:
parent
b1795f8c5a
commit
90e572c8b1
11 changed files with 117 additions and 42 deletions
|
@ -353,6 +353,7 @@ private:
|
|||
int _perRow = 0;
|
||||
QSize _singleSize;
|
||||
TimeId _setInstallDate = TimeId(0);
|
||||
StickerType _setThumbnailType = StickerType::Webp;
|
||||
ImageWithLocation _setThumbnail;
|
||||
|
||||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||
|
@ -755,6 +756,8 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
|
|||
set,
|
||||
thumb);
|
||||
if (result.location.valid()) {
|
||||
_setThumbnailType
|
||||
= Data::ThumbnailTypeFromPhotoSize(thumb);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -775,7 +778,7 @@ void StickerSetBox::Inner::gotSet(const MTPmessages_StickerSet &set) {
|
|||
set->installDate = _setInstallDate;
|
||||
set->stickers = _pack;
|
||||
set->emoji = _emoji;
|
||||
set->setThumbnail(_setThumbnail);
|
||||
set->setThumbnail(_setThumbnail, _setThumbnailType);
|
||||
}
|
||||
});
|
||||
}, [&](const MTPDmessages_stickerSetNotModified &data) {
|
||||
|
@ -855,7 +858,7 @@ void StickerSetBox::Inner::installDone(
|
|||
}
|
||||
const auto set = it->second.get();
|
||||
set->thumbnailDocumentId = _setThumbnailDocumentId;
|
||||
set->setThumbnail(_setThumbnail);
|
||||
set->setThumbnail(_setThumbnail, _setThumbnailType);
|
||||
set->stickers = _pack;
|
||||
set->emoji = _emoji;
|
||||
|
||||
|
|
|
@ -178,7 +178,6 @@ private:
|
|||
[[nodiscard]] bool isRecentSet() const;
|
||||
[[nodiscard]] bool isMasksSet() const;
|
||||
[[nodiscard]] bool isEmojiSet() const;
|
||||
[[nodiscard]] bool isWebm() const;
|
||||
[[nodiscard]] bool isInstalled() const;
|
||||
[[nodiscard]] bool isUnread() const;
|
||||
[[nodiscard]] bool isArchived() const;
|
||||
|
@ -1174,10 +1173,6 @@ bool StickersBox::Inner::Row::isEmojiSet() const {
|
|||
return (set->type() == Data::StickersType::Emoji);
|
||||
}
|
||||
|
||||
bool StickersBox::Inner::Row::isWebm() const {
|
||||
return (set->flags & SetFlag::Webm);
|
||||
}
|
||||
|
||||
bool StickersBox::Inner::Row::isInstalled() const {
|
||||
return (flagsOverride & SetFlag::Installed);
|
||||
}
|
||||
|
@ -1569,7 +1564,7 @@ void StickersBox::Inner::paintRowThumbnail(
|
|||
void StickersBox::Inner::validateLottieAnimation(not_null<Row*> row) {
|
||||
if (row->lottie
|
||||
|| !ChatHelpers::HasLottieThumbnail(
|
||||
row->set->flags,
|
||||
row->set->thumbnailType(),
|
||||
row->thumbnailMedia.get(),
|
||||
row->stickerMedia.get())) {
|
||||
return;
|
||||
|
@ -1592,7 +1587,7 @@ void StickersBox::Inner::validateLottieAnimation(not_null<Row*> row) {
|
|||
void StickersBox::Inner::validateWebmAnimation(not_null<Row*> row) {
|
||||
if (row->webm
|
||||
|| !ChatHelpers::HasWebmThumbnail(
|
||||
row->set->flags,
|
||||
row->set->thumbnailType(),
|
||||
row->thumbnailMedia.get(),
|
||||
row->stickerMedia.get())) {
|
||||
return;
|
||||
|
|
|
@ -668,8 +668,9 @@ GroupCall::GroupCall(
|
|||
GroupCall::~GroupCall() {
|
||||
destroyScreencast();
|
||||
destroyController();
|
||||
|
||||
Core::App().mediaDevices().setCaptureMuteTracker(this, false);
|
||||
if (!_rtmp) {
|
||||
Core::App().mediaDevices().setCaptureMuteTracker(this, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool GroupCall::isSharingScreen() const {
|
||||
|
@ -2091,14 +2092,16 @@ void GroupCall::setupMediaDevices() {
|
|||
_cameraCapture->switchToDevice(deviceId.value.toStdString(), false);
|
||||
}, _lifetime);
|
||||
|
||||
_muted.value() | rpl::start_with_next([=](MuteState state) {
|
||||
const auto devices = &Core::App().mediaDevices();
|
||||
const auto muted = (state != MuteState::Active)
|
||||
&& (state != MuteState::PushToTalk);
|
||||
const auto track = !muted || (state == MuteState::Muted);
|
||||
devices->setCaptureMuteTracker(this, track);
|
||||
devices->setCaptureMuted(muted);
|
||||
}, _lifetime);
|
||||
if (!_rtmp) {
|
||||
_muted.value() | rpl::start_with_next([=](MuteState state) {
|
||||
const auto devices = &Core::App().mediaDevices();
|
||||
const auto muted = (state != MuteState::Active)
|
||||
&& (state != MuteState::PushToTalk);
|
||||
const auto track = !muted || (state == MuteState::Muted);
|
||||
devices->setCaptureMuteTracker(this, track);
|
||||
devices->setCaptureMuted(muted);
|
||||
}, _lifetime);
|
||||
}
|
||||
}
|
||||
|
||||
void GroupCall::captureMuteChanged(bool mute) {
|
||||
|
|
|
@ -1182,7 +1182,7 @@ void StickersListFooter::validateIconLottieAnimation(
|
|||
if (icon.lottie
|
||||
|| !icon.sticker
|
||||
|| !HasLottieThumbnail(
|
||||
icon.set ? icon.set->flags : Data::StickersSetFlags(),
|
||||
icon.set ? icon.set->thumbnailType() : StickerType(),
|
||||
icon.thumbnailMedia.get(),
|
||||
icon.stickerMedia.get())) {
|
||||
return;
|
||||
|
@ -1211,7 +1211,7 @@ void StickersListFooter::validateIconWebmAnimation(
|
|||
if (icon.webm
|
||||
|| !icon.sticker
|
||||
|| !HasWebmThumbnail(
|
||||
icon.set ? icon.set->flags : Data::StickersSetFlags(),
|
||||
icon.set ? icon.set->thumbnailType() : StickerType(),
|
||||
icon.thumbnailMedia.get(),
|
||||
icon.stickerMedia.get())) {
|
||||
return;
|
||||
|
|
|
@ -138,11 +138,11 @@ not_null<Lottie::Animation*> LottieAnimationFromDocument(
|
|||
}
|
||||
|
||||
bool HasLottieThumbnail(
|
||||
Data::StickersSetFlags flags,
|
||||
StickerType thumbType,
|
||||
Data::StickersSetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media) {
|
||||
if (thumb) {
|
||||
return !(flags & Data::StickersSetFlag::Webm)
|
||||
return (thumbType == StickerType::Tgs)
|
||||
&& !thumb->content().isEmpty();
|
||||
} else if (!media) {
|
||||
return false;
|
||||
|
@ -200,11 +200,11 @@ std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
|
|||
}
|
||||
|
||||
bool HasWebmThumbnail(
|
||||
Data::StickersSetFlags flags,
|
||||
StickerType thumbType,
|
||||
Data::StickersSetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media) {
|
||||
if (thumb) {
|
||||
return (flags & Data::StickersSetFlag::Webm)
|
||||
return (thumbType == StickerType::Webm)
|
||||
&& !thumb->content().isEmpty();
|
||||
} else if (!media) {
|
||||
return false;
|
||||
|
|
|
@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
enum class StickerType : uchar;
|
||||
|
||||
namespace base {
|
||||
template <typename Enum>
|
||||
class Flags;
|
||||
|
@ -43,7 +45,7 @@ class PathShiftGradient;
|
|||
namespace Data {
|
||||
class DocumentMedia;
|
||||
class StickersSetThumbnailView;
|
||||
enum class StickersSetFlag;
|
||||
enum class StickersSetFlag : ushort;
|
||||
using StickersSetFlags = base::flags<StickersSetFlag>;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -90,7 +92,7 @@ enum class StickerLottieSize : uint8 {
|
|||
QSize box);
|
||||
|
||||
[[nodiscard]] bool HasLottieThumbnail(
|
||||
Data::StickersSetFlags flags,
|
||||
StickerType thumbType,
|
||||
Data::StickersSetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media);
|
||||
[[nodiscard]] std::unique_ptr<Lottie::SinglePlayer> LottieThumbnail(
|
||||
|
@ -101,7 +103,7 @@ enum class StickerLottieSize : uint8 {
|
|||
std::shared_ptr<Lottie::FrameRenderer> renderer = nullptr);
|
||||
|
||||
[[nodiscard]] bool HasWebmThumbnail(
|
||||
Data::StickersSetFlags flags,
|
||||
StickerType thumbType,
|
||||
Data::StickersSetThumbnailView *thumb,
|
||||
Data::DocumentMedia *media);
|
||||
[[nodiscard]] Media::Clip::ReaderPointer WebmThumbnail(
|
||||
|
|
|
@ -1003,6 +1003,7 @@ void Stickers::featuredReceived(
|
|||
auto it = sets.find(data->vid().v);
|
||||
const auto title = getSetTitle(*data);
|
||||
const auto installDate = data->vinstalled_date().value_or_empty();
|
||||
auto thumbnailType = StickerType::Webp;
|
||||
const auto thumbnail = [&] {
|
||||
if (const auto thumbs = data->vthumbs()) {
|
||||
for (const auto &thumb : thumbs->v) {
|
||||
|
@ -1011,6 +1012,7 @@ void Stickers::featuredReceived(
|
|||
*data,
|
||||
thumb);
|
||||
if (result.location.valid()) {
|
||||
thumbnailType = ThumbnailTypeFromPhotoSize(thumb);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1046,7 +1048,7 @@ void Stickers::featuredReceived(
|
|||
set->flags |= SetFlag::NotLoaded; // need to request this set
|
||||
}
|
||||
}
|
||||
it->second->setThumbnail(thumbnail);
|
||||
it->second->setThumbnail(thumbnail, thumbnailType);
|
||||
it->second->thumbnailDocumentId = data->vthumb_document_id().value_or_empty();
|
||||
featuredOrder.push_back(data->vid().v);
|
||||
if (it->second->stickers.isEmpty()
|
||||
|
@ -1415,6 +1417,7 @@ not_null<StickersSet*> Stickers::feedSet(const MTPStickerSet &info) {
|
|||
auto it = sets.find(data.vid().v);
|
||||
auto title = getSetTitle(data);
|
||||
auto oldFlags = StickersSetFlags(0);
|
||||
auto thumbnailType = StickerType::Webp;
|
||||
const auto thumbnail = [&] {
|
||||
if (const auto thumbs = data.vthumbs()) {
|
||||
for (const auto &thumb : thumbs->v) {
|
||||
|
@ -1423,6 +1426,7 @@ not_null<StickersSet*> Stickers::feedSet(const MTPStickerSet &info) {
|
|||
data,
|
||||
thumb);
|
||||
if (result.location.valid()) {
|
||||
thumbnailType = Data::ThumbnailTypeFromPhotoSize(thumb);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1467,7 +1471,7 @@ not_null<StickersSet*> Stickers::feedSet(const MTPStickerSet &info) {
|
|||
}
|
||||
}
|
||||
const auto set = it->second.get();
|
||||
set->setThumbnail(thumbnail);
|
||||
set->setThumbnail(thumbnail, thumbnailType);
|
||||
set->thumbnailDocumentId = data.vthumb_document_id().value_or_empty();
|
||||
auto changedFlags = (oldFlags ^ set->flags);
|
||||
if (changedFlags & SetFlag::Archived) {
|
||||
|
@ -1683,4 +1687,17 @@ RecentStickerPack &Stickers::getRecentPack() const {
|
|||
return cRefRecentStickers();
|
||||
}
|
||||
|
||||
StickerType ThumbnailTypeFromPhotoSize(const MTPPhotoSize &size) {
|
||||
const auto &type = size.match([&](const auto &data) {
|
||||
return data.vtype().v;
|
||||
});
|
||||
const auto ch = type.isEmpty() ? char() : type[0];
|
||||
switch (ch) {
|
||||
case 's': return StickerType::Webp;
|
||||
case 'a': return StickerType::Tgs;
|
||||
case 'v': return StickerType::Webm;
|
||||
}
|
||||
return StickerType::Webp;
|
||||
}
|
||||
|
||||
} // namespace Stickers
|
||||
|
|
|
@ -36,6 +36,8 @@ enum class StickersType : uchar {
|
|||
Masks,
|
||||
Emoji,
|
||||
};
|
||||
[[nodiscard]] StickerType ThumbnailTypeFromPhotoSize(
|
||||
const MTPPhotoSize &size);
|
||||
|
||||
class Stickers final {
|
||||
public:
|
||||
|
|
|
@ -118,7 +118,10 @@ bool StickersSet::channelStatus() const {
|
|||
return flags & StickersSetFlag::ChannelStatus;
|
||||
}
|
||||
|
||||
void StickersSet::setThumbnail(const ImageWithLocation &data) {
|
||||
void StickersSet::setThumbnail(
|
||||
const ImageWithLocation &data,
|
||||
StickerType type) {
|
||||
_thumbnailType = type;
|
||||
Data::UpdateCloudFile(
|
||||
_thumbnail,
|
||||
data,
|
||||
|
@ -139,6 +142,10 @@ bool StickersSet::hasThumbnail() const {
|
|||
return _thumbnail.location.valid();
|
||||
}
|
||||
|
||||
StickerType StickersSet::thumbnailType() const {
|
||||
return _thumbnailType;
|
||||
}
|
||||
|
||||
bool StickersSet::thumbnailLoading() const {
|
||||
return (_thumbnail.loader != nullptr);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_cloud_file.h"
|
||||
|
||||
class DocumentData;
|
||||
enum class StickerType : uchar;
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
|
@ -46,7 +47,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
enum class StickersSetFlag {
|
||||
enum class StickersSetFlag : ushort {
|
||||
Installed = (1 << 0),
|
||||
Archived = (1 << 1),
|
||||
Masks = (1 << 2),
|
||||
|
@ -55,7 +56,6 @@ enum class StickersSetFlag {
|
|||
Featured = (1 << 5),
|
||||
Unread = (1 << 6),
|
||||
Special = (1 << 7),
|
||||
Webm = (1 << 8),
|
||||
Emoji = (1 << 9),
|
||||
TextColor = (1 << 10),
|
||||
ChannelStatus = (1 << 11),
|
||||
|
@ -89,9 +89,10 @@ public:
|
|||
[[nodiscard]] bool textColor() const;
|
||||
[[nodiscard]] bool channelStatus() const;
|
||||
|
||||
void setThumbnail(const ImageWithLocation &data);
|
||||
void setThumbnail(const ImageWithLocation &data, StickerType type);
|
||||
|
||||
[[nodiscard]] bool hasThumbnail() const;
|
||||
[[nodiscard]] StickerType thumbnailType() const;
|
||||
[[nodiscard]] bool thumbnailLoading() const;
|
||||
[[nodiscard]] bool thumbnailFailed() const;
|
||||
void loadThumbnail();
|
||||
|
@ -111,6 +112,11 @@ public:
|
|||
int count = 0;
|
||||
int locked = 0;
|
||||
StickersSetFlags flags;
|
||||
|
||||
private:
|
||||
StickerType _thumbnailType = {};
|
||||
|
||||
public:
|
||||
TimeId installDate = 0;
|
||||
StickersPack covers;
|
||||
StickersPack stickers;
|
||||
|
|
|
@ -44,7 +44,7 @@ using Database = Cache::Database;
|
|||
constexpr auto kDelayedWriteTimeout = crl::time(1000);
|
||||
|
||||
constexpr auto kStickersVersionTag = quint32(-1);
|
||||
constexpr auto kStickersSerializeVersion = 3;
|
||||
constexpr auto kStickersSerializeVersion = 4;
|
||||
constexpr auto kMaxSavedStickerSetsCount = 1000;
|
||||
constexpr auto kDefaultStickerInstallDate = TimeId(1);
|
||||
|
||||
|
@ -1683,7 +1683,8 @@ void Account::writeStickerSet(
|
|||
<< qint32(count)
|
||||
<< qint32(set.flags)
|
||||
<< qint32(set.installDate)
|
||||
<< quint64(set.thumbnailDocumentId);
|
||||
<< quint64(set.thumbnailDocumentId)
|
||||
<< qint32(set.thumbnailType());
|
||||
Serialize::writeImageLocation(stream, set.thumbnailLocation());
|
||||
};
|
||||
if (set.flags & SetFlag::NotLoaded) {
|
||||
|
@ -1752,11 +1753,23 @@ void Account::writeStickerSets(
|
|||
continue;
|
||||
}
|
||||
|
||||
// id + accessHash + hash + title + shortName + stickersCount + flags + installDate
|
||||
// id
|
||||
// + accessHash
|
||||
// + hash
|
||||
// + title
|
||||
// + shortName
|
||||
// + stickersCount
|
||||
// + flags
|
||||
// + installDate
|
||||
// + thumbnailDocumentId
|
||||
// + thumbnailType
|
||||
// + thumbnailLocation
|
||||
size += sizeof(quint64) * 3
|
||||
+ Serialize::stringSize(raw->title)
|
||||
+ Serialize::stringSize(raw->shortName)
|
||||
+ sizeof(qint32) * 3
|
||||
+ sizeof(quint64)
|
||||
+ sizeof(qint32)
|
||||
+ Serialize::imageLocationSize(raw->thumbnailLocation());
|
||||
if (raw->flags & SetFlag::NotLoaded) {
|
||||
continue;
|
||||
|
@ -1838,8 +1851,7 @@ void Account::readStickerSets(
|
|||
quint32 versionTag = 0;
|
||||
qint32 version = 0;
|
||||
stickers.stream >> versionTag >> version;
|
||||
if (versionTag != kStickersVersionTag
|
||||
|| (version != 2 && version != kStickersSerializeVersion)) {
|
||||
if (versionTag != kStickersVersionTag || version < 2) {
|
||||
// Old data, without sticker set thumbnails.
|
||||
return failed();
|
||||
}
|
||||
|
@ -1858,6 +1870,7 @@ void Account::readStickerSets(
|
|||
qint32 setInstallDate = 0;
|
||||
Data::StickersSetFlags setFlags = 0;
|
||||
qint32 setFlagsValue = 0;
|
||||
qint32 setThumbnailType = qint32(StickerType::Webp);
|
||||
ImageLocation setThumbnail;
|
||||
|
||||
stickers.stream
|
||||
|
@ -1871,6 +1884,14 @@ void Account::readStickerSets(
|
|||
>> setInstallDate;
|
||||
if (version > 2) {
|
||||
stickers.stream >> setThumbnailDocumentId;
|
||||
if (version > 3) {
|
||||
stickers.stream >> setThumbnailType;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto kLegacyFlagWebm = (1 << 8);
|
||||
if ((version < 4) && (setFlagsValue & kLegacyFlagWebm)) {
|
||||
setThumbnailType = qint32(StickerType::Webm);
|
||||
}
|
||||
const auto thumbnail = Serialize::readImageLocation(
|
||||
stickers.version,
|
||||
|
@ -1903,7 +1924,8 @@ void Account::readStickerSets(
|
|||
}
|
||||
|
||||
auto it = sets.find(setId);
|
||||
if (it == sets.cend()) {
|
||||
auto settingSet = (it == sets.cend());
|
||||
if (settingSet) {
|
||||
// We will set this flags from order lists when reading those stickers.
|
||||
setFlags &= ~(SetFlag::Installed | SetFlag::Featured);
|
||||
it = sets.emplace(setId, std::make_unique<Data::StickersSet>(
|
||||
|
@ -1916,8 +1938,6 @@ void Account::readStickerSets(
|
|||
0,
|
||||
setFlags,
|
||||
setInstallDate)).first;
|
||||
it->second->setThumbnail(
|
||||
ImageWithLocation{ .location = setThumbnail });
|
||||
it->second->thumbnailDocumentId = setThumbnailDocumentId;
|
||||
}
|
||||
const auto set = it->second.get();
|
||||
|
@ -2014,6 +2034,26 @@ void Account::readStickerSets(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settingSet) {
|
||||
if (version < 4
|
||||
&& setThumbnailType == qint32(StickerType::Webp)
|
||||
&& !set->stickers.empty()
|
||||
&& set->stickers.front()->sticker()) {
|
||||
const auto first = set->stickers.front();
|
||||
setThumbnailType = qint32(first->sticker()->type);
|
||||
}
|
||||
const auto thumbType = [&] {
|
||||
switch (setThumbnailType) {
|
||||
case qint32(StickerType::Webp): return StickerType::Webp;
|
||||
case qint32(StickerType::Tgs): return StickerType::Tgs;
|
||||
case qint32(StickerType::Webm): return StickerType::Webm;
|
||||
}
|
||||
return StickerType::Webp;
|
||||
}();
|
||||
set->setThumbnail(
|
||||
ImageWithLocation{ .location = setThumbnail }, thumbType);
|
||||
}
|
||||
}
|
||||
|
||||
// Read orders of installed and featured stickers.
|
||||
|
|
Loading…
Add table
Reference in a new issue