mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 06:07:06 +02:00
Load chat cloud themes list.
This commit is contained in:
parent
70808dfa7d
commit
f3dd8c68b3
10 changed files with 192 additions and 32 deletions
|
@ -887,6 +887,7 @@ void ApplyChannelUpdate(
|
|||
session->changes().peerUpdated(channel, UpdateFlag::StickersSet);
|
||||
}
|
||||
}
|
||||
channel->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
||||
channel->fullUpdated();
|
||||
|
||||
if (canViewAdmins != channel->canViewAdmins()
|
||||
|
|
|
@ -428,6 +428,7 @@ void ApplyChatUpdate(not_null<ChatData*> chat, const MTPDchatFull &update) {
|
|||
SetTopPinnedMessageId(chat, pinned->v);
|
||||
}
|
||||
chat->checkFolder(update.vfolder_id().value_or_empty());
|
||||
chat->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
||||
chat->fullUpdated();
|
||||
chat->setAbout(qs(update.vabout()));
|
||||
|
||||
|
|
|
@ -31,21 +31,69 @@ constexpr auto kReloadTimeout = 3600 * crl::time(1000);
|
|||
|
||||
CloudTheme CloudTheme::Parse(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDtheme &data) {
|
||||
const MTPDtheme &data,
|
||||
bool parseSettings) {
|
||||
constexpr auto size = sizeof(CloudTheme);
|
||||
const auto document = data.vdocument();
|
||||
const auto paper = [&]() -> std::optional<WallPaper> {
|
||||
if (const auto settings = data.vsettings()) {
|
||||
settings->match([&](const MTPDthemeSettings &data) {
|
||||
return data.vwallpaper()
|
||||
? std::make_optional(
|
||||
WallPaper::Create(session, *data.vwallpaper()))
|
||||
: std::nullopt;
|
||||
});
|
||||
}
|
||||
return {};
|
||||
};
|
||||
const auto outgoingMessagesColors = [&] {
|
||||
auto result = std::vector<QColor>();
|
||||
if (const auto settings = data.vsettings()) {
|
||||
settings->match([&](const MTPDthemeSettings &data) {
|
||||
if (const auto colors = data.vmessage_colors()) {
|
||||
for (const auto color : colors->v) {
|
||||
result.push_back(ColorFromSerialized(color));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const auto accentColor = [&]() -> std::optional<QColor> {
|
||||
if (const auto settings = data.vsettings()) {
|
||||
settings->match([&](const MTPDthemeSettings &data) {
|
||||
return ColorFromSerialized(data.vaccent_color().v);
|
||||
});
|
||||
}
|
||||
return {};
|
||||
};
|
||||
return {
|
||||
data.vid().v,
|
||||
data.vaccess_hash().v,
|
||||
qs(data.vslug()),
|
||||
qs(data.vtitle()),
|
||||
(document
|
||||
.id = data.vid().v,
|
||||
.accessHash = data.vaccess_hash().v,
|
||||
.slug = qs(data.vslug()),
|
||||
.title = qs(data.vtitle()),
|
||||
.documentId = (document
|
||||
? session->data().processDocument(*document)->id
|
||||
: DocumentId(0)),
|
||||
data.is_creator() ? session->userId() : UserId(0),
|
||||
data.vinstalls_count().value_or_empty()
|
||||
.createdBy = data.is_creator() ? session->userId() : UserId(0),
|
||||
.usersCount = data.vinstalls_count().value_or_empty(),
|
||||
.paper = parseSettings ? paper() : std::nullopt,
|
||||
.accentColor = parseSettings ? accentColor() : std::nullopt,
|
||||
.outgoingMessagesColors = (parseSettings
|
||||
? outgoingMessagesColors()
|
||||
: std::vector<QColor>()),
|
||||
};
|
||||
}
|
||||
|
||||
CloudTheme CloudTheme::Parse(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPTheme &data,
|
||||
bool parseSettings) {
|
||||
return data.match([&](const MTPDtheme &data) {
|
||||
return CloudTheme::Parse(session, data, parseSettings);
|
||||
});
|
||||
}
|
||||
|
||||
QString CloudThemes::Format() {
|
||||
static const auto kResult = QString::fromLatin1("tdesktop");
|
||||
return kResult;
|
||||
|
@ -256,14 +304,14 @@ void CloudThemes::scheduleReload() {
|
|||
}
|
||||
|
||||
void CloudThemes::refresh() {
|
||||
if (_refreshRquestId) {
|
||||
if (_refreshRequestId) {
|
||||
return;
|
||||
}
|
||||
_refreshRquestId = _session->api().request(MTPaccount_GetThemes(
|
||||
_refreshRequestId = _session->api().request(MTPaccount_GetThemes(
|
||||
MTP_string(Format()),
|
||||
MTP_int(_hash)
|
||||
)).done([=](const MTPaccount_Themes &result) {
|
||||
_refreshRquestId = 0;
|
||||
_refreshRequestId = 0;
|
||||
result.match([&](const MTPDaccount_themes &data) {
|
||||
_hash = data.vhash().v;
|
||||
parseThemes(data.vthemes().v);
|
||||
|
@ -271,7 +319,7 @@ void CloudThemes::refresh() {
|
|||
}, [](const MTPDaccount_themesNotModified &) {
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_refreshRquestId = 0;
|
||||
_refreshRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
|
@ -279,13 +327,61 @@ void CloudThemes::parseThemes(const QVector<MTPTheme> &list) {
|
|||
_list.clear();
|
||||
_list.reserve(list.size());
|
||||
for (const auto &theme : list) {
|
||||
theme.match([&](const MTPDtheme &data) {
|
||||
_list.push_back(CloudTheme::Parse(_session, data));
|
||||
});
|
||||
_list.push_back(CloudTheme::Parse(_session, theme));
|
||||
}
|
||||
checkCurrentTheme();
|
||||
}
|
||||
|
||||
void CloudThemes::refreshChatThemes() {
|
||||
if (_chatThemesRequestId) {
|
||||
return;
|
||||
}
|
||||
_chatThemesRequestId = _session->api().request(MTPaccount_GetChatThemes(
|
||||
MTP_int(_chatThemesHash)
|
||||
)).done([=](const MTPaccount_ChatThemes &result) {
|
||||
_chatThemesRequestId = 0;
|
||||
result.match([&](const MTPDaccount_chatThemes &data) {
|
||||
_hash = data.vhash().v;
|
||||
parseChatThemes(data.vthemes().v);
|
||||
_chatThemesUpdates.fire({});
|
||||
}, [](const MTPDaccount_chatThemesNotModified &) {
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
_chatThemesRequestId = 0;
|
||||
}).send();
|
||||
}
|
||||
|
||||
const std::vector<ChatTheme> &CloudThemes::chatThemes() const {
|
||||
return _chatThemes;
|
||||
}
|
||||
|
||||
rpl::producer<> CloudThemes::chatThemesUpdated() const {
|
||||
return _chatThemesUpdates.events();
|
||||
}
|
||||
|
||||
std::optional<ChatTheme> CloudThemes::themeForEmoji(
|
||||
const QString &emoji) const {
|
||||
if (emoji.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
const auto i = ranges::find(_chatThemes, emoji, &ChatTheme::emoji);
|
||||
return (i != end(_chatThemes)) ? std::make_optional(*i) : std::nullopt;
|
||||
}
|
||||
|
||||
void CloudThemes::parseChatThemes(const QVector<MTPChatTheme> &list) {
|
||||
_chatThemes.clear();
|
||||
_chatThemes.reserve(list.size());
|
||||
for (const auto &theme : list) {
|
||||
theme.match([&](const MTPDchatTheme &data) {
|
||||
_chatThemes.push_back({
|
||||
.emoji = qs(data.vemoticon()),
|
||||
.light = CloudTheme::Parse(_session, data.vtheme(), true),
|
||||
.dark = CloudTheme::Parse(_session, data.vdark_theme(), true),
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void CloudThemes::checkCurrentTheme() {
|
||||
const auto &object = Window::Theme::Background()->themeObject();
|
||||
if (!object.cloud.id || !object.cloud.documentId) {
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
#include "data/data_wall_paper.h"
|
||||
|
||||
class DocumentData;
|
||||
|
||||
|
@ -31,10 +32,24 @@ struct CloudTheme {
|
|||
DocumentId documentId = 0;
|
||||
UserId createdBy = 0;
|
||||
int usersCount = 0;
|
||||
std::optional<WallPaper> paper;
|
||||
std::optional<QColor> accentColor;
|
||||
std::vector<QColor> outgoingMessagesColors;
|
||||
|
||||
static CloudTheme Parse(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPDtheme &data);
|
||||
const MTPDtheme &data,
|
||||
bool parseSettings = false);
|
||||
static CloudTheme Parse(
|
||||
not_null<Main::Session*> session,
|
||||
const MTPTheme &data,
|
||||
bool parseSettings = false);
|
||||
};
|
||||
|
||||
struct ChatTheme {
|
||||
QString emoji;
|
||||
CloudTheme light;
|
||||
CloudTheme dark;
|
||||
};
|
||||
|
||||
class CloudThemes final {
|
||||
|
@ -49,6 +64,12 @@ public:
|
|||
void savedFromEditor(const CloudTheme &data);
|
||||
void remove(uint64 cloudThemeId);
|
||||
|
||||
void refreshChatThemes();
|
||||
[[nodiscard]] const std::vector<ChatTheme> &chatThemes() const;
|
||||
[[nodiscard]] rpl::producer<> chatThemesUpdated() const;
|
||||
[[nodiscard]] std::optional<ChatTheme> themeForEmoji(
|
||||
const QString &emoji) const;
|
||||
|
||||
void applyUpdate(const MTPTheme &theme);
|
||||
|
||||
void resolve(
|
||||
|
@ -90,13 +111,20 @@ private:
|
|||
Fn<void(std::shared_ptr<Data::DocumentMedia>)> callback);
|
||||
void invokeForLoaded(LoadingDocument &value);
|
||||
|
||||
void parseChatThemes(const QVector<MTPChatTheme> &list);
|
||||
|
||||
const not_null<Main::Session*> _session;
|
||||
int32 _hash = 0;
|
||||
mtpRequestId _refreshRquestId = 0;
|
||||
mtpRequestId _refreshRequestId = 0;
|
||||
mtpRequestId _resolveRequestId = 0;
|
||||
std::vector<CloudTheme> _list;
|
||||
rpl::event_stream<> _updates;
|
||||
|
||||
int32 _chatThemesHash = 0;
|
||||
mtpRequestId _chatThemesRequestId = 0;
|
||||
std::vector<ChatTheme> _chatThemes;
|
||||
rpl::event_stream<> _chatThemesUpdates;
|
||||
|
||||
base::Timer _reloadCurrentTimer;
|
||||
LoadingDocument _updatingFrom;
|
||||
LoadingDocument _previewFrom;
|
||||
|
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_cloud_themes.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "base/crc32hash.h"
|
||||
#include "lang/lang_keys.h"
|
||||
|
@ -1012,6 +1013,17 @@ PeerId PeerData::groupCallDefaultJoinAs() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void PeerData::setThemeEmoji(const QString &emoji) {
|
||||
_themeEmoji = emoji;
|
||||
if (!emoji.isEmpty() && !owner().cloudThemes().themeForEmoji(emoji)) {
|
||||
owner().cloudThemes().refreshChatThemes();
|
||||
}
|
||||
}
|
||||
|
||||
const QString &PeerData::themeEmoji() const {
|
||||
return _themeEmoji;
|
||||
}
|
||||
|
||||
void PeerData::setIsBlocked(bool is) {
|
||||
const auto status = is
|
||||
? BlockStatus::Blocked
|
||||
|
|
|
@ -470,6 +470,9 @@ public:
|
|||
[[nodiscard]] Data::GroupCall *groupCall() const;
|
||||
[[nodiscard]] PeerId groupCallDefaultJoinAs() const;
|
||||
|
||||
void setThemeEmoji(const QString &emoji);
|
||||
[[nodiscard]] const QString &themeEmoji() const;
|
||||
|
||||
const PeerId id;
|
||||
QString name;
|
||||
MTPinputPeer input = MTP_inputPeerEmpty();
|
||||
|
@ -515,6 +518,7 @@ private:
|
|||
LoadedStatus _loadedStatus = LoadedStatus::Not;
|
||||
|
||||
QString _about;
|
||||
QString _themeEmoji;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -225,6 +225,7 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
|
|||
user->setAbout(qs(update.vabout().value_or_empty()));
|
||||
user->setCommonChatsCount(update.vcommon_chats_count().v);
|
||||
user->checkFolder(update.vfolder_id().value_or_empty());
|
||||
user->setThemeEmoji(qs(update.vtheme_emoticon().value_or_empty()));
|
||||
user->fullUpdated();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,25 +45,10 @@ constexpr auto kVersion = 1;
|
|||
return color ? SerializeColor(*color) : quint32(-1);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<QColor> MaybeColorFromSerialized(
|
||||
quint32 serialized) {
|
||||
return (serialized == quint32(-1))
|
||||
? std::nullopt
|
||||
: std::make_optional(QColor(
|
||||
int((serialized >> 16) & 0xFFU),
|
||||
int((serialized >> 8) & 0xFFU),
|
||||
int(serialized & 0xFFU)));
|
||||
}
|
||||
|
||||
[[nodiscard]] QColor DefaultBackgroundColor() {
|
||||
return QColor(213, 223, 233);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::optional<QColor> MaybeColorFromSerialized(
|
||||
const tl::conditional<MTPint> &mtp) {
|
||||
return mtp ? MaybeColorFromSerialized(mtp->v) : std::nullopt;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<QColor> ColorsFromMTP(
|
||||
const MTPDwallPaperSettings &data) {
|
||||
auto result = std::vector<QColor>();
|
||||
|
@ -791,6 +776,29 @@ QImage GenerateDitheredGradient(const Data::WallPaper &paper) {
|
|||
paper.gradientRotation());
|
||||
}
|
||||
|
||||
QColor ColorFromSerialized(quint32 serialized) {
|
||||
return QColor(
|
||||
int((serialized >> 16) & 0xFFU),
|
||||
int((serialized >> 8) & 0xFFU),
|
||||
int(serialized & 0xFFU));
|
||||
}
|
||||
|
||||
QColor ColorFromSerialized(MTPint serialized) {
|
||||
return ColorFromSerialized(serialized.v);
|
||||
}
|
||||
|
||||
std::optional<QColor> MaybeColorFromSerialized(
|
||||
quint32 serialized) {
|
||||
return (serialized == quint32(-1))
|
||||
? std::nullopt
|
||||
: std::make_optional(ColorFromSerialized(serialized));
|
||||
}
|
||||
|
||||
std::optional<QColor> MaybeColorFromSerialized(
|
||||
const tl::conditional<MTPint> &mtp) {
|
||||
return mtp ? std::make_optional(ColorFromSerialized(*mtp)) : std::nullopt;
|
||||
}
|
||||
|
||||
namespace details {
|
||||
|
||||
WallPaper UninitializedWallPaper() {
|
||||
|
|
|
@ -139,6 +139,13 @@ private:
|
|||
int rotation);
|
||||
[[nodiscard]] QImage GenerateDitheredGradient(const WallPaper &paper);
|
||||
|
||||
[[nodiscard]] QColor ColorFromSerialized(quint32 serialized);
|
||||
[[nodiscard]] QColor ColorFromSerialized(MTPint serialized);
|
||||
[[nodiscard]] std::optional<QColor> MaybeColorFromSerialized(
|
||||
quint32 serialized);
|
||||
[[nodiscard]] std::optional<QColor> MaybeColorFromSerialized(
|
||||
const tl::conditional<MTPint> &mtp);
|
||||
|
||||
namespace details {
|
||||
|
||||
[[nodiscard]] WallPaper UninitializedWallPaper();
|
||||
|
|
|
@ -1061,6 +1061,8 @@ void History::applyServiceChanges(
|
|||
}
|
||||
}
|
||||
}
|
||||
}, [&](const MTPDmessageActionSetChatTheme &data) {
|
||||
peer->setThemeEmoji(qs(data.vemoticon()));
|
||||
}, [](const auto &) {
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue