Move background to global settings.

This commit is contained in:
John Preston 2020-06-19 19:14:55 +04:00
parent 5433c16244
commit 2635ca33f8
16 changed files with 359 additions and 264 deletions

View File

@ -2896,8 +2896,12 @@ void ApiWrap::refreshFileReference(
MTPmessages_GetSavedGifs(MTP_int(0)),
[=] { crl::on_main(_session, [=] { local().writeSavedGifs(); }); });
}, [&](Data::FileOriginWallpaper data) {
request(MTPaccount_GetWallPaper(
MTP_inputWallPaper(
const auto useSlug = data.ownerId
&& (data.ownerId != session().userId())
&& !data.slug.isEmpty();
request(MTPaccount_GetWallPaper(useSlug
? MTP_inputWallPaperSlug(MTP_string(data.slug))
: MTP_inputWallPaper(
MTP_long(data.paperId),
MTP_long(data.accessHash))));
}, [&](Data::FileOriginTheme data) {

View File

@ -174,7 +174,7 @@ void BackgroundBox::removePaper(const Data::WallPaper &paper) {
}
session->data().removeWallpaper(paper);
session->api().request(MTPaccount_SaveWallPaper(
paper.mtpInput(),
paper.mtpInput(session),
MTP_bool(true),
paper.mtpSettings()
)).send();

View File

@ -506,7 +506,7 @@ void BackgroundPreviewBox::apply() {
_controller->content()->setChatBackground(_paper, std::move(_full));
if (install) {
_controller->session().api().request(MTPaccount_InstallWallPaper(
_paper.mtpInput(),
_paper.mtpInput(&_controller->session()),
_paper.mtpSettings()
)).send();
}

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/send_files_box.h"
#include "ui/widgets/input_fields.h"
#include "storage/serialize_common.h"
#include "window/themes/window_theme.h"
#include "facades.h"
namespace Core {
@ -87,8 +88,9 @@ QByteArray Settings::serialize() const {
stream << quint64(i);
}
stream
<< qint32(_autoDownloadDictionaries.current() ? 1 : 0);
<< qint32(_autoDownloadDictionaries.current() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileDay() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
}
return result;
}

View File

@ -61,13 +61,21 @@ struct FileOriginSavedGifs {
};
struct FileOriginWallpaper {
FileOriginWallpaper(uint64 paperId, uint64 accessHash)
FileOriginWallpaper(
uint64 paperId,
uint64 accessHash,
UserId ownerId,
const QString &slug)
: paperId(paperId)
, accessHash(accessHash) {
, accessHash(accessHash)
, ownerId(ownerId)
, slug(slug) {
}
uint64 paperId = 0;
uint64 accessHash = 0;
UserId ownerId = 0;
QString slug;
inline bool operator<(const FileOriginWallpaper &other) const {
return paperId < other.paperId;

View File

@ -196,11 +196,17 @@ void WallPaper::loadDocument() const {
}
FileOrigin WallPaper::fileOrigin() const {
return FileOriginWallpaper(_id, _accessHash);
return FileOriginWallpaper(_id, _accessHash, _ownerId, _slug);
}
MTPInputWallPaper WallPaper::mtpInput() const {
return MTP_inputWallPaper(MTP_long(_id), MTP_long(_accessHash));
UserId WallPaper::ownerId() const {
return _ownerId;
}
MTPInputWallPaper WallPaper::mtpInput(not_null<Main::Session*> session) const {
return (_ownerId && _ownerId != session->userId() && !_slug.isEmpty())
? MTP_inputWallPaperSlug(MTP_string(_slug))
: MTP_inputWallPaper(MTP_long(_id), MTP_long(_accessHash));
}
MTPWallPaperSettings WallPaper::mtpSettings() const {
@ -324,6 +330,7 @@ std::optional<WallPaper> WallPaper::Create(
}
auto result = WallPaper(data.vid().v);
result._accessHash = data.vaccess_hash().v;
result._ownerId = session->userId();
result._flags = data.vflags().v;
result._slug = qs(data.vslug());
result._document = document;
@ -372,7 +379,8 @@ QByteArray WallPaper::serialize() const {
<< _slug
<< qint32(_settings)
<< SerializeMaybeColor(_backgroundColor)
<< qint32(_intensity);
<< qint32(_intensity)
<< qint32(_ownerId);
}
return result;
}
@ -385,6 +393,7 @@ std::optional<WallPaper> WallPaper::FromSerialized(
auto id = quint64();
auto accessHash = quint64();
auto ownerId = qint32();
auto flags = qint32();
auto slug = QString();
auto settings = qint32();
@ -401,6 +410,9 @@ std::optional<WallPaper> WallPaper::FromSerialized(
>> settings
>> backgroundColor
>> intensity;
if (!stream.atEnd()) {
stream >> ownerId;
}
if (stream.status() != QDataStream::Ok) {
return std::nullopt;
} else if (intensity < 0 || intensity > 100) {
@ -408,6 +420,7 @@ std::optional<WallPaper> WallPaper::FromSerialized(
}
auto result = WallPaper(id);
result._accessHash = accessHash;
result._ownerId = ownerId;
result._flags = MTPDwallPaper::Flags::from_raw(flags);
result._slug = slug;
result._settings = MTPDwallPaperSettings::Flags::from_raw(settings);

View File

@ -41,7 +41,9 @@ public:
void loadDocumentThumbnail() const;
[[nodiscard]] FileOrigin fileOrigin() const;
[[nodiscard]] MTPInputWallPaper mtpInput() const;
[[nodiscard]] UserId ownerId() const;
[[nodiscard]] MTPInputWallPaper mtpInput(
not_null<Main::Session*> session) const;
[[nodiscard]] MTPWallPaperSettings mtpSettings() const;
[[nodiscard]] WallPaper withUrlParams(
@ -77,6 +79,7 @@ private:
WallPaperId _id = WallPaperId();
uint64 _accessHash = 0;
UserId _ownerId = 0;
MTPDwallPaper::Flags _flags;
QString _slug;

View File

@ -38,9 +38,7 @@ Storage::StartResult Domain::start(const QByteArray &passcode) {
const auto result = _local->start(passcode);
if (result == Storage::StartResult::Success) {
activateAfterStarting();
if (Local::oldSettingsVersion() < AppVersion) {
Local::writeSettings();
}
Local::rewriteSettingsIfNeeded();
} else {
Assert(!started());
}

View File

@ -577,6 +577,16 @@ bool ReadSetting(
Window::Theme::SetNightModeValue(nightMode == 1);
} break;
case dbiBackgroundKey: {
quint64 keyDay = 0, keyNight = 0;
stream >> keyDay >> keyNight;
if (!CheckStreamStatus(stream)) return false;
context.backgroundKeyDay = keyDay;
context.backgroundKeyNight = keyNight;
context.backgroundKeysRead = true;
} break;
case dbiLangPackKey: {
quint64 langPackKey = 0;
stream >> langPackKey;
@ -733,14 +743,15 @@ bool ReadSetting(
stream >> v;
if (!CheckStreamStatus(stream)) return false;
bool tile = (version < 8005 && !context.hasCustomDayBackground)
bool tile = (version < 8005 && !context.legacyHasCustomDayBackground)
? false
: (v == 1);
if (Window::Theme::IsNightMode()) {
context.tileNight = tile;
} else {
context.tileDay = tile;
} else {
context.tileNight = tile;
}
context.tileRead = true;
} break;
case dbiTileBackground: {
@ -748,8 +759,9 @@ bool ReadSetting(
stream >> tileDay >> tileNight;
if (!CheckStreamStatus(stream)) return false;
context.tileDay = (tileDay == 1);
context.tileNight = (tileNight == 1);
context.tileDay = tileDay;
context.tileNight = tileNight;
context.tileRead = true;
} break;
case dbiAdaptiveForWideOld: {

View File

@ -28,7 +28,7 @@ struct ReadSettingsContext {
}
// This field is read in ReadSetting.
bool hasCustomDayBackground = false;
bool legacyHasCustomDayBackground = false;
// Those fields are written in ReadSetting.
MTP::DcOptions fallbackConfigLegacyDcOptions
@ -51,6 +51,12 @@ struct ReadSettingsContext {
FileKey themeKeyLegacy = 0;
FileKey themeKeyDay = 0;
FileKey themeKeyNight = 0;
FileKey backgroundKeyDay = 0;
FileKey backgroundKeyNight = 0;
bool backgroundKeysRead = false;
bool tileDay = false;
bool tileNight = true;
bool tileRead = false;
FileKey langPackKey = 0;
FileKey languagesKey = 0;
@ -58,9 +64,6 @@ struct ReadSettingsContext {
std::vector<std::shared_ptr<MTP::AuthKey>> mtpLegacyKeys;
qint32 mtpLegacyMainDcId = 0;
qint32 mtpLegacyUserId = 0;
bool tileDay = false;
bool tileNight = true;
};
[[nodiscard]] bool ReadSetting(
@ -159,6 +162,7 @@ enum {
dbiApplicationSettings = 0x5e,
dbiDialogsFiltersOld = 0x5f,
dbiFallbackProductionConfig = 0x60,
dbiBackgroundKey = 0x61,
dbiEncryptedWithSalt = 333,
dbiEncrypted = 444,

View File

@ -43,6 +43,11 @@ namespace {
constexpr auto kThemeFileSizeLimit = 5 * 1024 * 1024;
constexpr auto kFileLoaderQueueStopTimeout = crl::time(5000);
constexpr auto kSavedBackgroundFormat = QImage::Format_ARGB32_Premultiplied;
constexpr auto kWallPaperLegacySerializeTagId = int32(-111);
constexpr auto kWallPaperSerializeTagId = int32(-112);
constexpr auto kWallPaperSidesLimit = 10'000;
const auto kThemeNewPathRelativeTag = qstr("special://new_tag");
using namespace Storage::details;
@ -70,7 +75,14 @@ FileKey _themeKeyLegacy = 0;
FileKey _langPackKey = 0;
FileKey _languagesKey = 0;
FileKey _backgroundKeyDay = 0;
FileKey _backgroundKeyNight = 0;
bool _useGlobalBackgroundKeys = false;
bool _backgroundCanWrite = true;
bool _backgroundMigrated = false;
int32 _oldSettingsVersion = 0;
bool _settingsRewritten;
enum class WriteMapWhen {
Now,
@ -120,8 +132,16 @@ void applyReadContext(ReadSettingsContext &&context) {
_themeKeyLegacy = context.themeKeyLegacy;
_themeKeyDay = context.themeKeyDay;
_themeKeyNight = context.themeKeyNight;
_backgroundKeyDay = context.backgroundKeyDay;
_backgroundKeyNight = context.backgroundKeyNight;
_useGlobalBackgroundKeys = context.backgroundKeysRead;
_langPackKey = context.langPackKey;
_languagesKey = context.languagesKey;
if (context.tileRead && _useGlobalBackgroundKeys) {
Window::Theme::Background()->setTileDayValue(context.tileDay);
Window::Theme::Background()->setTileNightValue(context.tileNight);
}
}
bool _readOldSettings(bool remove, ReadSettingsContext &context) {
@ -436,6 +456,7 @@ void writeSettings() {
// Theme keys and night mode.
size += sizeof(quint32) + sizeof(quint64) * 2 + sizeof(quint32);
size += sizeof(quint32) + sizeof(quint64) * 2;
if (_langPackKey) {
size += sizeof(quint32) + sizeof(quint64);
}
@ -471,6 +492,16 @@ void writeSettings() {
<< quint64(_themeKeyDay)
<< quint64(_themeKeyNight)
<< quint32(Window::Theme::IsNightMode() ? 1 : 0);
if (_useGlobalBackgroundKeys) {
data.stream
<< quint32(dbiBackgroundKey)
<< quint64(_backgroundKeyDay)
<< quint64(_backgroundKeyNight);
data.stream
<< quint32(dbiTileBackground)
<< qint32(Window::Theme::Background()->tileDay() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
}
if (_langPackKey) {
data.stream << quint32(dbiLangPackKey) << quint64(_langPackKey);
}
@ -487,6 +518,15 @@ void writeSettings() {
settings.writeEncrypted(data, SettingsKey);
}
void rewriteSettingsIfNeeded() {
if (_settingsRewritten
|| (_oldSettingsVersion == AppVersion && !_backgroundMigrated)) {
return;
}
_settingsRewritten = true;
writeSettings();
}
const QString &AutoupdatePrefix(const QString &replaceWith = {}) {
Expects(!Core::UpdaterDisabled());
@ -547,6 +587,207 @@ QString readAutoupdatePrefix() {
return result.replace(QRegularExpression("/+$"), QString());
}
void writeBackground(const Data::WallPaper &paper, const QImage &image) {
if (!_backgroundCanWrite) {
return;
}
_useGlobalBackgroundKeys = true;
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
auto imageData = QByteArray();
if (!image.isNull()) {
const auto width = qint32(image.width());
const auto height = qint32(image.height());
const auto perpixel = (image.depth() >> 3);
const auto srcperline = image.bytesPerLine();
const auto srcsize = srcperline * height;
const auto dstperline = width * perpixel;
const auto dstsize = dstperline * height;
const auto copy = (image.format() != kSavedBackgroundFormat)
? image.convertToFormat(kSavedBackgroundFormat)
: image;
imageData.resize(2 * sizeof(qint32) + dstsize);
auto dst = bytes::make_detached_span(imageData);
bytes::copy(dst, bytes::object_as_span(&width));
dst = dst.subspan(sizeof(qint32));
bytes::copy(dst, bytes::object_as_span(&height));
dst = dst.subspan(sizeof(qint32));
const auto src = bytes::make_span(image.constBits(), srcsize);
if (srcsize == dstsize) {
bytes::copy(dst, src);
} else {
for (auto y = 0; y != height; ++y) {
bytes::copy(dst, src.subspan(y * srcperline, dstperline));
dst = dst.subspan(dstperline);
}
}
}
if (!backgroundKey) {
backgroundKey = GenerateKey(_basePath);
writeSettings();
}
const auto serialized = paper.serialize();
quint32 size = sizeof(qint32)
+ Serialize::bytearraySize(serialized)
+ Serialize::bytearraySize(imageData);
EncryptedDescriptor data(size);
data.stream
<< qint32(kWallPaperSerializeTagId)
<< serialized
<< imageData;
FileWriteDescriptor file(backgroundKey, _basePath);
file.writeEncrypted(data, SettingsKey);
}
bool readBackground() {
FileReadDescriptor bg;
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
if (!ReadEncryptedFile(bg, backgroundKey, _basePath, SettingsKey)) {
if (backgroundKey) {
ClearKey(backgroundKey, _basePath);
backgroundKey = 0;
writeSettings();
}
return false;
}
qint32 legacyId = 0;
bg.stream >> legacyId;
const auto paper = [&] {
if (legacyId == kWallPaperLegacySerializeTagId) {
quint64 id = 0;
quint64 accessHash = 0;
quint32 flags = 0;
QString slug;
bg.stream
>> id
>> accessHash
>> flags
>> slug;
return Data::WallPaper::FromLegacySerialized(
id,
accessHash,
flags,
slug);
} else if (legacyId == kWallPaperSerializeTagId) {
QByteArray serialized;
bg.stream >> serialized;
return Data::WallPaper::FromSerialized(serialized);
} else {
return Data::WallPaper::FromLegacyId(legacyId);
}
}();
if (bg.stream.status() != QDataStream::Ok || !paper) {
return false;
}
QByteArray imageData;
bg.stream >> imageData;
const auto isOldEmptyImage = (bg.stream.status() != QDataStream::Ok);
if (isOldEmptyImage
|| Data::IsLegacy1DefaultWallPaper(*paper)
|| Data::IsDefaultWallPaper(*paper)) {
_backgroundCanWrite = false;
if (isOldEmptyImage || bg.version < 8005) {
Window::Theme::Background()->set(Data::DefaultWallPaper());
Window::Theme::Background()->setTile(false);
} else {
Window::Theme::Background()->set(*paper);
}
_backgroundCanWrite = true;
return true;
} else if (Data::IsThemeWallPaper(*paper) && imageData.isEmpty()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper);
_backgroundCanWrite = true;
return true;
}
auto image = QImage();
if (legacyId == kWallPaperSerializeTagId) {
const auto perpixel = 4;
auto src = bytes::make_span(imageData);
auto width = qint32();
auto height = qint32();
if (src.size() > 2 * sizeof(qint32)) {
bytes::copy(
bytes::object_as_span(&width),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
bytes::copy(
bytes::object_as_span(&height),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
if (width + height <= kWallPaperSidesLimit
&& src.size() == width * height * perpixel) {
image = QImage(
width,
height,
QImage::Format_ARGB32_Premultiplied);
if (!image.isNull()) {
const auto srcperline = width * perpixel;
const auto srcsize = srcperline * height;
const auto dstperline = image.bytesPerLine();
const auto dstsize = dstperline * height;
Assert(srcsize == dstsize);
bytes::copy(
bytes::make_span(image.bits(), dstsize),
src);
}
}
}
} else {
auto buffer = QBuffer(&imageData);
auto reader = QImageReader(&buffer);
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (!reader.read(&image)) {
image = QImage();
}
}
if (!image.isNull() || paper->backgroundColor()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper, std::move(image));
_backgroundCanWrite = true;
return true;
}
return false;
}
void moveLegacyBackground(
const QString &fromBasePath,
const MTP::AuthKeyPtr &fromLocalKey,
uint64 legacyBackgroundKeyDay,
uint64 legacyBackgroundKeyNight) {
if (_useGlobalBackgroundKeys
|| (!legacyBackgroundKeyDay && !legacyBackgroundKeyNight)) {
return;
}
const auto move = [&](uint64 from, FileKey &to) {
if (!from || to) {
return;
}
to = GenerateKey(_basePath);
FileReadDescriptor read;
if (!ReadEncryptedFile(read, from, fromBasePath, fromLocalKey)) {
return;
}
EncryptedDescriptor data;
data.data = read.data;
FileWriteDescriptor write(to, _basePath);
write.writeEncrypted(data, SettingsKey);
};
move(legacyBackgroundKeyDay, _backgroundKeyDay);
move(legacyBackgroundKeyNight, _backgroundKeyNight);
_backgroundMigrated = true;
}
void reset() {
if (_localLoader) {
_localLoader->stop();

View File

@ -41,16 +41,30 @@ namespace Export {
struct Settings;
} // namespace Export
namespace MTP {
class AuthKey;
using AuthKeyPtr = std::shared_ptr<AuthKey>;
} // namespace MTP
namespace Local {
void start();
void finish();
void writeSettings();
void rewriteSettingsIfNeeded();
void writeAutoupdatePrefix(const QString &prefix);
QString readAutoupdatePrefix();
void writeBackground(const Data::WallPaper &paper, const QImage &image);
bool readBackground();
void moveLegacyBackground(
const QString &fromBasePath,
const MTP::AuthKeyPtr &fromLocalKey,
uint64 legacyBackgroundKeyDay,
uint64 legacyBackgroundKeyNight);
void reset();
enum ClearManagerTask {

View File

@ -39,17 +39,12 @@ using namespace details;
using Database = Cache::Database;
constexpr auto kDelayedWriteTimeout = crl::time(1000);
constexpr auto kSavedBackgroundFormat = QImage::Format_ARGB32_Premultiplied;
constexpr auto kStickersVersionTag = quint32(-1);
constexpr auto kStickersSerializeVersion = 1;
constexpr auto kMaxSavedStickerSetsCount = 1000;
constexpr auto kDefaultStickerInstallDate = TimeId(1);
constexpr auto kWallPaperLegacySerializeTagId = int32(-111);
constexpr auto kWallPaperSerializeTagId = int32(-112);
constexpr auto kWallPaperSidesLimit = 10'000;
constexpr auto kSinglePeerTypeUser = qint32(1);
constexpr auto kSinglePeerTypeChat = qint32(2);
constexpr auto kSinglePeerTypeChannel = qint32(3);
@ -65,7 +60,7 @@ enum { // Local Storage Keys
lskLegacyStickerImages = 0x05, // legacy
lskLegacyAudios = 0x06, // legacy
lskRecentStickersOld = 0x07, // no data
lskBackgroundOld = 0x08, // no data
lskBackgroundOldOld = 0x08, // no data
lskUserSettings = 0x09, // no data
lskRecentHashtagsAndBots = 0x0a, // no data
lskStickersOld = 0x0b, // no data
@ -77,7 +72,7 @@ enum { // Local Storage Keys
lskTrustedBots = 0x11, // no data
lskFavedStickers = 0x12, // no data
lskExportSettings = 0x13, // no data
lskBackground = 0x14, // no data
lskBackgroundOld = 0x14, // no data
lskSelfSerialized = 0x15, // serialized self
};
@ -173,8 +168,8 @@ base::flat_set<QString> Account::collectGoodNames() const {
_archivedStickersKey,
_recentStickersKeyOld,
_savedGifsKey,
_backgroundKeyNight,
_backgroundKeyDay,
_legacyBackgroundKeyNight,
_legacyBackgroundKeyDay,
_recentHashtagsAndBotsKey,
_exportSettingsKey,
_trustedBotsKey,
@ -259,7 +254,7 @@ Account::ReadMapResult Account::readMapWith(
quint64 recentStickersKeyOld = 0;
quint64 installedStickersKey = 0, featuredStickersKey = 0, recentStickersKey = 0, favedStickersKey = 0, archivedStickersKey = 0;
quint64 savedGifsKey = 0;
quint64 backgroundKeyDay = 0, backgroundKeyNight = 0;
quint64 legacyBackgroundKeyDay = 0, legacyBackgroundKeyNight = 0;
quint64 userSettingsKey = 0, recentHashtagsAndBotsKey = 0, exportSettingsKey = 0;
while (!map.stream.atEnd()) {
quint32 keyType;
@ -315,13 +310,13 @@ Account::ReadMapResult Account::readMapWith(
case lskRecentStickersOld: {
map.stream >> recentStickersKeyOld;
} break;
case lskBackgroundOld: {
case lskBackgroundOldOld: {
map.stream >> (Window::Theme::IsNightMode()
? backgroundKeyNight
: backgroundKeyDay);
? legacyBackgroundKeyNight
: legacyBackgroundKeyDay);
} break;
case lskBackground: {
map.stream >> backgroundKeyDay >> backgroundKeyNight;
case lskBackgroundOld: {
map.stream >> legacyBackgroundKeyDay >> legacyBackgroundKeyNight;
} break;
case lskUserSettings: {
map.stream >> userSettingsKey;
@ -376,8 +371,8 @@ Account::ReadMapResult Account::readMapWith(
_favedStickersKey = favedStickersKey;
_archivedStickersKey = archivedStickersKey;
_savedGifsKey = savedGifsKey;
_backgroundKeyDay = backgroundKeyDay;
_backgroundKeyNight = backgroundKeyNight;
_legacyBackgroundKeyDay = legacyBackgroundKeyDay;
_legacyBackgroundKeyNight = legacyBackgroundKeyNight;
_settingsKey = userSettingsKey;
_recentHashtagsAndBotsKey = recentHashtagsAndBotsKey;
_exportSettingsKey = exportSettingsKey;
@ -392,6 +387,13 @@ Account::ReadMapResult Account::readMapWith(
if (_locationsKey) {
readLocations();
}
if (_legacyBackgroundKeyDay || _legacyBackgroundKeyNight) {
Local::moveLegacyBackground(
_basePath,
_localKey,
_legacyBackgroundKeyDay,
_legacyBackgroundKeyNight);
}
auto stored = readSessionSettings();
readMtpData();
@ -403,6 +405,7 @@ Account::ReadMapResult Account::readMapWith(
_oldMapVersion);
LOG(("Map read time: %1").arg(crl::now() - ms));
return ReadMapResult::Success;
}
@ -469,7 +472,6 @@ void Account::writeMap() {
}
if (_favedStickersKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_savedGifsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_backgroundKeyDay || _backgroundKeyNight) mapSize += sizeof(quint32) + sizeof(quint64) + sizeof(quint64);
if (_settingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_recentHashtagsAndBotsKey) mapSize += sizeof(quint32) + sizeof(quint64);
if (_exportSettingsKey) mapSize += sizeof(quint32) + sizeof(quint64);
@ -509,12 +511,6 @@ void Account::writeMap() {
if (_savedGifsKey) {
mapData.stream << quint32(lskSavedGifs) << quint64(_savedGifsKey);
}
if (_backgroundKeyDay || _backgroundKeyNight) {
mapData.stream
<< quint32(lskBackground)
<< quint64(_backgroundKeyDay)
<< quint64(_backgroundKeyNight);
}
if (_settingsKey) {
mapData.stream << quint32(lskUserSettings) << quint64(_settingsKey);
}
@ -542,7 +538,7 @@ void Account::reset() {
_favedStickersKey = 0;
_archivedStickersKey = 0;
_savedGifsKey = 0;
_backgroundKeyDay = _backgroundKeyNight = 0;
_legacyBackgroundKeyDay = _legacyBackgroundKeyNight = 0;
_settingsKey = _recentHashtagsAndBotsKey = _exportSettingsKey = 0;
_oldMapVersion = 0;
_fileLocations.clear();
@ -764,10 +760,6 @@ void Account::writeSessionSettings(Main::SessionSettings *stored) {
}
EncryptedDescriptor data(size);
data.stream
<< quint32(dbiTileBackground)
<< qint32(Window::Theme::Background()->tileDay() ? 1 : 0)
<< qint32(Window::Theme::Background()->tileNight() ? 1 : 0);
data.stream << quint32(dbiUseExternalVideoPlayer) << qint32(cUseExternalVideoPlayer());
data.stream << quint32(dbiCacheSettings) << qint64(_cacheTotalSizeLimit) << qint32(_cacheTotalTimeLimit) << qint64(_cacheBigFileTotalSizeLimit) << qint32(_cacheBigFileTotalTimeLimit);
if (!userData.isEmpty()) {
@ -783,7 +775,7 @@ void Account::writeSessionSettings(Main::SessionSettings *stored) {
ReadSettingsContext Account::prepareReadSettingsContext() const {
return ReadSettingsContext{
.hasCustomDayBackground = (_backgroundKeyDay != 0)
.legacyHasCustomDayBackground = (_legacyBackgroundKeyDay != 0)
};
}
@ -845,9 +837,10 @@ std::unique_ptr<Main::SessionSettings> Account::applyReadContext(
}
}
// #TODO multi
//Window::Theme::Background()->setTileDayValue(context.tileDay);
//Window::Theme::Background()->setTileNightValue(context.tileNight);
if (context.tileRead) {
Window::Theme::Background()->setTileDayValue(context.tileDay);
Window::Theme::Background()->setTileNightValue(context.tileNight);
}
return std::move(context.sessionSettingsStorage);
}
@ -1955,185 +1948,6 @@ void Account::readSavedGifs() {
}
}
void Account::writeBackground(
const Data::WallPaper &paper,
const QImage &image) {
if (!_backgroundCanWrite) {
return;
}
if (!_localKey) {
LOG(("App Error: localkey not created in writeBackground()"));
return;
}
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
auto imageData = QByteArray();
if (!image.isNull()) {
const auto width = qint32(image.width());
const auto height = qint32(image.height());
const auto perpixel = (image.depth() >> 3);
const auto srcperline = image.bytesPerLine();
const auto srcsize = srcperline * height;
const auto dstperline = width * perpixel;
const auto dstsize = dstperline * height;
const auto copy = (image.format() != kSavedBackgroundFormat)
? image.convertToFormat(kSavedBackgroundFormat)
: image;
imageData.resize(2 * sizeof(qint32) + dstsize);
auto dst = bytes::make_detached_span(imageData);
bytes::copy(dst, bytes::object_as_span(&width));
dst = dst.subspan(sizeof(qint32));
bytes::copy(dst, bytes::object_as_span(&height));
dst = dst.subspan(sizeof(qint32));
const auto src = bytes::make_span(image.constBits(), srcsize);
if (srcsize == dstsize) {
bytes::copy(dst, src);
} else {
for (auto y = 0; y != height; ++y) {
bytes::copy(dst, src.subspan(y * srcperline, dstperline));
dst = dst.subspan(dstperline);
}
}
}
if (!backgroundKey) {
backgroundKey = GenerateKey(_basePath);
writeMapQueued();
}
const auto serialized = paper.serialize();
quint32 size = sizeof(qint32)
+ Serialize::bytearraySize(serialized)
+ Serialize::bytearraySize(imageData);
EncryptedDescriptor data(size);
data.stream
<< qint32(kWallPaperSerializeTagId)
<< serialized
<< imageData;
FileWriteDescriptor file(backgroundKey, _basePath);
file.writeEncrypted(data, _localKey);
}
bool Account::readBackground() {
FileReadDescriptor bg;
auto &backgroundKey = Window::Theme::IsNightMode()
? _backgroundKeyNight
: _backgroundKeyDay;
if (!ReadEncryptedFile(bg, backgroundKey, _basePath, _localKey)) {
if (backgroundKey) {
ClearKey(backgroundKey, _basePath);
backgroundKey = 0;
writeMapDelayed();
}
return false;
}
qint32 legacyId = 0;
bg.stream >> legacyId;
const auto paper = [&] {
if (legacyId == kWallPaperLegacySerializeTagId) {
quint64 id = 0;
quint64 accessHash = 0;
quint32 flags = 0;
QString slug;
bg.stream
>> id
>> accessHash
>> flags
>> slug;
return Data::WallPaper::FromLegacySerialized(
id,
accessHash,
flags,
slug);
} else if (legacyId == kWallPaperSerializeTagId) {
QByteArray serialized;
bg.stream >> serialized;
return Data::WallPaper::FromSerialized(serialized);
} else {
return Data::WallPaper::FromLegacyId(legacyId);
}
}();
if (bg.stream.status() != QDataStream::Ok || !paper) {
return false;
}
QByteArray imageData;
bg.stream >> imageData;
const auto isOldEmptyImage = (bg.stream.status() != QDataStream::Ok);
if (isOldEmptyImage
|| Data::IsLegacy1DefaultWallPaper(*paper)
|| Data::IsDefaultWallPaper(*paper)) {
_backgroundCanWrite = false;
if (isOldEmptyImage || bg.version < 8005) {
Window::Theme::Background()->set(Data::DefaultWallPaper());
Window::Theme::Background()->setTile(false);
} else {
Window::Theme::Background()->set(*paper);
}
_backgroundCanWrite = true;
return true;
} else if (Data::IsThemeWallPaper(*paper) && imageData.isEmpty()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper);
_backgroundCanWrite = true;
return true;
}
auto image = QImage();
if (legacyId == kWallPaperSerializeTagId) {
const auto perpixel = 4;
auto src = bytes::make_span(imageData);
auto width = qint32();
auto height = qint32();
if (src.size() > 2 * sizeof(qint32)) {
bytes::copy(
bytes::object_as_span(&width),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
bytes::copy(
bytes::object_as_span(&height),
src.subspan(0, sizeof(qint32)));
src = src.subspan(sizeof(qint32));
if (width + height <= kWallPaperSidesLimit
&& src.size() == width * height * perpixel) {
image = QImage(
width,
height,
QImage::Format_ARGB32_Premultiplied);
if (!image.isNull()) {
const auto srcperline = width * perpixel;
const auto srcsize = srcperline * height;
const auto dstperline = image.bytesPerLine();
const auto dstsize = dstperline * height;
Assert(srcsize == dstsize);
bytes::copy(
bytes::make_span(image.bits(), dstsize),
src);
}
}
}
} else {
auto buffer = QBuffer(&imageData);
auto reader = QImageReader(&buffer);
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (!reader.read(&image)) {
image = QImage();
}
}
if (!image.isNull() || paper->backgroundColor()) {
_backgroundCanWrite = false;
Window::Theme::Background()->set(*paper, std::move(image));
_backgroundCanWrite = true;
return true;
}
return false;
}
void Account::writeRecentHashtagsAndBots() {
const auto &write = cRecentWriteHashtags();
const auto &search = cRecentSearchHashtags();

View File

@ -71,9 +71,6 @@ public:
void writeMtpData();
void writeMtpConfig();
void writeBackground(const Data::WallPaper &paper, const QImage &image);
bool readBackground();
void writeDrafts(not_null<History*> history);
void writeDrafts(
const PeerId &peer,
@ -232,8 +229,8 @@ private:
FileKey _archivedStickersKey = 0;
FileKey _savedGifsKey = 0;
FileKey _recentStickersKeyOld = 0;
FileKey _backgroundKeyDay = 0;
FileKey _backgroundKeyNight = 0;
FileKey _legacyBackgroundKeyDay = 0;
FileKey _legacyBackgroundKeyNight = 0;
FileKey _settingsKey = 0;
FileKey _recentHashtagsAndBotsKey = 0;
FileKey _exportSettingsKey = 0;
@ -245,7 +242,6 @@ private:
base::flat_set<uint64> _trustedBots;
bool _trustedBotsRead = false;
bool _backgroundCanWrite = true;
bool _readingUserSettings = false;
bool _recentHashtagsAndBotsWereRead = false;

View File

@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "main/main_session.h"
#include "apiwrap.h"
#include "storage/localstorage.h"
#include "storage/storage_account.h"
#include "storage/localimageloader.h"
#include "storage/file_upload.h"
#include "base/parse_helper.h"
@ -531,10 +530,6 @@ ChatBackground::ChatBackground() : _adjustableColors({
});
}
Storage::Account &ChatBackground::local() const {
return Core::App().activeAccount().local();
}
void ChatBackground::setThemeData(QImage &&themeImage, bool themeTile) {
_themeImage = validateBackgroundImage(std::move(themeImage));
_themeTile = themeTile;
@ -544,7 +539,7 @@ void ChatBackground::start() {
if (!Data::details::IsUninitializedWallPaper(_paper)) {
return;
}
if (!local().readBackground()) {
if (!Local::readBackground()) {
set(Data::ThemeWallPaper());
}
@ -659,7 +654,7 @@ void ChatBackground::set(const Data::WallPaper &paper, QImage image) {
setPaper(Data::DefaultWallPaper().withParamsFrom(_paper));
image.load(qsl(":/gui/art/bg.jpg"));
}
local().writeBackground(
Local::writeBackground(
_paper,
((Data::IsDefaultWallPaper(_paper)
|| Data::IsLegacy1DefaultWallPaper(_paper))
@ -875,7 +870,7 @@ void ChatBackground::setTile(bool tile) {
if (this->tile() != old) {
if (!Data::details::IsTestingThemeWallPaper(_paper)
&& !Data::details::IsTestingDefaultWallPaper(_paper)) {
local().writeSessionSettings();
Local::writeSettings();
}
notify(BackgroundUpdate(BackgroundUpdate::Type::Changed, tile));
}
@ -1030,9 +1025,9 @@ bool ChatBackground::isNonDefaultBackground() {
void ChatBackground::writeNewBackgroundSettings() {
if (tile() != _tileForRevert) {
local().writeSessionSettings();
Local::writeSettings();
}
local().writeBackground(
Local::writeBackground(
_paper,
((Data::IsThemeWallPaper(_paper)
|| Data::IsDefaultWallPaper(_paper))
@ -1116,13 +1111,10 @@ void ChatBackground::reapplyWithNightMode(
}
ClearApplying();
keepApplied(saved.object, settingExactTheme);
if (tile() != _tileForRevert) {
local().writeSessionSettings();
}
if (nightModeChanged) {
if (tile() != _tileForRevert || nightModeChanged) {
Local::writeSettings();
}
if (!settingExactTheme && !local().readBackground()) {
if (!settingExactTheme && !Local::readBackground()) {
set(Data::ThemeWallPaper());
}
};

View File

@ -14,10 +14,6 @@ namespace Main {
class Session;
} // namespace Main
namespace Storage {
class Account;
} // namespace Storage
namespace Window {
namespace Theme {
@ -181,8 +177,6 @@ private:
QColor original;
};
Storage::Account &local() const;
void ensureStarted();
void saveForRevert();
void setPreparedImage(QImage original, QImage prepared);