From e3cc8652e465f430ca040b25efeb2f2df6bf312c Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 30 Nov 2018 16:49:30 +0400 Subject: [PATCH] New structs for media autodownload settings. --- Telegram/SourceFiles/app.cpp | 3 - Telegram/SourceFiles/auth_session.cpp | 11 + Telegram/SourceFiles/auth_session.h | 9 + Telegram/SourceFiles/boxes/connection_box.cpp | 91 ++++-- Telegram/SourceFiles/core/utils.cpp | 2 + .../SourceFiles/data/data_auto_download.cpp | 279 ++++++++++++++++++ .../SourceFiles/data/data_auto_download.h | 110 +++++++ Telegram/SourceFiles/data/data_document.cpp | 53 ++-- Telegram/SourceFiles/data/data_document.h | 2 +- Telegram/SourceFiles/intro/introwidget.cpp | 6 +- Telegram/SourceFiles/settings.h | 8 - Telegram/SourceFiles/storage/localstorage.cpp | 34 ++- .../SourceFiles/ui/image/image_source.cpp | 20 +- Telegram/gyp/telegram_sources.txt | 2 + 14 files changed, 542 insertions(+), 88 deletions(-) create mode 100644 Telegram/SourceFiles/data/data_auto_download.cpp create mode 100644 Telegram/SourceFiles/data/data_auto_download.h diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index bd63c469a..7faeac059 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1269,9 +1269,6 @@ namespace App { } cSetRecentStickers(RecentStickerPack()); cSetReportSpamStatuses(ReportSpamStatuses()); - cSetAutoDownloadPhoto(0); - cSetAutoDownloadAudio(0); - cSetAutoDownloadGif(0); } void historyRegDependency(HistoryItem *dependent, HistoryItem *dependency) { diff --git a/Telegram/SourceFiles/auth_session.cpp b/Telegram/SourceFiles/auth_session.cpp index a6636ac8d..6b544ee9c 100644 --- a/Telegram/SourceFiles/auth_session.cpp +++ b/Telegram/SourceFiles/auth_session.cpp @@ -45,11 +45,13 @@ AuthSessionSettings::Variables::Variables() } QByteArray AuthSessionSettings::serialize() const { + const auto autoDownload = _variables.autoDownload.serialize(); auto size = sizeof(qint32) * 23; for (auto i = _variables.soundOverrides.cbegin(), e = _variables.soundOverrides.cend(); i != e; ++i) { size += Serialize::stringSize(i.key()) + Serialize::stringSize(i.value()); } size += _variables.groupStickersSectionHidden.size() * sizeof(quint64); + size += Serialize::bytearraySize(autoDownload); auto result = QByteArray(); result.reserve(size); @@ -88,6 +90,7 @@ QByteArray AuthSessionSettings::serialize() const { stream << qint32(_variables.includeMutedCounter ? 1 : 0); stream << qint32(_variables.countUnreadMessages ? 1 : 0); stream << qint32(_variables.exeLaunchWarning ? 1 : 0); + stream << autoDownload; } return result; } @@ -122,6 +125,7 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) qint32 includeMutedCounter = _variables.includeMutedCounter ? 1 : 0; qint32 countUnreadMessages = _variables.countUnreadMessages ? 1 : 0; qint32 exeLaunchWarning = _variables.exeLaunchWarning ? 1 : 0; + QByteArray autoDownload; stream >> selectorTab; stream >> lastSeenWarningSeen; @@ -195,11 +199,18 @@ void AuthSessionSettings::constructFromSerialized(const QByteArray &serialized) if (!stream.atEnd()) { stream >> exeLaunchWarning; } + if (!stream.atEnd()) { + stream >> autoDownload; + } if (stream.status() != QDataStream::Ok) { LOG(("App Error: " "Bad data for AuthSessionSettings::constructFromSerialized()")); return; } + if (!autoDownload.isEmpty() + && !_variables.autoDownload.setFromSerialized(autoDownload)) { + return; + } auto uncheckedTab = static_cast(selectorTab); switch (uncheckedTab) { diff --git a/Telegram/SourceFiles/auth_session.h b/Telegram/SourceFiles/auth_session.h index 71d0c90ef..fe3509072 100644 --- a/Telegram/SourceFiles/auth_session.h +++ b/Telegram/SourceFiles/auth_session.h @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include #include #include "base/timer.h" +#include "data/data_auto_download.h" class ApiWrap; enum class SendFilesWay; @@ -183,6 +184,13 @@ public: _variables.groupStickersSectionHidden.remove(peerId); } + Data::AutoDownload::Full &autoDownload() { + return _variables.autoDownload; + } + const Data::AutoDownload::Full &autoDownload() const { + return _variables.autoDownload; + } + bool hadLegacyCallsPeerToPeerNobody() const { return _variables.hadLegacyCallsPeerToPeerNobody; } @@ -234,6 +242,7 @@ private: bool includeMutedCounter = true; bool countUnreadMessages = true; bool exeLaunchWarning = true; + Data::AutoDownload::Full autoDownload; static constexpr auto kDefaultSupportChatsLimitSlice = 7 * 24 * 60 * 60; diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index a34056626..ab5917f56 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -945,9 +945,18 @@ void AutoDownloadBox::prepare() { void AutoDownloadBox::setupContent() { using namespace Settings; + using namespace Data::AutoDownload; + using Type = Data::AutoDownload::Type; + + constexpr auto kLegacyLimit = 10 * 1024 * 1024; setTitle(langFactory(lng_media_auto_title)); + const auto settings = &Auth().settings().autoDownload(); + const auto checked = [=](Source source, Type type) { + return (settings->bytesLimit(source, type) > 0); + }; + auto wrap = object_ptr(this); const auto content = wrap.data(); setInnerWidget(object_ptr( @@ -955,65 +964,89 @@ void AutoDownloadBox::setupContent() { std::move(wrap))); using pair = std::pair; - const auto pairValue = [](pair checkboxes) { - return (checkboxes.first->checked() ? 0 : dbiadNoPrivate) - | (checkboxes.second->checked() ? 0 : dbiadNoGroups); + const auto pairChecked = [](pair checkboxes) { + return std::make_pair( + checkboxes.first->checked(), + checkboxes.second->checked()); }; - const auto enabledSomething = [](int32 oldValue, int32 newValue) { - return (uint32(oldValue) & ~uint32(newValue)) != 0; + const auto enabledSomething = [=]( + Type type, + std::pair pair) { + return (!checked(Source::User, type) && pair.first) + || (!checked(Source::Group, type) && pair.second); }; - const auto addCheckbox = [&](int32 value, DBIAutoDownloadFlags flag) { - const auto label = (flag == dbiadNoPrivate) + const auto changedSomething = [=]( + Type type, + std::pair pair) { + return (checked(Source::User, type) != pair.first) + || (checked(Source::Group, type) != pair.second); + }; + const auto save = [=]( + Type type, + std::pair pair) { + const auto limit = [](bool checked) { + return checked ? kMaxBytesLimit : 0; + }; + settings->setBytesLimit(Source::User, type, limit(pair.first)); + settings->setBytesLimit(Source::Group, type, limit(pair.second)); + settings->setBytesLimit(Source::Channel, type, limit(pair.second)); + }; + const auto addCheckbox = [&](Type type, Source source) { + const auto label = (source == Source::User) ? lng_media_auto_private_chats : lng_media_auto_groups; return content->add( object_ptr( content, lang(label), - !(value & flag), + checked(source, type), st::settingsSendType), st::settingsSendTypePadding); }; - const auto addPair = [&](int32 value) { - const auto first = addCheckbox(value, dbiadNoPrivate); - const auto second = addCheckbox(value, dbiadNoGroups); + const auto addPair = [&](Type type) { + const auto first = addCheckbox(type, Source::User); + const auto second = addCheckbox(type, Source::Group); return pair(first, second); }; AddSubsectionTitle(content, lng_media_photo_title); - const auto photo = addPair(cAutoDownloadPhoto()); + const auto photo = addPair(Type::Photo); AddSkip(content); AddSkip(content); AddSubsectionTitle(content, lng_media_audio_title); - const auto audio = addPair(cAutoDownloadAudio()); + const auto audio = addPair(Type::VoiceMessage); AddSkip(content); AddSkip(content); AddSubsectionTitle(content, lng_media_gif_title); - const auto gif = addPair(cAutoDownloadGif()); + const auto gif = addPair(Type::GIF); AddSkip(content); addButton(langFactory(lng_connection_save), [=] { - const auto photoValue = pairValue(photo); - const auto audioValue = pairValue(audio); - const auto gifValue = pairValue(gif); + const auto photoChecked = pairChecked(photo); + const auto audioChecked = pairChecked(audio); + const auto gifChecked = pairChecked(gif); const auto photosEnabled = enabledSomething( - cAutoDownloadPhoto(), - photoValue); + Type::Photo, + photoChecked); const auto audioEnabled = enabledSomething( - cAutoDownloadAudio(), - audioValue); + Type::VoiceMessage, + audioChecked); const auto gifEnabled = enabledSomething( - cAutoDownloadGif(), - gifValue); - const auto photosChanged = (cAutoDownloadPhoto() != photoValue); - const auto documentsChanged = (cAutoDownloadAudio() != audioValue) - || (cAutoDownloadGif() != gifValue); - cSetAutoDownloadAudio(audioValue); - cSetAutoDownloadGif(gifValue); - cSetAutoDownloadPhoto(photoValue); + Type::GIF, + gifChecked); + const auto photosChanged = changedSomething( + Type::Photo, + photoChecked); + const auto documentsChanged = changedSomething( + Type::VoiceMessage, + audioChecked) || changedSomething(Type::GIF, gifChecked); if (photosChanged || documentsChanged) { + save(Type::Photo, photoChecked); + save(Type::VoiceMessage, audioChecked); + save(Type::GIF, gifChecked); + save(Type::VideoMessage, gifChecked); Local::writeUserSettings(); } if (photosEnabled) { diff --git a/Telegram/SourceFiles/core/utils.cpp b/Telegram/SourceFiles/core/utils.cpp index 417f6cba4..9c3c285b4 100644 --- a/Telegram/SourceFiles/core/utils.cpp +++ b/Telegram/SourceFiles/core/utils.cpp @@ -51,6 +51,8 @@ static_assert(sizeof(MTPint128) == 16, "Basic types size check failed"); static_assert(sizeof(MTPint256) == 32, "Basic types size check failed"); static_assert(sizeof(MTPdouble) == 8, "Basic types size check failed"); +static_assert(sizeof(int) >= 4, "Basic types size check failed"); + // Unixtime functions namespace { diff --git a/Telegram/SourceFiles/data/data_auto_download.cpp b/Telegram/SourceFiles/data/data_auto_download.cpp new file mode 100644 index 000000000..4efa07a08 --- /dev/null +++ b/Telegram/SourceFiles/data/data_auto_download.cpp @@ -0,0 +1,279 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "data/data_auto_download.h" + +#include "data/data_peer.h" +#include "data/data_photo.h" +#include "data/data_document.h" +#include "ui/image/image_source.h" +#include "ui/image/image.h" + +namespace Data { +namespace AutoDownload { +namespace { + +constexpr auto kDefaultMaxSize = 10 * 1024 * 1024; +constexpr auto kVersion = char(1); + +template +auto enums_view(int from, int till) { + using namespace ranges::view; + return ints(from, till) | transform([](int index) { + return static_cast(index); + }); +} + +template +auto enums_view(int till) { + return enums_view(0, till); +} + +void SetDefaultsForSource(Full &data, Source source) { + data.setBytesLimit(source, Type::Photo, kDefaultMaxSize); + data.setBytesLimit(source, Type::VoiceMessage, kDefaultMaxSize); + data.setBytesLimit(source, Type::VideoMessage, kDefaultMaxSize); + data.setBytesLimit(source, Type::GIF, kDefaultMaxSize); +} + +const Full &Defaults() { + static auto Result = [] { + auto result = Full::FullDisabled(); + for (const auto source : enums_view(kSourcesCount)) { + SetDefaultsForSource(result, source); + } + return result; + }(); + return Result; +} + +Source SourceFromPeer(not_null peer) { + if (peer->isUser()) { + return Source::User; + } else if (peer->isChat() || peer->isMegagroup()) { + return Source::Group; + } else { + return Source::Channel; + } +} + +Type TypeFromDocument(not_null document) { + if (document->isSong()) { + return Type::Music; + } else if (document->isVoiceMessage()) { + return Type::VoiceMessage; + } else if (document->isVideoMessage()) { + return Type::VideoMessage; + } else if (document->isAnimation()) { + return Type::GIF; + } else if (document->isVideoFile()) { + return Type::Video; + } + return Type::File; +} + +} // namespace + +void Single::setBytesLimit(int bytesLimit) { + Expects(bytesLimit >= 0 && bytesLimit <= kMaxBytesLimit); + + _limit = bytesLimit; +} + +bool Single::hasValue() const { + return (_limit >= 0); +} + +bool Single::shouldDownload(int fileSize) const { + Expects(hasValue()); + + return (_limit > 0) && (fileSize <= _limit); +} + +int Single::bytesLimit() const { + Expects(hasValue()); + + return _limit; +} + +qint32 Single::serialize() const { + return _limit; +} + +bool Single::setFromSerialized(qint32 serialized) { + if (serialized < -1 || serialized > kMaxBytesLimit) { + return false; + } + _limit = serialized; + return true; +} + +const Single &Set::single(Type type) const { + Expects(static_cast(type) >= 0 + && static_cast(type) < kTypesCount); + + return _data[static_cast(type)]; +} + +Single &Set::single(Type type) { + return const_cast(static_cast(this)->single(type)); +} + +void Set::setBytesLimit(Type type, int bytesLimit) { + single(type).setBytesLimit(bytesLimit); +} + +bool Set::hasValue(Type type) const { + return single(type).hasValue(); +} + +bool Set::shouldDownload(Type type, int fileSize) const { + return single(type).shouldDownload(fileSize); +} + +int Set::bytesLimit(Type type) const { + return single(type).bytesLimit(); +} + +qint32 Set::serialize(Type type) const { + return single(type).serialize(); +} + +bool Set::setFromSerialized(Type type, qint32 serialized) { + if (static_cast(type) < 0 + || static_cast(type) >= kTypesCount) { + return false; + } + return single(type).setFromSerialized(serialized); +} + +const Set &Full::set(Source source) const { + Expects(static_cast(source) >= 0 + && static_cast(source) < kSourcesCount); + + return _data[static_cast(source)]; +} + +Set &Full::set(Source source) { + return const_cast(static_cast(this)->set(source)); +} + +const Set &Full::setOrDefault(Source source, Type type) const { + const auto &my = set(source); + const auto &result = my.hasValue(type) ? my : Defaults().set(source); + + Ensures(result.hasValue(type)); + + return result; +} + +void Full::setBytesLimit(Source source, Type type, int bytesLimit) { + set(source).setBytesLimit(type, bytesLimit); +} + +bool Full::shouldDownload(Source source, Type type, int fileSize) const { + return setOrDefault(source, type).shouldDownload(type, fileSize); +} + +int Full::bytesLimit(Source source, Type type) const { + return setOrDefault(source, type).bytesLimit(type); +} + +QByteArray Full::serialize() const { + auto result = QByteArray(); + auto size = sizeof(qint8); + size += kSourcesCount * kTypesCount * sizeof(qint32); + result.reserve(size); + { + auto buffer = QBuffer(&result); + buffer.open(QIODevice::WriteOnly); + auto stream = QDataStream(&buffer); + stream << qint8(kVersion); + for (const auto source : enums_view(kSourcesCount)) { + for (const auto type : enums_view(kTypesCount)) { + stream << set(source).serialize(type); + } + } + } + return result; +} + +bool Full::setFromSerialized(const QByteArray &serialized) { + if (serialized.isEmpty()) { + return false; + } + + auto stream = QDataStream(serialized); + auto version = qint8(); + stream >> version; + if (stream.status() != QDataStream::Ok) { + return false; + } else if (version != kVersion) { + return false; + } + auto temp = Full(); + for (const auto source : enums_view(kSourcesCount)) { + for (const auto type : enums_view(kTypesCount)) { + auto value = qint32(); + stream >> value; + if (!temp.set(source).setFromSerialized(type, value)) { + return false; + } + } + } + _data = temp._data; + return true; +} + +Full Full::FullDisabled() { + auto result = Full(); + for (const auto source : enums_view(kSourcesCount)) { + for (const auto type : enums_view(kTypesCount)) { + result.setBytesLimit(source, type, 0); + } + } + return result; +} + +bool Should( + const Full &data, + not_null peer, + not_null document) { + if (document->sticker()) { + return true; + } + return data.shouldDownload( + SourceFromPeer(peer), + TypeFromDocument(document), + document->size); +} + +bool Should( + const Full &data, + not_null document) { + if (document->sticker()) { + return true; + } + const auto type = TypeFromDocument(document); + const auto size = document->size; + return data.shouldDownload(Source::User, type, size) + || data.shouldDownload(Source::Group, type, size) + || data.shouldDownload(Source::Channel, type, size); +} + +bool Should( + const Full &data, + not_null peer, + not_null image) { + return data.shouldDownload( + SourceFromPeer(peer), + Type::Photo, + image->bytesSize()); +} + +} // namespace AutoDownload +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_auto_download.h b/Telegram/SourceFiles/data/data_auto_download.h new file mode 100644 index 000000000..4143cf82e --- /dev/null +++ b/Telegram/SourceFiles/data/data_auto_download.h @@ -0,0 +1,110 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include + +namespace Images { +class Source; +} // namespace Images + +namespace Data { +namespace AutoDownload { + +constexpr auto kMaxBytesLimit = 3000 * 512 * 1024; + +enum class Source { + User = 0x00, + Group = 0x01, + Channel = 0x02, +}; + +constexpr auto kSourcesCount = 3; + +enum class Type { + Photo = 0x00, + Video = 0x01, + VoiceMessage = 0x02, + VideoMessage = 0x03, + Music = 0x04, + GIF = 0x05, + File = 0x06, +}; + +constexpr auto kTypesCount = 7; + +class Single { +public: + void setBytesLimit(int bytesLimit); + + bool hasValue() const; + bool shouldDownload(int fileSize) const; + int bytesLimit() const; + + qint32 serialize() const; + bool setFromSerialized(qint32 serialized); + +private: + int _limit = -1; + +}; + +class Set { +public: + void setBytesLimit(Type type, int bytesLimit); + + bool hasValue(Type type) const; + bool shouldDownload(Type type, int fileSize) const; + int bytesLimit(Type type) const; + + qint32 serialize(Type type) const; + bool setFromSerialized(Type type, qint32 serialized); + +private: + const Single &single(Type type) const; + Single &single(Type type); + + std::array _data; + +}; + +class Full { +public: + void setBytesLimit(Source source, Type type, int bytesLimit); + + bool shouldDownload(Source source, Type type, int fileSize) const; + int bytesLimit(Source source, Type type) const; + + QByteArray serialize() const; + bool setFromSerialized(const QByteArray &serialized); + + static Full FullDisabled(); + +private: + const Set &set(Source source) const; + Set &set(Source source); + const Set &setOrDefault(Source source, Type type) const; + + std::array _data; + +}; + +bool Should( + const Full &data, + not_null peer, + not_null document); +bool Should( + const Full &data, + not_null document); +bool Should( + const Full &data, + not_null peer, + not_null image); + +} // namespace AutoDownload +} // namespace Data diff --git a/Telegram/SourceFiles/data/data_document.cpp b/Telegram/SourceFiles/data/data_document.cpp index 77ebb6494..4ceb5d6ec 100644 --- a/Telegram/SourceFiles/data/data_document.cpp +++ b/Telegram/SourceFiles/data/data_document.cpp @@ -635,43 +635,44 @@ void DocumentData::automaticLoad( if (loaded() || status != FileReady) return; if (saveToCache() && _loader != CancelledMtpFileLoader) { - if (type == StickerDocument) { - save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId); - } else if (isAnimation()) { - bool loadFromCloud = false; - if (item) { - if (item->history()->peer->isUser()) { - loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate); - } else { - loadFromCloud = !(cAutoDownloadGif() & dbiadNoGroups); - } - } else { // if load at least anywhere - loadFromCloud = !(cAutoDownloadGif() & dbiadNoPrivate) || !(cAutoDownloadGif() & dbiadNoGroups); - } - save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true); - } else if (isVoiceMessage()) { - if (item) { - bool loadFromCloud = false; - if (item->history()->peer->isUser()) { - loadFromCloud = !(cAutoDownloadAudio() & dbiadNoPrivate); - } else { - loadFromCloud = !(cAutoDownloadAudio() & dbiadNoGroups); - } - save(origin, QString(), _actionOnLoad, _actionOnLoadMsgId, loadFromCloud ? LoadFromCloudOrLocal : LoadFromLocalOnly, true); - } + if (type == StickerDocument + || isAnimation() + || (isVoiceMessage() && item)) { + const auto shouldLoadFromCloud = item + ? Data::AutoDownload::Should( + Auth().settings().autoDownload(), + item->history()->peer, + this) + : Data::AutoDownload::Should( + Auth().settings().autoDownload(), + this); + const auto loadFromCloud = shouldLoadFromCloud + ? LoadFromCloudOrLocal + : LoadFromLocalOnly; + save( + origin, + QString(), + _actionOnLoad, + _actionOnLoadMsgId, + loadFromCloud, + true); } } } void DocumentData::automaticLoadSettingsChanged() { - if (loaded() || status != FileReady || (!isAnimation() && !isVoiceMessage()) || !saveToCache() || _loader != CancelledMtpFileLoader) { + if (_loader != CancelledMtpFileLoader + || status != FileReady + || loaded()) { return; } _loader = nullptr; } void DocumentData::performActionOnLoad() { - if (_actionOnLoad == ActionOnLoadNone) return; + if (_actionOnLoad == ActionOnLoadNone) { + return; + } auto loc = location(true); auto already = loc.name(); diff --git a/Telegram/SourceFiles/data/data_document.h b/Telegram/SourceFiles/data/data_document.h index 9db7fd849..1d6079060 100644 --- a/Telegram/SourceFiles/data/data_document.h +++ b/Telegram/SourceFiles/data/data_document.h @@ -84,7 +84,7 @@ public: void automaticLoad( Data::FileOrigin origin, - const HistoryItem *item); // auto load sticker or video + const HistoryItem *item); void automaticLoadSettingsChanged(); enum FilePathResolveType { diff --git a/Telegram/SourceFiles/intro/introwidget.cpp b/Telegram/SourceFiles/intro/introwidget.cpp index 696ce8909..0a25df48a 100644 --- a/Telegram/SourceFiles/intro/introwidget.cpp +++ b/Telegram/SourceFiles/intro/introwidget.cpp @@ -43,14 +43,14 @@ namespace { constexpr str_const kDefaultCountry = "US"; void PrepareSupportMode() { + using Data::AutoDownload::Full; + anim::SetDisabled(true); Local::writeSettings(); Global::SetDesktopNotify(false); Global::SetSoundNotify(false); - cSetAutoDownloadAudio(dbiadNoPrivate | dbiadNoGroups); - cSetAutoDownloadGif(dbiadNoPrivate | dbiadNoGroups); - cSetAutoDownloadPhoto(dbiadNoPrivate | dbiadNoGroups); + Auth().settings().autoDownload() = Full::FullDisabled(); cSetAutoPlayGif(false); Local::writeUserSettings(); } diff --git a/Telegram/SourceFiles/settings.h b/Telegram/SourceFiles/settings.h index 1016a3910..af3a8da97 100644 --- a/Telegram/SourceFiles/settings.h +++ b/Telegram/SourceFiles/settings.h @@ -173,14 +173,6 @@ DeclareRefSetting(SavedPeersByTime, SavedPeersByTime); typedef QMap ReportSpamStatuses; DeclareRefSetting(ReportSpamStatuses, ReportSpamStatuses); -enum DBIAutoDownloadFlags { - dbiadNoPrivate = 0x01, - dbiadNoGroups = 0x02, -}; - -DeclareSetting(int32, AutoDownloadPhoto); -DeclareSetting(int32, AutoDownloadAudio); -DeclareSetting(int32, AutoDownloadGif); DeclareSetting(bool, AutoPlayGif); constexpr auto kInterfaceScaleAuto = 0; diff --git a/Telegram/SourceFiles/storage/localstorage.cpp b/Telegram/SourceFiles/storage/localstorage.cpp index 0876bf105..7038e5278 100644 --- a/Telegram/SourceFiles/storage/localstorage.cpp +++ b/Telegram/SourceFiles/storage/localstorage.cpp @@ -566,7 +566,7 @@ enum { dbiIncludeMutedOld = 0x31, dbiMegagroupSizeMax = 0x32, dbiDownloadPath = 0x33, - dbiAutoDownload = 0x34, + dbiAutoDownloadOld = 0x34, dbiSavedGifsLimit = 0x35, dbiShowingSavedGifsOld = 0x36, dbiAutoPlay = 0x37, @@ -1057,14 +1057,37 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version, ReadSetting Global::SetSoundNotify(v == 1); } break; - case dbiAutoDownload: { + case dbiAutoDownloadOld: { qint32 photo, audio, gif; stream >> photo >> audio >> gif; if (!_checkStreamStatus(stream)) return false; - cSetAutoDownloadPhoto(photo); - cSetAutoDownloadAudio(audio); - cSetAutoDownloadGif(gif); + using namespace Data::AutoDownload; + auto &settings = GetStoredAuthSessionCache().autoDownload(); + const auto limit = [](qint32 value, qint32 mask) { + constexpr auto kLegacyLimit = 10 * 1024 * 1024; + return (value & mask) ? 0 : kLegacyLimit; + }; + const auto set = [&](Type type, qint32 value) { + constexpr auto kNoPrivate = qint32(0x01); + constexpr auto kNoGroups = qint32(0x02); + settings.setBytesLimit( + Source::User, + type, + limit(value, kNoPrivate)); + settings.setBytesLimit( + Source::Group, + type, + limit(value, kNoGroups)); + settings.setBytesLimit( + Source::Channel, + type, + limit(value, kNoGroups)); + }; + set(Type::Photo, photo); + set(Type::VoiceMessage, audio); + set(Type::GIF, gif); + set(Type::VideoMessage, gif); } break; case dbiAutoPlay: { @@ -2029,7 +2052,6 @@ void _writeUserSettings() { data.stream << quint32(dbiDialogLastPath) << cDialogLastPath(); data.stream << quint32(dbiSongVolume) << qint32(qRound(Global::SongVolume() * 1e6)); data.stream << quint32(dbiVideoVolume) << qint32(qRound(Global::VideoVolume() * 1e6)); - data.stream << quint32(dbiAutoDownload) << qint32(cAutoDownloadPhoto()) << qint32(cAutoDownloadAudio()) << qint32(cAutoDownloadGif()); data.stream << quint32(dbiDialogsMode) << qint32(Global::DialogsModeEnabled() ? 1 : 0) << static_cast(Global::DialogsMode()); data.stream << quint32(dbiModerateMode) << qint32(Global::ModerateModeEnabled() ? 1 : 0); data.stream << quint32(dbiAutoPlay) << qint32(cAutoPlayGif() ? 1 : 0); diff --git a/Telegram/SourceFiles/ui/image/image_source.cpp b/Telegram/SourceFiles/ui/image/image_source.cpp index e7075d613..071d2b309 100644 --- a/Telegram/SourceFiles/ui/image/image_source.cpp +++ b/Telegram/SourceFiles/ui/image/image_source.cpp @@ -351,12 +351,10 @@ void RemoteSource::automaticLoad( Data::FileOrigin origin, const HistoryItem *item) { if (_loader != CancelledFileLoader && item) { - bool loadFromCloud = false; - if (item->history()->peer->isUser()) { - loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate); - } else { - loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups); - } + const auto loadFromCloud = Data::AutoDownload::Should( + Auth().settings().autoDownload(), + item->history()->peer, + this); if (_loader) { if (loadFromCloud) _loader->permitLoadFromCloud(); @@ -656,12 +654,10 @@ void DelayedStorageSource::automaticLoad( const HistoryItem *item) { if (_location.isNull()) { if (!_loadCancelled && item) { - bool loadFromCloud = false; - if (item->history()->peer->isUser()) { - loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoPrivate); - } else { - loadFromCloud = !(cAutoDownloadPhoto() & dbiadNoGroups); - } + const auto loadFromCloud = Data::AutoDownload::Should( + Auth().settings().autoDownload(), + item->history()->peer, + this); if (_loadRequested) { if (loadFromCloud) _loadFromCloud = loadFromCloud; diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index 482979736..be4c7d0e8 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -138,6 +138,8 @@ <(src_loc)/core/version.h <(src_loc)/data/data_abstract_structure.cpp <(src_loc)/data/data_abstract_structure.h +<(src_loc)/data/data_auto_download.cpp +<(src_loc)/data/data_auto_download.h <(src_loc)/data/data_channel_admins.cpp <(src_loc)/data/data_channel_admins.h <(src_loc)/data/data_document.cpp