563 lines
19 KiB
C++
563 lines
19 KiB
C++
/*
|
|
This file is part of Telegram Desktop,
|
|
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_media_unwrapped.h"
|
|
|
|
#include "history/view/media/history_view_media_common.h"
|
|
#include "history/view/media/history_view_sticker.h"
|
|
#include "history/view/history_view_element.h"
|
|
#include "history/view/history_view_cursor_state.h"
|
|
#include "history/history_item.h"
|
|
#include "history/history_item_components.h"
|
|
#include "lottie/lottie_single_player.h"
|
|
#include "ui/cached_round_corners.h"
|
|
#include "ui/chat/chat_style.h"
|
|
#include "styles/style_chat.h"
|
|
|
|
namespace HistoryView {
|
|
namespace {
|
|
|
|
constexpr auto kMaxForwardedBarLines = 4;
|
|
|
|
} // namespace
|
|
|
|
auto UnwrappedMedia::Content::stickerTakeLottie(
|
|
not_null<DocumentData*> data,
|
|
const Lottie::ColorReplacements *replacements)
|
|
-> std::unique_ptr<Lottie::SinglePlayer> {
|
|
return nullptr;
|
|
}
|
|
|
|
QSize UnwrappedMedia::Content::countCurrentSize(int newWidth) {
|
|
return countOptimalSize();
|
|
}
|
|
|
|
UnwrappedMedia::UnwrappedMedia(
|
|
not_null<Element*> parent,
|
|
std::unique_ptr<Content> content)
|
|
: Media(parent)
|
|
, _content(std::move(content)) {
|
|
}
|
|
|
|
QSize UnwrappedMedia::countOptimalSize() {
|
|
_content->refreshLink();
|
|
const auto optimal = _content->countOptimalSize();
|
|
auto maxWidth = optimal.width();
|
|
const auto minimal = st::emojiSize;
|
|
auto minHeight = std::max(optimal.height(), minimal);
|
|
if (_parent->media() == this) {
|
|
const auto item = _parent->data();
|
|
const auto via = item->Get<HistoryMessageVia>();
|
|
const auto reply = _parent->displayedReply();
|
|
const auto forwarded = getDisplayedForwardedInfo();
|
|
if (forwarded) {
|
|
forwarded->create(via);
|
|
}
|
|
maxWidth += additionalWidth(via, reply, forwarded);
|
|
accumulate_max(maxWidth, _parent->reactionsOptimalWidth());
|
|
if (const auto size = _parent->rightActionSize()) {
|
|
minHeight = std::max(
|
|
minHeight,
|
|
st::historyFastShareBottom + size->height());
|
|
}
|
|
}
|
|
return { maxWidth, minHeight };
|
|
}
|
|
|
|
QSize UnwrappedMedia::countCurrentSize(int newWidth) {
|
|
const auto item = _parent->data();
|
|
accumulate_min(newWidth, maxWidth());
|
|
_contentSize = _content->countCurrentSize(newWidth);
|
|
auto newHeight = std::max(minHeight(), _contentSize.height());
|
|
_additionalOnTop = false;
|
|
if (_parent->media() != this) {
|
|
return { newWidth, newHeight };
|
|
}
|
|
if (_parent->hasOutLayout()
|
|
&& !_parent->delegate()->elementIsChatWide()) {
|
|
// Add some height to isolated emoji for the timestamp info.
|
|
const auto infoHeight = st::msgDateImgPadding.y() * 2
|
|
+ st::msgDateFont->height;
|
|
const auto minimal = std::min(
|
|
st::largeEmojiSize + 2 * st::largeEmojiOutline,
|
|
_contentSize.height());
|
|
accumulate_max(newHeight, minimal + st::msgDateImgDelta + infoHeight);
|
|
}
|
|
accumulate_max(newWidth, _parent->reactionsOptimalWidth());
|
|
const auto via = item->Get<HistoryMessageVia>();
|
|
const auto reply = _parent->displayedReply();
|
|
const auto forwarded = getDisplayedForwardedInfo();
|
|
if (via || reply || forwarded) {
|
|
const auto paddings = 3 * st::msgReplyPadding.left();
|
|
const auto additional = additionalWidth(via, reply, forwarded);
|
|
const auto optimalw = maxWidth() - additional;
|
|
const auto additionalMinWidth = std::min(additional, st::msgMinWidth / 2);
|
|
_additionalOnTop = (optimalw + paddings + additionalMinWidth) > newWidth;
|
|
const auto surrounding = surroundingInfo(via, reply, forwarded, additional - st::msgReplyPadding.left());
|
|
if (_additionalOnTop) {
|
|
_topAdded = surrounding.height;
|
|
newHeight += _topAdded;
|
|
} else {
|
|
const auto infoHeight = st::msgDateImgPadding.y() * 2
|
|
+ st::msgDateFont->height;
|
|
const auto minimal = surrounding.height
|
|
+ st::msgDateImgDelta
|
|
+ infoHeight;
|
|
newHeight = std::max(newHeight, minimal);
|
|
}
|
|
const auto availw = newWidth
|
|
- (_additionalOnTop ? 0 : optimalw)
|
|
- paddings;
|
|
if (via) {
|
|
via->resize(availw);
|
|
}
|
|
if (reply) {
|
|
reply->resize(availw);
|
|
}
|
|
}
|
|
return { newWidth, newHeight };
|
|
}
|
|
|
|
void UnwrappedMedia::draw(Painter &p, const PaintContext &context) const {
|
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
|
return;
|
|
}
|
|
const auto rightAligned = context.outbg
|
|
&& !_parent->delegate()->elementIsChatWide();
|
|
const auto inWebPage = (_parent->media() != this);
|
|
const auto item = _parent->data();
|
|
auto usex = 0;
|
|
auto usew = _contentSize.width();
|
|
if (!inWebPage && rightAligned) {
|
|
usex = width() - usew;
|
|
}
|
|
if (rtl()) {
|
|
usex = width() - usex - usew;
|
|
}
|
|
|
|
const auto usey = rightAligned ? _topAdded : (height() - _contentSize.height());
|
|
const auto useh = rightAligned
|
|
? std::max(
|
|
_contentSize.height(),
|
|
height() - st::msgDateImgPadding.y() * 2 - st::msgDateFont->height)
|
|
: _contentSize.height();
|
|
const auto inner = QRect(usex, usey, usew, useh);
|
|
if (context.skipDrawingParts != PaintContext::SkipDrawingParts::Content) {
|
|
_content->draw(p, context, inner);
|
|
}
|
|
|
|
if (!inWebPage && (context.skipDrawingParts
|
|
!= PaintContext::SkipDrawingParts::Surrounding)) {
|
|
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
|
|
const auto reply = inWebPage ? nullptr : _parent->displayedReply();
|
|
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
|
|
drawSurrounding(p, inner, context, via, reply, forwarded);
|
|
}
|
|
}
|
|
|
|
UnwrappedMedia::SurroundingInfo UnwrappedMedia::surroundingInfo(
|
|
const HistoryMessageVia *via,
|
|
const HistoryMessageReply *reply,
|
|
const HistoryMessageForwarded *forwarded,
|
|
int outerw) const {
|
|
if (!via && !reply && !forwarded) {
|
|
return {};
|
|
}
|
|
auto height = st::msgReplyPadding.top() + st::msgReplyPadding.bottom();
|
|
const auto innerw = outerw - st::msgReplyPadding.left() - st::msgReplyPadding.right();
|
|
auto forwardedHeightReal = forwarded
|
|
? forwarded->text.countHeight(innerw)
|
|
: 0;
|
|
auto forwardedHeight = std::min(
|
|
forwardedHeightReal,
|
|
kMaxForwardedBarLines * st::msgServiceNameFont->height);
|
|
const auto breakEverywhere = (forwardedHeightReal > forwardedHeight);
|
|
if (forwarded) {
|
|
height += forwardedHeight;
|
|
} else if (via) {
|
|
height += st::msgServiceNameFont->height
|
|
+ (reply ? st::msgReplyPadding.top() : 0);
|
|
}
|
|
if (reply) {
|
|
height += st::msgReplyBarSize.height();
|
|
}
|
|
return { height, forwardedHeight, breakEverywhere };
|
|
}
|
|
|
|
void UnwrappedMedia::drawSurrounding(
|
|
Painter &p,
|
|
const QRect &inner,
|
|
const PaintContext &context,
|
|
const HistoryMessageVia *via,
|
|
const HistoryMessageReply *reply,
|
|
const HistoryMessageForwarded *forwarded) const {
|
|
const auto st = context.st;
|
|
const auto sti = context.imageStyle();
|
|
const auto rightAligned = context.outbg
|
|
&& !_parent->delegate()->elementIsChatWide();
|
|
const auto rightActionSize = _parent->rightActionSize();
|
|
const auto fullRight = calculateFullRight(inner);
|
|
auto fullBottom = height();
|
|
if (needInfoDisplay()) {
|
|
_parent->drawInfo(
|
|
p,
|
|
context,
|
|
fullRight,
|
|
fullBottom,
|
|
inner.x() * 2 + inner.width(),
|
|
InfoDisplayType::Background);
|
|
}
|
|
auto replyRight = 0;
|
|
auto rectw = _additionalOnTop
|
|
? std::min(width() - st::msgReplyPadding.left(), additionalWidth(via, reply, forwarded))
|
|
: (width() - inner.width() - st::msgReplyPadding.left());
|
|
if (const auto surrounding = surroundingInfo(via, reply, forwarded, rectw)) {
|
|
auto recth = surrounding.height;
|
|
int rectx = _additionalOnTop
|
|
? (rightAligned ? (inner.width() + st::msgReplyPadding.left() - rectw) : 0)
|
|
: (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()));
|
|
int recty = 0;
|
|
if (rtl()) rectx = width() - rectx - rectw;
|
|
|
|
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCorners);
|
|
p.setPen(st->msgServiceFg());
|
|
rectx += st::msgReplyPadding.left();
|
|
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();
|
|
if (forwarded) {
|
|
p.setTextPalette(st->serviceTextPalette());
|
|
forwarded->text.drawElided(p, rectx, recty + st::msgReplyPadding.top(), rectw, kMaxForwardedBarLines, style::al_left, 0, -1, 0, surrounding.forwardedBreakEverywhere);
|
|
p.restoreTextPalette();
|
|
|
|
const auto skip = std::min(
|
|
forwarded->text.countHeight(rectw),
|
|
kMaxForwardedBarLines * st::msgServiceNameFont->height);
|
|
recty += skip;
|
|
} else if (via) {
|
|
p.setFont(st::msgDateFont);
|
|
p.drawTextLeft(rectx, recty + st::msgReplyPadding.top(), 2 * rectx + rectw, via->text);
|
|
|
|
const auto skip = st::msgServiceNameFont->height
|
|
+ (reply ? st::msgReplyPadding.top() : 0);
|
|
recty += skip;
|
|
}
|
|
if (reply) {
|
|
reply->paint(p, _parent, context, rectx, recty, rectw, false);
|
|
}
|
|
replyRight = rectx + rectw;
|
|
}
|
|
if (rightActionSize) {
|
|
const auto position = calculateFastActionPosition(
|
|
fullBottom,
|
|
replyRight,
|
|
fullRight,
|
|
*rightActionSize);
|
|
const auto outer = 2 * inner.x() + inner.width();
|
|
_parent->drawRightAction(p, context, position.x(), position.y(), outer);
|
|
}
|
|
}
|
|
|
|
PointState UnwrappedMedia::pointState(QPoint point) const {
|
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
|
return PointState::Outside;
|
|
}
|
|
|
|
const auto rightAligned = _parent->hasOutLayout()
|
|
&& !_parent->delegate()->elementIsChatWide();
|
|
const auto inWebPage = (_parent->media() != this);
|
|
const auto item = _parent->data();
|
|
auto usex = 0;
|
|
auto usew = _contentSize.width();
|
|
if (!inWebPage && rightAligned) {
|
|
usex = width() - usew;
|
|
}
|
|
if (rtl()) {
|
|
usex = width() - usex - usew;
|
|
}
|
|
|
|
const auto datey = height() - st::msgDateImgPadding.y() * 2
|
|
- st::msgDateFont->height;
|
|
const auto usey = rightAligned ? _topAdded : (height() - _contentSize.height());
|
|
const auto useh = rightAligned
|
|
? std::max(_contentSize.height(), datey)
|
|
: _contentSize.height();
|
|
const auto inner = QRect(usex, usey, usew, useh);
|
|
|
|
// Rectangle of date bubble.
|
|
if (point.x() < calculateFullRight(inner) && point.y() > datey) {
|
|
return PointState::Inside;
|
|
}
|
|
|
|
return inner.contains(point) ? PointState::Inside : PointState::Outside;
|
|
}
|
|
|
|
TextState UnwrappedMedia::textState(QPoint point, StateRequest request) const {
|
|
auto result = TextState(_parent);
|
|
if (width() < st::msgPadding.left() + st::msgPadding.right() + 1) {
|
|
return result;
|
|
}
|
|
|
|
const auto rightAligned = _parent->hasOutLayout()
|
|
&& !_parent->delegate()->elementIsChatWide();
|
|
const auto inWebPage = (_parent->media() != this);
|
|
const auto item = _parent->data();
|
|
auto usex = 0;
|
|
auto usew = _contentSize.width();
|
|
if (!inWebPage && rightAligned) {
|
|
usex = width() - usew;
|
|
}
|
|
if (rtl()) {
|
|
usex = width() - usex - usew;
|
|
}
|
|
|
|
const auto usey = rightAligned ? _topAdded : (height() - _contentSize.height());
|
|
const auto useh = rightAligned
|
|
? std::max(
|
|
_contentSize.height(),
|
|
height() - st::msgDateImgPadding.y() * 2 - st::msgDateFont->height)
|
|
: _contentSize.height();
|
|
const auto inner = QRect(usex, usey, usew, useh);
|
|
|
|
if (_parent->media() == this) {
|
|
const auto via = inWebPage ? nullptr : item->Get<HistoryMessageVia>();
|
|
const auto reply = inWebPage ? nullptr : _parent->displayedReply();
|
|
const auto forwarded = inWebPage ? nullptr : getDisplayedForwardedInfo();
|
|
auto replyRight = 0;
|
|
auto rectw = _additionalOnTop
|
|
? std::min(width() - st::msgReplyPadding.left(), additionalWidth(via, reply, forwarded))
|
|
: (width() - inner.width() - st::msgReplyPadding.left());
|
|
if (const auto surrounding = surroundingInfo(via, reply, forwarded, rectw)) {
|
|
auto recth = surrounding.height;
|
|
int rectx = _additionalOnTop
|
|
? (rightAligned ? (inner.width() + st::msgReplyPadding.left() - rectw) : 0)
|
|
: (rightAligned ? 0 : (inner.width() + st::msgReplyPadding.left()));
|
|
int recty = 0;
|
|
if (rtl()) rectx = width() - rectx - rectw;
|
|
|
|
if (forwarded) {
|
|
if (QRect(rectx, recty, rectw, st::msgReplyPadding.top() + surrounding.forwardedHeight).contains(point)) {
|
|
auto textRequest = request.forText();
|
|
if (surrounding.forwardedBreakEverywhere) {
|
|
textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere;
|
|
}
|
|
const auto innerw = rectw - st::msgReplyPadding.left() - st::msgReplyPadding.right();
|
|
result = TextState(_parent, forwarded->text.getState(
|
|
point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()),
|
|
innerw,
|
|
textRequest));
|
|
result.symbol = 0;
|
|
result.afterSymbol = false;
|
|
if (surrounding.forwardedBreakEverywhere) {
|
|
result.cursor = CursorState::Forwarded;
|
|
} else {
|
|
result.cursor = CursorState::None;
|
|
}
|
|
return result;
|
|
}
|
|
recty += surrounding.forwardedHeight;
|
|
recth -= surrounding.forwardedHeight;
|
|
} else if (via) {
|
|
int viah = st::msgReplyPadding.top() + st::msgServiceNameFont->height + (reply ? 0 : st::msgReplyPadding.bottom());
|
|
if (QRect(rectx, recty, rectw, viah).contains(point)) {
|
|
result.link = via->link;
|
|
return result;
|
|
}
|
|
int skip = st::msgServiceNameFont->height + (reply ? 2 * st::msgReplyPadding.top() : 0);
|
|
recty += skip;
|
|
recth -= skip;
|
|
}
|
|
if (reply) {
|
|
if (QRect(rectx, recty, rectw, recth).contains(point)) {
|
|
result.link = reply->replyToLink();
|
|
return result;
|
|
}
|
|
}
|
|
replyRight = rectx + rectw - st::msgReplyPadding.right();
|
|
}
|
|
const auto fullRight = calculateFullRight(inner);
|
|
const auto rightActionSize = _parent->rightActionSize();
|
|
auto fullBottom = height();
|
|
const auto bottomInfoResult = _parent->bottomInfoTextState(
|
|
fullRight,
|
|
fullBottom,
|
|
point,
|
|
InfoDisplayType::Background);
|
|
if (bottomInfoResult.link
|
|
|| bottomInfoResult.cursor != CursorState::None) {
|
|
return bottomInfoResult;
|
|
}
|
|
if (rightActionSize) {
|
|
const auto position = calculateFastActionPosition(
|
|
fullBottom,
|
|
replyRight,
|
|
fullRight,
|
|
*rightActionSize);
|
|
if (QRect(position.x(), position.y(), rightActionSize->width(), rightActionSize->height()).contains(point)) {
|
|
result.link = _parent->rightActionLink();
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
auto pixLeft = usex + (usew - _contentSize.width()) / 2;
|
|
auto pixTop = (minHeight() - _contentSize.height()) / 2;
|
|
// Link of content can be nullptr (e.g. sticker without stickerpack).
|
|
// So we have to process it to avoid overriding the previous result.
|
|
if (_content->link()
|
|
&& QRect({ pixLeft, pixTop }, _contentSize).contains(point)) {
|
|
result.link = _content->link();
|
|
return result;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
bool UnwrappedMedia::hasTextForCopy() const {
|
|
return _content->hasTextForCopy();
|
|
}
|
|
|
|
QRect UnwrappedMedia::contentRectForReactions() 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 = _contentSize.width();
|
|
accumulate_max(usew, _parent->reactionsOptimalWidth());
|
|
if (rightAligned) {
|
|
usex = width() - usew;
|
|
}
|
|
if (rtl()) {
|
|
usex = width() - usex - usew;
|
|
}
|
|
const auto usey = rightAligned ? _topAdded : (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::optional<int> UnwrappedMedia::reactionButtonCenterOverride() const {
|
|
const auto fullRight = calculateFullRight(contentRectForReactions());
|
|
const auto right = fullRight
|
|
- _parent->infoWidth()
|
|
- st::msgDateImgPadding.x() * 2
|
|
- st::msgReplyPadding.left();
|
|
return right - st::reactionCornerSize.width() / 2;
|
|
}
|
|
|
|
QPoint UnwrappedMedia::resolveCustomInfoRightBottom() const {
|
|
const auto inner = contentRectForReactions();
|
|
const auto fullBottom = inner.y() + inner.height();
|
|
const auto fullRight = calculateFullRight(inner);
|
|
const auto skipx = st::msgDateImgPadding.x();
|
|
const auto skipy = st::msgDateImgPadding.y();
|
|
return QPoint(fullRight - skipx, fullBottom - skipy);
|
|
}
|
|
|
|
std::unique_ptr<Lottie::SinglePlayer> UnwrappedMedia::stickerTakeLottie(
|
|
not_null<DocumentData*> data,
|
|
const Lottie::ColorReplacements *replacements) {
|
|
return _content->stickerTakeLottie(data, replacements);
|
|
}
|
|
|
|
//void UnwrappedMedia::externalLottieProgressing(bool external) {
|
|
// _content->externalLottieProgressing(external);
|
|
//}
|
|
//
|
|
//bool UnwrappedMedia::externalLottieTill(ExternalLottieInfo info) {
|
|
// return _content->externalLottieTill(info);
|
|
//}
|
|
//
|
|
//ExternalLottieInfo UnwrappedMedia::externalLottieInfo() const {
|
|
// return _content->externalLottieInfo();
|
|
//}
|
|
|
|
int UnwrappedMedia::calculateFullRight(const QRect &inner) const {
|
|
const auto rightAligned = _parent->hasOutLayout()
|
|
&& !_parent->delegate()->elementIsChatWide();
|
|
const auto infoWidth = _parent->infoWidth()
|
|
+ st::msgDateImgPadding.x() * 2
|
|
+ st::msgReplyPadding.left();
|
|
const auto rightActionSize = _parent->rightActionSize();
|
|
const auto rightSkip = st::msgPadding.left()
|
|
+ (_parent->hasFromPhoto()
|
|
? st::msgMargin.right()
|
|
: st::msgPadding.right());
|
|
const auto rightActionWidth = rightActionSize
|
|
? (st::historyFastShareLeft * 2
|
|
+ rightActionSize->width())
|
|
: 0;
|
|
auto fullRight = inner.x()
|
|
+ inner.width()
|
|
+ (rightAligned ? 0 : infoWidth);
|
|
if (fullRight + rightActionWidth + rightSkip > _parent->width()) {
|
|
fullRight = _parent->width() - rightActionWidth - rightSkip;
|
|
}
|
|
return fullRight;
|
|
}
|
|
|
|
QPoint UnwrappedMedia::calculateFastActionPosition(
|
|
int fullBottom,
|
|
int replyRight,
|
|
int fullRight,
|
|
QSize size) const {
|
|
const auto fastShareTop = (fullBottom
|
|
- st::historyFastShareBottom
|
|
- size.height());
|
|
const auto doesRightActionHitReply = replyRight && (fastShareTop <
|
|
st::msgReplyBarSize.height()
|
|
+ st::msgReplyPadding.top()
|
|
+ st::msgReplyPadding.bottom());
|
|
const auto fastShareLeft = ((doesRightActionHitReply
|
|
? replyRight
|
|
: fullRight) + st::historyFastShareLeft);
|
|
return QPoint(fastShareLeft, fastShareTop);
|
|
}
|
|
|
|
bool UnwrappedMedia::needInfoDisplay() const {
|
|
return _parent->data()->isSending()
|
|
|| _parent->data()->hasFailed()
|
|
|| _parent->isUnderCursor()
|
|
|| _parent->rightActionSize()
|
|
|| _parent->isLastAndSelfMessage()
|
|
|| (_parent->hasOutLayout()
|
|
&& !_parent->delegate()->elementIsChatWide()
|
|
&& _content->alwaysShowOutTimestamp());
|
|
}
|
|
|
|
int UnwrappedMedia::additionalWidth(
|
|
const HistoryMessageVia *via,
|
|
const HistoryMessageReply *reply,
|
|
const HistoryMessageForwarded *forwarded) const {
|
|
auto result = st::msgReplyPadding.left() + _parent->infoWidth() + 2 * st::msgDateImgPadding.x();
|
|
if (forwarded) {
|
|
accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + forwarded->text.maxWidth() + st::msgReplyPadding.right());
|
|
} else if (via) {
|
|
accumulate_max(result, st::msgReplyPadding.left() + st::msgReplyPadding.left() + via->maxWidth + st::msgReplyPadding.left());
|
|
}
|
|
if (reply) {
|
|
accumulate_max(result, st::msgReplyPadding.left() + reply->replyToWidth());
|
|
}
|
|
return result;
|
|
}
|
|
|
|
auto UnwrappedMedia::getDisplayedForwardedInfo() const
|
|
-> const HistoryMessageForwarded * {
|
|
return _parent->displayForwardedFrom()
|
|
? _parent->data()->Get<HistoryMessageForwarded>()
|
|
: nullptr;
|
|
}
|
|
|
|
} // namespace HistoryView
|