Improve reply preview above the field.

This commit is contained in:
John Preston 2023-11-13 10:07:46 +04:00
parent 617be49e55
commit edb7cf197a
23 changed files with 215 additions and 191 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 759 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -2714,6 +2714,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_forwarding_from_two" = "{user} and {second_user}";
"lng_inline_switch_choose" = "Choose conversation...";
"lng_inline_switch_cant" = "Sorry, no way to write here :(";
"lng_preview_reply_to" = "Reply to {name}";
"lng_preview_reply_to_quote" = "Reply to quote by {name}";
"lng_reply_in_another_title" = "Reply in...";
"lng_reply_in_another_chat" = "Reply in Another Chat";

View file

@ -827,11 +827,13 @@ historyEmojiStatusInfoLabel: FlatLabel(historyContactStatusLabel) {
}
historyContactStatusMinSkip: 16px;
historyReplySkip: 51px;
historyReplySkip: 53px;
historyReplyNameFg: windowActiveTextFg;
historyReplyHeight: 49px;
historyReplyIconPosition: point(5px, 5px);
historyReplyIcon: icon {{ "chat/input_reply", historyReplyIconFg }};
historyReplyIconPosition: point(7px, 7px);
historyReplyIcon: icon {{ "chat/input_reply_settings", historyReplyIconFg }};
historyLinkIcon: icon {{ "chat/input_link_settings", historyReplyIconFg }};
historyQuoteIcon: icon {{ "chat/input_reply_quote", historyReplyIconFg }};
historyForwardIcon: icon {{ "chat/input_forward", historyReplyIconFg }};
historyEditIcon: icon {{ "chat/input_edit", historyReplyIconFg }};
historyReplyCancel: IconButton {

View file

@ -101,6 +101,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_pinned_bar.h"
#include "history/view/history_view_group_call_bar.h"
#include "history/view/history_view_item_preview.h"
#include "history/view/history_view_reply.h"
#include "history/view/history_view_requests_bar.h"
#include "history/view/history_view_sticker_toast.h"
#include "history/view/history_view_translate_bar.h"
@ -4374,11 +4375,10 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
void HistoryWidget::updateOverStates(QPoint pos) {
const auto isReadyToForward = readyToForward();
const auto skip = isReadyToForward ? 0 : st::historyReplySkip;
const auto detailsRect = QRect(
skip,
0,
_field->y() - st::historySendPadding - st::historyReplyHeight,
width() - skip - _fieldBarCancel->width(),
width() - _fieldBarCancel->width(),
st::historyReplyHeight);
const auto hasWebPage = !!_previewDrawPreview;
const auto inDetails = detailsRect.contains(pos)
@ -4418,10 +4418,6 @@ void HistoryWidget::leaveToChildEvent(QEvent *e, QWidget *child) { // e -- from
}
void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
if (_replyForwardPressed) {
_replyForwardPressed = false;
update(0, _field->y() - st::historySendPadding - st::historyReplyHeight, width(), st::historyReplyHeight);
}
}
void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) {
@ -6243,20 +6239,7 @@ bool HistoryWidget::cornerButtonsHas(HistoryView::CornerButtonType type) {
void HistoryWidget::mousePressEvent(QMouseEvent *e) {
const auto isReadyToForward = readyToForward();
const auto hasSecondLayer = (_editMsgId
|| _replyTo
|| isReadyToForward
|| _kbReplyTo);
_replyForwardPressed = hasSecondLayer && QRect(
0,
_field->y() - st::historySendPadding - st::historyReplyHeight,
st::historyReplySkip,
st::historyReplyHeight).contains(e->pos());
if (_replyForwardPressed
&& !_fieldBarCancel->isHidden()
&& !isReadyToForward) {
updateField();
} else if (_inPhotoEdit && _photoEditMedia) {
if (_inPhotoEdit && _photoEditMedia) {
EditCaptionBox::StartPhotoEdit(
controller(),
_photoEditMedia,
@ -7486,7 +7469,6 @@ void HistoryWidget::cancelEdit() {
void HistoryWidget::cancelFieldAreaState() {
controller()->hideLayer();
_replyForwardPressed = false;
if (_previewDrawPreview) {
_preview->apply({ .removed = true });
} else if (_editMsgId) {
@ -7818,25 +7800,23 @@ void HistoryWidget::updateForwarding() {
}
void HistoryWidget::updateReplyToName() {
if (_editMsgId) {
if (!_history || _editMsgId) {
return;
} else if (!_replyEditMsg && (_replyTo || !_kbReplyTo)) {
return;
}
const auto from = [&] {
const auto item = _replyEditMsg ? _replyEditMsg : _kbReplyTo;
if (const auto from = item->displayFrom()) {
return from;
}
return item->author().get();
}();
_replyToName.setText(
st::msgNameStyle,
from->name(),
Ui::NameTextOptions());
_replyToNameVersion = (_replyEditMsg
? _replyEditMsg
: _kbReplyTo)->author()->nameVersion();
const auto context = Core::MarkedTextContext{
.session = &_history->session(),
.customEmojiRepaint = [] {},
.customEmojiLoopLimit = 1,
};
const auto to = _replyEditMsg ? _replyEditMsg : _kbReplyTo;
const auto replyToQuote = _replyTo && !_replyTo.quote.empty();
_replyToName.setMarkedText(
st::fwdTextStyle,
HistoryView::Reply::ComposePreviewName(_history, to, replyToQuote),
Ui::NameTextOptions(),
context);
}
void HistoryWidget::updateField() {
@ -7856,12 +7836,6 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
auto hasForward = readyToForward();
auto drawMsgText = (_editMsgId || _replyTo) ? _replyEditMsg : _kbReplyTo;
if (_editMsgId || _replyTo || (!hasForward && _kbReplyTo)) {
if (!_editMsgId
&& drawMsgText
&& (_replyToNameVersion
< drawMsgText->author()->nameVersion())) {
updateReplyToName();
}
backy -= st::historyReplyHeight;
backh += st::historyReplyHeight;
} else if (hasForward) {
@ -7871,12 +7845,11 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
backy -= st::historyReplyHeight;
backh += st::historyReplyHeight;
}
auto drawWebPagePreview = _previewDrawPreview && !_replyForwardPressed;
p.setInactive(
controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any));
p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg);
const auto media = (!drawWebPagePreview && drawMsgText)
const auto media = (!_previewDrawPreview && drawMsgText)
? drawMsgText->media()
: nullptr;
const auto hasPreview = media && media->hasReplyPreview();
@ -7890,86 +7863,11 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
});
}
if (_editMsgId || _replyTo || (!hasForward && _kbReplyTo)) {
const auto now = crl::now();
const auto paused = p.inactive();
const auto pausedSpoiler = paused || On(PowerSaving::kChatSpoiler);
auto replyLeft = st::historyReplySkip;
(_editMsgId ? st::historyEditIcon : st::historyReplyIcon).paint(p, st::historyReplyIconPosition + QPoint(0, backy), width());
if (!drawWebPagePreview) {
if (drawMsgText) {
if (hasPreview) {
if (preview) {
const auto overEdit = _photoEditMedia
? _inPhotoEditOver.value(_inPhotoEdit ? 1. : 0.)
: 0.;
auto to = QRect(
replyLeft,
backy + (st::historyReplyHeight - st::historyReplyPreview) / 2,
st::historyReplyPreview,
st::historyReplyPreview);
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
preview->size() / style::DevicePixelRatio(),
{
.options = Images::Option::RoundSmall,
.outer = to.size(),
}));
if (_replySpoiler) {
if (overEdit > 0.) {
p.setOpacity(1. - overEdit);
}
Ui::FillSpoilerRect(
p,
to,
Ui::DefaultImageSpoiler().frame(
_replySpoiler->index(now, pausedSpoiler)));
}
if (overEdit > 0.) {
p.setOpacity(overEdit);
p.fillRect(to, st::historyEditMediaBg);
st::historyEditMedia.paintInCenter(p, to);
p.setOpacity(1.);
}
}
replyLeft += st::historyReplyPreview + st::msgReplyBarSkip;
}
p.setPen(st::historyReplyNameFg);
if (_editMsgId) {
paintEditHeader(p, rect, replyLeft, backy);
} else {
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
}
p.setPen(st::historyComposeAreaFg);
_replyEditMsgText.draw(p, {
.position = QPoint(
replyLeft,
backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height),
.availableWidth = width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right(),
.palette = &st::historyComposeAreaPalette,
.spoiler = Ui::Text::DefaultSpoilerCache(),
.now = now,
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = pausedSpoiler,
.elisionLines = 1,
});
} else {
p.setFont(st::msgDateFont);
p.setPen(st::historyComposeAreaFgService);
p.drawText(replyLeft, backy + (st::historyReplyHeight - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
}
}
} else if (hasForward) {
st::historyForwardIcon.paint(p, st::historyReplyIconPosition + QPoint(0, backy), width());
if (!drawWebPagePreview) {
const auto x = st::historyReplySkip;
const auto available = width()
- x
- _fieldBarCancel->width()
- st::msgReplyPadding.right();
_forwardPanel->paint(p, x, backy, available, width());
}
}
if (drawWebPagePreview) {
if (_previewDrawPreview) {
st::historyLinkIcon.paint(
p,
st::historyReplyIconPosition + QPoint(0, backy),
width());
const auto textTop = backy + st::msgReplyPadding.top();
auto previewLeft = st::historyReplySkip;
@ -7998,6 +7896,87 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
previewLeft,
textTop + st::msgServiceNameFont->height,
elidedWidth);
} else if (_editMsgId || _replyTo || (!hasForward && _kbReplyTo)) {
const auto now = crl::now();
const auto paused = p.inactive();
const auto pausedSpoiler = paused || On(PowerSaving::kChatSpoiler);
auto replyLeft = st::historyReplySkip;
(_editMsgId
? st::historyEditIcon
: (_replyTo && !_replyTo.quote.empty())
? st::historyQuoteIcon
: st::historyReplyIcon).paint(
p,
st::historyReplyIconPosition + QPoint(0, backy),
width());
if (drawMsgText) {
if (hasPreview) {
if (preview) {
const auto overEdit = _photoEditMedia
? _inPhotoEditOver.value(_inPhotoEdit ? 1. : 0.)
: 0.;
auto to = QRect(
replyLeft,
backy + (st::historyReplyHeight - st::historyReplyPreview) / 2,
st::historyReplyPreview,
st::historyReplyPreview);
p.drawPixmap(to.x(), to.y(), preview->pixSingle(
preview->size() / style::DevicePixelRatio(),
{
.options = Images::Option::RoundSmall,
.outer = to.size(),
}));
if (_replySpoiler) {
if (overEdit > 0.) {
p.setOpacity(1. - overEdit);
}
Ui::FillSpoilerRect(
p,
to,
Ui::DefaultImageSpoiler().frame(
_replySpoiler->index(now, pausedSpoiler)));
}
if (overEdit > 0.) {
p.setOpacity(overEdit);
p.fillRect(to, st::historyEditMediaBg);
st::historyEditMedia.paintInCenter(p, to);
p.setOpacity(1.);
}
}
replyLeft += st::historyReplyPreview + st::msgReplyBarSkip;
}
p.setPen(st::historyReplyNameFg);
if (_editMsgId) {
paintEditHeader(p, rect, replyLeft, backy);
} else {
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
}
p.setPen(st::historyComposeAreaFg);
_replyEditMsgText.draw(p, {
.position = QPoint(
replyLeft,
backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height),
.availableWidth = width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right(),
.palette = &st::historyComposeAreaPalette,
.spoiler = Ui::Text::DefaultSpoilerCache(),
.now = now,
.pausedEmoji = paused || On(PowerSaving::kEmojiChat),
.pausedSpoiler = pausedSpoiler,
.elisionLines = 1,
});
} else {
p.setFont(st::msgDateFont);
p.setPen(st::historyComposeAreaFgService);
p.drawText(replyLeft, backy + (st::historyReplyHeight - st::msgDateFont->height) / 2 + st::msgDateFont->ascent, st::msgDateFont->elided(tr::lng_profile_loading(tr::now), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()));
}
} else if (hasForward) {
st::historyForwardIcon.paint(p, st::historyReplyIconPosition + QPoint(0, backy), width());
const auto x = st::historyReplySkip;
const auto available = width()
- x
- _fieldBarCancel->width()
- st::msgReplyPadding.right();
_forwardPanel->paint(p, x, backy, available, width());
}
}

View file

@ -647,7 +647,6 @@ private:
MTP::Sender _api;
FullReplyTo _replyTo;
Ui::Text::String _replyToName;
int _replyToNameVersion = 0;
FullReplyTo _processingReplyTo;
HistoryItem *_processingReplyItem = nullptr;
@ -688,8 +687,6 @@ private:
Ui::Text::String _previewTitle;
Ui::Text::String _previewDescription;
bool _replyForwardPressed = false;
PeerData *_peer = nullptr;
bool _canSendMessages = false;

View file

@ -51,6 +51,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/controls/history_view_voice_record_bar.h"
#include "history/view/controls/history_view_ttl_button.h"
#include "history/view/controls/history_view_webpage_processor.h"
#include "history/view/history_view_reply.h"
#include "history/view/history_view_webpage_preview.h"
#include "inline_bots/bot_attach_web_view.h"
#include "inline_bots/inline_results_widget.h"
@ -192,7 +193,6 @@ private:
Ui::Text::String _shownMessageText;
std::unique_ptr<Ui::SpoilerAnimation> _shownPreviewSpoiler;
Ui::Animations::Simple _inPhotoEditOver;
int _shownMessageNameVersion = -1;
bool _shownMessageHasPreview : 1 = false;
bool _inPhotoEdit : 1 = false;
bool _photoEditAllowed : 1 = false;
@ -245,7 +245,6 @@ void FieldHeader::init() {
updateVisible();
}, lifetime());
const auto leftIconPressed = lifetime().make_state<bool>(false);
paintRequest(
) | rpl::start_with_next([=] {
Painter p(this);
@ -253,21 +252,29 @@ void FieldHeader::init() {
p.fillRect(rect(), st::historyComposeAreaBg);
const auto position = st::historyReplyIconPosition;
if (isEditingMessage()) {
if (_preview.parsed) {
st::historyLinkIcon.paint(p, position, width());
} else if (isEditingMessage()) {
st::historyEditIcon.paint(p, position, width());
} else if (readyToForward()) {
st::historyForwardIcon.paint(p, position, width());
} else if (replyingToMessage()) {
st::historyReplyIcon.paint(p, position, width());
} else if (const auto reply = replyingToMessage()) {
if (!reply.quote.empty()) {
st::historyQuoteIcon.paint(p, position, width());
} else {
st::historyReplyIcon.paint(p, position, width());
}
}
(_preview.parsed && !*leftIconPressed)
? paintWebPage(
if (_preview.parsed) {
paintWebPage(
p,
_history ? _history->peer : _data->session().user())
: (isEditingMessage() || !readyToForward())
? paintEditOrReplyToMessage(p)
: paintForwardInfo(p);
_history ? _history->peer : _data->session().user());
} else if (isEditingMessage() || !readyToForward()) {
paintEditOrReplyToMessage(p);
} else {
paintForwardInfo(p);
}
}, lifetime());
_editMsgId.value(
@ -359,13 +366,9 @@ void FieldHeader::init() {
updateOver(inPreviewRect, inPhotoEdit);
return;
}
const auto isLeftIcon = (pos.x() < st::historyReplySkip);
const auto isLeftButton = (e->button() == Qt::LeftButton);
if (type == QEvent::MouseButtonPress) {
if (isLeftButton && isLeftIcon && !inPreviewRect) {
*leftIconPressed = true;
update();
} else if (isLeftButton && inPhotoEdit) {
if (isLeftButton && inPhotoEdit) {
_editPhotoRequests.fire({});
} else if (isLeftButton && inPreviewRect) {
const auto reply = replyingToMessage();
@ -384,11 +387,6 @@ void FieldHeader::init() {
_editOptionsRequests.fire({});
}
}
} else if (type == QEvent::MouseButtonRelease) {
if (isLeftButton && *leftIconPressed) {
*leftIconPressed = false;
update();
}
}
}, lifetime());
}
@ -431,9 +429,21 @@ void FieldHeader::setShownMessage(HistoryItem *item) {
st::msgNameStyle,
tr::lng_edit_message(tr::now),
Ui::NameTextOptions());
} else if (item) {
const auto context = Core::MarkedTextContext{
.session = &_history->session(),
.customEmojiRepaint = [] {},
.customEmojiLoopLimit = 1,
};
const auto replyTo = _replyTo.current();
const auto quote = replyTo && !replyTo.quote.empty();
_shownMessageName.setMarkedText(
st::fwdTextStyle,
HistoryView::Reply::ComposePreviewName(_history, item, quote),
Ui::NameTextOptions(),
context);
} else {
_shownMessageName.clear();
_shownMessageNameVersion = -1;
}
updateVisible();
update();
@ -545,19 +555,6 @@ void FieldHeader::paintEditOrReplyToMessage(Painter &p) {
return;
}
if (!isEditingMessage()) {
const auto user = _shownMessage->displayFrom()
? _shownMessage->displayFrom()
: _shownMessage->author().get();
if (_shownMessageNameVersion < user->nameVersion()) {
_shownMessageName.setText(
st::msgNameStyle,
user->name(),
Ui::NameTextOptions());
_shownMessageNameVersion = user->nameVersion();
}
}
const auto media = _shownMessage->media();
_shownMessageHasPreview = media && media->hasReplyPreview();
const auto preview = _shownMessageHasPreview
@ -692,12 +689,11 @@ FullReplyTo FieldHeader::getDraftReply() const {
void FieldHeader::updateControlsGeometry(QSize size) {
const auto isReadyToForward = readyToForward();
const auto skip = isReadyToForward ? 0 : st::historyReplySkip;
_cancel->moveToRight(0, 0);
_clickableRect = QRect(
skip,
0,
width() - skip - _cancel->width(),
0,
width() - _cancel->width(),
height());
_shownMessagePreviewRect = QRect(
st::historyReplySkip,

View file

@ -642,6 +642,8 @@ void DraftOptionsBox(
if (const auto current = state->quote.current()) {
result.messageId = current.item->fullId();
result.quote = current.text;
} else {
result.quote = {};
}
return result;
};

View file

@ -394,10 +394,11 @@ void Reply::updateName(
viaBotUsername = bot->username();
}
}
const auto history = view->history();
const auto &fields = data->fields();
const auto sender = resolvedSender.value_or(this->sender(view, data));
const auto externalPeer = fields.externalPeerId
? view->history()->owner().peer(fields.externalPeerId).get()
? history->owner().peer(fields.externalPeerId).get()
: nullptr;
const auto displayAsExternal = data->displayAsExternal(view->data());
const auto groupNameAdded = displayAsExternal
@ -415,38 +416,20 @@ void Reply::updateName(
+ st::historyReplyPreviewMargin.right()
- st::historyReplyPadding.left())
: 0;
const auto peerIcon = [](PeerData *peer) {
using namespace std;
return !peer
? pair(&st::historyReplyUser, st::historyReplyUserPadding)
: peer->isBroadcast()
? pair(&st::historyReplyChannel, st::historyReplyChannelPadding)
: (peer->isChannel() || peer->isChat())
? pair(&st::historyReplyGroup, st::historyReplyGroupPadding)
: pair(&st::historyReplyUser, st::historyReplyUserPadding);
};
const auto peerEmoji = [&](PeerData *peer) {
const auto owner = &view->history()->owner();
const auto icon = peerIcon(peer);
return Ui::Text::SingleCustomEmoji(
owner->customEmojiManager().registerInternalEmoji(
*icon.first,
icon.second));
};
auto nameFull = TextWithEntities();
if (displayAsExternal && !groupNameAdded && !fields.storyId) {
nameFull.append(peerEmoji(sender));
nameFull.append(PeerEmoji(history, sender));
}
nameFull.append(name);
if (groupNameAdded) {
nameFull.append(' ').append(peerEmoji(externalPeer));
nameFull.append(' ').append(PeerEmoji(history, externalPeer));
nameFull.append(externalPeer->name());
}
if (!viaBotUsername.isEmpty()) {
nameFull.append(u" @"_q).append(viaBotUsername);
}
const auto context = Core::MarkedTextContext{
.session = &view->history()->session(),
.session = &history->session(),
.customEmojiRepaint = [] {},
.customEmojiLoopLimit = 1,
};
@ -813,6 +796,61 @@ void Reply::stopLastRipple() {
}
}
TextWithEntities Reply::PeerEmoji(
not_null<History*> history,
PeerData *peer) {
using namespace std;
const auto icon = !peer
? pair(&st::historyReplyUser, st::historyReplyUserPadding)
: peer->isBroadcast()
? pair(&st::historyReplyChannel, st::historyReplyChannelPadding)
: (peer->isChannel() || peer->isChat())
? pair(&st::historyReplyGroup, st::historyReplyGroupPadding)
: pair(&st::historyReplyUser, st::historyReplyUserPadding);
const auto owner = &history->owner();
return Ui::Text::SingleCustomEmoji(
owner->customEmojiManager().registerInternalEmoji(
*icon.first,
icon.second));
}
TextWithEntities Reply::ComposePreviewName(
not_null<History*> history,
not_null<HistoryItem*> to,
bool quote) {
const auto sender = [&] {
if (const auto from = to->displayFrom()) {
return not_null(from);
}
return to->author();
}();
const auto toPeer = to->history()->peer;
const auto displayAsExternal = (to->history() != history);
const auto groupNameAdded = displayAsExternal
&& (toPeer != sender)
&& (toPeer->isChat() || toPeer->isMegagroup());
const auto shorten = groupNameAdded || quote;
auto nameFull = TextWithEntities();
using namespace HistoryView;
if (displayAsExternal && !groupNameAdded) {
nameFull.append(Reply::PeerEmoji(history, sender));
}
nameFull.append(shorten ? sender->shortName() : sender->name());
if (groupNameAdded) {
nameFull.append(' ').append(Reply::PeerEmoji(history, toPeer));
nameFull.append(toPeer->name());
}
return (quote
? tr::lng_preview_reply_to_quote
: tr::lng_preview_reply_to)(
tr::now,
lt_name,
nameFull,
Ui::Text::WithEntities);
}
void Reply::unloadPersistentAnimation() {
_text.unloadPersistentAnimation();
}

View file

@ -63,6 +63,14 @@ public:
return _link;
}
[[nodiscard]] static TextWithEntities PeerEmoji(
not_null<History*> history,
PeerData *peer);
[[nodiscard]] static TextWithEntities ComposePreviewName(
not_null<History*> history,
not_null<HistoryItem*> to,
bool quote);
private:
[[nodiscard]] Ui::Text::GeometryDescriptor textGeometry(
int available,