mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 17:51:41 -05:00
Update current theme in realtime.
This commit is contained in:
parent
1cda90c3c5
commit
e3d7bf771f
3 changed files with 132 additions and 1 deletions
|
@ -7,12 +7,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "data/data_cloud_themes.h"
|
#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_session.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_file_origin.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr auto kFirstReloadTimeout = 60 * crl::time(1000);
|
||||||
|
constexpr auto kReloadTimeout = 3600 * crl::time(1000);
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
CloudTheme CloudTheme::Parse(
|
CloudTheme CloudTheme::Parse(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
|
@ -36,7 +45,103 @@ QString CloudThemes::Format() {
|
||||||
}
|
}
|
||||||
|
|
||||||
CloudThemes::CloudThemes(not_null<Main::Session*> session)
|
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() {
|
void CloudThemes::refresh() {
|
||||||
|
|
|
@ -7,6 +7,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "base/timer.h"
|
||||||
|
|
||||||
|
class DocumentData;
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
@ -37,15 +41,31 @@ public:
|
||||||
[[nodiscard]] const std::vector<CloudTheme> &list() const;
|
[[nodiscard]] const std::vector<CloudTheme> &list() const;
|
||||||
void apply(const CloudTheme &data);
|
void apply(const CloudTheme &data);
|
||||||
|
|
||||||
|
void applyUpdate(const MTPTheme &theme);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseThemes(const QVector<MTPTheme> &list);
|
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;
|
const not_null<Main::Session*> _session;
|
||||||
int32 _hash = 0;
|
int32 _hash = 0;
|
||||||
mtpRequestId _requestId = 0;
|
mtpRequestId _requestId = 0;
|
||||||
std::vector<CloudTheme> _list;
|
std::vector<CloudTheme> _list;
|
||||||
rpl::event_stream<> _updates;
|
rpl::event_stream<> _updates;
|
||||||
|
|
||||||
|
base::Timer _reloadCurrentTimer;
|
||||||
|
DocumentData *_updatingFrom = nullptr;
|
||||||
|
rpl::lifetime _updatingFromLifetime;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -4612,5 +4612,11 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
////// Cloud themes
|
||||||
|
case mtpc_updateTheme: {
|
||||||
|
const auto &data = update.c_updateTheme();
|
||||||
|
session().data().cloudThemes().applyUpdate(data.vtheme());
|
||||||
|
} break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue