mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 22:27:20 +02:00
Improve reactions position and colors.
This commit is contained in:
parent
38c296b69f
commit
4228557722
17 changed files with 195 additions and 55 deletions
|
@ -746,7 +746,7 @@ bool HistoryItem::suggestDeleteAllReport() const {
|
|||
}
|
||||
|
||||
bool HistoryItem::canReact() const {
|
||||
return isRegular();
|
||||
return isRegular() && !isService();
|
||||
}
|
||||
|
||||
void HistoryItem::addReaction(const QString &reaction) {
|
||||
|
|
|
@ -359,15 +359,23 @@ QSize Message::performCountOptimalSize() {
|
|||
}
|
||||
minHeight = hasVisibleText() ? item->_text.minHeight() : 0;
|
||||
if (reactionsInBubble) {
|
||||
accumulate_max(maxWidth, std::min(
|
||||
st::msgMaxWidth,
|
||||
(st::msgPadding.left()
|
||||
+ _reactions->maxWidth()
|
||||
+ st::msgPadding.right())));
|
||||
const auto reactionsMaxWidth = st::msgPadding.left()
|
||||
+ _reactions->maxWidth()
|
||||
+ st::msgPadding.right();
|
||||
accumulate_max(
|
||||
maxWidth,
|
||||
std::min(st::msgMaxWidth, reactionsMaxWidth));
|
||||
if (!mediaDisplayed) {
|
||||
minHeight += st::mediaInBubbleSkip;
|
||||
}
|
||||
minHeight += _reactions->minHeight();
|
||||
if (maxWidth >= reactionsMaxWidth) {
|
||||
minHeight += _reactions->minHeight();
|
||||
} else {
|
||||
const auto widthForReactions = maxWidth
|
||||
- st::msgPadding.left()
|
||||
- st::msgPadding.right();
|
||||
minHeight += _reactions->resizeGetHeight(widthForReactions);
|
||||
}
|
||||
}
|
||||
if (!mediaOnBottom) {
|
||||
minHeight += st::msgPadding.bottom();
|
||||
|
@ -457,13 +465,6 @@ QSize Message::performCountOptimalSize() {
|
|||
maxWidth = st::msgMinWidth;
|
||||
minHeight = 0;
|
||||
}
|
||||
if (_reactions && !reactionsInBubble) {
|
||||
// if we have a text bubble we can resize it to fit the keyboard
|
||||
// but if we have only media we don't do that
|
||||
if (hasVisibleText()) {
|
||||
accumulate_max(maxWidth, _reactions->maxWidth());
|
||||
}
|
||||
}
|
||||
if (const auto markup = item->inlineReplyMarkup()) {
|
||||
if (!markup->inlineKeyboard) {
|
||||
markup->inlineKeyboard = std::make_unique<ReplyKeyboard>(
|
||||
|
@ -601,8 +602,11 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
|||
|
||||
if (_reactions && !reactionsInBubble) {
|
||||
const auto reactionsHeight = st::mediaInBubbleSkip + _reactions->height();
|
||||
const auto reactionsLeft = (!bubble && mediaDisplayed)
|
||||
? media->contentRectForReactionButton().x()
|
||||
: 0;
|
||||
g.setHeight(g.height() - reactionsHeight);
|
||||
const auto reactionsPosition = QPoint(g.left(), g.top() + g.height() + st::mediaInBubbleSkip);
|
||||
const auto reactionsPosition = QPoint(reactionsLeft + g.left(), g.top() + g.height() + st::mediaInBubbleSkip);
|
||||
p.translate(reactionsPosition);
|
||||
_reactions->paint(p, context, g.width(), context.clip.translated(-reactionsPosition));
|
||||
p.translate(-reactionsPosition);
|
||||
|
@ -1250,7 +1254,9 @@ TextState Message::textState(
|
|||
return result;
|
||||
}
|
||||
|
||||
const auto bubble = drawBubble();
|
||||
const auto reactionsInBubble = _reactions && embedReactionsInBubble();
|
||||
const auto mediaDisplayed = media && media->isDisplayed();
|
||||
auto keyboard = item->inlineReplyKeyboard();
|
||||
auto keyboardHeight = 0;
|
||||
if (keyboard) {
|
||||
|
@ -1260,17 +1266,19 @@ TextState Message::textState(
|
|||
|
||||
if (_reactions && !reactionsInBubble) {
|
||||
const auto reactionsHeight = st::mediaInBubbleSkip + _reactions->height();
|
||||
const auto reactionsLeft = (!bubble && mediaDisplayed)
|
||||
? media->contentRectForReactionButton().x()
|
||||
: 0;
|
||||
g.setHeight(g.height() - reactionsHeight);
|
||||
const auto reactionsPosition = QPoint(g.left(), g.top() + g.height() + st::mediaInBubbleSkip);
|
||||
const auto reactionsPosition = QPoint(reactionsLeft + g.left(), g.top() + g.height() + st::mediaInBubbleSkip);
|
||||
if (_reactions->getState(point - reactionsPosition, &result)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawBubble()) {
|
||||
if (bubble) {
|
||||
const auto inBubble = g.contains(point);
|
||||
auto entry = logEntryOriginal();
|
||||
auto mediaDisplayed = media && media->isDisplayed();
|
||||
|
||||
// Entry page is always a bubble bottom.
|
||||
auto mediaOnBottom = (mediaDisplayed && media->isBubbleBottom()) || (entry/* && entry->isBubbleBottom()*/);
|
||||
|
@ -1807,17 +1815,39 @@ TextSelection Message::adjustSelection(
|
|||
Reactions::ButtonParameters Message::reactionButtonParameters(
|
||||
QPoint position,
|
||||
const TextState &reactionState) const {
|
||||
auto result = Reactions::ButtonParameters{ .context = data()->fullId() };
|
||||
const auto outbg = result.outbg = hasOutLayout();
|
||||
using namespace Reactions;
|
||||
auto result = ButtonParameters{ .context = data()->fullId() };
|
||||
const auto outbg = hasOutLayout();
|
||||
result.style = (!_comments && !embedReactionsInBubble())
|
||||
? ButtonStyle::Service
|
||||
: outbg
|
||||
? ButtonStyle::Outgoing
|
||||
: ButtonStyle::Incoming;
|
||||
const auto geometry = countGeometry();
|
||||
result.pointer = position;
|
||||
const auto onTheLeft = (outbg && !delegate()->elementIsChatWide());
|
||||
const auto leftAdd = onTheLeft ? 0 : geometry.width();
|
||||
result.center = geometry.topLeft() + (onTheLeft
|
||||
? (QPoint(0, geometry.height()) + QPoint(
|
||||
|
||||
const auto keyboard = data()->inlineReplyKeyboard();
|
||||
const auto keyboardHeight = keyboard
|
||||
? (st::msgBotKbButton.margin + keyboard->naturalHeight())
|
||||
: 0;
|
||||
const auto reactionsHeight = (_reactions && !embedReactionsInBubble())
|
||||
? (st::mediaInBubbleSkip + _reactions->height())
|
||||
: 0;
|
||||
const auto innerHeight = geometry.height()
|
||||
- keyboardHeight
|
||||
- reactionsHeight;
|
||||
const auto contentRect = (result.style == ButtonStyle::Service
|
||||
&& !drawBubble())
|
||||
? media()->contentRectForReactionButton().translated(
|
||||
geometry.topLeft())
|
||||
: geometry;
|
||||
result.center = contentRect.topLeft() + (onTheLeft
|
||||
? (QPoint(0, innerHeight) + QPoint(
|
||||
-st::reactionCornerCenter.x(),
|
||||
st::reactionCornerCenter.y()))
|
||||
: (QPoint(geometry.width(), geometry.height())
|
||||
: (QPoint(contentRect.width(), innerHeight)
|
||||
+ st::reactionCornerCenter));
|
||||
if (reactionState.itemId != result.context) {
|
||||
const auto top = marginTop();
|
||||
|
@ -2739,7 +2769,11 @@ int Message::resizeContentGetHeight(int newWidth) {
|
|||
newHeight = 0;
|
||||
}
|
||||
if (_reactions && !reactionsInBubble) {
|
||||
newHeight += st::mediaInBubbleSkip + _reactions->resizeGetHeight(contentWidth);
|
||||
const auto reactionsWidth = (!bubble && mediaDisplayed)
|
||||
? media->contentRectForReactionButton().width()
|
||||
: contentWidth;
|
||||
newHeight += st::mediaInBubbleSkip
|
||||
+ _reactions->resizeGetHeight(reactionsWidth);
|
||||
}
|
||||
|
||||
if (const auto keyboard = item->inlineReplyKeyboard()) {
|
||||
|
|
|
@ -25,6 +25,7 @@ constexpr auto kActivateDuration = crl::time(150);
|
|||
constexpr auto kExpandDuration = crl::time(150);
|
||||
constexpr auto kInCacheIndex = 0;
|
||||
constexpr auto kOutCacheIndex = 1;
|
||||
constexpr auto kServiceCacheIndex = 2;
|
||||
constexpr auto kShadowCacheIndex = 0;
|
||||
constexpr auto kEmojiCacheIndex = 1;
|
||||
constexpr auto kMaskCacheIndex = 2;
|
||||
|
@ -86,8 +87,8 @@ Button::Button(
|
|||
|
||||
Button::~Button() = default;
|
||||
|
||||
bool Button::outbg() const {
|
||||
return _outbg;
|
||||
ButtonStyle Button::style() const {
|
||||
return _style;
|
||||
}
|
||||
|
||||
bool Button::isHidden() const {
|
||||
|
@ -150,8 +151,8 @@ void Button::applyParameters(
|
|||
? State::Active
|
||||
: State::Shown;
|
||||
applyState(state, update);
|
||||
if (_outbg != parameters.outbg) {
|
||||
_outbg = parameters.outbg;
|
||||
if (_style != parameters.style) {
|
||||
_style = parameters.style;
|
||||
if (update) {
|
||||
update(_geometry);
|
||||
}
|
||||
|
@ -264,12 +265,12 @@ Manager::Manager(
|
|||
QRect({}, _outer).center() - _innerActive.center());
|
||||
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
_cacheInOut = QImage(
|
||||
_outer.width() * 2 * ratio,
|
||||
_cacheInOutService = QImage(
|
||||
_outer.width() * 3 * ratio,
|
||||
_outer.height() * kFramesCount * ratio,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
_cacheInOut.setDevicePixelRatio(ratio);
|
||||
_cacheInOut.fill(Qt::transparent);
|
||||
_cacheInOutService.setDevicePixelRatio(ratio);
|
||||
_cacheInOutService.fill(Qt::transparent);
|
||||
_cacheParts = QImage(
|
||||
_outer.width() * kCacheColumsCount * ratio,
|
||||
_outer.height() * kFramesCount * ratio,
|
||||
|
@ -529,8 +530,8 @@ void Manager::paintButton(
|
|||
const auto geometry = button->geometry();
|
||||
const auto position = geometry.topLeft();
|
||||
const auto size = geometry.size();
|
||||
const auto outbg = button->outbg();
|
||||
const auto patterned = outbg
|
||||
const auto style = button->style();
|
||||
const auto patterned = (style == ButtonStyle::Outgoing)
|
||||
&& context.bubblesPattern
|
||||
&& !context.viewport.isEmpty()
|
||||
&& !context.bubblesPattern->pixmap.size().isEmpty();
|
||||
|
@ -547,15 +548,19 @@ void Manager::paintButton(
|
|||
_cacheForPattern,
|
||||
QRect(QPoint(), geometry.size() * style::DevicePixelRatio()));
|
||||
} else {
|
||||
const auto &stm = context.st->messageStyle(outbg, false);
|
||||
const auto background = stm.msgBg->c;
|
||||
const auto background = (style == ButtonStyle::Service)
|
||||
? context.st->msgServiceFg()->c
|
||||
: context.st->messageStyle(
|
||||
(style == ButtonStyle::Outgoing),
|
||||
false
|
||||
).msgBg->c;
|
||||
const auto source = validateFrame(
|
||||
outbg,
|
||||
style,
|
||||
frameIndex,
|
||||
scale,
|
||||
stm.msgBg->c,
|
||||
background,
|
||||
shadow);
|
||||
paintLongImage(p, geometry, _cacheInOut, source);
|
||||
paintLongImage(p, geometry, _cacheInOutService, source);
|
||||
}
|
||||
|
||||
const auto mainEmojiPosition = position + (button->expandUp()
|
||||
|
@ -746,20 +751,32 @@ QRect Manager::validateEmoji(int frameIndex, float64 scale) {
|
|||
}
|
||||
|
||||
QRect Manager::validateFrame(
|
||||
bool outbg,
|
||||
ButtonStyle style,
|
||||
int frameIndex,
|
||||
float64 scale,
|
||||
const QColor &background,
|
||||
const QColor &shadow) {
|
||||
applyPatternedShadow(shadow);
|
||||
auto &valid = outbg ? _validOut : _validIn;
|
||||
auto &color = outbg ? _backgroundOut : _backgroundIn;
|
||||
auto &valid = (style == ButtonStyle::Service)
|
||||
? _validService
|
||||
: (style == ButtonStyle::Outgoing)
|
||||
? _validOut
|
||||
: _validIn;
|
||||
auto &color = (style == ButtonStyle::Service)
|
||||
? _backgroundService
|
||||
: (style == ButtonStyle::Outgoing)
|
||||
? _backgroundOut
|
||||
: _backgroundIn;
|
||||
if (color != background) {
|
||||
color = background;
|
||||
ranges::fill(valid, false);
|
||||
}
|
||||
|
||||
const auto columnIndex = outbg ? kOutCacheIndex : kInCacheIndex;
|
||||
const auto columnIndex = (style == ButtonStyle::Service)
|
||||
? kServiceCacheIndex
|
||||
: (style == ButtonStyle::Outgoing)
|
||||
? kOutCacheIndex
|
||||
: kInCacheIndex;
|
||||
const auto result = cacheRect(frameIndex, columnIndex);
|
||||
if (valid[frameIndex]) {
|
||||
return result;
|
||||
|
@ -767,7 +784,7 @@ QRect Manager::validateFrame(
|
|||
|
||||
const auto shadowSource = validateShadow(frameIndex, scale, shadow);
|
||||
const auto position = result.topLeft() / style::DevicePixelRatio();
|
||||
auto p = QPainter(&_cacheInOut);
|
||||
auto p = QPainter(&_cacheInOutService);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
p.drawImage(position, _cacheParts, shadowSource);
|
||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
|
|
|
@ -27,7 +27,9 @@ struct TextState;
|
|||
namespace HistoryView::Reactions {
|
||||
|
||||
enum class ButtonStyle {
|
||||
Bubble,
|
||||
Incoming,
|
||||
Outgoing,
|
||||
Service,
|
||||
};
|
||||
|
||||
enum class ExpandDirection {
|
||||
|
@ -46,11 +48,10 @@ struct ButtonParameters {
|
|||
FullMsgId context;
|
||||
QPoint center;
|
||||
QPoint pointer;
|
||||
ButtonStyle style = ButtonStyle::Bubble;
|
||||
ButtonStyle style = ButtonStyle::Incoming;
|
||||
int reactionsCount = 1;
|
||||
int visibleTop = 0;
|
||||
int visibleBottom = 0;
|
||||
bool outbg = false;
|
||||
};
|
||||
|
||||
enum class ButtonState {
|
||||
|
@ -70,7 +71,7 @@ public:
|
|||
using State = ButtonState;
|
||||
void applyState(State state);
|
||||
|
||||
[[nodiscard]] bool outbg() const;
|
||||
[[nodiscard]] ButtonStyle style() const;
|
||||
[[nodiscard]] bool expandUp() const;
|
||||
[[nodiscard]] bool isHidden() const;
|
||||
[[nodiscard]] QRect geometry() const;
|
||||
|
@ -101,7 +102,7 @@ private:
|
|||
int _finalHeight = 0;
|
||||
int _scroll = 0;
|
||||
ExpandDirection _expandDirection = ExpandDirection::Up;
|
||||
bool _outbg = false;
|
||||
ButtonStyle _style = ButtonStyle::Incoming;
|
||||
|
||||
};
|
||||
|
||||
|
@ -171,7 +172,7 @@ private:
|
|||
const QColor &shadow);
|
||||
QRect validateEmoji(int frameIndex, float64 scale);
|
||||
QRect validateFrame(
|
||||
bool outbg,
|
||||
ButtonStyle style,
|
||||
int frameIndex,
|
||||
float64 scale,
|
||||
const QColor &background,
|
||||
|
@ -198,17 +199,19 @@ private:
|
|||
QSize _outer;
|
||||
QRectF _inner;
|
||||
QRect _innerActive;
|
||||
QImage _cacheInOut;
|
||||
QImage _cacheInOutService;
|
||||
QImage _cacheParts;
|
||||
QImage _cacheForPattern;
|
||||
QImage _shadowBuffer;
|
||||
std::array<bool, kFramesCount> _validIn = { { false } };
|
||||
std::array<bool, kFramesCount> _validOut = { { false } };
|
||||
std::array<bool, kFramesCount> _validService = { { false } };
|
||||
std::array<bool, kFramesCount> _validShadow = { { false } };
|
||||
std::array<bool, kFramesCount> _validEmoji = { { false } };
|
||||
std::array<bool, kFramesCount> _validMask = { { false } };
|
||||
QColor _backgroundIn;
|
||||
QColor _backgroundOut;
|
||||
QColor _backgroundService;
|
||||
QColor _shadow;
|
||||
|
||||
std::shared_ptr<Data::DocumentMedia> _mainReactionMedia;
|
||||
|
|
|
@ -22,6 +22,11 @@ namespace {
|
|||
constexpr auto kInNonChosenOpacity = 0.12;
|
||||
constexpr auto kOutNonChosenOpacity = 0.18;
|
||||
|
||||
[[nodiscard]] QColor AdaptChosenServiceFg(QColor serviceBg) {
|
||||
serviceBg.setAlpha(std::max(serviceBg.alpha(), 192));
|
||||
return serviceBg;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
InlineList::InlineList(
|
||||
|
@ -146,6 +151,14 @@ QSize InlineList::countCurrentSize(int newWidth) {
|
|||
return { newWidth, height + add };
|
||||
}
|
||||
|
||||
int InlineList::placeAndResizeGetHeight(QRect available) {
|
||||
const auto result = resizeGetHeight(available.width());
|
||||
for (auto &button : _buttons) {
|
||||
button.geometry.translate(available.x(), 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void InlineList::paint(
|
||||
Painter &p,
|
||||
const PaintContext &context,
|
||||
|
@ -173,9 +186,7 @@ void InlineList::paint(
|
|||
}
|
||||
p.setBrush(stm->msgFileBg);
|
||||
} else {
|
||||
p.setBrush(chosen
|
||||
? st->msgServiceBgSelected()
|
||||
: st->msgServiceBg());
|
||||
p.setBrush(chosen ? st->msgServiceFg() : st->msgServiceBg());
|
||||
}
|
||||
const auto radius = geometry.height() / 2.;
|
||||
p.drawRoundedRect(geometry, radius, radius);
|
||||
|
@ -192,7 +203,9 @@ void InlineList::paint(
|
|||
p.drawImage(inner.topLeft(), button.image);
|
||||
}
|
||||
p.setPen(!inbubble
|
||||
? st->msgServiceFg()
|
||||
? (chosen
|
||||
? QPen(AdaptChosenServiceFg(st->msgServiceBg()->c))
|
||||
: st->msgServiceFg())
|
||||
: !chosen
|
||||
? stm->msgServiceFg
|
||||
: context.outbg
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
|
||||
void update(Data &&data, int availableWidth);
|
||||
QSize countCurrentSize(int newWidth) override;
|
||||
[[nodiscard]] int placeAndResizeGetHeight(QRect available);
|
||||
|
||||
void updateSkipBlock(int width, int height);
|
||||
void removeSkipBlock();
|
||||
|
|
|
@ -1170,6 +1170,27 @@ bool Gif::needsBubble() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
QRect Gif::contentRectForReactionButton() const {
|
||||
if (isSeparateRoundVideo()) {
|
||||
return QRect(0, 0, width(), height());
|
||||
}
|
||||
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
||||
auto usex = 0, usew = paintw;
|
||||
const auto outbg = _parent->hasOutLayout();
|
||||
const auto item = _parent->data();
|
||||
const auto via = item->Get<HistoryMessageVia>();
|
||||
const auto reply = _parent->displayedReply();
|
||||
const auto forwarded = item->Get<HistoryMessageForwarded>();
|
||||
if (via || reply || forwarded) {
|
||||
usew = maxWidth() - additionalWidth(via, reply, forwarded);
|
||||
if (outbg) {
|
||||
usex = width() - usew;
|
||||
}
|
||||
}
|
||||
if (rtl()) usex = width() - usex - usew;
|
||||
return style::rtlrect(usex + paintx, painty, usew, painth, width());
|
||||
}
|
||||
|
||||
int Gif::additionalWidth() const {
|
||||
const auto item = _parent->data();
|
||||
return additionalWidth(
|
||||
|
|
|
@ -96,6 +96,7 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return _caption.isEmpty();
|
||||
}
|
||||
QRect contentRectForReactionButton() const override;
|
||||
QString additionalInfoString() const override;
|
||||
|
||||
bool skipBubbleTail() const override {
|
||||
|
|
|
@ -345,6 +345,10 @@ bool Location::needsBubble() const {
|
|||
|| _parent->displayFromName();
|
||||
}
|
||||
|
||||
QRect Location::contentRectForReactionButton() const {
|
||||
return QRect(0, 0, width(), height());
|
||||
}
|
||||
|
||||
int Location::fullWidth() const {
|
||||
return st::locationSize.width();
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return true;
|
||||
}
|
||||
QRect contentRectForReactionButton() const override;
|
||||
|
||||
bool skipBubbleTail() const override {
|
||||
return isRoundedInBubbleBottom();
|
||||
|
|
|
@ -205,6 +205,9 @@ public:
|
|||
}
|
||||
[[nodiscard]] virtual bool needsBubble() const = 0;
|
||||
[[nodiscard]] virtual bool customInfoLayout() const = 0;
|
||||
[[nodiscard]] virtual QRect contentRectForReactionButton() const {
|
||||
Unexpected("Media::contentRectForReactionButton");
|
||||
}
|
||||
[[nodiscard]] virtual QMargins bubbleMargins() const {
|
||||
return QMargins();
|
||||
}
|
||||
|
|
|
@ -730,6 +730,10 @@ bool GroupedMedia::needsBubble() const {
|
|||
return _needBubble;
|
||||
}
|
||||
|
||||
QRect GroupedMedia::contentRectForReactionButton() const {
|
||||
return QRect(0, 0, width(), height());
|
||||
}
|
||||
|
||||
bool GroupedMedia::computeNeedBubble() const {
|
||||
if (!_caption.isEmpty() || _mode == Mode::Column) {
|
||||
return true;
|
||||
|
|
|
@ -84,6 +84,7 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return _caption.isEmpty() && (_mode != Mode::Column);
|
||||
}
|
||||
QRect contentRectForReactionButton() const override;
|
||||
bool allowsFastShare() const override {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -401,6 +401,37 @@ TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
|||
return result;
|
||||
}
|
||||
|
||||
QRect UnwrappedMedia::contentRectForReactionButton() const {
|
||||
const auto inWebPage = (_parent->media() != this);
|
||||
if (inWebPage) {
|
||||
return QRect(0, 0, width(), height());
|
||||
}
|
||||
const auto rightAligned = _parent->hasOutLayout()
|
||||
&& !_parent->delegate()->elementIsChatWide();
|
||||
const auto item = _parent->data();
|
||||
const auto via = item->Get<HistoryMessageVia>();
|
||||
const auto reply = _parent->displayedReply();
|
||||
const auto forwarded = getDisplayedForwardedInfo();
|
||||
auto usex = 0;
|
||||
auto usew = maxWidth();
|
||||
if (!inWebPage) {
|
||||
usew -= additionalWidth(via, reply, forwarded);
|
||||
if (rightAligned) {
|
||||
usex = width() - usew;
|
||||
}
|
||||
}
|
||||
if (rtl()) {
|
||||
usex = width() - usex - usew;
|
||||
}
|
||||
const auto usey = rightAligned ? 0 : (height() - _contentSize.height());
|
||||
const auto useh = rightAligned
|
||||
? std::max(
|
||||
_contentSize.height(),
|
||||
height() - st::msgDateImgPadding.y() * 2 - st::msgDateFont->height)
|
||||
: _contentSize.height();
|
||||
return QRect(usex, usey, usew, useh);
|
||||
}
|
||||
|
||||
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie(
|
||||
not_null<DocumentData*> data,
|
||||
const Lottie::ColorReplacements *replacements) {
|
||||
|
|
|
@ -81,6 +81,7 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return true;
|
||||
}
|
||||
QRect contentRectForReactionButton() const override;
|
||||
void stickerClearLoopPlayed() override {
|
||||
_content->stickerClearLoopPlayed();
|
||||
}
|
||||
|
|
|
@ -831,6 +831,10 @@ bool Photo::needsBubble() const {
|
|||
|| _parent->displayFromName());
|
||||
}
|
||||
|
||||
QRect Photo::contentRectForReactionButton() const {
|
||||
return QRect(0, 0, width(), height());
|
||||
}
|
||||
|
||||
bool Photo::isReadyForOpen() const {
|
||||
ensureDataMediaCreated();
|
||||
return _dataMedia->loaded();
|
||||
|
|
|
@ -82,6 +82,7 @@ public:
|
|||
bool customInfoLayout() const override {
|
||||
return _caption.isEmpty();
|
||||
}
|
||||
QRect contentRectForReactionButton() const override;
|
||||
bool skipBubbleTail() const override {
|
||||
return isRoundedInBubbleBottom() && _caption.isEmpty();
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue