Added stickerset preview to webpages.

This commit is contained in:
23rd 2024-04-18 21:24:40 +03:00 committed by John Preston
parent f43f99cff2
commit ed13a325e9
5 changed files with 80 additions and 7 deletions

View file

@ -4729,6 +4729,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_view_button_boost" = "Boost";
"lng_view_button_giftcode" = "Open";
"lng_view_button_iv" = "Instant View";
"lng_view_button_stickerset" = "View stickers";
"lng_view_button_emojipack" = "View emoji";
"lng_sponsored_hide_ads" = "Hide";
"lng_sponsored_title" = "What are sponsored messages?";

View file

@ -137,6 +137,10 @@ bool Sticker::emojiSticker() const {
return _emojiSticker;
}
bool Sticker::webpagePart() const {
return _webpagePart;
}
void Sticker::initSize(int customSize) {
if (customSize > 0) {
const auto original = Size(_data);
@ -355,6 +359,8 @@ void Sticker::paintPath(
helper.emplace(Ui::CustomEmoji::PreviewColorFromTextColor(
ComputeEmojiTextColor(context)));
pathGradient->overrideColors(helper->color(), helper->color());
} else if (webpagePart()) {
pathGradient->overrideColors(st::shadowFg, st::shadowFg);
} else if (context.selected()) {
pathGradient->overrideColors(
context.st->msgServiceBgSelected(),
@ -513,6 +519,10 @@ void Sticker::setEmojiSticker() {
_emojiSticker = true;
}
void Sticker::setWebpagePart() {
_webpagePart = true;
}
void Sticker::setupPlayer() {
Expects(_dataMedia != nullptr);

View file

@ -69,6 +69,7 @@ public:
void setCustomCachingTag(ChatHelpers::StickerLottieSize tag);
void setCustomEmojiPart();
void setEmojiSticker();
void setWebpagePart();
[[nodiscard]] bool atTheEnd() const {
return (_frameIndex >= 0) && (_frameIndex + 1 == _framesCount);
}
@ -98,6 +99,7 @@ private:
[[nodiscard]] bool hasPremiumEffect() const;
[[nodiscard]] bool customEmojiPart() const;
[[nodiscard]] bool emojiSticker() const;
[[nodiscard]] bool webpagePart() const;
void paintAnimationFrame(
Painter &p,
const PaintContext &context,
@ -137,6 +139,7 @@ private:
bool _skipPremiumEffect : 1 = false;
bool _customEmojiPart : 1 = false;
bool _emojiSticker : 1 = false;
bool _webpagePart : 1 = false;
};

View file

@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_reply.h"
#include "history/view/history_view_sponsored_click_handler.h"
#include "history/view/media/history_view_media_common.h"
#include "history/view/media/history_view_sticker.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
#include "menu/menu_sponsored.h"
@ -179,6 +180,10 @@ constexpr auto kMaxOriginalEntryLines = 8192;
? tr::lng_view_button_user(tr::now)
: (type == WebPageType::BotApp)
? tr::lng_view_button_bot_app(tr::now)
: (page->stickerSet && page->stickerSet->isEmoji)
? tr::lng_view_button_emojipack(tr::now)
: (type == WebPageType::StickerSet)
? tr::lng_view_button_stickerset(tr::now)
: QString());
if (page->iv) {
const auto manager = &page->owner().customEmojiManager();
@ -211,7 +216,8 @@ constexpr auto kMaxOriginalEntryLines = 8192;
&& (webpage->photo || webpage->document))
|| ((type == WebPageType::WallPaper)
&& webpage->document
&& webpage->document->isWallPaper());
&& webpage->document->isWallPaper())
|| (type == WebPageType::StickerSet);
}
} // namespace
@ -285,6 +291,24 @@ QSize WebPage::countOptimalSize() {
}
const auto lineHeight = UnitedLineHeight();
if (_data->stickerSet && !_stickerSet) {
_stickerSet = std::make_unique<StickerSet>();
for (const auto &sticker : _data->stickerSet->items) {
if (!sticker->sticker()) {
continue;
}
_stickerSet->views.push_back(
std::make_unique<Sticker>(_parent, sticker, true));
}
const auto side = std::ceil(_stickerSet->views.size() / 2.);
const auto box = lineHeight * 2;
const auto single = box / side;
for (const auto &view : _stickerSet->views) {
view->setWebpagePart();
view->initSize(single);
}
}
if (!_openl && (!_data->url.isEmpty() || _sponsoredData)) {
const auto original = _parent->data()->originalText();
const auto previewOfHiddenUrl = [&] {
@ -510,21 +534,22 @@ QSize WebPage::countCurrentSize(int newWidth) {
const auto innerWidth = newWidth - rect::m::sum::h(padding);
auto newHeight = 0;
const auto specialRightPix = (_sponsoredData || _stickerSet);
const auto lineHeight = UnitedLineHeight();
const auto linesMax = (_sponsoredData || isLogEntryOriginal())
const auto linesMax = (specialRightPix || isLogEntryOriginal())
? kMaxOriginalEntryLines
: 5;
const auto siteNameHeight = _siteNameLines ? lineHeight : 0;
const auto twoTitleLines = 2 * st::webPageTitleFont->height;
const auto descriptionLineHeight = st::webPageDescriptionFont->height;
const auto asSponsored = (!!_sponsoredData);
if (asArticle() || asSponsored) {
const auto sponsoredUserpic = (asSponsored && _sponsoredData->peer);
if (asArticle() || specialRightPix) {
const auto sponsoredUserpic = (_sponsoredData
&& _sponsoredData->peer);
constexpr auto kSponsoredUserpicLines = 2;
_pixh = lineHeight
* (asSponsored ? kSponsoredUserpicLines : linesMax);
* (specialRightPix ? kSponsoredUserpicLines : linesMax);
do {
_pixw = asSponsored
_pixw = specialRightPix
? _pixh
: ArticleThumbWidth(_data->photo, _pixh);
const auto wleft = innerWidth
@ -644,6 +669,7 @@ void WebPage::ensurePhotoMediaCreated() const {
bool WebPage::hasHeavyPart() const {
return _photoMedia
|| (_sponsoredData && !_sponsoredData->userpicView.null())
|| (_stickerSet)
|| (_attach ? _attach->hasHeavyPart() : false);
}
@ -727,6 +753,30 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
}
auto lineHeight = UnitedLineHeight();
if (_stickerSet) {
const auto viewsCount = _stickerSet->views.size();
const auto topLeft = QPoint(inner.left() + paintw - _pixh, tshift);
const auto side = std::ceil(viewsCount / 2.);
const auto box = lineHeight * 2;
const auto single = box / side;
for (auto i = 0; i < side; i++) {
for (auto j = 0; j < side; j++) {
const auto index = i * side + j;
if (viewsCount <= index) {
break;
}
const auto &view = _stickerSet->views[index];
const auto size = view->countOptimalSize();
const auto offsetX = (single - size.width()) / 2.;
const auto offsetY = (single - size.height()) / 2.;
const auto x = j * size.width() + offsetX;
const auto y = i * size.height() + offsetY;
const auto w = size.width();
const auto h = size.height();
view->draw(p, context, QRect(QPoint(x, y) + topLeft, size));
}
}
}
if (asArticle()) {
ensurePhotoMediaCreated();

View file

@ -21,6 +21,8 @@ class RippleAnimation;
namespace HistoryView {
class Sticker;
class WebPage : public Media {
public:
WebPage(
@ -130,6 +132,12 @@ private:
mutable std::shared_ptr<Data::PhotoMedia> _photoMedia;
mutable std::unique_ptr<Ui::RippleAnimation> _ripple;
struct StickerSet final {
std::vector<std::unique_ptr<Sticker>> views;
};
std::unique_ptr<StickerSet> _stickerSet;
struct SponsoredData final {
PeerData *peer = nullptr;
Ui::PeerUserpicView userpicView;