Open theme preview after loading.

This commit is contained in:
John Preston 2019-09-06 18:31:01 +03:00
parent 95ee17bd54
commit 37a4c79c81
7 changed files with 138 additions and 56 deletions

View File

@ -284,6 +284,14 @@ void Application::showDocument(not_null<DocumentData*> document, HistoryItem *it
}
}
void Application::showTheme(
not_null<DocumentData*> document,
const Data::CloudTheme &cloud) {
_mediaView->showTheme(document, cloud);
_mediaView->activateWindow();
_mediaView->setFocus();
}
PeerData *Application::ui_getPeerForMouseAction() {
if (_mediaView && !_mediaView->isHidden()) {
return _mediaView->ui_getPeerForMouseAction();

View File

@ -68,6 +68,10 @@ class Translator;
class CloudManager;
} // namespace Lang
namespace Data {
struct CloudTheme;
} // namespace Data
namespace Core {
class Launcher;
@ -103,6 +107,9 @@ public:
void showPhoto(not_null<PhotoData*> photo, HistoryItem *item);
void showPhoto(not_null<PhotoData*> photo, not_null<PeerData*> item);
void showDocument(not_null<DocumentData*> document, HistoryItem *item);
void showTheme(
not_null<DocumentData*> document,
const Data::CloudTheme &cloud);
PeerData *ui_getPeerForMouseAction();
QPoint getPointForCallPanelCenter() const;

View File

@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "main/main_session.h"
#include "boxes/confirm_box.h"
#include "core/application.h" // Core::App().showTheme.
#include "lang/lang_keys.h"
#include "apiwrap.h"
#include "mainwindow.h"
@ -147,26 +148,7 @@ void CloudThemes::resolve(
MTP_inputThemeSlug(MTP_string(slug)),
MTP_long(0)
)).done([=](const MTPTheme &result) {
result.match([&](const MTPDtheme &data) {
const auto cloud = CloudTheme::Parse(_session, data);
if (cloud.documentId) {
const auto document = _session->data().document(
cloud.documentId);
DocumentOpenClickHandler::Open(
Data::FileOrigin(),
document,
_session->data().message(clickFromMessageId));
} else if (cloud.createdBy == _session->userId()) {
Ui::show(Box(
Window::Theme::CreateForExistingBox,
&App::wnd()->controller(),
cloud));
} else {
Ui::show(Box<InformBox>(
tr::lng_theme_no_desktop(tr::now)));
}
}, [&](const MTPDthemeDocumentNotModified &data) {
});
showPreview(result);
}).fail([=](const RPCError &error) {
if (error.type() == qstr("THEME_FORMAT_INVALID")) {
Ui::show(Box<InformBox>(
@ -175,30 +157,80 @@ void CloudThemes::resolve(
}).send();
}
void CloudThemes::showPreview(const MTPTheme &data) {
data.match([&](const MTPDtheme &data) {
showPreview(CloudTheme::Parse(_session, data));
}, [&](const MTPDthemeDocumentNotModified &data) {
LOG(("API Error: Unexpected themeDocumentNotModified."));
});
}
void CloudThemes::showPreview(const CloudTheme &cloud) {
if (const auto documentId = cloud.documentId) {
previewFromDocument(cloud, _session->data().document(documentId));
} else if (cloud.createdBy == _session->userId()) {
Ui::show(Box(
Window::Theme::CreateForExistingBox,
&App::wnd()->controller(),
cloud));
} else {
Ui::show(Box<InformBox>(
tr::lng_theme_no_desktop(tr::now)));
}
}
void CloudThemes::updateFromDocument(
const CloudTheme &cloud,
not_null<DocumentData*> document) {
if (_updatingFrom) {
_updatingFrom->cancel();
} else {
loadDocumentAndInvoke(_updatingFrom, document, [=] {
auto preview = Window::Theme::PreviewFromFile(
document->data(),
document->location().name(),
cloud);
if (preview) {
Window::Theme::Apply(std::move(preview));
}
});
}
void CloudThemes::previewFromDocument(
const CloudTheme &cloud,
not_null<DocumentData*> document) {
loadDocumentAndInvoke(_previewFrom, document, [=] {
Core::App().showTheme(document, cloud);
});
}
void CloudThemes::loadDocumentAndInvoke(
LoadingDocument &value,
not_null<DocumentData*> document,
Fn<void()> callback) {
const auto alreadyWaiting = (value.document != nullptr);
if (alreadyWaiting) {
value.document->cancel();
}
value.document = document;
value.document->save(Data::FileOrigin(), QString()); // #TODO themes
value.callback = std::move(callback);
if (document->loaded()) {
invokeForLoaded(value);
return;
}
if (!alreadyWaiting) {
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);
return document->loaded();
}) | rpl::start_with_next([=, &value] {
invokeForLoaded(value);
}, value.subscription);
}
}
_updatingFrom = document;
_updatingFrom->save(Data::FileOrigin(), QString()); // #TODO themes
void CloudThemes::invokeForLoaded(LoadingDocument &value) {
const auto onstack = std::move(value.callback);
value = LoadingDocument();
onstack();
}
void CloudThemes::scheduleReload() {

View File

@ -44,8 +44,16 @@ public:
void applyUpdate(const MTPTheme &theme);
void resolve(const QString &slug, const FullMsgId &clickFromMessageId);
void showPreview(const MTPTheme &data);
void showPreview(const CloudTheme &cloud);
private:
struct LoadingDocument {
DocumentData *document = nullptr;
rpl::lifetime subscription;
Fn<void()> callback;
};
void parseThemes(const QVector<MTPTheme> &list);
void install();
@ -56,6 +64,14 @@ private:
void updateFromDocument(
const CloudTheme &cloud,
not_null<DocumentData*> document);
void previewFromDocument(
const CloudTheme &cloud,
not_null<DocumentData*> document);
void loadDocumentAndInvoke(
LoadingDocument &value,
not_null<DocumentData*> document,
Fn<void()> callback);
void invokeForLoaded(LoadingDocument &value);
const not_null<Main::Session*> _session;
int32 _hash = 0;
@ -65,8 +81,8 @@ private:
rpl::event_stream<> _updates;
base::Timer _reloadCurrentTimer;
DocumentData *_updatingFrom = nullptr;
rpl::lifetime _updatingFromLifetime;
LoadingDocument _updatingFrom;
LoadingDocument _previewFrom;
uint64 _installedDayThemeId = 0;
uint64 _installedNightThemeId = 0;

View File

@ -1744,6 +1744,19 @@ void OverlayWidget::showPhoto(not_null<PhotoData*> photo, not_null<PeerData*> co
}
void OverlayWidget::showDocument(not_null<DocumentData*> document, HistoryItem *context) {
showDocument(document, context, Data::CloudTheme());
}
void OverlayWidget::showTheme(
not_null<DocumentData*> document,
const Data::CloudTheme &cloud) {
showDocument(document, nullptr, cloud);
}
void OverlayWidget::showDocument(
not_null<DocumentData*> document,
HistoryItem *context,
const Data::CloudTheme &cloud) {
if (context) {
setContext(context);
} else {
@ -1754,7 +1767,7 @@ void OverlayWidget::showDocument(not_null<DocumentData*> document, HistoryItem *
_photo = nullptr;
_streamingStartPaused = false;
displayDocument(document, context);
displayDocument(document, context, cloud);
preloadData(0);
activateControls();
}
@ -1813,7 +1826,10 @@ void OverlayWidget::redisplayContent() {
}
// Empty messages shown as docs: doc can be nullptr.
void OverlayWidget::displayDocument(DocumentData *doc, HistoryItem *item) {
void OverlayWidget::displayDocument(
DocumentData *doc,
HistoryItem *item,
const Data::CloudTheme &cloud) {
if (isHidden()) {
moveToScreen();
}
@ -1822,6 +1838,7 @@ void OverlayWidget::displayDocument(DocumentData *doc, HistoryItem *item) {
clearStreaming();
destroyThemePreview();
_doc = doc;
_themeCloudData = cloud;
_photo = nullptr;
_radial.stop();
@ -2223,7 +2240,7 @@ void OverlayWidget::initThemePreview() {
const auto cloud = (i != end(cloudList)) ? *i : Data::CloudTheme();
const auto isTrusted = (cloud.documentId != 0);
const auto fields = [&] {
auto result = cloud;
auto result = _themeCloudData.id ? _themeCloudData : cloud;
if (!result.documentId) {
result.documentId = _doc->id;
}

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_shared_media.h"
#include "data/data_user_photos.h"
#include "data/data_web_page.h"
#include "data/data_cloud_themes.h" // Data::CloudTheme.
#include "media/view/media_view_playback_controls.h"
namespace Ui {
@ -70,7 +71,12 @@ public:
void showPhoto(not_null<PhotoData*> photo, HistoryItem *context);
void showPhoto(not_null<PhotoData*> photo, not_null<PeerData*> context);
void showDocument(not_null<DocumentData*> document, HistoryItem *context);
void showDocument(
not_null<DocumentData*> document,
HistoryItem *context);
void showTheme(
not_null<DocumentData*> document,
const Data::CloudTheme &cloud);
void leaveToChildEvent(QEvent *e, QWidget *child) override { // e -- from enterEvent() of child TWidget
updateOverState(OverNone);
@ -229,8 +235,15 @@ private:
void resizeCenteredControls();
void resizeContentByScreenSize();
void showDocument(
not_null<DocumentData*> document,
HistoryItem *context,
const Data::CloudTheme &cloud);
void displayPhoto(not_null<PhotoData*> photo, HistoryItem *item);
void displayDocument(DocumentData *document, HistoryItem *item);
void displayDocument(
DocumentData *document,
HistoryItem *item,
const Data::CloudTheme &cloud = Data::CloudTheme());
void displayFinished();
void redisplayContent();
void findCurrent();
@ -455,6 +468,7 @@ private:
std::unique_ptr<Window::Theme::Preview> _themePreview;
object_ptr<Ui::RoundButton> _themeApply = { nullptr };
object_ptr<Ui::RoundButton> _themeCancel = { nullptr };
Data::CloudTheme _themeCloudData;
bool _wasRepainted = false;

View File

@ -481,19 +481,7 @@ void CloudList::insert(int index, const Data::CloudTheme &theme) {
|| i->waiting) {
return;
}
const auto documentId = i->theme.documentId;
if (!documentId) {
if (amCreator(i->theme)) {
_window->window().show(
Box(CreateForExistingBox, &_window->window(), i->theme));
}
return;
}
const auto document = _window->session().data().document(documentId);
DocumentOpenClickHandler::Open(
Data::FileOrigin(),
document,
nullptr);
_window->session().data().cloudThemes().showPreview(i->theme);
});
auto &element = *_elements.insert(
begin(_elements) + index,