mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Use MediaInBubble for chat intro fake-message.
This commit is contained in:
parent
0887348611
commit
5381fe5a1a
5 changed files with 277 additions and 54 deletions
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "history/view/media/history_view_giveaway.h"
|
||||||
#include "history/view/media/history_view_service_box.h"
|
#include "history/view/media/history_view_service_box.h"
|
||||||
#include "history/view/media/history_view_sticker_player_abstract.h"
|
#include "history/view/media/history_view_sticker_player_abstract.h"
|
||||||
#include "history/view/media/history_view_sticker.h"
|
#include "history/view/media/history_view_sticker.h"
|
||||||
|
@ -106,6 +107,49 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto GenerateChatIntro(
|
||||||
|
not_null<Element*> parent,
|
||||||
|
Element *replacing,
|
||||||
|
const Data::ChatIntro &data)
|
||||||
|
-> Fn<void(Fn<void(std::unique_ptr<MediaInBubble::Part>)>)> {
|
||||||
|
return [=](Fn<void(std::unique_ptr<MediaInBubble::Part>)> push) {
|
||||||
|
auto pushText = [&](
|
||||||
|
TextWithEntities text,
|
||||||
|
QMargins margins = {},
|
||||||
|
const base::flat_map<uint16, ClickHandlerPtr> &links = {}) {
|
||||||
|
if (text.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
push(std::make_unique<TextMediaInBubblePart>(
|
||||||
|
std::move(text),
|
||||||
|
margins,
|
||||||
|
links));
|
||||||
|
};
|
||||||
|
const auto title = data
|
||||||
|
? data.title
|
||||||
|
: tr::lng_chat_intro_default_title(tr::now);
|
||||||
|
const auto description = data
|
||||||
|
? data.description
|
||||||
|
: tr::lng_chat_intro_default_message(tr::now);
|
||||||
|
pushText(Ui::Text::Bold(title), st::chatIntroTitleMargin);
|
||||||
|
pushText({ description }, title.isEmpty()
|
||||||
|
? st::chatIntroTitleMargin
|
||||||
|
: st::chatIntroMargin);
|
||||||
|
const auto sticker = [=] {
|
||||||
|
using Tag = ChatHelpers::StickerLottieSize;
|
||||||
|
return StickerInBubblePart::Data{
|
||||||
|
.sticker = data.sticker,
|
||||||
|
.size = st::chatIntroStickerSize,
|
||||||
|
.cacheTag = Tag::ChatIntroHelloSticker,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
push(std::make_unique<StickerInBubblePart>(
|
||||||
|
parent,
|
||||||
|
replacing,
|
||||||
|
sticker));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
PremiumRequiredBox::PremiumRequiredBox(not_null<Element*> parent)
|
PremiumRequiredBox::PremiumRequiredBox(not_null<Element*> parent)
|
||||||
: _parent(parent) {
|
: _parent(parent) {
|
||||||
}
|
}
|
||||||
|
@ -330,13 +374,18 @@ void AboutView::make(Data::ChatIntro data) {
|
||||||
| MessageFlag::FakeHistoryItem
|
| MessageFlag::FakeHistoryItem
|
||||||
| MessageFlag::Local),
|
| MessageFlag::Local),
|
||||||
.from = _history->peer->id,
|
.from = _history->peer->id,
|
||||||
}, PreparedServiceText{ { data.description } });
|
}, PreparedServiceText{ { } });
|
||||||
|
|
||||||
setItem(AdminLog::OwnedItem(_delegate, item), data.sticker);
|
auto owned = AdminLog::OwnedItem(_delegate, item);
|
||||||
|
owned->overrideMedia(std::make_unique<HistoryView::MediaInBubble>(
|
||||||
_item->overrideMedia(std::make_unique<ServiceBox>(
|
owned.get(),
|
||||||
_item.get(),
|
GenerateChatIntro(owned.get(), _item.get(), data),
|
||||||
std::make_unique<ChatIntroBox>(_item.get(), data)));
|
HistoryView::MediaInBubbleDescriptor{
|
||||||
|
.maxWidth = st::chatIntroWidth,
|
||||||
|
.service = true,
|
||||||
|
.hideServiceText = true,
|
||||||
|
}));
|
||||||
|
setItem(std::move(owned), data.sticker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AboutView::setItem(AdminLog::OwnedItem item, DocumentData *sticker) {
|
void AboutView::setItem(AdminLog::OwnedItem item, DocumentData *sticker) {
|
||||||
|
|
|
@ -632,6 +632,4 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr auto size = sizeof(Element);
|
|
||||||
|
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
|
@ -73,10 +73,21 @@ bool MediaInBubble::Part::hasHeavyPart() {
|
||||||
void MediaInBubble::Part::unloadHeavyPart() {
|
void MediaInBubble::Part::unloadHeavyPart() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto MediaInBubble::Part::stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements
|
||||||
|
) -> std::unique_ptr<StickerPlayer> {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
MediaInBubble::MediaInBubble(
|
MediaInBubble::MediaInBubble(
|
||||||
not_null<Element*> parent,
|
not_null<Element*> parent,
|
||||||
Fn<void(Fn<void(std::unique_ptr<Part>)>)> generate)
|
Fn<void(Fn<void(std::unique_ptr<Part>)>)> generate,
|
||||||
: Media(parent) {
|
MediaInBubbleDescriptor &&descriptor)
|
||||||
|
: Media(parent)
|
||||||
|
, _maxWidthCap(descriptor.maxWidth)
|
||||||
|
, _service(descriptor.service)
|
||||||
|
, _hideServiceText(descriptor.hideServiceText) {
|
||||||
generate([&](std::unique_ptr<Part> part) {
|
generate([&](std::unique_ptr<Part> part) {
|
||||||
_entries.push_back({
|
_entries.push_back({
|
||||||
.object = std::move(part),
|
.object = std::move(part),
|
||||||
|
@ -92,7 +103,9 @@ MediaInBubble::~MediaInBubble() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize MediaInBubble::countOptimalSize() {
|
QSize MediaInBubble::countOptimalSize() {
|
||||||
const auto maxWidth = st::chatGiveawayWidth;
|
const auto maxWidth = _maxWidthCap
|
||||||
|
? _maxWidthCap
|
||||||
|
: st::chatGiveawayWidth;
|
||||||
|
|
||||||
auto top = 0;
|
auto top = 0;
|
||||||
for (auto &entry : _entries) {
|
for (auto &entry : _entries) {
|
||||||
|
@ -104,19 +117,26 @@ QSize MediaInBubble::countOptimalSize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize MediaInBubble::countCurrentSize(int newWidth) {
|
QSize MediaInBubble::countCurrentSize(int newWidth) {
|
||||||
return { maxWidth(), minHeight()};
|
return { maxWidth(), minHeight() };
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaInBubble::draw(Painter &p, const PaintContext &context) const {
|
void MediaInBubble::draw(Painter &p, const PaintContext &context) const {
|
||||||
const auto outer = width();
|
const auto outer = width();
|
||||||
if (outer < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
if (outer < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
const auto radius = st::msgServiceGiftBoxRadius;
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(context.st->msgServiceBg());
|
||||||
|
p.drawRoundedRect(QRect(0, 0, width(), height()), radius, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto translated = 0;
|
auto translated = 0;
|
||||||
for (const auto &entry : _entries) {
|
for (const auto &entry : _entries) {
|
||||||
const auto raw = entry.object.get();
|
const auto raw = entry.object.get();
|
||||||
const auto height = raw->height();
|
const auto height = raw->height();
|
||||||
raw->draw(p, context, outer);
|
raw->draw(p, this, context, outer);
|
||||||
translated += height;
|
translated += height;
|
||||||
p.translate(0, height);
|
p.translate(0, height);
|
||||||
}
|
}
|
||||||
|
@ -159,10 +179,28 @@ void MediaInBubble::clickHandlerPressedChanged(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<StickerPlayer> MediaInBubble::stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements) {
|
||||||
|
for (const auto &entry : _entries) {
|
||||||
|
if (auto result = entry.object->stickerTakePlayer(
|
||||||
|
data,
|
||||||
|
replacements)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool MediaInBubble::hideFromName() const {
|
bool MediaInBubble::hideFromName() const {
|
||||||
return !parent()->data()->Has<HistoryMessageForwarded>();
|
return !parent()->data()->Has<HistoryMessageForwarded>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MediaInBubble::hideServiceText() const {
|
||||||
|
return _hideServiceText;
|
||||||
|
}
|
||||||
|
|
||||||
bool MediaInBubble::hasHeavyPart() const {
|
bool MediaInBubble::hasHeavyPart() const {
|
||||||
for (const auto &entry : _entries) {
|
for (const auto &entry : _entries) {
|
||||||
if (entry.object->hasHeavyPart()) {
|
if (entry.object->hasHeavyPart()) {
|
||||||
|
@ -200,15 +238,21 @@ TextMediaInBubblePart::TextMediaInBubblePart(
|
||||||
|
|
||||||
void TextMediaInBubblePart::draw(
|
void TextMediaInBubblePart::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const {
|
int outerWidth) const {
|
||||||
p.setPen(context.messageStyle()->historyTextFg);
|
const auto service = owner->service();
|
||||||
|
p.setPen(service
|
||||||
|
? context.st->msgServiceFg()
|
||||||
|
: context.messageStyle()->historyTextFg);
|
||||||
_text.draw(p, {
|
_text.draw(p, {
|
||||||
.position = { (outerWidth - width()) / 2, _margins.top() },
|
.position = { (outerWidth - width()) / 2, _margins.top() },
|
||||||
.outerWidth = outerWidth,
|
.outerWidth = outerWidth,
|
||||||
.availableWidth = width(),
|
.availableWidth = width(),
|
||||||
.align = style::al_top,
|
.align = style::al_top,
|
||||||
.palette = &context.messageStyle()->textPalette,
|
.palette = &(service
|
||||||
|
? context.st->serviceTextPalette()
|
||||||
|
: context.messageStyle()->textPalette),
|
||||||
.now = context.now,
|
.now = context.now,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -253,6 +297,7 @@ TextDelimeterPart::TextDelimeterPart(
|
||||||
|
|
||||||
void TextDelimeterPart::draw(
|
void TextDelimeterPart::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const {
|
int outerWidth) const {
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
|
@ -294,18 +339,18 @@ QSize TextDelimeterPart::countCurrentSize(int newWidth) {
|
||||||
return { newWidth, minHeight() };
|
return { newWidth, minHeight() };
|
||||||
}
|
}
|
||||||
|
|
||||||
StickerWithBadgePart::StickerWithBadgePart(
|
StickerInBubblePart::StickerInBubblePart(
|
||||||
not_null<Element*> parent,
|
not_null<Element*> parent,
|
||||||
Fn<Data()> lookup,
|
Element *replacing,
|
||||||
QString badge)
|
Fn<Data()> lookup)
|
||||||
: _parent(parent)
|
: _parent(parent)
|
||||||
, _lookup(std::move(lookup))
|
, _lookup(std::move(lookup)) {
|
||||||
, _badgeText(badge) {
|
ensureCreated(replacing);
|
||||||
ensureCreated();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerWithBadgePart::draw(
|
void StickerInBubblePart::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const {
|
int outerWidth) const {
|
||||||
const auto stickerSize = st::msgServiceGiftBoxStickerSize;
|
const auto stickerSize = st::msgServiceGiftBoxStickerSize;
|
||||||
|
@ -314,51 +359,99 @@ void StickerWithBadgePart::draw(
|
||||||
st::chatGiveawayStickerTop + _skipTop,
|
st::chatGiveawayStickerTop + _skipTop,
|
||||||
stickerSize,
|
stickerSize,
|
||||||
stickerSize);
|
stickerSize);
|
||||||
|
ensureCreated();
|
||||||
if (_sticker) {
|
if (_sticker) {
|
||||||
_sticker->draw(p, context, sticker);
|
_sticker->draw(p, context, sticker);
|
||||||
paintBadge(p, context);
|
|
||||||
} else {
|
|
||||||
ensureCreated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StickerWithBadgePart::hasHeavyPart() {
|
bool StickerInBubblePart::hasHeavyPart() {
|
||||||
return _sticker && _sticker->hasHeavyPart();
|
return _sticker && _sticker->hasHeavyPart();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerWithBadgePart::unloadHeavyPart() {
|
void StickerInBubblePart::unloadHeavyPart() {
|
||||||
if (_sticker) {
|
if (_sticker) {
|
||||||
_sticker->unloadHeavyPart();
|
_sticker->unloadHeavyPart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize StickerWithBadgePart::countOptimalSize() {
|
std::unique_ptr<StickerPlayer> StickerInBubblePart::stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements) {
|
||||||
|
return _sticker
|
||||||
|
? _sticker->stickerTakePlayer(data, replacements)
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize StickerInBubblePart::countOptimalSize() {
|
||||||
const auto size = st::msgServiceGiftBoxStickerSize;
|
const auto size = st::msgServiceGiftBoxStickerSize;
|
||||||
return { size, st::chatGiveawayStickerTop + size };
|
return { size, st::chatGiveawayStickerTop + size };
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize StickerWithBadgePart::countCurrentSize(int newWidth) {
|
QSize StickerInBubblePart::countCurrentSize(int newWidth) {
|
||||||
return { newWidth, minHeight() };
|
return { newWidth, minHeight() };
|
||||||
}
|
}
|
||||||
|
|
||||||
void StickerWithBadgePart::ensureCreated() const {
|
void StickerInBubblePart::ensureCreated(Element *replacing) const {
|
||||||
if (_sticker) {
|
if (_sticker) {
|
||||||
return;
|
return;
|
||||||
} else if (const auto data = _lookup()) {
|
} else if (const auto data = _lookup()) {
|
||||||
const auto document = data.sticker;
|
const auto sticker = data.sticker;
|
||||||
if (const auto sticker = document->sticker()) {
|
if (const auto info = sticker->sticker()) {
|
||||||
const auto skipPremiumEffect = false;
|
const auto skipPremiumEffect = true;
|
||||||
_skipTop = data.skipTop;
|
_skipTop = data.skipTop;
|
||||||
_sticker.emplace(_parent, document, skipPremiumEffect, _parent);
|
_sticker.emplace(_parent, sticker, skipPremiumEffect, replacing);
|
||||||
_sticker->setDiceIndex(sticker->alt, 1);
|
if (data.singleTimePlayback) {
|
||||||
_sticker->initSize(data.isGiftBoxSticker
|
_sticker->setDiceIndex(info->alt, 1);
|
||||||
? st::msgServiceGiftBoxStickerSize
|
}
|
||||||
: 0);
|
_sticker->initSize(data.size);
|
||||||
|
_sticker->setCustomCachingTag(data.cacheTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StickerWithBadgePart::StickerWithBadgePart(
|
||||||
|
not_null<Element*> parent,
|
||||||
|
Element *replacing,
|
||||||
|
Fn<Data()> lookup,
|
||||||
|
QString badge)
|
||||||
|
: _sticker(parent, replacing, std::move(lookup))
|
||||||
|
, _badgeText(badge) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerWithBadgePart::draw(
|
||||||
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
|
const PaintContext &context,
|
||||||
|
int outerWidth) const {
|
||||||
|
_sticker.draw(p, owner, context, outerWidth);
|
||||||
|
if (_sticker.resolved()) {
|
||||||
|
paintBadge(p, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StickerWithBadgePart::hasHeavyPart() {
|
||||||
|
return _sticker.hasHeavyPart();
|
||||||
|
}
|
||||||
|
|
||||||
|
void StickerWithBadgePart::unloadHeavyPart() {
|
||||||
|
_sticker.unloadHeavyPart();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<StickerPlayer> StickerWithBadgePart::stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements) {
|
||||||
|
return _sticker.stickerTakePlayer(data, replacements);
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize StickerWithBadgePart::countOptimalSize() {
|
||||||
|
return _sticker.countOptimalSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize StickerWithBadgePart::countCurrentSize(int newWidth) {
|
||||||
|
return _sticker.countCurrentSize(newWidth);
|
||||||
|
}
|
||||||
|
|
||||||
void StickerWithBadgePart::paintBadge(
|
void StickerWithBadgePart::paintBadge(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
const PaintContext &context) const {
|
const PaintContext &context) const {
|
||||||
|
@ -383,7 +476,7 @@ void StickerWithBadgePart::paintBadge(
|
||||||
p.drawRoundedRect(inner, radius, radius);
|
p.drawRoundedRect(inner, radius, radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_parent->usesBubblePattern(context)) {
|
if (!_sticker.parent()->usesBubblePattern(context)) {
|
||||||
paintContent(p);
|
paintContent(p);
|
||||||
} else {
|
} else {
|
||||||
Ui::PaintPatternBubblePart(
|
Ui::PaintPatternBubblePart(
|
||||||
|
@ -458,6 +551,7 @@ PeerBubbleListPart::~PeerBubbleListPart() = default;
|
||||||
|
|
||||||
void PeerBubbleListPart::draw(
|
void PeerBubbleListPart::draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const {
|
int outerWidth) const {
|
||||||
if (_peers.empty()) {
|
if (_peers.empty()) {
|
||||||
|
@ -647,10 +741,15 @@ auto GenerateGiveawayStart(
|
||||||
const auto sticker = [=] {
|
const auto sticker = [=] {
|
||||||
const auto &session = parent->history()->session();
|
const auto &session = parent->history()->session();
|
||||||
auto &packs = session.giftBoxStickersPacks();
|
auto &packs = session.giftBoxStickersPacks();
|
||||||
return Data{ packs.lookup(months), 0, true };
|
return Data{
|
||||||
|
.sticker = packs.lookup(months),
|
||||||
|
.size = st::msgServiceGiftBoxStickerSize,
|
||||||
|
.singleTimePlayback = true,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
push(std::make_unique<StickerWithBadgePart>(
|
push(std::make_unique<StickerWithBadgePart>(
|
||||||
parent,
|
parent,
|
||||||
|
nullptr,
|
||||||
sticker,
|
sticker,
|
||||||
tr::lng_prizes_badge(
|
tr::lng_prizes_badge(
|
||||||
tr::now,
|
tr::now,
|
||||||
|
@ -778,11 +877,15 @@ auto GenerateGiveawayResults(
|
||||||
const auto &session = parent->history()->session();
|
const auto &session = parent->history()->session();
|
||||||
auto &packs = session.diceStickersPacks();
|
auto &packs = session.diceStickersPacks();
|
||||||
const auto &emoji = Stickers::DicePacks::kPartyPopper;
|
const auto &emoji = Stickers::DicePacks::kPartyPopper;
|
||||||
const auto skip = st::chatGiveawayWinnersTopSkip;
|
return Data{
|
||||||
return Data{ packs.lookup(emoji, 0), skip };
|
.sticker = packs.lookup(emoji, 0),
|
||||||
|
.skipTop = st::chatGiveawayWinnersTopSkip,
|
||||||
|
.singleTimePlayback = true,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
push(std::make_unique<StickerWithBadgePart>(
|
push(std::make_unique<StickerWithBadgePart>(
|
||||||
parent,
|
parent,
|
||||||
|
nullptr,
|
||||||
sticker,
|
sticker,
|
||||||
tr::lng_prizes_badge(
|
tr::lng_prizes_badge(
|
||||||
tr::now,
|
tr::now,
|
||||||
|
|
|
@ -22,6 +22,12 @@ class RippleAnimation;
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
|
struct MediaInBubbleDescriptor {
|
||||||
|
int maxWidth = 0;
|
||||||
|
bool service = false;
|
||||||
|
bool hideServiceText = false;
|
||||||
|
};
|
||||||
|
|
||||||
class MediaInBubble final : public Media {
|
class MediaInBubble final : public Media {
|
||||||
public:
|
public:
|
||||||
class Part : public Object {
|
class Part : public Object {
|
||||||
|
@ -30,6 +36,7 @@ public:
|
||||||
|
|
||||||
virtual void draw(
|
virtual void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const = 0;
|
int outerWidth) const = 0;
|
||||||
[[nodiscard]] virtual TextState textState(
|
[[nodiscard]] virtual TextState textState(
|
||||||
|
@ -41,13 +48,22 @@ public:
|
||||||
bool pressed);
|
bool pressed);
|
||||||
[[nodiscard]] virtual bool hasHeavyPart();
|
[[nodiscard]] virtual bool hasHeavyPart();
|
||||||
virtual void unloadHeavyPart();
|
virtual void unloadHeavyPart();
|
||||||
|
[[nodiscard]] virtual auto stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements
|
||||||
|
) -> std::unique_ptr<StickerPlayer>;
|
||||||
};
|
};
|
||||||
|
|
||||||
MediaInBubble(
|
MediaInBubble(
|
||||||
not_null<Element*> parent,
|
not_null<Element*> parent,
|
||||||
Fn<void(Fn<void(std::unique_ptr<Part>)>)> generate);
|
Fn<void(Fn<void(std::unique_ptr<Part>)>)> generate,
|
||||||
|
MediaInBubbleDescriptor &&descriptor = {});
|
||||||
~MediaInBubble();
|
~MediaInBubble();
|
||||||
|
|
||||||
|
[[nodiscard]] bool service() const {
|
||||||
|
return _service;
|
||||||
|
}
|
||||||
|
|
||||||
void draw(Painter &p, const PaintContext &context) const override;
|
void draw(Painter &p, const PaintContext &context) const override;
|
||||||
TextState textState(QPoint point, StateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
|
@ -59,12 +75,16 @@ public:
|
||||||
bool pressed) override;
|
bool pressed) override;
|
||||||
|
|
||||||
bool needsBubble() const override {
|
bool needsBubble() const override {
|
||||||
return true;
|
return !_service;;
|
||||||
}
|
}
|
||||||
bool customInfoLayout() const override {
|
bool customInfoLayout() const override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<StickerPlayer> stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements) override;
|
||||||
|
|
||||||
bool toggleSelectionByHandlerClick(
|
bool toggleSelectionByHandlerClick(
|
||||||
const ClickHandlerPtr &p) const override {
|
const ClickHandlerPtr &p) const override {
|
||||||
return true;
|
return true;
|
||||||
|
@ -74,6 +94,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hideFromName() const override;
|
bool hideFromName() const override;
|
||||||
|
bool hideServiceText() const override;
|
||||||
|
|
||||||
void unloadHeavyPart() override;
|
void unloadHeavyPart() override;
|
||||||
bool hasHeavyPart() const override;
|
bool hasHeavyPart() const override;
|
||||||
|
@ -89,6 +110,9 @@ private:
|
||||||
[[nodiscard]] QMargins inBubblePadding() const;
|
[[nodiscard]] QMargins inBubblePadding() const;
|
||||||
|
|
||||||
std::vector<Entry> _entries;
|
std::vector<Entry> _entries;
|
||||||
|
int _maxWidthCap = 0;
|
||||||
|
bool _service : 1 = false;
|
||||||
|
bool _hideServiceText : 1 = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -101,6 +125,7 @@ public:
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const override;
|
int outerWidth) const override;
|
||||||
TextState textState(
|
TextState textState(
|
||||||
|
@ -123,6 +148,7 @@ public:
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const override;
|
int outerWidth) const override;
|
||||||
|
|
||||||
|
@ -135,24 +161,34 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class StickerWithBadgePart final : public MediaInBubble::Part {
|
class StickerInBubblePart final : public MediaInBubble::Part {
|
||||||
public:
|
public:
|
||||||
struct Data {
|
struct Data {
|
||||||
DocumentData *sticker = nullptr;
|
DocumentData *sticker = nullptr;
|
||||||
int skipTop = 0;
|
int skipTop = 0;
|
||||||
bool isGiftBoxSticker = false;
|
int size = 0;
|
||||||
|
ChatHelpers::StickerLottieSize cacheTag = {};
|
||||||
|
bool singleTimePlayback = false;
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
return sticker != nullptr;
|
return sticker != nullptr;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
StickerWithBadgePart(
|
StickerInBubblePart(
|
||||||
not_null<Element*> parent,
|
not_null<Element*> parent,
|
||||||
Fn<Data()> lookup,
|
Element *replacing,
|
||||||
QString badge);
|
Fn<Data()> lookup);
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<Element*> parent() const {
|
||||||
|
return _parent;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool resolved() const {
|
||||||
|
return _sticker.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const override;
|
int outerWidth) const override;
|
||||||
bool hasHeavyPart() override;
|
bool hasHeavyPart() override;
|
||||||
|
@ -161,16 +197,50 @@ public:
|
||||||
QSize countOptimalSize() override;
|
QSize countOptimalSize() override;
|
||||||
QSize countCurrentSize(int newWidth) override;
|
QSize countCurrentSize(int newWidth) override;
|
||||||
|
|
||||||
|
std::unique_ptr<StickerPlayer> stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ensureCreated() const;
|
void ensureCreated(Element *replacing = nullptr) const;
|
||||||
void validateBadge(const PaintContext &context) const;
|
|
||||||
void paintBadge(Painter &p, const PaintContext &context) const;
|
|
||||||
|
|
||||||
const not_null<Element*> _parent;
|
const not_null<Element*> _parent;
|
||||||
Fn<Data()> _lookup;
|
Fn<Data()> _lookup;
|
||||||
QString _badgeText;
|
|
||||||
mutable int _skipTop = 0;
|
mutable int _skipTop = 0;
|
||||||
mutable std::optional<Sticker> _sticker;
|
mutable std::optional<Sticker> _sticker;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class StickerWithBadgePart final : public MediaInBubble::Part {
|
||||||
|
public:
|
||||||
|
using Data = StickerInBubblePart::Data;
|
||||||
|
StickerWithBadgePart(
|
||||||
|
not_null<Element*> parent,
|
||||||
|
Element *replacing,
|
||||||
|
Fn<Data()> lookup,
|
||||||
|
QString badge);
|
||||||
|
|
||||||
|
void draw(
|
||||||
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
|
const PaintContext &context,
|
||||||
|
int outerWidth) const override;
|
||||||
|
bool hasHeavyPart() override;
|
||||||
|
void unloadHeavyPart() override;
|
||||||
|
|
||||||
|
QSize countOptimalSize() override;
|
||||||
|
QSize countCurrentSize(int newWidth) override;
|
||||||
|
|
||||||
|
std::unique_ptr<StickerPlayer> stickerTakePlayer(
|
||||||
|
not_null<DocumentData*> data,
|
||||||
|
const Lottie::ColorReplacements *replacements) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void validateBadge(const PaintContext &context) const;
|
||||||
|
void paintBadge(Painter &p, const PaintContext &context) const;
|
||||||
|
|
||||||
|
StickerInBubblePart _sticker;
|
||||||
|
QString _badgeText;
|
||||||
mutable QColor _badgeFg;
|
mutable QColor _badgeFg;
|
||||||
mutable QColor _badgeBorder;
|
mutable QColor _badgeBorder;
|
||||||
mutable QImage _badge;
|
mutable QImage _badge;
|
||||||
|
@ -187,6 +257,7 @@ public:
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
|
not_null<const MediaInBubble*> owner,
|
||||||
const PaintContext &context,
|
const PaintContext &context,
|
||||||
int outerWidth) const override;
|
int outerWidth) const override;
|
||||||
TextState textState(
|
TextState textState(
|
||||||
|
|
|
@ -1064,3 +1064,5 @@ historyIvIconPadding: margins(2px, 2px, 2px, 0px);
|
||||||
|
|
||||||
chatIntroStickerSize: 96px;
|
chatIntroStickerSize: 96px;
|
||||||
chatIntroWidth: 224px;
|
chatIntroWidth: 224px;
|
||||||
|
chatIntroTitleMargin: margins(11px, 16px, 11px, 4px);
|
||||||
|
chatIntroMargin: margins(11px, 0px, 11px, 0px);
|
||||||
|
|
Loading…
Add table
Reference in a new issue