diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index 7e33e0cb3c..9070a01bd2 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -3127,23 +3127,33 @@ void ApiWrap::sendMediaWithRandomId( uint64 randomId) { const auto history = item->history(); const auto replyTo = item->replyToId(); + + auto caption = item->originalText(); + TextUtilities::Trim(caption); + auto sentEntities = TextUtilities::EntitiesToMTP( + caption.entities, + TextUtilities::ConvertOption::SkipLocal); + const auto flags = MTPmessages_SendMedia::Flags(0) | (replyTo ? MTPmessages_SendMedia::Flag::f_reply_to_msg_id : MTPmessages_SendMedia::Flag(0)) | (IsSilentPost(item, silent) ? MTPmessages_SendMedia::Flag::f_silent + : MTPmessages_SendMedia::Flag(0)) + | (!sentEntities.v.isEmpty() + ? MTPmessages_SendMedia::Flag::f_entities : MTPmessages_SendMedia::Flag(0)); - const auto message = QString(); // #TODO l76 caption + history->sendRequestId = request(MTPmessages_SendMedia( MTP_flags(flags), history->peer->input, MTP_int(replyTo), media, - MTP_string(message), + MTP_string(caption.text), MTP_long(randomId), MTPnullMarkup, - MTPnullEntities + sentEntities )).done([=](const MTPUpdates &result) { applyUpdates(result); }).fail([=](const RPCError &error) { sendMessageFail(error); }).afterRequest(history->sendRequestId @@ -3169,13 +3179,21 @@ void ApiWrap::sendAlbumWithUploaded( Assert(itemIt != album->items.end()); Assert(!itemIt->media); - const auto original = item->originalText(); // #TODO l76 entities + auto caption = item->originalText(); + TextUtilities::Trim(caption); + auto sentEntities = TextUtilities::EntitiesToMTP( + caption.entities, + TextUtilities::ConvertOption::SkipLocal); + const auto flags = !sentEntities.v.isEmpty() + ? MTPDinputSingleMedia::Flag::f_entities + : MTPDinputSingleMedia::Flag(0); + itemIt->media = MTP_inputSingleMedia( media, - MTP_flags(0), + MTP_flags(flags), MTP_long(randomId), - MTP_string(original.text), - MTPnullEntities); + MTP_string(caption.text), + sentEntities); sendAlbumIfReady(album.get()); } diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 703267c453..f5e3db2c1f 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -24,15 +24,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL EditCaptionBox::EditCaptionBox( QWidget*, - not_null<Data::Media*> media, - FullMsgId msgId) -: _msgId(msgId) { - Expects(media->allowsEditCaption()); + not_null<HistoryItem*> item) +: _msgId(item->fullId()) { + Expects(item->media() != nullptr); + Expects(item->media()->allowsEditCaption()); QSize dimensions; ImagePtr image; DocumentData *doc = nullptr; + const auto media = item->media(); if (const auto photo = media->photo()) { _photo = true; dimensions = QSize(photo->full->width(), photo->full->height()); @@ -49,7 +50,7 @@ EditCaptionBox::EditCaptionBox( } doc = document; } - auto caption = media->caption(); + auto caption = item->originalText().text; if (!_animated && (dimensions.isEmpty() || doc || image->isNull())) { if (image->isNull()) { diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.h b/Telegram/SourceFiles/boxes/edit_caption_box.h index eff1d52176..14c4c037f3 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.h +++ b/Telegram/SourceFiles/boxes/edit_caption_box.h @@ -19,7 +19,7 @@ class InputArea; class EditCaptionBox : public BoxContent, public RPCSender { public: - EditCaptionBox(QWidget*, not_null<Data::Media*> media, FullMsgId msgId); + EditCaptionBox(QWidget*, not_null<HistoryItem*> item); protected: void prepare() override; diff --git a/Telegram/SourceFiles/data/data_groups.cpp b/Telegram/SourceFiles/data/data_groups.cpp index bfdfd86952..6f9261d2fb 100644 --- a/Telegram/SourceFiles/data/data_groups.cpp +++ b/Telegram/SourceFiles/data/data_groups.cpp @@ -100,8 +100,7 @@ HistoryItemsList::const_iterator Groups::findPositionForItem( if (!IsServerMsgId(itemId)) { return last; } - auto result = begin(group); - while (result != last) { + for (auto result = begin(group); result != last; ++result) { const auto alreadyId = (*result)->id; if (IsServerMsgId(alreadyId) && alreadyId > itemId) { return result; diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 200ff73b20..1023b6e504 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -182,10 +182,6 @@ bool Media::canBeGrouped() const { return false; } -QString Media::caption() const { - return QString(); -} - QString Media::chatsListText() const { auto result = notificationText(); return result.isEmpty() @@ -236,11 +232,9 @@ std::unique_ptr<HistoryMedia> Media::createView( MediaPhoto::MediaPhoto( not_null<HistoryItem*> parent, - not_null<PhotoData*> photo, - const QString &caption) + not_null<PhotoData*> photo) : Media(parent) -, _photo(photo) -, _caption(caption) { +, _photo(photo) { } MediaPhoto::MediaPhoto( @@ -258,7 +252,7 @@ MediaPhoto::~MediaPhoto() { std::unique_ptr<Media> MediaPhoto::clone(not_null<HistoryItem*> parent) { return _chat ? std::make_unique<MediaPhoto>(parent, _chat, _photo) - : std::make_unique<MediaPhoto>(parent, _photo, _caption); + : std::make_unique<MediaPhoto>(parent, _photo); } PhotoData *MediaPhoto::photo() const { @@ -283,17 +277,17 @@ bool MediaPhoto::canBeGrouped() const { return true; } -QString MediaPhoto::caption() const { - return _caption; -} - QString MediaPhoto::notificationText() const { - return WithCaptionNotificationText(lang(lng_in_dlg_photo), _caption); + return WithCaptionNotificationText( + lang(lng_in_dlg_photo), + parent()->originalText().text); //return WithCaptionNotificationText(lang(lng_in_dlg_album), _caption); } QString MediaPhoto::chatsListText() const { - return WithCaptionDialogsText(lang(lng_in_dlg_photo), _caption); + return WithCaptionDialogsText( + lang(lng_in_dlg_photo), + parent()->originalText().text); //return WithCaptionDialogsText(lang(lng_in_dlg_album), _caption); } @@ -408,17 +402,14 @@ std::unique_ptr<HistoryMedia> MediaPhoto::createView( return std::make_unique<HistoryPhoto>( message, realParent, - _photo, - _caption); + _photo); } MediaFile::MediaFile( not_null<HistoryItem*> parent, - not_null<DocumentData*> document, - const QString &caption) + not_null<DocumentData*> document) : Media(parent) , _document(document) -, _caption(caption) , _emoji(document->sticker() ? document->sticker()->alt : QString()) { Auth().data().registerDocumentItem(_document, parent); @@ -434,7 +425,7 @@ MediaFile::~MediaFile() { } std::unique_ptr<Media> MediaFile::clone(not_null<HistoryItem*> parent) { - return std::make_unique<MediaFile>(parent, _document, _caption); + return std::make_unique<MediaFile>(parent, _document); } DocumentData *MediaFile::document() const { @@ -493,7 +484,7 @@ QString MediaFile::chatsListText() const { } return lang(lng_in_dlg_file); }(); - return WithCaptionDialogsText(type, _caption); + return WithCaptionDialogsText(type, parent()->originalText().text); } QString MediaFile::notificationText() const { @@ -518,7 +509,7 @@ QString MediaFile::notificationText() const { } return lang(lng_in_dlg_file); }(); - return WithCaptionNotificationText(type, _caption); + return WithCaptionNotificationText(type, parent()->originalText().text); } QString MediaFile::pinnedTextSubstring() const { @@ -622,15 +613,14 @@ std::unique_ptr<HistoryMedia> MediaFile::createView( if (_document->sticker()) { return std::make_unique<HistorySticker>(message, _document); } else if (_document->isAnimation()) { - return std::make_unique<HistoryGif>(message, _document, _caption); + return std::make_unique<HistoryGif>(message, _document); } else if (_document->isVideoFile()) { return std::make_unique<HistoryVideo>( message, realParent, - _document, - _caption); + _document); } - return std::make_unique<HistoryDocument>(message, _document, _caption); + return std::make_unique<HistoryDocument>(message, _document); } MediaContact::MediaContact( @@ -847,8 +837,12 @@ WebPageData *MediaWebPage::webpage() const { return _page; } +QString MediaWebPage::chatsListText() const { + return notificationText(); +} + QString MediaWebPage::notificationText() const { - return QString(); + return parent()->originalText().text; } QString MediaWebPage::pinnedTextSubstring() const { diff --git a/Telegram/SourceFiles/data/data_media_types.h b/Telegram/SourceFiles/data/data_media_types.h index 8c30e901c8..dc10632fa9 100644 --- a/Telegram/SourceFiles/data/data_media_types.h +++ b/Telegram/SourceFiles/data/data_media_types.h @@ -82,7 +82,6 @@ public: virtual bool uploading() const; virtual Storage::SharedMediaTypesMask sharedMediaTypes() const; virtual bool canBeGrouped() const; - virtual QString caption() const; virtual bool hasReplyPreview() const; virtual ImagePtr replyPreview() const; // Returns text with link-start and link-end commands for service-color highlighting. @@ -120,8 +119,7 @@ class MediaPhoto : public Media { public: MediaPhoto( not_null<HistoryItem*> parent, - not_null<PhotoData*> photo, - const QString &caption); + not_null<PhotoData*> photo); MediaPhoto( not_null<HistoryItem*> parent, not_null<PeerData*> chat, @@ -135,7 +133,6 @@ public: bool uploading() const override; Storage::SharedMediaTypesMask sharedMediaTypes() const override; bool canBeGrouped() const override; - QString caption() const override; QString chatsListText() const override; QString notificationText() const override; QString pinnedTextSubstring() const override; @@ -152,7 +149,6 @@ public: private: not_null<PhotoData*> _photo; PeerData *_chat = nullptr; - QString _caption; }; @@ -160,8 +156,7 @@ class MediaFile : public Media { public: MediaFile( not_null<HistoryItem*> parent, - not_null<DocumentData*> document, - const QString &caption); + not_null<DocumentData*> document); ~MediaFile(); std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override; @@ -187,7 +182,6 @@ public: private: not_null<DocumentData*> _document; - QString _caption; QString _emoji; }; @@ -289,6 +283,7 @@ public: std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override; WebPageData *webpage() const override; + QString chatsListText() const override; QString notificationText() const override; QString pinnedTextSubstring() const override; bool allowsEdit() const override; diff --git a/Telegram/SourceFiles/data/data_session.cpp b/Telegram/SourceFiles/data/data_session.cpp index e7194f2bbb..974cca01a1 100644 --- a/Telegram/SourceFiles/data/data_session.cpp +++ b/Telegram/SourceFiles/data/data_session.cpp @@ -208,14 +208,14 @@ rpl::producer<not_null<ViewElement*>> Session::viewResizeRequest() const { return _viewResizeRequest.events(); } -void Session::requestItemViewRefresh(not_null<const HistoryItem*> item) { +void Session::requestItemViewRefresh(not_null<HistoryItem*> item) { if (const auto view = item->mainView()) { view->setPendingResize(); } _itemViewRefreshRequest.fire_copy(item); } -rpl::producer<not_null<const HistoryItem*>> Session::itemViewRefreshRequest() const { +rpl::producer<not_null<HistoryItem*>> Session::itemViewRefreshRequest() const { return _itemViewRefreshRequest.events(); } diff --git a/Telegram/SourceFiles/data/data_session.h b/Telegram/SourceFiles/data/data_session.h index 27bfb84b01..e6f2bf0a3a 100644 --- a/Telegram/SourceFiles/data/data_session.h +++ b/Telegram/SourceFiles/data/data_session.h @@ -73,8 +73,8 @@ public: rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const; void requestViewResize(not_null<ViewElement*> view); rpl::producer<not_null<ViewElement*>> viewResizeRequest() const; - void requestItemViewRefresh(not_null<const HistoryItem*> item); - rpl::producer<not_null<const HistoryItem*>> itemViewRefreshRequest() const; + void requestItemViewRefresh(not_null<HistoryItem*> item); + rpl::producer<not_null<HistoryItem*>> itemViewRefreshRequest() const; void requestItemPlayInline(not_null<const HistoryItem*> item); rpl::producer<not_null<const HistoryItem*>> itemPlayInlineRequest() const; void notifyHistoryUnloaded(not_null<const History*> history); @@ -448,7 +448,7 @@ private: rpl::event_stream<not_null<const ViewElement*>> _viewRepaintRequest; rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest; rpl::event_stream<not_null<ViewElement*>> _viewResizeRequest; - rpl::event_stream<not_null<const HistoryItem*>> _itemViewRefreshRequest; + rpl::event_stream<not_null<HistoryItem*>> _itemViewRefreshRequest; rpl::event_stream<not_null<const HistoryItem*>> _itemPlayInlineRequest; rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved; rpl::event_stream<not_null<const History*>> _historyUnloaded; diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 87d43b35b2..8648b5e8ee 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -974,7 +974,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } } - if (msg && !_contextMenuLink && (!msg->emptyText() || mediaHasTextForCopy)) { + if (msg && !_contextMenuLink && (view->hasVisibleText() || mediaHasTextForCopy)) { _menu->addAction(lang(lng_context_copy_text), [=] { copyContextText(itemId); })->setEnabled(true); diff --git a/Telegram/SourceFiles/history/history.cpp b/Telegram/SourceFiles/history/history.cpp index 5c0a90ec32..ac099511c3 100644 --- a/Telegram/SourceFiles/history/history.cpp +++ b/Telegram/SourceFiles/history/history.cpp @@ -785,7 +785,7 @@ not_null<HistoryItem*> History::createItemDocument( UserId from, const QString &postAuthor, DocumentData *document, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) { return HistoryMessage::create( this, @@ -810,7 +810,7 @@ not_null<HistoryItem*> History::createItemPhoto( UserId from, const QString &postAuthor, PhotoData *photo, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) { return HistoryMessage::create( this, @@ -933,7 +933,7 @@ not_null<HistoryItem*> History::addNewDocument( UserId from, const QString &postAuthor, DocumentData *document, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) { return addNewItem( createItemDocument( @@ -959,7 +959,7 @@ not_null<HistoryItem*> History::addNewPhoto( UserId from, const QString &postAuthor, PhotoData *photo, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) { return addNewItem( createItemPhoto( @@ -2494,6 +2494,7 @@ void History::clearUpTill(MsgId availableMinId) { if (!lastMsg) { App::main()->checkPeerHistory(peer); } + Auth().data().sendHistoryChangeNotifications(); } void History::applyGroupAdminChanges( @@ -2626,6 +2627,29 @@ void HistoryBlock::remove(not_null<Element*> view) { } } +void HistoryBlock::refreshView(not_null<Element*> view) { + Expects(view->block() == this); + + const auto item = view->data(); + auto refreshed = item->createView(HistoryInner::ElementDelegate()); + + auto blockIndex = indexInHistory(); + auto itemIndex = view->indexInBlock(); + if (_history->scrollTopItem == view) { + _history->scrollTopItem = refreshed.get(); + } + + messages[itemIndex] = std::move(refreshed); + messages[itemIndex]->attachToBlock(this, itemIndex); + if (itemIndex + 1 < messages.size()) { + messages[itemIndex + 1]->previousInBlocksChanged(); + } else if (blockIndex + 1 < _history->blocks.size()) { + _history->blocks[blockIndex + 1]->messages.front()->previousInBlocksChanged(); + } else if (!_history->blocks.empty() && !_history->blocks.back()->messages.empty()) { + _history->blocks.back()->messages.back()->nextInBlocksChanged(); + } +} + HistoryBlock::~HistoryBlock() { clear(); } diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 186ba1fc3e..911e391e0c 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -159,8 +159,8 @@ public: HistoryItem *addToHistory(const MTPMessage &msg); not_null<HistoryItem*> addNewService(MsgId msgId, QDateTime date, const QString &text, MTPDmessage::Flags flags = 0, bool newMsg = true); not_null<HistoryItem*> addNewForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, UserId from, const QString &postAuthor, HistoryMessage *item); - not_null<HistoryItem*> addNewDocument(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, DocumentData *doc, const QString &caption, const MTPReplyMarkup &markup); - not_null<HistoryItem*> addNewPhoto(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, PhotoData *photo, const QString &caption, const MTPReplyMarkup &markup); + not_null<HistoryItem*> addNewDocument(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, DocumentData *doc, const TextWithEntities &caption, const MTPReplyMarkup &markup); + not_null<HistoryItem*> addNewPhoto(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, PhotoData *photo, const TextWithEntities &caption, const MTPReplyMarkup &markup); not_null<HistoryItem*> addNewGame(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, GameData *game, const MTPReplyMarkup &markup); // Used only internally and for channel admin log. @@ -400,8 +400,8 @@ protected: void clearBlocks(bool leaveItems); not_null<HistoryItem*> createItemForwarded(MsgId id, MTPDmessage::Flags flags, QDateTime date, UserId from, const QString &postAuthor, HistoryMessage *msg); - not_null<HistoryItem*> createItemDocument(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, DocumentData *doc, const QString &caption, const MTPReplyMarkup &markup); - not_null<HistoryItem*> createItemPhoto(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, PhotoData *photo, const QString &caption, const MTPReplyMarkup &markup); + not_null<HistoryItem*> createItemDocument(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, DocumentData *doc, const TextWithEntities &caption, const MTPReplyMarkup &markup); + not_null<HistoryItem*> createItemPhoto(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, PhotoData *photo, const TextWithEntities &caption, const MTPReplyMarkup &markup); not_null<HistoryItem*> createItemGame(MsgId id, MTPDmessage::Flags flags, UserId viaBotId, MsgId replyTo, QDateTime date, UserId from, const QString &postAuthor, GameData *game, const MTPReplyMarkup &markup); not_null<HistoryItem*> addNewItem( @@ -559,6 +559,7 @@ public: void clear(bool leaveItems = false); void remove(not_null<Element*> view); + void refreshView(not_null<Element*> view); int resizeGetHeight(int newWidth, bool resizeAllItems); int y() const { diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 2c8e8203c4..5dca6465b5 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1542,7 +1542,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } } - if (msg && !_contextMenuLink && (!msg->emptyText() || mediaHasTextForCopy)) { + if (msg && view && !_contextMenuLink && (view->hasVisibleText() || mediaHasTextForCopy)) { _menu->addAction(lang(lng_context_copy_text), [=] { copyContextText(itemId); })->setEnabled(true); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 33f203c3ff..27438a2c1e 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -90,15 +90,13 @@ void HistoryItem::finishCreate() { void HistoryItem::finishEdition(int oldKeyboardTop) { Auth().data().requestItemViewRefresh(this); invalidateChatsListEntry(); - //if (groupId()) { - // history()->fixGroupAfterEdition(this); - //} - //if (isHiddenByGroup()) { // #TODO group views - // // Perhaps caption was changed, we should refresh the group. - // const auto group = Get<HistoryMessageGroup>(); - // group->leader->setPendingInitDimensions(); - // group->leader->invalidateChatsListEntry(); - //} + if (const auto group = Auth().data().groups().find(this)) { + const auto leader = group->items.back(); + if (leader != this) { + Auth().data().requestItemViewRefresh(leader); + leader->invalidateChatsListEntry(); + } + } //if (oldKeyboardTop >= 0) { // #TODO edit bot message // if (auto keyboard = Get<HistoryMessageReplyMarkup>()) { @@ -290,6 +288,13 @@ void HistoryItem::destroy() { delete this; } +void HistoryItem::refreshMainView() { + if (const auto view = mainView()) { + Auth().data().notifyHistoryChangeDelayed(_history); + view->refreshInBlock(); + } +} + void HistoryItem::removeMainView() { if (const auto view = mainView()) { if (const auto channelHistory = _history->asChannelHistory()) { @@ -297,7 +302,6 @@ void HistoryItem::removeMainView() { } Auth().data().notifyHistoryChangeDelayed(_history); view->removeFromBlock(); - _mainView = nullptr; } } @@ -677,10 +681,12 @@ HistoryItem *HistoryItem::nextItem() const { QString HistoryItem::notificationText() const { auto getText = [this]() { - if (emptyText()) { - return _media ? _media->notificationText() : QString(); + if (_media) { + return _media->notificationText(); + } else if (!emptyText()) { + return _text.originalText(); } - return _text.originalText(); + return QString(); }; auto result = getText(); @@ -692,10 +698,12 @@ QString HistoryItem::notificationText() const { QString HistoryItem::inDialogsText(DrawInDialog way) const { auto getText = [this]() { - if (emptyText()) { - return _media ? _media->chatsListText() : QString(); + if (_media) { + return _media->chatsListText(); + } else if (!emptyText()) { + return TextUtilities::Clean(_text.originalText()); } - return TextUtilities::Clean(_text.originalText()); + return QString(); }; const auto plainText = getText(); const auto sender = [&]() -> PeerData* { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index 6d208d35b6..4ac0df8a07 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -95,6 +95,7 @@ public: void setMainView(HistoryView::Element *view) { _mainView = view; } + void refreshMainView(); void clearMainView(); void removeMainView(); @@ -196,6 +197,9 @@ public: bool emptyText() const { return _text.isEmpty(); } + Text cloneText() const { + return _text; + } bool isPinned() const; bool canPin() const; diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index f007626900..312a438b55 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -271,7 +271,7 @@ void HistoryMessageReply::paint( auto replyToAsMsg = replyToMsg->toHistoryMessage(); if (!(flags & PaintFlag::InBubble)) { - } else if ((replyToAsMsg && replyToAsMsg->emptyText()) || replyToMsg->serviceMsg()) { + } else if (!replyToAsMsg) { p.setPen(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg)); } else { p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg)); diff --git a/Telegram/SourceFiles/history/history_media.h b/Telegram/SourceFiles/history/history_media.h index 4ba5970380..0cc21f2cce 100644 --- a/Telegram/SourceFiles/history/history_media.h +++ b/Telegram/SourceFiles/history/history_media.h @@ -74,6 +74,9 @@ public: virtual bool hasTextForCopy() const { return false; } + virtual bool hideMessageText() const { + return true; + } virtual bool allowsFastShare() const { return false; } diff --git a/Telegram/SourceFiles/history/history_media_grouped.cpp b/Telegram/SourceFiles/history/history_media_grouped.cpp index 43bf630c10..34f4410fe4 100644 --- a/Telegram/SourceFiles/history/history_media_grouped.cpp +++ b/Telegram/SourceFiles/history/history_media_grouped.cpp @@ -367,29 +367,20 @@ HistoryMessageEdited *HistoryGroupedMedia::displayedEditBadge() const { } void HistoryGroupedMedia::updateNeedBubbleState() { - const auto getItemCaption = [](const Part &part) { - if (const auto media = part.item->media()) { - return TextWithEntities{ media->caption(), EntitiesInText() }; - // #TODO group caption - } - return part.content->getCaption(); - }; - const auto captionText = [&] { - auto result = getItemCaption(_parts.front()); - if (result.text.isEmpty()) { - return result; + const auto hasCaption = [&] { + if (_parts.front().item->emptyText()) { + return false; } for (auto i = 1, count = int(_parts.size()); i != count; ++i) { - if (!getItemCaption(_parts[i]).text.isEmpty()) { - return TextWithEntities(); + if (!_parts[i].item->emptyText()) { + return false; } } - return result; + return true; }(); - _caption.setText( - st::messageTextStyle, - captionText.text + _parent->skipBlock(), - Ui::ItemTextNoMonoOptions(_parent->data())); + if (hasCaption) { + _caption = _parts.front().item->cloneText(); + } _needBubble = computeNeedBubble(); } diff --git a/Telegram/SourceFiles/history/history_media_types.cpp b/Telegram/SourceFiles/history/history_media_types.cpp index da72f82f62..b01bfb73e2 100644 --- a/Telegram/SourceFiles/history/history_media_types.cpp +++ b/Telegram/SourceFiles/history/history_media_types.cpp @@ -72,25 +72,21 @@ std::unique_ptr<HistoryMedia> CreateAttach( } else if (document->isAnimation()) { return std::make_unique<HistoryGif>( parent, - document, - QString()); + document); } else if (document->isVideoFile()) { return std::make_unique<HistoryVideo>( parent, parent->data(), - document, - QString()); + document); } return std::make_unique<HistoryDocument>( parent, - document, - QString()); + document); } else if (photo) { return std::make_unique<HistoryPhoto>( parent, parent->data(), - photo, - QString()); + photo); } return nullptr; } @@ -223,8 +219,7 @@ HistoryFileMedia::~HistoryFileMedia() = default; HistoryPhoto::HistoryPhoto( not_null<Element*> parent, not_null<HistoryItem*> realParent, - not_null<PhotoData*> photo, - const QString &caption) + not_null<PhotoData*> photo) : HistoryFileMedia(parent) , _data(photo) , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { @@ -233,12 +228,7 @@ HistoryPhoto::HistoryPhoto( std::make_shared<PhotoOpenClickHandler>(_data, fullId), std::make_shared<PhotoSaveClickHandler>(_data, fullId), std::make_shared<PhotoCancelClickHandler>(_data, fullId)); - if (!caption.isEmpty()) { - _caption.setText( - st::messageTextStyle, - caption + _parent->skipBlock(), - Ui::ItemTextNoMonoOptions(_parent->data())); - } + _caption = realParent->cloneText(); create(realParent->fullId()); } @@ -263,7 +253,9 @@ void HistoryPhoto::create(FullMsgId contextId, PeerData *chat) { } QSize HistoryPhoto::countOptimalSize() { - if (_caption.hasSkipBlock()) { + if (_parent->media() != this) { + _caption = Text(); + } else if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( _parent->skipBlockWidth(), _parent->skipBlockHeight()); @@ -733,19 +725,13 @@ DocumentViewRegister::~DocumentViewRegister() { HistoryVideo::HistoryVideo( not_null<Element*> parent, not_null<HistoryItem*> realParent, - not_null<DocumentData*> document, - const QString &caption) + not_null<DocumentData*> document) : HistoryFileMedia(parent) , DocumentViewRegister(parent, document) , _data(document) , _thumbw(1) , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { - if (!caption.isEmpty()) { - _caption.setText( - st::messageTextStyle, - caption + _parent->skipBlock(), - Ui::ItemTextNoMonoOptions(_parent->data())); - } + _caption = realParent->cloneText(); setDocumentLinks(_data, realParent); @@ -755,7 +741,9 @@ HistoryVideo::HistoryVideo( } QSize HistoryVideo::countOptimalSize() { - if (_caption.hasSkipBlock()) { + if (_parent->media() != this) { + _caption = Text(); + } else if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( _parent->skipBlockWidth(), _parent->skipBlockHeight()); @@ -1206,12 +1194,12 @@ ImagePtr HistoryVideo::replyPreview() { HistoryDocument::HistoryDocument( not_null<Element*> parent, - not_null<DocumentData*> document, - const QString &caption) + not_null<DocumentData*> document) : HistoryFileMedia(parent) , DocumentViewRegister(parent, document) , _data(document) { const auto item = parent->data(); + auto caption = item->cloneText(); createComponents(!caption.isEmpty()); if (auto named = Get<HistoryDocumentNamed>()) { @@ -1223,10 +1211,7 @@ HistoryDocument::HistoryDocument( setStatusSize(FileStatusSizeReady); if (auto captioned = Get<HistoryDocumentCaptioned>()) { - captioned->_caption.setText( - st::messageTextStyle, - caption + _parent->skipBlock(), - Ui::ItemTextNoMonoOptions(item)); + captioned->_caption = std::move(caption); } } @@ -1284,12 +1269,16 @@ QSize HistoryDocument::countOptimalSize() { const auto item = _parent->data(); auto captioned = Get<HistoryDocumentCaptioned>(); - if (captioned && captioned->_caption.hasSkipBlock()) { + if (_parent->media() != this) { + if (captioned) { + RemoveComponents(HistoryDocumentCaptioned::Bit()); + captioned = nullptr; + } + } else if (captioned && captioned->_caption.hasSkipBlock()) { captioned->_caption.updateSkipBlock( _parent->skipBlockWidth(), _parent->skipBlockHeight()); } - auto thumbed = Get<HistoryDocumentThumbed>(); if (thumbed) { _data->thumb->load(); @@ -1953,8 +1942,7 @@ ImagePtr HistoryDocument::replyPreview() { HistoryGif::HistoryGif( not_null<Element*> parent, - not_null<DocumentData*> document, - const QString &caption) + not_null<DocumentData*> document) : HistoryFileMedia(parent) , DocumentViewRegister(parent, document) , _data(document) @@ -1964,18 +1952,14 @@ HistoryGif::HistoryGif( setStatusSize(FileStatusSizeReady); - if (!caption.isEmpty() && !_data->isVideoMessage()) { - _caption.setText( - st::messageTextStyle, - caption + _parent->skipBlock(), - Ui::ItemTextNoMonoOptions(item)); - } - + _caption = item->cloneText(); _data->thumb->load(); } QSize HistoryGif::countOptimalSize() { - if (_caption.hasSkipBlock()) { + if (_parent->media() != this) { + _caption = Text(); + } else if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( _parent->skipBlockWidth(), _parent->skipBlockHeight()); diff --git a/Telegram/SourceFiles/history/history_media_types.h b/Telegram/SourceFiles/history/history_media_types.h index 5eee32f5d8..6e56fbab44 100644 --- a/Telegram/SourceFiles/history/history_media_types.h +++ b/Telegram/SourceFiles/history/history_media_types.h @@ -130,8 +130,7 @@ public: HistoryPhoto( not_null<Element*> parent, not_null<HistoryItem*> realParent, - not_null<PhotoData*> photo, - const QString &caption); + not_null<PhotoData*> photo); HistoryPhoto( not_null<Element*> parent, not_null<PeerData*> chat, @@ -243,8 +242,7 @@ public: HistoryVideo( not_null<Element*> parent, not_null<HistoryItem*> realParent, - not_null<DocumentData*> document, - const QString &caption); + not_null<DocumentData*> document); HistoryMediaType type() const override { return MediaTypeVideo; @@ -336,8 +334,7 @@ class HistoryDocument public: HistoryDocument( not_null<Element*> parent, - not_null<DocumentData*> document, - const QString &caption); + not_null<DocumentData*> document); HistoryMediaType type() const override { return _data->isVoiceMessage() @@ -407,8 +404,8 @@ private: void setStatusSize(int newSize, qint64 realDuration = 0) const; bool updateStatusText() const; // returns showPause - // Callback is a void(const QString &, const QString &, const Text &) functor. - // It will be called as callback(attachType, attachFileName, attachCaption). + // Callback is a void(const QString &, const QString &, const Text &) functor. + // It will be called as callback(attachType, attachFileName, attachCaption). template <typename Callback> void buildStringRepresentation(Callback callback) const; @@ -420,8 +417,7 @@ class HistoryGif : public HistoryFileMedia, public DocumentViewRegister { public: HistoryGif( not_null<Element*> parent, - not_null<DocumentData*> document, - const QString &caption); + not_null<DocumentData*> document); HistoryMediaType type() const override { return MediaTypeGif; @@ -703,6 +699,10 @@ public: void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override; HistoryTextState getState(QPoint point, HistoryStateRequest request) const override; + bool hideMessageText() const override { + return false; + } + [[nodiscard]] TextSelection adjustSelection( TextSelection selection, TextSelectType type) const override; @@ -918,6 +918,10 @@ public: } static QString fillAmountAndCurrency(uint64 amount, const QString ¤cy); + bool hideMessageText() const override { + return false; + } + void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override; HistoryTextState getState(QPoint point, HistoryStateRequest request) const override; diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index 289dc1aabb..794661c04a 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -308,9 +308,6 @@ HistoryMessage::HistoryMessage( if (msg.has_reply_markup()) config.mtpMarkup = &msg.vreply_markup; if (msg.has_edit_date()) config.editDate = ::date(msg.vedit_date); if (msg.has_post_author()) config.author = qs(msg.vpost_author); - if (msg.has_grouped_id()) { - setGroupId(MessageGroupId::FromRaw(msg.vgrouped_id.v)); - } createComponents(config); @@ -323,6 +320,10 @@ HistoryMessage::HistoryMessage( ? TextUtilities::EntitiesFromMTP(msg.ventities.v) : EntitiesInText(); setText({ text, entities }); + + if (msg.has_grouped_id()) { + setGroupId(MessageGroupId::FromRaw(msg.vgrouped_id.v)); + } } HistoryMessage::HistoryMessage( @@ -444,13 +445,13 @@ HistoryMessage::HistoryMessage( UserId from, const QString &postAuthor, not_null<DocumentData*> document, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) : HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { createComponentsHelper(flags, replyTo, viaBotId, postAuthor, markup); - _media = std::make_unique<Data::MediaFile>(this, document, caption); - setText(TextWithEntities()); + _media = std::make_unique<Data::MediaFile>(this, document); + setText(caption); } HistoryMessage::HistoryMessage( @@ -463,13 +464,13 @@ HistoryMessage::HistoryMessage( UserId from, const QString &postAuthor, not_null<PhotoData*> photo, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) : HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { createComponentsHelper(flags, replyTo, viaBotId, postAuthor, markup); - _media = std::make_unique<Data::MediaPhoto>(this, photo, caption); - setText(TextWithEntities()); + _media = std::make_unique<Data::MediaPhoto>(this, photo); + setText(caption); } HistoryMessage::HistoryMessage( @@ -705,11 +706,15 @@ QString FormatViewsCount(int views) { } void HistoryMessage::refreshMedia(const MTPMessageMedia *media) { - const auto wasGrouped = Auth().data().groups().isGrouped(this); _media = nullptr; if (media) { setMedia(*media); } +} + +void HistoryMessage::refreshSentMedia(const MTPMessageMedia *media) { + const auto wasGrouped = Auth().data().groups().isGrouped(this); + refreshMedia(media); if (wasGrouped) { Auth().data().groups().refreshMessage(this); } @@ -772,8 +777,7 @@ std::unique_ptr<Data::Media> HistoryMessage::CreateMedia( } else if (data.has_photo() && data.vphoto.type() == mtpc_photo) { return std::make_unique<Data::MediaPhoto>( item, - Auth().data().photo(data.vphoto.c_photo()), - /*data.has_caption() ? qs(data.vcaption) : */QString()); // #TODO l76 caption + Auth().data().photo(data.vphoto.c_photo())); } else { LOG(("API Error: " "Got MTPMessageMediaPhoto " @@ -790,8 +794,7 @@ std::unique_ptr<Data::Media> HistoryMessage::CreateMedia( && data.vdocument.type() == mtpc_document) { return std::make_unique<Data::MediaFile>( item, - Auth().data().document(data.vdocument.c_document()), - /*data.has_caption() ? qs(data.vcaption) :*/ QString()); // #TODO l76 caption + Auth().data().document(data.vdocument.c_document())); } else { LOG(("API Error: " "Got MTPMessageMediaDocument " @@ -900,12 +903,12 @@ void HistoryMessage::applyEditionToEmpty() { void HistoryMessage::updateSentMedia(const MTPMessageMedia *media) { if (_flags & MTPDmessage_ClientFlag::f_from_inline_bot) { if (!media || !_media || !_media->updateInlineResultMedia(*media)) { - refreshMedia(media); + refreshSentMedia(media); } _flags &= ~MTPDmessage_ClientFlag::f_from_inline_bot; } else { if (!media || !_media || !_media->updateSentMedia(*media)) { - refreshMedia(media); + refreshSentMedia(media); } } Auth().data().requestItemResize(this); diff --git a/Telegram/SourceFiles/history/history_message.h b/Telegram/SourceFiles/history/history_message.h index dbdfa26a97..2bdf89b933 100644 --- a/Telegram/SourceFiles/history/history_message.h +++ b/Telegram/SourceFiles/history/history_message.h @@ -79,7 +79,7 @@ public: UserId from, const QString &postAuthor, not_null<DocumentData*> document, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) { return _create( history, @@ -104,7 +104,7 @@ public: UserId from, const QString &postAuthor, not_null<PhotoData*> photo, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup) { return _create( history, @@ -144,6 +144,7 @@ public: } void refreshMedia(const MTPMessageMedia *media); + void refreshSentMedia(const MTPMessageMedia *media); void setMedia(const MTPMessageMedia &media); static std::unique_ptr<Data::Media> CreateMedia( not_null<HistoryMessage*> item, @@ -234,7 +235,7 @@ private: UserId from, const QString &postAuthor, not_null<DocumentData*> document, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup); // local document HistoryMessage( not_null<History*> history, @@ -246,7 +247,7 @@ private: UserId from, const QString &postAuthor, not_null<PhotoData*> photo, - const QString &caption, + const TextWithEntities &caption, const MTPReplyMarkup &markup); // local photo HistoryMessage( not_null<History*> history, diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 3e99a62550..02c6fe849e 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -571,10 +571,8 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont }, lifetime()); Auth().data().itemViewRefreshRequest( ) | rpl::start_with_next([this](auto item) { - if (const auto view = item->mainView()) { - updateHistoryGeometry(); - } - }); + item->refreshMainView(); + }, lifetime()); subscribe(Auth().data().contactsLoaded(), [this](bool) { if (_peer) { updateReportSpamStatus(); @@ -4288,7 +4286,7 @@ void HistoryWidget::sendFileConfirmed( MTP_string(file->caption), photo, MTPnullMarkup, - MTPnullEntities,// #TODO l76 entities + MTPnullEntities, // #TODO caption entities MTP_int(1), MTPint(), MTP_string(messagePostAuthor), @@ -4313,7 +4311,7 @@ void HistoryWidget::sendFileConfirmed( MTP_string(file->caption), document, MTPnullMarkup, - MTPnullEntities, // #TODO l76 entities + MTPnullEntities, // #TODO caption entities MTP_int(1), MTPint(), MTP_string(messagePostAuthor), @@ -4341,7 +4339,7 @@ void HistoryWidget::sendFileConfirmed( MTP_string(file->caption), document, MTPnullMarkup, - MTPnullEntities,// #TODO l76 entities + MTPnullEntities, // #TODO caption entities MTP_int(1), MTPint(), MTP_string(messagePostAuthor), @@ -5143,7 +5141,7 @@ bool HistoryWidget::onStickerSend(DocumentData *sticker) { return false; } } - return sendExistingDocument(sticker, QString()); + return sendExistingDocument(sticker, TextWithEntities()); } void HistoryWidget::onPhotoSend(PhotoData *photo) { @@ -5155,7 +5153,7 @@ void HistoryWidget::onPhotoSend(PhotoData *photo) { return; } } - sendExistingPhoto(photo, QString()); + sendExistingPhoto(photo, TextWithEntities()); } void HistoryWidget::onInlineResultSend( @@ -5368,7 +5366,7 @@ void HistoryWidget::destroyPinnedBar() { bool HistoryWidget::sendExistingDocument( DocumentData *doc, - const QString &caption) { + TextWithEntities caption) { if (!_peer || !_peer->canWrite() || !doc) { return false; } @@ -5409,6 +5407,15 @@ bool HistoryWidget::sendExistingDocument( } auto messageFromId = channelPost ? 0 : Auth().userId(); auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString(); + + TextUtilities::Trim(caption); + auto sentEntities = TextUtilities::EntitiesToMTP( + caption.entities, + TextUtilities::ConvertOption::SkipLocal); + if (!sentEntities.v.isEmpty()) { + sendFlags |= MTPmessages_SendMedia::Flag::f_entities; + } + _history->addNewDocument( newId.msg, flags, @@ -5420,7 +5427,6 @@ bool HistoryWidget::sendExistingDocument( doc, caption, MTPnullMarkup); - _history->sendRequestId = MTP::send( MTPmessages_SendMedia( MTP_flags(sendFlags), @@ -5430,10 +5436,10 @@ bool HistoryWidget::sendExistingDocument( MTP_flags(0), mtpInput, MTPint()), - MTP_string(caption), + MTP_string(caption.text), MTP_long(randomId), MTPnullMarkup, - MTPnullEntities), // #TODO l76 entities + sentEntities), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, @@ -5461,7 +5467,7 @@ bool HistoryWidget::sendExistingDocument( void HistoryWidget::sendExistingPhoto( PhotoData *photo, - const QString &caption) { + TextWithEntities caption) { if (!_peer || !_peer->canWrite() || !photo) { return; } @@ -5497,6 +5503,15 @@ void HistoryWidget::sendExistingPhoto( } auto messageFromId = channelPost ? 0 : Auth().userId(); auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString(); + + TextUtilities::Trim(caption); + auto sentEntities = TextUtilities::EntitiesToMTP( + caption.entities, + TextUtilities::ConvertOption::SkipLocal); + if (!sentEntities.v.isEmpty()) { + sendFlags |= MTPmessages_SendMedia::Flag::f_entities; + } + _history->addNewPhoto( newId.msg, flags, @@ -5518,10 +5533,10 @@ void HistoryWidget::sendExistingPhoto( MTP_flags(0), MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTPint()), - MTP_string(caption), + MTP_string(caption.text), MTP_long(randomId), MTPnullMarkup, - MTPnullEntities), // #TODO l76 entities + sentEntities), App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcFail(&MainWidget::sendMessageFail), 0, @@ -5627,7 +5642,7 @@ void HistoryWidget::editMessage(FullMsgId itemId) { void HistoryWidget::editMessage(not_null<HistoryItem*> item) { if (const auto media = item->media()) { if (media->allowsEditCaption()) { - Ui::show(Box<EditCaptionBox>(media, item->fullId())); + Ui::show(Box<EditCaptionBox>(item)); return; } } @@ -6391,7 +6406,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) { } else { _replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); } - p.setPen(((drawMsgText->toHistoryMessage() && drawMsgText->toHistoryMessage()->emptyText()) || drawMsgText->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg); + p.setPen(!drawMsgText->toHistoryMessage() ? st::historyComposeAreaFgService : st::historyComposeAreaFg); _replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); } else { p.setFont(st::msgDateFont); @@ -6552,7 +6567,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) { p.setFont(st::msgServiceNameFont); p.drawText(left, top + st::msgServiceNameFont->ascent, lang(lng_pinned_message)); - p.setPen(((_pinnedBar->msg->toHistoryMessage() && _pinnedBar->msg->toHistoryMessage()->emptyText()) || _pinnedBar->msg->serviceMsg()) ? st::historyComposeAreaFgService : st::historyComposeAreaFg); + p.setPen(!_pinnedBar->msg->toHistoryMessage() ? st::historyComposeAreaFgService : st::historyComposeAreaFg); _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right()); } else { p.setFont(st::msgDateFont); diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 9f5e160911..b7673db2af 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -593,8 +593,8 @@ private: void destroyPinnedBar(); void unpinDone(const MTPUpdates &updates); - bool sendExistingDocument(DocumentData *doc, const QString &caption); - void sendExistingPhoto(PhotoData *photo, const QString &caption); + bool sendExistingDocument(DocumentData *doc, TextWithEntities caption); + void sendExistingPhoto(PhotoData *photo, TextWithEntities caption); void drawField(Painter &p, const QRect &rect); void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const; diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index c8b761a6ad..57313e3700 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -470,6 +470,10 @@ QDateTime Element::displayedEditDate() const { return QDateTime(); } +bool Element::hasVisibleText() const { + return false; +} + HistoryBlock *Element::block() { return _block; } @@ -495,6 +499,12 @@ void Element::removeFromBlock() { _block->remove(this); } +void Element::refreshInBlock() { + Expects(_block != nullptr); + + _block->refreshView(this); +} + void Element::setIndexInBlock(int index) { Expects(_block != nullptr); Expects(index >= 0); diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index 52282d33d9..169c578284 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -173,12 +173,14 @@ public: virtual ClickHandlerPtr rightActionLink() const; virtual bool displayEditedBadge() const; virtual QDateTime displayedEditDate() const; + virtual bool hasVisibleText() const; // Legacy blocks structure. HistoryBlock *block(); const HistoryBlock *block() const; void attachToBlock(not_null<HistoryBlock*> block, int index); void removeFromBlock(); + void refreshInBlock(); void setIndexInBlock(int index); int indexInBlock() const; Element *previousInBlocks() const; diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 016a4eae89..12ce5e8662 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -874,7 +874,7 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } } } - if (msg && !_contextMenuLink && (!msg->emptyText() || mediaHasTextForCopy)) { + if (!_contextMenuLink && (view->hasVisibleText() || mediaHasTextForCopy)) { _menu->addAction(lang(lng_context_copy_text), [=] { copyContextText(itemId); })->setEnabled(true); diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 73000510b3..da773d572a 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -258,7 +258,7 @@ QSize Message::performCountOptimalSize() { } maxWidth = item->plainMaxWidth(); - minHeight = item->emptyText() ? 0 : item->_text.minHeight(); + minHeight = hasVisibleText() ? item->_text.minHeight() : 0; if (!mediaOnBottom) { minHeight += st::msgPadding.bottom(); if (mediaDisplayed) minHeight += st::mediaInBubbleSkip; @@ -333,7 +333,7 @@ QSize Message::performCountOptimalSize() { // if we have a text bubble we can resize it to fit the keyboard // but if we have only media we don't do that - if (!item->emptyText()) { + if (hasVisibleText()) { accumulate_max(maxWidth, markup->inlineKeyboard->naturalWidth()); } } @@ -1278,7 +1278,7 @@ bool Message::drawBubble() const { } const auto media = this->media(); return media - ? (!item->emptyText() || media->needsBubble()) + ? (hasVisibleText() || media->needsBubble()) : !item->isEmpty(); } @@ -1401,7 +1401,7 @@ void Message::updateMediaInBubbleState() { mediaHasSomethingBelow = true; mediaHasSomethingAbove = getMediaHasSomethingAbove(); auto entryState = (mediaHasSomethingAbove - || !item->emptyText() + || hasVisibleText() || (media && media->isDisplayed())) ? MediaInBubbleState::Bottom : MediaInBubbleState::None; @@ -1420,7 +1420,7 @@ void Message::updateMediaInBubbleState() { if (!entry) { mediaHasSomethingAbove = getMediaHasSomethingAbove(); } - if (!item->emptyText()) { + if (hasVisibleText()) { if (media->isAboveMessage()) { mediaHasSomethingBelow = true; } else { @@ -1554,15 +1554,15 @@ int Message::resizeContentGetHeight(int newWidth) { entry->resizeGetHeight(countGeometry().width()); } } else { - if (item->emptyText()) { - newHeight = 0; - } else { + if (hasVisibleText()) { auto textWidth = qMax(contentWidth - st::msgPadding.left() - st::msgPadding.right(), 1); if (textWidth != item->_textWidth) { item->_textWidth = textWidth; item->_textHeight = item->_text.countHeight(textWidth); } newHeight = item->_textHeight; + } else { + newHeight = 0; } if (!mediaOnBottom) { newHeight += st::msgPadding.bottom(); @@ -1616,6 +1616,14 @@ int Message::resizeContentGetHeight(int newWidth) { return newHeight; } +bool Message::hasVisibleText() const { + if (message()->emptyText()) { + return false; + } + const auto media = this->media(); + return !media || !media->hideMessageText(); +} + QSize Message::performCountCurrentSize(int newWidth) { const auto item = message(); const auto newHeight = resizeContentGetHeight(newWidth); diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 6e21a2092c..f393a0f077 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -128,6 +128,7 @@ private: int resizeContentGetHeight(int newWidth); QSize performCountOptimalSize() override; QSize performCountCurrentSize(int newWidth) override; + bool hasVisibleText() const override; bool displayFastShare() const; bool displayGoToOriginal() const; diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp index af3b8de2fe..3e53ed29cd 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp +++ b/Telegram/SourceFiles/inline_bots/inline_bot_send_data.cpp @@ -135,8 +135,7 @@ void SendPhoto::addToHistory( fromId, postAuthor, _photo, - _message, - //_entities, + { _message, _entities }, markup); } @@ -171,8 +170,7 @@ void SendFile::addToHistory( fromId, postAuthor, _document, - _message, - //_entities, + { _message, _entities }, markup); } diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 6cb58d7812..78b1a46972 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -1237,14 +1237,11 @@ void MediaView::refreshMediaViewer() { void MediaView::refreshCaption(HistoryItem *item) { _caption = Text(); - - const auto media = item ? item->media() : nullptr; - if (!media) { + if (!item) { return; } - - const auto caption = media->caption(); - if (caption.isEmpty()) { + const auto caption = item->originalText(); + if (caption.text.isEmpty()) { return; } const auto asBot = [&] { @@ -1256,7 +1253,7 @@ void MediaView::refreshCaption(HistoryItem *item) { _caption = Text(st::msgMinWidth); _caption.setMarkedText( st::mediaviewCaptionStyle, - { caption, EntitiesInText() }, // #TODO caption entities parse + caption, Ui::ItemTextOptions(item)); }