Support by-emoji background resolve in preview.

This commit is contained in:
John Preston 2023-12-20 21:44:34 -04:00
parent 41ae1f56ed
commit d5a1c354d0
4 changed files with 86 additions and 49 deletions

View File

@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/cached_round_corners.h"
#include "ui/painter.h"
#include "ui/ui_utility.h"
#include "window/section_widget.h"
#include "window/window_session_controller.h"
#include "window/themes/window_theme.h"
#include "styles/style_chat.h"
@ -471,13 +472,28 @@ ThemeDocumentBox::ThemeDocumentBox(
not_null<Element*> parent,
const Data::WallPaper &paper)
: _parent(parent)
, _preview(
parent,
, _emojiId(paper.emojiId()) {
Window::WallPaperResolved(
&_parent->history()->owner(),
&paper
) | rpl::start_with_next([=](const Data::WallPaper *paper) {
_parent->repaint();
if (!paper) {
_preview.reset();
} else {
createPreview(*paper);
}
}, _lifetime);
}
void ThemeDocumentBox::createPreview(const Data::WallPaper &paper) {
_preview.emplace(
_parent,
paper.document(),
paper,
st::msgServicePhotoWidth) {
_preview.initDimensions();
_preview.resizeGetHeight(_preview.maxWidth());
st::msgServicePhotoWidth);
_preview->initDimensions();
_preview->resizeGetHeight(_preview->maxWidth());
}
ThemeDocumentBox::~ThemeDocumentBox() = default;
@ -487,7 +503,9 @@ int ThemeDocumentBox::top() {
}
QSize ThemeDocumentBox::size() {
return { _preview.maxWidth(), _preview.minHeight() };
return _preview
? QSize(_preview->maxWidth(), _preview->minHeight())
: QSize(st::msgServicePhotoWidth, st::msgServicePhotoWidth);
}
QString ThemeDocumentBox::title() {
@ -560,9 +578,11 @@ void ThemeDocumentBox::draw(
Painter &p,
const PaintContext &context,
const QRect &geometry) {
p.translate(geometry.topLeft());
_preview.draw(p, context);
p.translate(-geometry.topLeft());
if (_preview) {
p.translate(geometry.topLeft());
_preview->draw(p, context);
p.translate(-geometry.topLeft());
}
}
void ThemeDocumentBox::stickerClearLoopPlayed() {
@ -575,11 +595,13 @@ std::unique_ptr<StickerPlayer> ThemeDocumentBox::stickerTakePlayer(
}
bool ThemeDocumentBox::hasHeavyPart() {
return _preview.hasHeavyPart();
return _preview && _preview->hasHeavyPart();
}
void ThemeDocumentBox::unloadHeavyPart() {
_preview.unloadHeavyPart();
if (_preview) {
_preview->unloadHeavyPart();
}
}
} // namespace HistoryView

View File

@ -119,8 +119,12 @@ public:
void unloadHeavyPart() override;
private:
void createPreview(const Data::WallPaper &paper);
const not_null<Element*> _parent;
ThemeDocument _preview;
QString _emojiId;
std::optional<ThemeDocument> _preview;
rpl::lifetime _lifetime;
};

View File

@ -56,43 +56,7 @@ struct ResolvedPaper {
peer,
Data::PeerUpdate::Flag::ChatWallPaper
) | rpl::map([=]() -> rpl::producer<const Data::WallPaper*> {
const auto paper = peer->wallPaper();
const auto id = paper ? paper->emojiId() : QString();
if (id.isEmpty()) {
return rpl::single(paper);
}
const auto themes = &peer->owner().cloudThemes();
auto fromThemes = [=](bool force)
-> rpl::producer<const Data::WallPaper*> {
if (themes->chatThemes().empty() && !force) {
return nullptr;
}
return Window::Theme::IsNightModeValue(
) | rpl::map([=](bool dark) -> const Data::WallPaper* {
const auto &list = themes->chatThemes();
const auto i = ranges::find(
list,
id,
&Data::CloudTheme::emoticon);
if (i != end(list)) {
using Type = Data::CloudThemeType;
const auto type = dark ? Type::Dark : Type::Light;
const auto j = i->settings.find(type);
if (j != end(i->settings) && j->second.paper) {
return &*j->second.paper;
}
}
return nullptr;
});
};
if (auto result = fromThemes(false)) {
return result;
}
themes->refreshChatThemes();
return themes->chatThemesUpdated(
) | rpl::take(1) | rpl::map([=] {
return fromThemes(true);
}) | rpl::flatten_latest();
return WallPaperResolved(&peer->owner(), peer->wallPaper());
}) | rpl::flatten_latest();
}
@ -202,6 +166,47 @@ struct ResolvedTheme {
} // namespace
rpl::producer<const Data::WallPaper*> WallPaperResolved(
not_null<Data::Session*> owner,
const Data::WallPaper *paper) {
const auto id = paper ? paper->emojiId() : QString();
if (id.isEmpty()) {
return rpl::single(paper);
}
const auto themes = &owner->cloudThemes();
auto fromThemes = [=](bool force)
-> rpl::producer<const Data::WallPaper*> {
if (themes->chatThemes().empty() && !force) {
return nullptr;
}
return Window::Theme::IsNightModeValue(
) | rpl::map([=](bool dark) -> const Data::WallPaper* {
const auto &list = themes->chatThemes();
const auto i = ranges::find(
list,
id,
&Data::CloudTheme::emoticon);
if (i != end(list)) {
using Type = Data::CloudThemeType;
const auto type = dark ? Type::Dark : Type::Light;
const auto j = i->settings.find(type);
if (j != end(i->settings) && j->second.paper) {
return &*j->second.paper;
}
}
return nullptr;
});
};
if (auto result = fromThemes(false)) {
return result;
}
themes->refreshChatThemes();
return themes->chatThemesUpdated(
) | rpl::take(1) | rpl::map([=] {
return fromThemes(true);
}) | rpl::flatten_latest();
}
AbstractSectionWidget::AbstractSectionWidget(
QWidget *parent,
not_null<SessionController*> controller,

View File

@ -23,6 +23,8 @@ class Show;
namespace Data {
struct ReactionId;
class ForumTopic;
class WallPaper;
class Session;
} // namespace Data
namespace Main {
@ -251,4 +253,8 @@ private:
not_null<HistoryItem*> item,
const Data::ReactionId &id);
[[nodiscard]] rpl::producer<const Data::WallPaper*> WallPaperResolved(
not_null<Data::Session*> owner,
const Data::WallPaper *paper);
} // namespace Window