Generate previews for cloud theme links.

This commit is contained in:
John Preston 2019-09-09 14:56:05 +03:00
parent 6d29dc3b36
commit ee5423762a
20 changed files with 193 additions and 80 deletions

View file

@ -1149,6 +1149,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_media_size_limit" = "Limit by size";
"lng_media_size_up_to" = "up to {size}";
"lng_media_chat_background" = "Chat background";
"lng_media_color_theme" = "Color theme";
"lng_emoji_category1" = "People";
"lng_emoji_category2" = "Nature";

View file

@ -650,6 +650,7 @@ void DocumentData::validateGoodThumbnail() {
if (!isVideoFile()
&& !isAnimation()
&& !isWallPaper()
&& !isTheme()
&& (!sticker() || !sticker()->animated)) {
_goodThumbnail = nullptr;
} else if (!_goodThumbnail && hasRemoteLocation()) {
@ -1470,7 +1471,8 @@ bool DocumentData::isGifv() const {
bool DocumentData::isTheme() const {
return
_filename.endsWith(
_mimeString == qstr("application/x-tgtheme-tdesktop")
|| _filename.endsWith(
qstr(".tdesktop-theme"),
Qt::CaseInsensitive)
|| _filename.endsWith(

View file

@ -10,8 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_session.h"
#include "data/data_document.h"
#include "data/data_file_origin.h"
#include "data/data_cloud_themes.h"
#include "media/clip/media_clip_reader.h"
#include "lottie/lottie_animation.h"
#include "window/themes/window_theme_preview.h"
#include "main/main_session.h"
#include <QtCore/QBuffer>
@ -27,6 +29,7 @@ enum class FileType {
Video,
AnimatedSticker,
WallPaper,
Theme,
};
QImage Prepare(
@ -37,6 +40,8 @@ QImage Prepare(
return ::Media::Clip::PrepareForSending(path, data).thumbnail;
} else if (type == FileType::AnimatedSticker) {
return Lottie::ReadThumbnail(Lottie::ReadContent(data, path));
} else if (type == FileType::Theme) {
return Window::Theme::GeneratePreview(data, path);
}
const auto validateSize = [](QSize size) {
return (size.width() + size.height()) < 10'000;
@ -78,6 +83,8 @@ void GoodThumbSource::generate(base::binary_guard &&guard) {
const auto data = _document->data();
const auto type = _document->isWallPaper()
? FileType::WallPaper
: _document->isTheme()
? FileType::Theme
: _document->sticker()
? FileType::AnimatedSticker
: FileType::Video;
@ -143,13 +150,13 @@ void GoodThumbSource::ready(
_document->goodThumbnailCacheKey(),
Storage::Cache::Database::TaggedValue{
std::move(bytes),
Data::kImageCacheTag });
kImageCacheTag });
}
Auth().downloaderTaskFinished().notify();
});
}
void GoodThumbSource::load(Data::FileOrigin origin) {
void GoodThumbSource::load(FileOrigin origin) {
if (loading() || _empty) {
return;
}
@ -178,7 +185,7 @@ void GoodThumbSource::load(Data::FileOrigin origin) {
std::move(callback));
}
void GoodThumbSource::loadEvenCancelled(Data::FileOrigin origin) {
void GoodThumbSource::loadEvenCancelled(FileOrigin origin) {
_empty = false;
load(origin);
}
@ -193,7 +200,7 @@ void GoodThumbSource::unload() {
}
void GoodThumbSource::automaticLoad(
Data::FileOrigin origin,
FileOrigin origin,
const HistoryItem *item) {
}
@ -235,7 +242,7 @@ void GoodThumbSource::setDelayedStorageLocation(
const StorageImageLocation &location) {
}
void GoodThumbSource::performDelayedLoad(Data::FileOrigin origin) {
void GoodThumbSource::performDelayedLoad(FileOrigin origin) {
}
bool GoodThumbSource::isDelayedStorageImage() const {

View file

@ -17,13 +17,13 @@ class GoodThumbSource : public Images::Source {
public:
explicit GoodThumbSource(not_null<DocumentData*> document);
void load(Data::FileOrigin origin) override;
void loadEvenCancelled(Data::FileOrigin origin) override;
void load(FileOrigin origin) override;
void loadEvenCancelled(FileOrigin origin) override;
QImage takeLoaded() override;
void unload() override;
void automaticLoad(
Data::FileOrigin origin,
FileOrigin origin,
const HistoryItem *item) override;
void automaticLoadSettingsChanged() override;
@ -38,7 +38,7 @@ public:
std::optional<Storage::Cache::Key> cacheKey() override;
void setDelayedStorageLocation(
const StorageImageLocation &location) override;
void performDelayedLoad(Data::FileOrigin origin) override;
void performDelayedLoad(FileOrigin origin) override;
bool isDelayedStorageImage() const override;
void setImageBytes(const QByteArray &bytes) override;

View file

@ -51,6 +51,9 @@ struct FileReferenceAccumulator {
if (const auto document = data.vdocument()) {
push(*document);
}
if (const auto documents = data.vdocuments()) {
push(*documents);
}
if (const auto photo = data.vphoto()) {
push(*photo);
}

View file

@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_call.h"
#include "history/view/media/history_view_web_page.h"
#include "history/view/media/history_view_poll.h"
#include "history/view/media/history_view_theme_document.h"
#include "ui/image/image.h"
#include "ui/image/image_source.h"
#include "ui/text_options.h"
@ -779,6 +780,10 @@ std::unique_ptr<HistoryView::Media> MediaFile::createView(
message,
realParent,
_document);
} else if (_document->isTheme() && _document->hasThumbnail()) {
return std::make_unique<HistoryView::ThemeDocument>(
message,
_document);
}
return std::make_unique<HistoryView::Document>(message, _document);
}

View file

@ -2762,6 +2762,17 @@ void Session::webpageApplyFields(
const auto pendingTill = TimeId(0);
const auto photo = data.vphoto();
const auto document = data.vdocument();
const auto lookupThemeDocument = [&]() -> DocumentData* {
if (const auto documents = data.vdocuments()) {
for (const auto &document : documents->v) {
const auto processed = processDocument(document);
if (processed->isTheme()) {
return processed;
}
}
}
return nullptr;
};
webpageApplyFields(
page,
ParseWebPageType(data),
@ -2771,7 +2782,7 @@ void Session::webpageApplyFields(
qs(data.vtitle().value_or_empty()),
description,
photo ? processPhoto(*photo).get() : nullptr,
document ? processDocument(*document).get() : nullptr,
document ? processDocument(*document).get() : lookupThemeDocument(),
WebPageCollage(data),
data.vduration().value_or_empty(),
qs(data.vauthor().value_or_empty()),

View file

@ -139,6 +139,8 @@ WebPageType ParseWebPageType(const MTPDwebPage &page) {
return WebPageType::Profile;
} else if (type == qstr("telegram_background")) {
return WebPageType::WallPaper;
} else if (type == qstr("telegram_theme")) {
return WebPageType::Theme;
} else if (page.vcached_page()) {
return WebPageType::ArticleWithIV;
} else {

View file

@ -15,6 +15,7 @@ enum class WebPageType {
Video,
Profile,
WallPaper,
Theme,
Article,
ArticleWithIV,
};

View file

@ -18,6 +18,7 @@ maxVideoMessageSize: 240px;
maxSignatureSize: 144px;
maxWallPaperWidth: 160px;
maxWallPaperHeight: 240px;
historyThemeSize: size(309px, 200px);
historyMinimalWidth: 380px;

View file

@ -16,7 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_document.h"
#include "history/view/media/history_view_sticker.h"
#include "history/view/media/history_view_video.h"
#include "history/view/media/history_view_wall_paper.h"
#include "history/view/media/history_view_theme_document.h"
#include "styles/style_history.h"
namespace HistoryView {
@ -80,8 +80,8 @@ std::unique_ptr<Media> CreateAttach(
parent,
parent->data(),
document);
} else if (document->isWallPaper()) {
return std::make_unique<WallPaper>(
} else if (document->isWallPaper() || document->isTheme()) {
return std::make_unique<ThemeDocument>(
parent,
document,
webpageUrl);

View file

@ -5,7 +5,7 @@ the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/media/history_view_wall_paper.h"
#include "history/view/media/history_view_theme_document.h"
#include "layout.h"
#include "history/history_item.h"
@ -19,22 +19,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
WallPaper::WallPaper(
ThemeDocument::ThemeDocument(
not_null<Element*> parent,
not_null<DocumentData*> document,
const QString &url)
: File(parent, parent->data())
, _data(document) {
Expects(_data->hasThumbnail());
Expects(_data->hasThumbnail() || _data->isTheme());
fillPatternFieldsFrom(url);
if (_data->isWallPaper()) {
fillPatternFieldsFrom(url);
}
_data->thumbnail()->load(parent->data()->fullId());
_data->loadThumbnail(_parent->data()->fullId());
setDocumentLinks(_data, parent->data());
setStatusSize(FileStatusSizeReady, _data->size, -1, 0);
}
void WallPaper::fillPatternFieldsFrom(const QString &url) {
void ThemeDocument::fillPatternFieldsFrom(const QString &url) {
const auto paramsPosition = url.indexOf('?');
if (paramsPosition < 0) {
return;
@ -49,7 +51,10 @@ void WallPaper::fillPatternFieldsFrom(const QString &url) {
_background = paper.backgroundColor().value_or(kDefaultBackground);
}
QSize WallPaper::countOptimalSize() {
QSize ThemeDocument::countOptimalSize() {
if (_data->isTheme()) {
return st::historyThemeSize;
}
auto tw = ConvertScale(_data->thumbnail()->width());
auto th = ConvertScale(_data->thumbnail()->height());
if (!tw || !th) {
@ -66,7 +71,12 @@ QSize WallPaper::countOptimalSize() {
return { maxWidth, minHeight };
}
QSize WallPaper::countCurrentSize(int newWidth) {
QSize ThemeDocument::countCurrentSize(int newWidth) {
if (_data->isTheme()) {
_pixw = st::historyThemeSize.width();
_pixh = st::historyThemeSize.height();
return st::historyThemeSize;
}
auto tw = ConvertScale(_data->thumbnail()->width());
auto th = ConvertScale(_data->thumbnail()->height());
if (!tw || !th) {
@ -86,7 +96,7 @@ QSize WallPaper::countCurrentSize(int newWidth) {
return { newWidth, newHeight };
}
void WallPaper::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const {
void ThemeDocument::draw(Painter &p, const QRect &r, TextSelection selection, crl::time ms) const {
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) return;
_data->automaticLoad(_realParent->fullId(), _parent->data());
@ -166,7 +176,7 @@ void WallPaper::draw(Painter &p, const QRect &r, TextSelection selection, crl::t
}
}
void WallPaper::validateThumbnail() const {
void ThemeDocument::validateThumbnail() const {
if (_thumbnailGood > 0) {
return;
}
@ -179,7 +189,7 @@ void WallPaper::validateThumbnail() const {
good->load({});
}
}
if (_thumbnailGood >= 0) {
if (_thumbnailGood >= 0 || !_data->thumbnail()) {
return;
}
if (_data->thumbnail()->loaded()) {
@ -191,11 +201,12 @@ void WallPaper::validateThumbnail() const {
}
}
void WallPaper::prepareThumbnailFrom(
void ThemeDocument::prepareThumbnailFrom(
not_null<Image*> image,
int good) const {
Expects(_thumbnailGood <= good);
const auto isTheme = _data->isTheme();
const auto isPattern = _data->isPatternWallPaper();
auto options = Images::Option::Smooth
| (good >= 0 ? Images::Option(0) : Images::Option::Blurred)
@ -203,8 +214,8 @@ void WallPaper::prepareThumbnailFrom(
? Images::Option::TransparentBackground
: Images::Option(0));
auto original = image->original();
auto tw = ConvertScale(_data->thumbnail()->width());
auto th = ConvertScale(_data->thumbnail()->height());
auto tw = isTheme ? _pixw : ConvertScale(_data->thumbnail()->width());
auto th = isTheme ? _pixh : ConvertScale(_data->thumbnail()->height());
if (!tw || !th) {
tw = th = 1;
}
@ -226,7 +237,7 @@ void WallPaper::prepareThumbnailFrom(
_thumbnailGood = good;
}
TextState WallPaper::textState(QPoint point, StateRequest request) const {
TextState ThemeDocument::textState(QPoint point, StateRequest request) const {
auto result = TextState(_parent);
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
@ -248,24 +259,24 @@ TextState WallPaper::textState(QPoint point, StateRequest request) const {
return result;
}
float64 WallPaper::dataProgress() const {
float64 ThemeDocument::dataProgress() const {
return _data->progress();
}
bool WallPaper::dataFinished() const {
bool ThemeDocument::dataFinished() const {
return !_data->loading()
&& (!_data->uploading() || _data->waitingForAlbum());
}
bool WallPaper::dataLoaded() const {
bool ThemeDocument::dataLoaded() const {
return _data->loaded();
}
bool WallPaper::isReadyForOpen() const {
bool ThemeDocument::isReadyForOpen() const {
return _data->loaded();
}
QString WallPaper::additionalInfoString() const {
QString ThemeDocument::additionalInfoString() const {
// This will force message info (time) to be displayed below
// this attachment in WebPage media.
static auto result = QString(" ");

View file

@ -11,9 +11,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
class WallPaper : public File {
class ThemeDocument : public File {
public:
WallPaper(
ThemeDocument(
not_null<Element*> parent,
not_null<DocumentData*> document,
const QString &url = QString());
@ -59,6 +59,8 @@ private:
int _pixh = 1;
mutable QPixmap _thumbnail;
mutable int _thumbnailGood = -1; // -1 inline, 0 thumbnail, 1 good
// For wallpaper documents.
QColor _background;
int _intensity = 0;

View file

@ -129,7 +129,9 @@ QSize WebPage::countOptimalSize() {
_openl = previewOfHiddenUrl
? std::make_shared<HiddenUrlClickHandler>(_data->url)
: std::make_shared<UrlClickHandler>(_data->url, true);
if (_data->document && _data->document->isWallPaper()) {
if (_data->document
&& (_data->document->isWallPaper()
|| _data->document->isTheme())) {
_openl = std::make_shared<DocumentWrappedClickHandler>(
std::move(_openl),
_data->document,
@ -652,7 +654,7 @@ ClickHandlerPtr WebPage::replaceAttachLink(
return link;
}
if (_data->document) {
if (_data->document->isWallPaper()) {
if (_data->document->isWallPaper() || _data->document->isTheme()) {
return _openl;
}
} else if (_data->photo) {
@ -674,7 +676,7 @@ TextSelection WebPage::adjustSelection(TextSelection selection, TextSelectType t
if ((!_titleLines && !_descriptionLines) || selection.to <= _siteName.length()) {
return _siteName.adjustSelection(selection, type);
}
auto titleSelection = _title.adjustSelection(toTitleSelection(selection), type);
if ((!_siteNameLines && !_descriptionLines) || (selection.from >= _siteName.length() && selection.to <= _description.length())) {
return fromTitleSelection(titleSelection);
@ -708,7 +710,7 @@ void WebPage::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed)
bool WebPage::enforceBubbleWidth() const {
return (_attach != nullptr)
&& (_data->document != nullptr)
&& _data->document->isWallPaper();
&& (_data->document->isWallPaper() || _data->document->isTheme());
}
void WebPage::playAnimation(bool autoplay) {
@ -779,6 +781,8 @@ int WebPage::bottomInfoPadding() const {
QString WebPage::displayedSiteName() const {
return (_data->document && _data->document->isWallPaper())
? tr::lng_media_chat_background(tr::now)
: (_data->document && _data->document->isWallPaper())
? tr::lng_media_color_theme(tr::now)
: _data->siteName;
}

View file

@ -2251,7 +2251,12 @@ void OverlayWidget::initThemePreview() {
const auto id = _themePreviewId = rand_value<uint64>();
const auto weak = make_weak(this);
crl::async([=, data = std::move(current)]() mutable {
auto preview = GeneratePreview(bytes, path, fields, std::move(data));
auto preview = GeneratePreview(
bytes,
path,
fields,
std::move(data),
Window::Theme::PreviewType::Extended);
crl::on_main(weak, [=, result = std::move(preview)]() mutable {
if (id != _themePreviewId) {
return;

View file

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "storage/file_download.h"
#include "storage/storage_media_prepare.h"
#include "window/themes/window_theme_preview.h"
#include "mainwidget.h"
#include "mainwindow.h"
#include "main/main_session.h"
@ -78,13 +79,6 @@ PreparedFileThumbnail PrepareFileThumbnail(QImage &&original) {
return result;
}
PreparedFileThumbnail PrepareAnimatedStickerThumbnail(
const QString &file,
const QByteArray &bytes) {
return PrepareFileThumbnail(
Lottie::ReadThumbnail(Lottie::ReadContent(bytes, file)));
}
bool FileThumbnailUploadRequired(const QString &filemime, int32 filesize) {
constexpr auto kThumbnailUploadBySize = 5 * 1024 * 1024;
const auto kThumbnailKnownMimes = {
@ -818,6 +812,15 @@ void FileLoadTask::process() {
}
thumbnail = PrepareFileThumbnail(std::move(video->thumbnail));
} else if (filemime == qstr("application/x-tdesktop-theme")
|| filemime == qstr("application/x-tgtheme-tdesktop")) {
goodThumbnail = Window::Theme::GeneratePreview(_content, _filepath);
if (!goodThumbnail.isNull()) {
QBuffer buffer(&goodThumbnailBytes);
goodThumbnail.save(&buffer, "JPG", kThumbnailQuality);
thumbnail = PrepareFileThumbnail(base::duplicate(goodThumbnail));
}
}
}

View file

@ -465,15 +465,26 @@ SendMediaReady PrepareThemeMedia(
PreparedPhotoThumbs thumbnails;
QVector<MTPPhotoSize> sizes;
//const auto push = [&](const char *type, QImage &&image) {
// sizes.push_back(MTP_photoSize(
// MTP_string(type),
// MTP_fileLocationToBeDeprecated(MTP_long(0), MTP_int(0)),
// MTP_int(image.width()),
// MTP_int(image.height()), MTP_int(0)));
// thumbnails.emplace(type[0], std::move(image));
//};
//push("s", scaled(320));
auto thumbnail = GeneratePreview(content, QString()).scaled(
320,
320,
Qt::KeepAspectRatio,
Qt::SmoothTransformation);
auto thumbnailBytes = QByteArray();
{
QBuffer buffer(&thumbnailBytes);
thumbnail.save(&buffer, "JPG", 87);
}
const auto push = [&](const char *type, QImage &&image) {
sizes.push_back(MTP_photoSize(
MTP_string(type),
MTP_fileLocationToBeDeprecated(MTP_long(0), MTP_int(0)),
MTP_int(image.width()),
MTP_int(image.height()), MTP_int(0)));
thumbnails.emplace(type[0], std::move(image));
};
push("s", std::move(thumbnail));
const auto filename = File::NameFromUserString(name)
+ qsl(".tdesktop-theme");
@ -506,7 +517,7 @@ SendMediaReady PrepareThemeMedia(
MTP_photoEmpty(MTP_long(0)),
thumbnails,
document,
QByteArray(),
thumbnailBytes,
0);
}
@ -520,7 +531,7 @@ Fn<void()> SavePreparedTheme(
Fn<void(SaveErrorType,QString)> fail) {
Expects(window->account().sessionExists());
using Storage::UploadedDocument;
using Storage::UploadedThumbDocument;
struct State {
FullMsgId id;
bool generating = false;
@ -539,6 +550,7 @@ Fn<void()> SavePreparedTheme(
const auto creating = !fields.id
|| (fields.createdBy != session->userId());
const auto oldDocumentId = creating ? 0 : fields.documentId;
const auto changed = (parsed.background != originalParsed.background)
|| (parsed.tiled != originalParsed.tiled)
|| PaletteChanged(parsed.palette, originalParsed.palette, fields);
@ -602,11 +614,11 @@ Fn<void()> SavePreparedTheme(
}).send();
};
const auto uploadTheme = [=](const UploadedDocument &data) {
const auto uploadTheme = [=](const UploadedThumbDocument &data) {
state->requestId = api->request(MTPaccount_UploadTheme(
MTP_flags(0),
MTP_flags(MTPaccount_UploadTheme::Flag::f_thumb),
data.file,
MTPInputFile(), // thumb
data.thumb,
MTP_string(state->filename),
MTP_string("application/x-tgtheme-tdesktop")
)).done([=](const MTPDocument &result) {
@ -625,10 +637,10 @@ Fn<void()> SavePreparedTheme(
state->filename = media.filename;
state->themeContent = theme;
session->uploader().documentReady(
) | rpl::filter([=](const UploadedDocument &data) {
session->uploader().thumbDocumentReady(
) | rpl::filter([=](const UploadedThumbDocument &data) {
return data.fullId == state->id;
}) | rpl::start_with_next([=](const UploadedDocument &data) {
}) | rpl::start_with_next([=](const UploadedThumbDocument &data) {
uploadTheme(data);
}, state->lifetime);

View file

@ -83,9 +83,12 @@ QString fillLetters(const QString &name) {
class Generator {
public:
Generator(const Instance &theme, CurrentData &&current);
Generator(
const Instance &theme,
CurrentData &&current,
PreviewType type);
QImage generate();
[[nodiscard]] QImage generate();
private:
enum class Status {
@ -131,6 +134,7 @@ private:
Ui::Text::String replyText = { st::msgMinWidth };
};
[[nodiscard]] bool extended() const;
void prepare();
void addRow(QString name, int peerIndex, QString date, QString text);
@ -162,7 +166,8 @@ private:
const Instance &_theme;
const style::palette &_palette;
CurrentData _current;
const CurrentData _current;
const PreviewType _type;
Painter *_p = nullptr;
QRect _rect;
@ -188,10 +193,19 @@ private:
};
bool Generator::extended() const {
return (_type == PreviewType::Extended);
}
void Generator::prepare() {
_rect = QRect(0, 0, st::themePreviewMargin.left() + st::themePreviewSize.width() + st::themePreviewMargin.right(), st::themePreviewMargin.top() + st::themePreviewSize.height() + st::themePreviewMargin.bottom());
_inner = _rect.marginsRemoved(st::themePreviewMargin);
_body = _inner.marginsRemoved(QMargins(0, Platform::PreviewTitleHeight(), 0, 0));
const auto size = extended()
? QRect(
QPoint(),
st::themePreviewSize).marginsAdded(st::themePreviewMargin).size()
: st::themePreviewSize;
_rect = QRect(QPoint(), size);
_inner = extended() ? _rect.marginsRemoved(st::themePreviewMargin) : _rect;
_body = extended() ? _inner.marginsRemoved(QMargins(0, Platform::PreviewTitleHeight(), 0, 0)) : _inner;
_dialogs = QRect(_body.x(), _body.y(), st::themePreviewDialogsWidth, _body.height());
_dialogsList = _dialogs.marginsRemoved(QMargins(0, st::dialogsFilterPadding.y() + st::dialogsMenuToggle.height + st::dialogsFilterPadding.y(), 0, st::dialogsPadding.y()));
_topBar = QRect(_dialogs.x() + _dialogs.width(), _dialogs.y(), _body.width() - _dialogs.width(), st::topBarHeight);
@ -339,10 +353,14 @@ void Generator::generateData() {
_bubbles.back().replyText.setText(st::messageTextStyle, "Mark Twain said that " + QString() + QChar(9757) + QChar(55356) + QChar(57339), Ui::DialogTextOptions());
}
Generator::Generator(const Instance &theme, CurrentData &&current)
Generator::Generator(
const Instance &theme,
CurrentData &&current,
PreviewType type)
: _theme(theme)
, _palette(_theme.palette)
, _current(std::move(current)) {
, _current(std::move(current))
, _type(type) {
}
QImage Generator::generate() {
@ -368,7 +386,9 @@ QImage Generator::generate() {
paintDialogs();
paintHistoryShadows();
}
Platform::PreviewWindowFramePaint(result, _palette, _body, _rect.width());
if (extended()) {
Platform::PreviewWindowFramePaint(result, _palette, _body, _rect.width());
}
return result;
}
@ -944,18 +964,32 @@ std::unique_ptr<Preview> GeneratePreview(
const QByteArray &bytes,
const QString &filepath,
const Data::CloudTheme &cloud,
CurrentData &&data) {
CurrentData &&data,
PreviewType type) {
auto result = PreviewFromFile(bytes, filepath, cloud);
if (!result) {
return nullptr;
}
result->preview = Generator(
result->instance,
std::move(data)
std::move(data),
type
).generate();
return result;
}
QImage GeneratePreview(
const QByteArray &bytes,
const QString &filepath) {
const auto preview = GeneratePreview(
bytes,
filepath,
Data::CloudTheme(),
CurrentData{ Data::ThemeWallPaper().id() },
PreviewType::Normal);
return preview ? preview->preview : QImage();
}
int DefaultPreviewTitleHeight() {
return st::titleHeight;
}

View file

@ -17,11 +17,16 @@ namespace Window {
namespace Theme {
struct CurrentData {
int32 backgroundId = 0;
WallPaperId backgroundId = 0;
QImage backgroundImage;
bool backgroundTiled = false;
};
enum class PreviewType {
Normal,
Extended,
};
[[nodiscard]] QString CachedThemePath(uint64 documentId);
std::unique_ptr<Preview> PreviewFromFile(
@ -32,7 +37,11 @@ std::unique_ptr<Preview> GeneratePreview(
const QByteArray &bytes,
const QString &filepath,
const Data::CloudTheme &cloud,
CurrentData &&data);
CurrentData &&data,
PreviewType type);
QImage GeneratePreview(
const QByteArray &bytes,
const QString &filepath);
int DefaultPreviewTitleHeight();
void DefaultPreviewWindowFramePaint(

View file

@ -316,10 +316,10 @@
<(src_loc)/history/view/media/history_view_poll.cpp
<(src_loc)/history/view/media/history_view_sticker.h
<(src_loc)/history/view/media/history_view_sticker.cpp
<(src_loc)/history/view/media/history_view_theme_document.h
<(src_loc)/history/view/media/history_view_theme_document.cpp
<(src_loc)/history/view/media/history_view_video.h
<(src_loc)/history/view/media/history_view_video.cpp
<(src_loc)/history/view/media/history_view_wall_paper.h
<(src_loc)/history/view/media/history_view_wall_paper.cpp
<(src_loc)/history/view/media/history_view_web_page.h
<(src_loc)/history/view/media/history_view_web_page.cpp
<(src_loc)/history/view/history_view_compose_controls.cpp