diff --git a/Telegram/Resources/icons/chat/input_forward.png b/Telegram/Resources/icons/chat/input_forward.png index c04e20ceb..2d9c78335 100644 Binary files a/Telegram/Resources/icons/chat/input_forward.png and b/Telegram/Resources/icons/chat/input_forward.png differ diff --git a/Telegram/Resources/icons/chat/input_forward@2x.png b/Telegram/Resources/icons/chat/input_forward@2x.png index c500804d0..26e435458 100644 Binary files a/Telegram/Resources/icons/chat/input_forward@2x.png and b/Telegram/Resources/icons/chat/input_forward@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_forward@3x.png b/Telegram/Resources/icons/chat/input_forward@3x.png index 9df3f2369..488f8e1e1 100644 Binary files a/Telegram/Resources/icons/chat/input_forward@3x.png and b/Telegram/Resources/icons/chat/input_forward@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_link_settings.png b/Telegram/Resources/icons/chat/input_link_settings.png new file mode 100644 index 000000000..bd01d4ad1 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_link_settings.png differ diff --git a/Telegram/Resources/icons/chat/input_link_settings@2x.png b/Telegram/Resources/icons/chat/input_link_settings@2x.png new file mode 100644 index 000000000..0eb12d203 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_link_settings@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_link_settings@3x.png b/Telegram/Resources/icons/chat/input_link_settings@3x.png new file mode 100644 index 000000000..851858faf Binary files /dev/null and b/Telegram/Resources/icons/chat/input_link_settings@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply.png b/Telegram/Resources/icons/chat/input_reply.png deleted file mode 100644 index f20b99773..000000000 Binary files a/Telegram/Resources/icons/chat/input_reply.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_reply@2x.png b/Telegram/Resources/icons/chat/input_reply@2x.png deleted file mode 100644 index e44f5f79e..000000000 Binary files a/Telegram/Resources/icons/chat/input_reply@2x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_reply@3x.png b/Telegram/Resources/icons/chat/input_reply@3x.png deleted file mode 100644 index 97688789f..000000000 Binary files a/Telegram/Resources/icons/chat/input_reply@3x.png and /dev/null differ diff --git a/Telegram/Resources/icons/chat/input_reply_quote.png b/Telegram/Resources/icons/chat/input_reply_quote.png new file mode 100644 index 000000000..0f0ade5dc Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_quote.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_quote@2x.png b/Telegram/Resources/icons/chat/input_reply_quote@2x.png new file mode 100644 index 000000000..c7bcb7d8e Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_quote@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_quote@3x.png b/Telegram/Resources/icons/chat/input_reply_quote@3x.png new file mode 100644 index 000000000..f1bc500a1 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_quote@3x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_settings.png b/Telegram/Resources/icons/chat/input_reply_settings.png new file mode 100644 index 000000000..9b67e535c Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_settings.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_settings@2x.png b/Telegram/Resources/icons/chat/input_reply_settings@2x.png new file mode 100644 index 000000000..2a4aef116 Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_settings@2x.png differ diff --git a/Telegram/Resources/icons/chat/input_reply_settings@3x.png b/Telegram/Resources/icons/chat/input_reply_settings@3x.png new file mode 100644 index 000000000..e2f131d6a Binary files /dev/null and b/Telegram/Resources/icons/chat/input_reply_settings@3x.png differ diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index 39c744769..fc0ca0d22 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -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"; diff --git a/Telegram/SourceFiles/chat_helpers/chat_helpers.style b/Telegram/SourceFiles/chat_helpers/chat_helpers.style index d100850ee..3739ef7e3 100644 --- a/Telegram/SourceFiles/chat_helpers/chat_helpers.style +++ b/Telegram/SourceFiles/chat_helpers/chat_helpers.style @@ -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 { diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 05a339a80..07dcbb56c 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -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()); } } diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 87b7edde9..10a54c858 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -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; diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 540d4ca5f..f697baf00 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -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 _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(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, diff --git a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp index 850ecfe6b..6812cb273 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_draft_options.cpp @@ -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; }; diff --git a/Telegram/SourceFiles/history/view/history_view_reply.cpp b/Telegram/SourceFiles/history/view/history_view_reply.cpp index 6899a0832..10877d5c1 100644 --- a/Telegram/SourceFiles/history/view/history_view_reply.cpp +++ b/Telegram/SourceFiles/history/view/history_view_reply.cpp @@ -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, + 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, + not_null 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(); } diff --git a/Telegram/SourceFiles/history/view/history_view_reply.h b/Telegram/SourceFiles/history/view/history_view_reply.h index 5322d5c09..4b30a842d 100644 --- a/Telegram/SourceFiles/history/view/history_view_reply.h +++ b/Telegram/SourceFiles/history/view/history_view_reply.h @@ -63,6 +63,14 @@ public: return _link; } + [[nodiscard]] static TextWithEntities PeerEmoji( + not_null history, + PeerData *peer); + [[nodiscard]] static TextWithEntities ComposePreviewName( + not_null history, + not_null to, + bool quote); + private: [[nodiscard]] Ui::Text::GeometryDescriptor textGeometry( int available,