From 839e59075d201d19dc6ff9fd65a531769445c7bd Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 20 Jun 2017 22:48:53 +0300 Subject: [PATCH] Display log entry original data in HistoryMessage. --- Telegram/Resources/langs/lang.strings | 2 +- Telegram/SourceFiles/app.cpp | 21 ++++-- Telegram/SourceFiles/app.h | 3 +- .../history/history_admin_log_item.cpp | 8 +-- Telegram/SourceFiles/history/history_item.cpp | 19 ++++-- Telegram/SourceFiles/history/history_item.h | 16 ++--- .../history/history_media_types.cpp | 14 ++-- .../SourceFiles/history/history_media_types.h | 12 ++-- .../SourceFiles/history/history_message.cpp | 66 ++++++++++++++++--- .../SourceFiles/history/history_message.h | 4 +- Telegram/SourceFiles/historywidget.cpp | 8 +-- .../SourceFiles/overview/overview_layout.cpp | 8 +-- Telegram/SourceFiles/structs.cpp | 2 +- Telegram/SourceFiles/structs.h | 5 +- 14 files changed, 127 insertions(+), 61 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index f453bde74..a7dc4bfae 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1344,7 +1344,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org "lng_admin_log_signatures_disabled" = "{from} disabled signatures"; "lng_admin_log_pinned_message" = "{from} pinned message:"; "lng_admin_log_edited_caption" = "{from} edited caption:"; -"lng_admin_log_removed_caption" = "{from} removed caption:"; +"lng_admin_log_removed_caption" = "{from} removed caption"; "lng_admin_log_previous_caption" = "Original caption"; "lng_admin_log_edited_message" = "{from} edited message:"; "lng_admin_log_previous_message" = "Original message"; diff --git a/Telegram/SourceFiles/app.cpp b/Telegram/SourceFiles/app.cpp index c5c1d43b6..1a1b0224c 100644 --- a/Telegram/SourceFiles/app.cpp +++ b/Telegram/SourceFiles/app.cpp @@ -1497,11 +1497,18 @@ namespace { } WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert) { - return App::webPageSet(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), webpage.has_site_name() ? qs(webpage.vsite_name) : QString(), webpage.has_title() ? qs(webpage.vtitle) : QString(), webpage.has_description() ? qs(webpage.vdescription) : QString(), webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : 0, webpage.has_document() ? App::feedDocument(webpage.vdocument) : 0, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0); + auto description = TextWithEntities { webpage.has_description() ? textClean(qs(webpage.vdescription)) : QString() }; + auto siteName = webpage.has_site_name() ? qs(webpage.vsite_name) : QString(); + auto parseFlags = TextParseLinks | TextParseMultiline | TextParseRichText; + if (siteName == qstr("Twitter") || siteName == qstr("Instagram")) { + parseFlags |= TextParseHashtags | TextParseMentions; + } + textParseEntities(description.text, parseFlags, &description.entities); + return App::webPageSet(webpage.vid.v, convert, webpage.has_type() ? qs(webpage.vtype) : qsl("article"), qs(webpage.vurl), qs(webpage.vdisplay_url), siteName, webpage.has_title() ? qs(webpage.vtitle) : QString(), description, webpage.has_photo() ? App::feedPhoto(webpage.vphoto) : nullptr, webpage.has_document() ? App::feedDocument(webpage.vdocument) : nullptr, webpage.has_duration() ? webpage.vduration.v : 0, webpage.has_author() ? qs(webpage.vauthor) : QString(), 0); } WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert) { - return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), QString(), 0, 0, 0, QString(), webpage.vdate.v); + return App::webPageSet(webpage.vid.v, convert, QString(), QString(), QString(), QString(), QString(), TextWithEntities(), nullptr, nullptr, 0, QString(), webpage.vdate.v); } WebPageData *feedWebPage(const MTPWebPage &webpage) { @@ -1518,6 +1525,10 @@ namespace { return nullptr; } + WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content) { + return App::webPageSet(webPageId, nullptr, qsl("article"), QString(), QString(), siteName, QString(), content, nullptr, nullptr, 0, QString(), 0); + } + GameData *feedGame(const MTPDgame &game, GameData *convert) { return App::gameSet(game.vid.v, convert, game.vaccess_hash.v, qs(game.vshort_name), qs(game.vtitle), qs(game.vdescription), App::feedPhoto(game.vphoto), game.has_document() ? App::feedDocument(game.vdocument) : nullptr); } @@ -1778,7 +1789,7 @@ namespace { return i.value(); } - WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *document, int32 duration, const QString &author, int32 pendingTill) { + WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *document, int32 duration, const QString &author, int32 pendingTill) { if (convert) { if (convert->id != webPage) { auto i = webPagesData.find(convert->id); @@ -1793,7 +1804,7 @@ namespace { convert->displayUrl = textClean(displayUrl); convert->siteName = textClean(siteName); convert->title = textOneLine(textClean(title)); - convert->description = textClean(description); + convert->description = description; convert->photo = photo; convert->document = document; convert->duration = duration; @@ -1824,7 +1835,7 @@ namespace { result->displayUrl = textClean(displayUrl); result->siteName = textClean(siteName); result->title = textOneLine(textClean(title)); - result->description = textClean(description); + result->description = description; result->photo = photo; result->document = document; result->duration = duration; diff --git a/Telegram/SourceFiles/app.h b/Telegram/SourceFiles/app.h index c7251333b..f3aeeee83 100644 --- a/Telegram/SourceFiles/app.h +++ b/Telegram/SourceFiles/app.h @@ -104,6 +104,7 @@ namespace App { WebPageData *feedWebPage(const MTPDwebPage &webpage, WebPageData *convert = nullptr); WebPageData *feedWebPage(const MTPDwebPagePending &webpage, WebPageData *convert = nullptr); WebPageData *feedWebPage(const MTPWebPage &webpage); + WebPageData *feedWebPage(WebPageId webPageId, const QString &siteName, const TextWithEntities &content); GameData *feedGame(const MTPDgame &game, GameData *convert = nullptr); PeerData *peer(const PeerId &id, PeerData::LoadedStatus restriction = PeerData::NotLoaded); @@ -156,7 +157,7 @@ namespace App { DocumentData *document(const DocumentId &document); DocumentData *documentSet(const DocumentId &document, DocumentData *convert, const uint64 &access, int32 version, int32 date, const QVector &attributes, const QString &mime, const ImagePtr &thumb, int32 dc, int32 size, const StorageImageLocation &thumbLocation); WebPageData *webPage(const WebPageId &webPage); - WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill); + WebPageData *webPageSet(const WebPageId &webPage, WebPageData *convert, const QString &type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, PhotoData *photo, DocumentData *doc, int32 duration, const QString &author, int32 pendingTill); GameData *game(const GameId &game); GameData *gameSet(const GameId &game, GameData *convert, const uint64 &accessHash, const QString &shortName, const QString &title, const QString &description, PhotoData *photo, DocumentData *doc); LocationData *location(const LocationCoords &coords); diff --git a/Telegram/SourceFiles/history/history_admin_log_item.cpp b/Telegram/SourceFiles/history/history_admin_log_item.cpp index 11eb9a5cb..209940ab5 100644 --- a/Telegram/SourceFiles/history/history_admin_log_item.cpp +++ b/Telegram/SourceFiles/history/history_admin_log_item.cpp @@ -49,7 +49,7 @@ MTPMessage PrepareLogMessage(const MTPMessage &message, MsgId newId, int32 newDa } break; case mtpc_message: { auto &data = message.c_message(); - auto flags = data.vflags.v & ~(MTPDmessage::Flag::f_out | MTPDmessage::Flag::f_post | MTPDmessage::Flag::f_reply_to_msg_id); + auto flags = data.vflags.v & ~(MTPDmessage::Flag::f_out | MTPDmessage::Flag::f_post | MTPDmessage::Flag::f_reply_to_msg_id | MTPDmessage::Flag::f_edit_date); return MTP_message(MTP_flags(flags), MTP_int(newId), data.vfrom_id, data.vto_id, data.vfwd_from, data.vvia_bot_id, data.vreply_to_msg_id, MTP_int(newDate), data.vmessage, data.vmedia, data.vreply_markup, data.ventities, data.vviews, data.vedit_date); } break; } @@ -273,7 +273,7 @@ Item::Item(gsl::not_null history, LocalIdManager &idManager, const MTP auto body = HistoryMessage::create(_history, idManager.next(), bodyFlags, bodyReplyTo, bodyViaBotId, ::date(date), peerToUser(_from->id), newDescription); if (!oldValue.isEmpty()) { auto oldDescription = PrepareText(oldValue, QString()); - body->addLogEntryOriginal(lang(lng_admin_log_previous_description), oldDescription); + body->addLogEntryOriginal(_id, lang(lng_admin_log_previous_description), oldDescription); } addPart(body); }; @@ -294,7 +294,7 @@ Item::Item(gsl::not_null history, LocalIdManager &idManager, const MTP auto body = HistoryMessage::create(_history, idManager.next(), bodyFlags, bodyReplyTo, bodyViaBotId, ::date(date), peerToUser(_from->id), newLink); if (!oldValue.isEmpty()) { auto oldLink = PrepareText(Messenger::Instance().createInternalLinkFull(oldValue), QString()); - body->addLogEntryOriginal(lang(lng_admin_log_previous_link), oldLink); + body->addLogEntryOriginal(_id, lang(lng_admin_log_previous_link), oldLink); } addPart(body); }; @@ -342,7 +342,7 @@ Item::Item(gsl::not_null history, LocalIdManager &idManager, const MTP auto detachExistingItem = false; auto body = _history->createItem(PrepareLogMessage(action.vnew_message, idManager.next(), date.v), applyServiceAction, detachExistingItem); if (!oldValue.text.isEmpty()) { - body->addLogEntryOriginal(lang(canHaveCaption ? lng_admin_log_previous_caption : lng_admin_log_previous_description), oldValue); + body->addLogEntryOriginal(_id, lang(canHaveCaption ? lng_admin_log_previous_caption : lng_admin_log_previous_message), oldValue); } addPart(body); }; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 9a6f25f62..0d1adf7b8 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "lang/lang_keys.h" #include "mainwidget.h" #include "history/history_service_layout.h" +#include "history/history_media_types.h" #include "media/media_clip_reader.h" #include "styles/style_dialogs.h" #include "styles/style_history.h" @@ -543,9 +544,18 @@ void HistoryMessageDate::paint(Painter &p, int y, int w) const { HistoryLayout::ServiceMessagePainter::paintDate(p, _text, _width, y, w); } -HistoryMessageLogEntryOriginal::HistoryMessageLogEntryOriginal() : _text(st::msgMinWidth - st::webPageLeft) { +HistoryMessageLogEntryOriginal::HistoryMessageLogEntryOriginal() = default; + +HistoryMessageLogEntryOriginal::HistoryMessageLogEntryOriginal(HistoryMessageLogEntryOriginal &&other) : _page(std::move(other._page)) { } +HistoryMessageLogEntryOriginal &HistoryMessageLogEntryOriginal::operator=(HistoryMessageLogEntryOriginal &&other) { + _page = std::move(other._page); + return *this; +} + +HistoryMessageLogEntryOriginal::~HistoryMessageLogEntryOriginal() = default; + HistoryMediaPtr::HistoryMediaPtr(std::unique_ptr pointer) : _pointer(std::move(pointer)) { if (_pointer) { _pointer->attachToParent(); @@ -659,13 +669,12 @@ void HistoryItem::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pres Ui::repaintHistoryItem(this); } -void HistoryItem::addLogEntryOriginal(const QString &label, const TextWithEntities &content) { +void HistoryItem::addLogEntryOriginal(WebPageId localId, const QString &label, const TextWithEntities &content) { Expects(isLogEntry()); AddComponents(HistoryMessageLogEntryOriginal::Bit()); auto original = Get(); - original->_label = label; - original->_labelWidth = st::webPageTitleFont->width(label); - original->_text.setMarkedText(st::webPageDescriptionStyle, content); + auto webpage = App::feedWebPage(localId, label, content); + original->_page = std::make_unique(this, webpage); } void HistoryItem::destroy() { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 5d7ec47df..f16aa4caf 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -414,16 +414,16 @@ struct HistoryMessageUnreadBar : public RuntimeComponent { HistoryMessageLogEntryOriginal(); + HistoryMessageLogEntryOriginal(HistoryMessageLogEntryOriginal &&other); + HistoryMessageLogEntryOriginal &operator=(HistoryMessageLogEntryOriginal &&other); + ~HistoryMessageLogEntryOriginal(); - void paint(Painter &p, int y, int w) const; - HistoryTextState getState(int x, int y, HistoryStateRequest request) const; - - QString _label; - int _labelWidth = 0; - Text _text; + std::unique_ptr _page; }; @@ -520,7 +520,7 @@ public: bool isLogEntry() const { return (id > ServerMaxMsgId); } - void addLogEntryOriginal(const QString &label, const TextWithEntities &content); + void addLogEntryOriginal(WebPageId localId, const QString &label, const TextWithEntities &content); History *history() const { return _history; @@ -868,7 +868,7 @@ public: } bool isEmpty() const { - return _text.isEmpty() && !_media; + return _text.isEmpty() && !_media && !Has(); } void clipCallback(Media::Clip::Notification notification); diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index d4c9d9955..0db124ef3 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -3090,7 +3090,7 @@ int unitedLineHeight() { } // namespace -HistoryWebPage::HistoryWebPage(gsl::not_null parent, WebPageData *data) : HistoryMedia(parent) +HistoryWebPage::HistoryWebPage(gsl::not_null parent, gsl::not_null data) : HistoryMedia(parent) , _data(data) , _title(st::msgMinWidth - st::webPageLeft) , _description(st::msgMinWidth - st::webPageLeft) { @@ -3121,7 +3121,7 @@ void HistoryWebPage::initDimensions() { // init layout auto title = textOneLine(_data->title.isEmpty() ? _data->author : _data->title); - if (!_data->description.isEmpty() && title.isEmpty() && _data->siteName.isEmpty() && !_data->url.isEmpty()) { + if (!_data->description.text.isEmpty() && title.isEmpty() && _data->siteName.isEmpty() && !_data->url.isEmpty()) { _data->siteName = siteNameFromUrl(_data->url); } if (!_data->document && _data->photo && _data->type != WebPagePhoto && _data->type != WebPageVideo) { @@ -3132,7 +3132,7 @@ void HistoryWebPage::initDimensions() { } else { _asArticle = true; } - if (_asArticle && _data->description.isEmpty() && title.isEmpty() && _data->siteName.isEmpty()) { + if (_asArticle && _data->description.text.isEmpty() && title.isEmpty() && _data->siteName.isEmpty()) { _asArticle = false; } } else { @@ -3157,19 +3157,19 @@ void HistoryWebPage::initDimensions() { } // init strings - if (_description.isEmpty() && !_data->description.isEmpty()) { + if (_description.isEmpty() && !_data->description.text.isEmpty()) { auto text = _data->description; if (!_asArticle && !_attach) { - text += _parent->skipBlock(); + text.text += _parent->skipBlock(); } - const TextParseOptions *opts = &_webpageDescriptionOptions; + auto opts = &_webpageDescriptionOptions; if (_data->siteName == qstr("Twitter")) { opts = &_twitterDescriptionOptions; } else if (_data->siteName == qstr("Instagram")) { opts = &_instagramDescriptionOptions; } - _description.setText(st::webPageDescriptionStyle, text, *opts); + _description.setMarkedText(st::webPageDescriptionStyle, text, *opts); } if (_title.isEmpty() && !title.isEmpty()) { if (!_asArticle && !_attach && _description.isEmpty()) { diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h index bd0a55af9..dea68a9b4 100644 --- a/Telegram/SourceFiles/history/history_media_types.h +++ b/Telegram/SourceFiles/history/history_media_types.h @@ -788,7 +788,7 @@ private: class HistoryWebPage : public HistoryMedia { public: - HistoryWebPage(gsl::not_null parent, WebPageData *data); + HistoryWebPage(gsl::not_null parent, gsl::not_null data); HistoryWebPage(gsl::not_null parent, const HistoryWebPage &other); HistoryMediaType type() const override { return MediaTypeWebPage; @@ -821,13 +821,13 @@ public: void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) override; bool isDisplayed() const override { - return !_data->pendingTill; + return !_data->pendingTill && !_parent->Has(); } DocumentData *getDocument() override { - return _attach ? _attach->getDocument() : 0; + return _attach ? _attach->getDocument() : nullptr; } Media::Clip::Reader *getClipReader() override { - return _attach ? _attach->getClipReader() : 0; + return _attach ? _attach->getClipReader() : nullptr; } bool playInline(bool autoplay) override { return _attach ? _attach->playInline(autoplay) : false; @@ -842,7 +842,7 @@ public: bool hasReplyPreview() const override; ImagePtr replyPreview() override; - WebPageData *webpage() { + gsl::not_null webpage() { return _data; } @@ -867,7 +867,7 @@ private: QMargins inBubblePadding() const; int bottomInfoPadding() const; - WebPageData *_data; + gsl::not_null _data; ClickHandlerPtr _openl; std::unique_ptr _attach; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index dc6af58f6..496798722 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -539,6 +539,17 @@ void HistoryMessage::createComponentsHelper(MTPDmessage::Flags flags, MsgId repl } void HistoryMessage::updateMediaInBubbleState() { + auto mediaHasSomethingBelow = false; + auto mediaHasSomethingAbove = false; + auto getMediaHasSomethingAbove = [this] { + return displayFromName() || displayForwardedFrom() || Has() || Has(); + }; + if (auto entry = Get()) { + mediaHasSomethingBelow = true; + mediaHasSomethingAbove = getMediaHasSomethingAbove(); + auto entryState = (mediaHasSomethingAbove || !emptyText() || (_media && _media->isDisplayed())) ? MediaInBubbleState::Bottom : MediaInBubbleState::None; + entry->_page->setInBubbleState(entryState); + } if (!_media) { return; } @@ -548,22 +559,20 @@ void HistoryMessage::updateMediaInBubbleState() { return; } - bool hasSomethingAbove = displayFromName() || displayForwardedFrom() || Has() || Has(); - bool hasSomethingBelow = false; if (!emptyText()) { if (_media->isAboveMessage()) { - hasSomethingBelow = true; + mediaHasSomethingBelow = true; } else { - hasSomethingAbove = true; + mediaHasSomethingAbove = true; } } - auto computeState = [hasSomethingAbove, hasSomethingBelow] { - if (hasSomethingAbove) { - if (hasSomethingBelow) { + auto computeState = [mediaHasSomethingAbove, mediaHasSomethingBelow] { + if (mediaHasSomethingAbove) { + if (mediaHasSomethingBelow) { return MediaInBubbleState::Middle; } return MediaInBubbleState::Bottom; - } else if (hasSomethingBelow) { + } else if (mediaHasSomethingBelow) { return MediaInBubbleState::Top; } return MediaInBubbleState::None; @@ -811,6 +820,10 @@ void HistoryMessage::initDimensions() { _textHeight = 0; } } + auto entry = Get(); + if (entry) { + entry->_page->initDimensions(); + } _maxw = plainMaxWidth(); _minh = emptyText() ? 0 : _text.minHeight(); @@ -844,6 +857,12 @@ void HistoryMessage::initDimensions() { } if (_namew > _maxw) _maxw = _namew; } + if (entry) { + accumulate_max(_maxw, entry->_page->maxWidth()); + } + } + if (entry) { + _minh += entry->_page->minHeight(); } } else if (_media) { _media->initDimensions(); @@ -873,6 +892,13 @@ void HistoryMessage::initDimensions() { } } +bool HistoryMessage::drawBubble() const { + if (Has()) { + return true; + } + return _media ? (!emptyText() || _media->needsBubble()) : !isEmpty(); +} + void HistoryMessage::countPositionAndSize(int32 &left, int32 &width) const { int32 maxwidth = qMin(int(st::msgMaxWidth), _maxw), hwidth = _history->width; if (_media && _media->currentWidth() < maxwidth) { @@ -1348,6 +1374,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, T fromNameUpdated(width); } + auto entry = Get(); auto mediaDisplayed = _media && _media->isDisplayed(); auto top = marginTop(); auto r = QRect(left, top, width, height - top - marginBottom()); @@ -1356,7 +1383,7 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, T auto displayTail = skipTail ? RectPart::None : (outbg && !Adaptive::ChatWide()) ? RectPart::Right : RectPart::Left; HistoryLayout::paintBubble(p, r, _history->width, selected, outbg, displayTail); - QRect trect(r.marginsAdded(-st::msgPadding)); + auto trect = r.marginsAdded(-st::msgPadding); if (mediaDisplayed && _media->isBubbleTop()) { trect.setY(trect.y() - st::msgPadding.top()); } else { @@ -1368,6 +1395,9 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, T if (mediaDisplayed && _media->isBubbleBottom()) { trect.setHeight(trect.height() + st::msgPadding.bottom()); } + if (entry) { + trect.setHeight(trect.height() - entry->_page->height()); + } auto needDrawInfo = true; if (mediaDisplayed) { auto mediaAboveText = _media->isAboveMessage(); @@ -1390,6 +1420,13 @@ void HistoryMessage::draw(Painter &p, const QRect &r, TextSelection selection, T } else { paintText(p, trect, selection); } + if (entry) { + auto entryLeft = r.x(); + auto entryTop = trect.y() + trect.height(); + p.translate(entryLeft, entryTop); + entry->_page->draw(p, r.translated(-entryLeft, -entryTop), TextSelection(), ms); + p.translate(-entryLeft, -entryTop); + } if (needDrawInfo) { HistoryMessage::drawInfo(p, r.x() + r.width(), r.y() + r.height(), 2 * r.x() + r.width(), selected, InfoDisplayDefault); } @@ -1520,6 +1557,7 @@ int HistoryMessage::performResizeGetHeight(int width) { auto forwarded = Get(); auto reply = Get(); auto via = Get(); + auto entry = Get(); auto mediaDisplayed = false; auto mediaInBubbleState = MediaInBubbleState::None; @@ -1529,7 +1567,12 @@ int HistoryMessage::performResizeGetHeight(int width) { } if (width >= _maxw) { _height = _minh; - if (mediaDisplayed) _media->resizeGetHeight(_maxw); + if (mediaDisplayed) { + _media->resizeGetHeight(_maxw); + } + if (entry) { + entry->_page->resizeGetHeight(_maxw); + } } else { if (emptyText()) { _height = 0; @@ -1552,6 +1595,9 @@ int HistoryMessage::performResizeGetHeight(int width) { } else { _height += st::msgPadding.top() + st::msgPadding.bottom(); } + if (entry) { + _height += entry->_page->resizeGetHeight(width); + } } if (displayFromName()) { diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index b7b9b0727..7332ff751 100644 --- a/Telegram/SourceFiles/history/history_message.h +++ b/Telegram/SourceFiles/history/history_message.h @@ -54,9 +54,7 @@ public: int32 plainMaxWidth() const; void countPositionAndSize(int32 &left, int32 &width) const; - bool drawBubble() const { - return _media ? (!emptyText() || _media->needsBubble()) : !isEmpty(); - } + bool drawBubble() const; bool hasBubble() const override { return drawBubble(); } diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index ec1b183f5..a77faa8e5 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -6030,20 +6030,20 @@ void HistoryWidget::updatePreview() { QString title, desc; if (_previewData->siteName.isEmpty()) { if (_previewData->title.isEmpty()) { - if (_previewData->description.isEmpty()) { + if (_previewData->description.text.isEmpty()) { title = _previewData->author; desc = ((_previewData->document && !_previewData->document->name.isEmpty()) ? _previewData->document->name : _previewData->url); } else { - title = _previewData->description; + title = _previewData->description.text; desc = _previewData->author.isEmpty() ? ((_previewData->document && !_previewData->document->name.isEmpty()) ? _previewData->document->name : _previewData->url) : _previewData->author; } } else { title = _previewData->title; - desc = _previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? ((_previewData->document && !_previewData->document->name.isEmpty()) ? _previewData->document->name : _previewData->url) : _previewData->author) : _previewData->description; + desc = _previewData->description.text.isEmpty() ? (_previewData->author.isEmpty() ? ((_previewData->document && !_previewData->document->name.isEmpty()) ? _previewData->document->name : _previewData->url) : _previewData->author) : _previewData->description.text; } } else { title = _previewData->siteName; - desc = _previewData->title.isEmpty() ? (_previewData->description.isEmpty() ? (_previewData->author.isEmpty() ? ((_previewData->document && !_previewData->document->name.isEmpty()) ? _previewData->document->name : _previewData->url) : _previewData->author) : _previewData->description) : _previewData->title; + desc = _previewData->title.isEmpty() ? (_previewData->description.text.isEmpty() ? (_previewData->author.isEmpty() ? ((_previewData->document && !_previewData->document->name.isEmpty()) ? _previewData->document->name : _previewData->url) : _previewData->author) : _previewData->description.text) : _previewData->title; } if (title.isEmpty()) { if (_previewData->document) { diff --git a/Telegram/SourceFiles/overview/overview_layout.cpp b/Telegram/SourceFiles/overview/overview_layout.cpp index c628c4c82..f4b4cfc7b 100644 --- a/Telegram/SourceFiles/overview/overview_layout.cpp +++ b/Telegram/SourceFiles/overview/overview_layout.cpp @@ -1014,16 +1014,16 @@ Link::Link(HistoryMedia *media, HistoryItem *parent) : ItemBase(parent) { } } - _page = (media && media->type() == MediaTypeWebPage) ? static_cast(media)->webpage() : 0; + _page = (media && media->type() == MediaTypeWebPage) ? static_cast(media)->webpage().get() : nullptr; if (_page) { mainUrl = _page->url; if (_page->document) { - _photol.reset(new DocumentOpenClickHandler(_page->document)); + _photol = MakeShared(_page->document); } else if (_page->photo) { if (_page->type == WebPageProfile || _page->type == WebPageVideo) { _photol = MakeShared(_page->url); } else if (_page->type == WebPagePhoto || _page->siteName == qstr("Twitter") || _page->siteName == qstr("Facebook")) { - _photol.reset(new PhotoOpenClickHandler(_page->photo)); + _photol = MakeShared(_page->photo); } else { _photol = MakeShared(_page->url); } @@ -1034,7 +1034,7 @@ Link::Link(HistoryMedia *media, HistoryItem *parent) : ItemBase(parent) { _photol = MakeShared(mainUrl); } if (from >= till && _page) { - text = _page->description; + text = _page->description.text; from = 0; till = text.size(); } diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index 1edb09bc9..6a56d7281 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -2083,7 +2083,7 @@ QString DocumentData::composeNameString(const QString &filename, const QString & return songPerformer + QString::fromUtf8(" \xe2\x80\x93 ") + trackTitle; } -WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const QString &description, DocumentData *document, PhotoData *photo, int32 duration, const QString &author, int32 pendingTill) : id(id) +WebPageData::WebPageData(const WebPageId &id, WebPageType type, const QString &url, const QString &displayUrl, const QString &siteName, const QString &title, const TextWithEntities &description, DocumentData *document, PhotoData *photo, int32 duration, const QString &author, int32 pendingTill) : id(id) , type(type) , url(url) , displayUrl(displayUrl) diff --git a/Telegram/SourceFiles/structs.h b/Telegram/SourceFiles/structs.h index e386b20a9..7c9e8d7e3 100644 --- a/Telegram/SourceFiles/structs.h +++ b/Telegram/SourceFiles/structs.h @@ -1537,7 +1537,7 @@ inline WebPageType toWebPageType(const QString &type) { } struct WebPageData { - WebPageData(const WebPageId &id, WebPageType type = WebPageArticle, const QString &url = QString(), const QString &displayUrl = QString(), const QString &siteName = QString(), const QString &title = QString(), const QString &description = QString(), DocumentData *doc = nullptr, PhotoData *photo = nullptr, int32 duration = 0, const QString &author = QString(), int32 pendingTill = -1); + WebPageData(const WebPageId &id, WebPageType type = WebPageArticle, const QString &url = QString(), const QString &displayUrl = QString(), const QString &siteName = QString(), const QString &title = QString(), const TextWithEntities &description = TextWithEntities(), DocumentData *doc = nullptr, PhotoData *photo = nullptr, int32 duration = 0, const QString &author = QString(), int32 pendingTill = -1); void forget() { if (document) document->forget(); @@ -1546,7 +1546,8 @@ struct WebPageData { WebPageId id; WebPageType type; - QString url, displayUrl, siteName, title, description; + QString url, displayUrl, siteName, title; + TextWithEntities description; int32 duration; QString author; PhotoData *photo;