Improve reply preview above the field.
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 759 B |
Before Width: | Height: | Size: 858 B After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/chat/input_link_settings.png
Normal file
After Width: | Height: | Size: 829 B |
BIN
Telegram/Resources/icons/chat/input_link_settings@2x.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
Telegram/Resources/icons/chat/input_link_settings@3x.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 593 B |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.8 KiB |
BIN
Telegram/Resources/icons/chat/input_reply_quote.png
Normal file
After Width: | Height: | Size: 676 B |
BIN
Telegram/Resources/icons/chat/input_reply_quote@2x.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
Telegram/Resources/icons/chat/input_reply_quote@3x.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Telegram/Resources/icons/chat/input_reply_settings.png
Normal file
After Width: | Height: | Size: 711 B |
BIN
Telegram/Resources/icons/chat/input_reply_settings@2x.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Telegram/Resources/icons/chat/input_reply_settings@3x.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
|
@ -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";
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|