Update current theme in realtime.

This commit is contained in:
John Preston 2019-09-06 16:35:26 +03:00
parent 1cda90c3c5
commit e3d7bf771f
3 changed files with 132 additions and 1 deletions

View File

@ -7,12 +7,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/data_cloud_themes.h"
#include "window/themes/window_theme.h"
#include "window/themes/window_theme_preview.h"
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_file_origin.h"
#include "main/main_session.h"
#include "apiwrap.h"
namespace Data {
namespace {
constexpr auto kFirstReloadTimeout = 60 * crl::time(1000);
constexpr auto kReloadTimeout = 3600 * crl::time(1000);
} // namespace
CloudTheme CloudTheme::Parse(
not_null<Main::Session*> session,
@ -36,7 +45,103 @@ QString CloudThemes::Format() {
}
CloudThemes::CloudThemes(not_null<Main::Session*> session)
: _session(session) {
: _session(session)
, _reloadCurrentTimer([=] { reloadCurrent(); }) {
setupReload();
}
void CloudThemes::setupReload() {
using namespace Window::Theme;
if (needReload()) {
_reloadCurrentTimer.callOnce(kFirstReloadTimeout);
}
base::ObservableViewer(
*Background()
) | rpl::filter([](const BackgroundUpdate &update) {
return (update.type == BackgroundUpdate::Type::ApplyingTheme);
}) | rpl::map([=] {
return needReload();
}) | rpl::start_with_next([=](bool need) {
if (need) {
scheduleReload();
} else {
_reloadCurrentTimer.cancel();
}
}, _lifetime);
}
bool CloudThemes::needReload() const {
const auto &fields = Window::Theme::Background()->themeObject().cloud;
return fields.id && fields.documentId;
}
void CloudThemes::reloadCurrent() {
if (!needReload()) {
return;
}
const auto &fields = Window::Theme::Background()->themeObject().cloud;
_session->api().request(MTPaccount_GetTheme(
MTP_string(Format()),
MTP_inputTheme(MTP_long(fields.id), MTP_long(fields.accessHash)),
MTP_long(fields.documentId)
)).done([=](const MTPTheme &result) {
applyUpdate(result);
}).fail([=](const RPCError &error) {
_reloadCurrentTimer.callOnce(kReloadTimeout);
}).send();
}
void CloudThemes::applyUpdate(const MTPTheme &theme) {
theme.match([&](const MTPDtheme &data) {
const auto cloud = CloudTheme::Parse(_session, data);
const auto &object = Window::Theme::Background()->themeObject();
if ((cloud.id != object.cloud.id)
|| (cloud.documentId == object.cloud.documentId)) {
return;
}
if (const auto updated = data.vdocument()) {
updateFromDocument(
cloud,
_session->data().processDocument(*updated));
}
}, [&](const MTPDthemeDocumentNotModified &data) {
});
scheduleReload();
}
void CloudThemes::updateFromDocument(
const CloudTheme &cloud,
not_null<DocumentData*> document) {
if (_updatingFrom) {
_updatingFrom->cancel();
} else {
base::ObservableViewer(
_session->downloaderTaskFinished()
) | rpl::filter([=] {
return _updatingFrom->loaded();
}) | rpl::start_with_next([=] {
_updatingFromLifetime.destroy();
auto preview = Window::Theme::PreviewFromFile(
document->data(),
document->location().name(),
cloud);
if (preview) {
Window::Theme::Apply(std::move(preview));
}
}, _updatingFromLifetime);
}
_updatingFrom = document;
_updatingFrom->save(Data::FileOrigin(), QString()); // #TODO themes
}
void CloudThemes::scheduleReload() {
if (needReload()) {
_reloadCurrentTimer.callOnce(kReloadTimeout);
} else {
_reloadCurrentTimer.cancel();
}
}
void CloudThemes::refresh() {

View File

@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "base/timer.h"
class DocumentData;
namespace Main {
class Session;
} // namespace Main
@ -37,15 +41,31 @@ public:
[[nodiscard]] const std::vector<CloudTheme> &list() const;
void apply(const CloudTheme &data);
void applyUpdate(const MTPTheme &theme);
private:
void parseThemes(const QVector<MTPTheme> &list);
void setupReload();
[[nodiscard]] bool needReload() const;
void scheduleReload();
void reloadCurrent();
void updateFromDocument(
const CloudTheme &cloud,
not_null<DocumentData*> document);
const not_null<Main::Session*> _session;
int32 _hash = 0;
mtpRequestId _requestId = 0;
std::vector<CloudTheme> _list;
rpl::event_stream<> _updates;
base::Timer _reloadCurrentTimer;
DocumentData *_updatingFrom = nullptr;
rpl::lifetime _updatingFromLifetime;
rpl::lifetime _lifetime;
};
} // namespace Data

View File

@ -4612,5 +4612,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
}
} break;
////// Cloud themes
case mtpc_updateTheme: {
const auto &data = update.c_updateTheme();
session().data().cloudThemes().applyUpdate(data.vtheme());
} break;
}
}