diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 6f5966de6..414f098e2 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -353,6 +353,7 @@ private: int _perRow = 0; QSize _singleSize; TimeId _setInstallDate = TimeId(0); + StickerType _setThumbnailType = StickerType::Webp; ImageWithLocation _setThumbnail; const std::unique_ptr _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; diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 94c11d00f..01f6a1ed1 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -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) { 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) { void StickersBox::Inner::validateWebmAnimation(not_null row) { if (row->webm || !ChatHelpers::HasWebmThumbnail( - row->set->flags, + row->set->thumbnailType(), row->thumbnailMedia.get(), row->stickerMedia.get())) { return; diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index 5f7346913..fda260064 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -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) { diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp b/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp index d77a7cafd..a33462f4a 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_footer.cpp @@ -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; diff --git a/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp b/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp index fe36c825c..5e2aceb7a 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp +++ b/Telegram/SourceFiles/chat_helpers/stickers_lottie.cpp @@ -138,11 +138,11 @@ not_null 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 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; diff --git a/Telegram/SourceFiles/chat_helpers/stickers_lottie.h b/Telegram/SourceFiles/chat_helpers/stickers_lottie.h index d1581374f..156d0a9bb 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_lottie.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_lottie.h @@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +enum class StickerType : uchar; + namespace base { template 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; } // 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 LottieThumbnail( @@ -101,7 +103,7 @@ enum class StickerLottieSize : uint8 { std::shared_ptr renderer = nullptr); [[nodiscard]] bool HasWebmThumbnail( - Data::StickersSetFlags flags, + StickerType thumbType, Data::StickersSetThumbnailView *thumb, Data::DocumentMedia *media); [[nodiscard]] Media::Clip::ReaderPointer WebmThumbnail( diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.cpp b/Telegram/SourceFiles/data/stickers/data_stickers.cpp index c18a1c3bf..11c410da3 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers.cpp @@ -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 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 Stickers::feedSet(const MTPStickerSet &info) { data, thumb); if (result.location.valid()) { + thumbnailType = Data::ThumbnailTypeFromPhotoSize(thumb); return result; } } @@ -1467,7 +1471,7 @@ not_null 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 diff --git a/Telegram/SourceFiles/data/stickers/data_stickers.h b/Telegram/SourceFiles/data/stickers/data_stickers.h index f469f173c..7b8937846 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers.h +++ b/Telegram/SourceFiles/data/stickers/data_stickers.h @@ -36,6 +36,8 @@ enum class StickersType : uchar { Masks, Emoji, }; +[[nodiscard]] StickerType ThumbnailTypeFromPhotoSize( + const MTPPhotoSize &size); class Stickers final { public: diff --git a/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp b/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp index dc53c0a35..324377242 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp +++ b/Telegram/SourceFiles/data/stickers/data_stickers_set.cpp @@ -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); } diff --git a/Telegram/SourceFiles/data/stickers/data_stickers_set.h b/Telegram/SourceFiles/data/stickers/data_stickers_set.h index e9124471c..e77ee46b5 100644 --- a/Telegram/SourceFiles/data/stickers/data_stickers_set.h +++ b/Telegram/SourceFiles/data/stickers/data_stickers_set.h @@ -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; diff --git a/Telegram/SourceFiles/storage/storage_account.cpp b/Telegram/SourceFiles/storage/storage_account.cpp index c961c891b..ca04135e8 100644 --- a/Telegram/SourceFiles/storage/storage_account.cpp +++ b/Telegram/SourceFiles/storage/storage_account.cpp @@ -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( @@ -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.