Handle item view refresh, fix groups.

This commit is contained in:
John Preston 2018-01-18 16:59:22 +03:00
parent 91f369a0b3
commit 950126865e
30 changed files with 277 additions and 216 deletions

View File

@ -3127,23 +3127,33 @@ void ApiWrap::sendMediaWithRandomId(
uint64 randomId) { uint64 randomId) {
const auto history = item->history(); const auto history = item->history();
const auto replyTo = item->replyToId(); 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) const auto flags = MTPmessages_SendMedia::Flags(0)
| (replyTo | (replyTo
? MTPmessages_SendMedia::Flag::f_reply_to_msg_id ? MTPmessages_SendMedia::Flag::f_reply_to_msg_id
: MTPmessages_SendMedia::Flag(0)) : MTPmessages_SendMedia::Flag(0))
| (IsSilentPost(item, silent) | (IsSilentPost(item, silent)
? MTPmessages_SendMedia::Flag::f_silent ? MTPmessages_SendMedia::Flag::f_silent
: MTPmessages_SendMedia::Flag(0))
| (!sentEntities.v.isEmpty()
? MTPmessages_SendMedia::Flag::f_entities
: MTPmessages_SendMedia::Flag(0)); : MTPmessages_SendMedia::Flag(0));
const auto message = QString(); // #TODO l76 caption
history->sendRequestId = request(MTPmessages_SendMedia( history->sendRequestId = request(MTPmessages_SendMedia(
MTP_flags(flags), MTP_flags(flags),
history->peer->input, history->peer->input,
MTP_int(replyTo), MTP_int(replyTo),
media, media,
MTP_string(message), MTP_string(caption.text),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPnullMarkup,
MTPnullEntities sentEntities
)).done([=](const MTPUpdates &result) { applyUpdates(result); )).done([=](const MTPUpdates &result) { applyUpdates(result);
}).fail([=](const RPCError &error) { sendMessageFail(error); }).fail([=](const RPCError &error) { sendMessageFail(error);
}).afterRequest(history->sendRequestId }).afterRequest(history->sendRequestId
@ -3169,13 +3179,21 @@ void ApiWrap::sendAlbumWithUploaded(
Assert(itemIt != album->items.end()); Assert(itemIt != album->items.end());
Assert(!itemIt->media); 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( itemIt->media = MTP_inputSingleMedia(
media, media,
MTP_flags(0), MTP_flags(flags),
MTP_long(randomId), MTP_long(randomId),
MTP_string(original.text), MTP_string(caption.text),
MTPnullEntities); sentEntities);
sendAlbumIfReady(album.get()); sendAlbumIfReady(album.get());
} }

View File

@ -24,15 +24,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
EditCaptionBox::EditCaptionBox( EditCaptionBox::EditCaptionBox(
QWidget*, QWidget*,
not_null<Data::Media*> media, not_null<HistoryItem*> item)
FullMsgId msgId) : _msgId(item->fullId()) {
: _msgId(msgId) { Expects(item->media() != nullptr);
Expects(media->allowsEditCaption()); Expects(item->media()->allowsEditCaption());
QSize dimensions; QSize dimensions;
ImagePtr image; ImagePtr image;
DocumentData *doc = nullptr; DocumentData *doc = nullptr;
const auto media = item->media();
if (const auto photo = media->photo()) { if (const auto photo = media->photo()) {
_photo = true; _photo = true;
dimensions = QSize(photo->full->width(), photo->full->height()); dimensions = QSize(photo->full->width(), photo->full->height());
@ -49,7 +50,7 @@ EditCaptionBox::EditCaptionBox(
} }
doc = document; doc = document;
} }
auto caption = media->caption(); auto caption = item->originalText().text;
if (!_animated && (dimensions.isEmpty() || doc || image->isNull())) { if (!_animated && (dimensions.isEmpty() || doc || image->isNull())) {
if (image->isNull()) { if (image->isNull()) {

View File

@ -19,7 +19,7 @@ class InputArea;
class EditCaptionBox : public BoxContent, public RPCSender { class EditCaptionBox : public BoxContent, public RPCSender {
public: public:
EditCaptionBox(QWidget*, not_null<Data::Media*> media, FullMsgId msgId); EditCaptionBox(QWidget*, not_null<HistoryItem*> item);
protected: protected:
void prepare() override; void prepare() override;

View File

@ -100,8 +100,7 @@ HistoryItemsList::const_iterator Groups::findPositionForItem(
if (!IsServerMsgId(itemId)) { if (!IsServerMsgId(itemId)) {
return last; return last;
} }
auto result = begin(group); for (auto result = begin(group); result != last; ++result) {
while (result != last) {
const auto alreadyId = (*result)->id; const auto alreadyId = (*result)->id;
if (IsServerMsgId(alreadyId) && alreadyId > itemId) { if (IsServerMsgId(alreadyId) && alreadyId > itemId) {
return result; return result;

View File

@ -182,10 +182,6 @@ bool Media::canBeGrouped() const {
return false; return false;
} }
QString Media::caption() const {
return QString();
}
QString Media::chatsListText() const { QString Media::chatsListText() const {
auto result = notificationText(); auto result = notificationText();
return result.isEmpty() return result.isEmpty()
@ -236,11 +232,9 @@ std::unique_ptr<HistoryMedia> Media::createView(
MediaPhoto::MediaPhoto( MediaPhoto::MediaPhoto(
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<PhotoData*> photo, not_null<PhotoData*> photo)
const QString &caption)
: Media(parent) : Media(parent)
, _photo(photo) , _photo(photo) {
, _caption(caption) {
} }
MediaPhoto::MediaPhoto( MediaPhoto::MediaPhoto(
@ -258,7 +252,7 @@ MediaPhoto::~MediaPhoto() {
std::unique_ptr<Media> MediaPhoto::clone(not_null<HistoryItem*> parent) { std::unique_ptr<Media> MediaPhoto::clone(not_null<HistoryItem*> parent) {
return _chat return _chat
? std::make_unique<MediaPhoto>(parent, _chat, _photo) ? std::make_unique<MediaPhoto>(parent, _chat, _photo)
: std::make_unique<MediaPhoto>(parent, _photo, _caption); : std::make_unique<MediaPhoto>(parent, _photo);
} }
PhotoData *MediaPhoto::photo() const { PhotoData *MediaPhoto::photo() const {
@ -283,17 +277,17 @@ bool MediaPhoto::canBeGrouped() const {
return true; return true;
} }
QString MediaPhoto::caption() const {
return _caption;
}
QString MediaPhoto::notificationText() const { 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); //return WithCaptionNotificationText(lang(lng_in_dlg_album), _caption);
} }
QString MediaPhoto::chatsListText() const { 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); //return WithCaptionDialogsText(lang(lng_in_dlg_album), _caption);
} }
@ -408,17 +402,14 @@ std::unique_ptr<HistoryMedia> MediaPhoto::createView(
return std::make_unique<HistoryPhoto>( return std::make_unique<HistoryPhoto>(
message, message,
realParent, realParent,
_photo, _photo);
_caption);
} }
MediaFile::MediaFile( MediaFile::MediaFile(
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document)
const QString &caption)
: Media(parent) : Media(parent)
, _document(document) , _document(document)
, _caption(caption)
, _emoji(document->sticker() ? document->sticker()->alt : QString()) { , _emoji(document->sticker() ? document->sticker()->alt : QString()) {
Auth().data().registerDocumentItem(_document, parent); Auth().data().registerDocumentItem(_document, parent);
@ -434,7 +425,7 @@ MediaFile::~MediaFile() {
} }
std::unique_ptr<Media> MediaFile::clone(not_null<HistoryItem*> parent) { 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 { DocumentData *MediaFile::document() const {
@ -493,7 +484,7 @@ QString MediaFile::chatsListText() const {
} }
return lang(lng_in_dlg_file); return lang(lng_in_dlg_file);
}(); }();
return WithCaptionDialogsText(type, _caption); return WithCaptionDialogsText(type, parent()->originalText().text);
} }
QString MediaFile::notificationText() const { QString MediaFile::notificationText() const {
@ -518,7 +509,7 @@ QString MediaFile::notificationText() const {
} }
return lang(lng_in_dlg_file); return lang(lng_in_dlg_file);
}(); }();
return WithCaptionNotificationText(type, _caption); return WithCaptionNotificationText(type, parent()->originalText().text);
} }
QString MediaFile::pinnedTextSubstring() const { QString MediaFile::pinnedTextSubstring() const {
@ -622,15 +613,14 @@ std::unique_ptr<HistoryMedia> MediaFile::createView(
if (_document->sticker()) { if (_document->sticker()) {
return std::make_unique<HistorySticker>(message, _document); return std::make_unique<HistorySticker>(message, _document);
} else if (_document->isAnimation()) { } else if (_document->isAnimation()) {
return std::make_unique<HistoryGif>(message, _document, _caption); return std::make_unique<HistoryGif>(message, _document);
} else if (_document->isVideoFile()) { } else if (_document->isVideoFile()) {
return std::make_unique<HistoryVideo>( return std::make_unique<HistoryVideo>(
message, message,
realParent, realParent,
_document, _document);
_caption);
} }
return std::make_unique<HistoryDocument>(message, _document, _caption); return std::make_unique<HistoryDocument>(message, _document);
} }
MediaContact::MediaContact( MediaContact::MediaContact(
@ -847,8 +837,12 @@ WebPageData *MediaWebPage::webpage() const {
return _page; return _page;
} }
QString MediaWebPage::chatsListText() const {
return notificationText();
}
QString MediaWebPage::notificationText() const { QString MediaWebPage::notificationText() const {
return QString(); return parent()->originalText().text;
} }
QString MediaWebPage::pinnedTextSubstring() const { QString MediaWebPage::pinnedTextSubstring() const {

View File

@ -82,7 +82,6 @@ public:
virtual bool uploading() const; virtual bool uploading() const;
virtual Storage::SharedMediaTypesMask sharedMediaTypes() const; virtual Storage::SharedMediaTypesMask sharedMediaTypes() const;
virtual bool canBeGrouped() const; virtual bool canBeGrouped() const;
virtual QString caption() const;
virtual bool hasReplyPreview() const; virtual bool hasReplyPreview() const;
virtual ImagePtr replyPreview() const; virtual ImagePtr replyPreview() const;
// Returns text with link-start and link-end commands for service-color highlighting. // Returns text with link-start and link-end commands for service-color highlighting.
@ -120,8 +119,7 @@ class MediaPhoto : public Media {
public: public:
MediaPhoto( MediaPhoto(
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<PhotoData*> photo, not_null<PhotoData*> photo);
const QString &caption);
MediaPhoto( MediaPhoto(
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<PeerData*> chat, not_null<PeerData*> chat,
@ -135,7 +133,6 @@ public:
bool uploading() const override; bool uploading() const override;
Storage::SharedMediaTypesMask sharedMediaTypes() const override; Storage::SharedMediaTypesMask sharedMediaTypes() const override;
bool canBeGrouped() const override; bool canBeGrouped() const override;
QString caption() const override;
QString chatsListText() const override; QString chatsListText() const override;
QString notificationText() const override; QString notificationText() const override;
QString pinnedTextSubstring() const override; QString pinnedTextSubstring() const override;
@ -152,7 +149,6 @@ public:
private: private:
not_null<PhotoData*> _photo; not_null<PhotoData*> _photo;
PeerData *_chat = nullptr; PeerData *_chat = nullptr;
QString _caption;
}; };
@ -160,8 +156,7 @@ class MediaFile : public Media {
public: public:
MediaFile( MediaFile(
not_null<HistoryItem*> parent, not_null<HistoryItem*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document);
const QString &caption);
~MediaFile(); ~MediaFile();
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override; std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
@ -187,7 +182,6 @@ public:
private: private:
not_null<DocumentData*> _document; not_null<DocumentData*> _document;
QString _caption;
QString _emoji; QString _emoji;
}; };
@ -289,6 +283,7 @@ public:
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override; std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
WebPageData *webpage() const override; WebPageData *webpage() const override;
QString chatsListText() const override;
QString notificationText() const override; QString notificationText() const override;
QString pinnedTextSubstring() const override; QString pinnedTextSubstring() const override;
bool allowsEdit() const override; bool allowsEdit() const override;

View File

@ -208,14 +208,14 @@ rpl::producer<not_null<ViewElement*>> Session::viewResizeRequest() const {
return _viewResizeRequest.events(); return _viewResizeRequest.events();
} }
void Session::requestItemViewRefresh(not_null<const HistoryItem*> item) { void Session::requestItemViewRefresh(not_null<HistoryItem*> item) {
if (const auto view = item->mainView()) { if (const auto view = item->mainView()) {
view->setPendingResize(); view->setPendingResize();
} }
_itemViewRefreshRequest.fire_copy(item); _itemViewRefreshRequest.fire_copy(item);
} }
rpl::producer<not_null<const HistoryItem*>> Session::itemViewRefreshRequest() const { rpl::producer<not_null<HistoryItem*>> Session::itemViewRefreshRequest() const {
return _itemViewRefreshRequest.events(); return _itemViewRefreshRequest.events();
} }

View File

@ -73,8 +73,8 @@ public:
rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const; rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const;
void requestViewResize(not_null<ViewElement*> view); void requestViewResize(not_null<ViewElement*> view);
rpl::producer<not_null<ViewElement*>> viewResizeRequest() const; rpl::producer<not_null<ViewElement*>> viewResizeRequest() const;
void requestItemViewRefresh(not_null<const HistoryItem*> item); void requestItemViewRefresh(not_null<HistoryItem*> item);
rpl::producer<not_null<const HistoryItem*>> itemViewRefreshRequest() const; rpl::producer<not_null<HistoryItem*>> itemViewRefreshRequest() const;
void requestItemPlayInline(not_null<const HistoryItem*> item); void requestItemPlayInline(not_null<const HistoryItem*> item);
rpl::producer<not_null<const HistoryItem*>> itemPlayInlineRequest() const; rpl::producer<not_null<const HistoryItem*>> itemPlayInlineRequest() const;
void notifyHistoryUnloaded(not_null<const History*> history); 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 ViewElement*>> _viewRepaintRequest;
rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest; rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest;
rpl::event_stream<not_null<ViewElement*>> _viewResizeRequest; 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*>> _itemPlayInlineRequest;
rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved; rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved;
rpl::event_stream<not_null<const History*>> _historyUnloaded; rpl::event_stream<not_null<const History*>> _historyUnloaded;

View File

@ -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), [=] { _menu->addAction(lang(lng_context_copy_text), [=] {
copyContextText(itemId); copyContextText(itemId);
})->setEnabled(true); })->setEnabled(true);

View File

@ -785,7 +785,7 @@ not_null<HistoryItem*> History::createItemDocument(
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
DocumentData *document, DocumentData *document,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
return HistoryMessage::create( return HistoryMessage::create(
this, this,
@ -810,7 +810,7 @@ not_null<HistoryItem*> History::createItemPhoto(
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
PhotoData *photo, PhotoData *photo,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
return HistoryMessage::create( return HistoryMessage::create(
this, this,
@ -933,7 +933,7 @@ not_null<HistoryItem*> History::addNewDocument(
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
DocumentData *document, DocumentData *document,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
return addNewItem( return addNewItem(
createItemDocument( createItemDocument(
@ -959,7 +959,7 @@ not_null<HistoryItem*> History::addNewPhoto(
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
PhotoData *photo, PhotoData *photo,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
return addNewItem( return addNewItem(
createItemPhoto( createItemPhoto(
@ -2494,6 +2494,7 @@ void History::clearUpTill(MsgId availableMinId) {
if (!lastMsg) { if (!lastMsg) {
App::main()->checkPeerHistory(peer); App::main()->checkPeerHistory(peer);
} }
Auth().data().sendHistoryChangeNotifications();
} }
void History::applyGroupAdminChanges( 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() { HistoryBlock::~HistoryBlock() {
clear(); clear();
} }

View File

@ -159,8 +159,8 @@ public:
HistoryItem *addToHistory(const MTPMessage &msg); 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*> 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*> 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*> 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 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 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); 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. // Used only internally and for channel admin log.
@ -400,8 +400,8 @@ protected:
void clearBlocks(bool leaveItems); 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*> 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*> 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 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 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*> 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( not_null<HistoryItem*> addNewItem(
@ -559,6 +559,7 @@ public:
void clear(bool leaveItems = false); void clear(bool leaveItems = false);
void remove(not_null<Element*> view); void remove(not_null<Element*> view);
void refreshView(not_null<Element*> view);
int resizeGetHeight(int newWidth, bool resizeAllItems); int resizeGetHeight(int newWidth, bool resizeAllItems);
int y() const { int y() const {

View File

@ -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), [=] { _menu->addAction(lang(lng_context_copy_text), [=] {
copyContextText(itemId); copyContextText(itemId);
})->setEnabled(true); })->setEnabled(true);

View File

@ -90,15 +90,13 @@ void HistoryItem::finishCreate() {
void HistoryItem::finishEdition(int oldKeyboardTop) { void HistoryItem::finishEdition(int oldKeyboardTop) {
Auth().data().requestItemViewRefresh(this); Auth().data().requestItemViewRefresh(this);
invalidateChatsListEntry(); invalidateChatsListEntry();
//if (groupId()) { if (const auto group = Auth().data().groups().find(this)) {
// history()->fixGroupAfterEdition(this); const auto leader = group->items.back();
//} if (leader != this) {
//if (isHiddenByGroup()) { // #TODO group views Auth().data().requestItemViewRefresh(leader);
// // Perhaps caption was changed, we should refresh the group. leader->invalidateChatsListEntry();
// const auto group = Get<HistoryMessageGroup>(); }
// group->leader->setPendingInitDimensions(); }
// group->leader->invalidateChatsListEntry();
//}
//if (oldKeyboardTop >= 0) { // #TODO edit bot message //if (oldKeyboardTop >= 0) { // #TODO edit bot message
// if (auto keyboard = Get<HistoryMessageReplyMarkup>()) { // if (auto keyboard = Get<HistoryMessageReplyMarkup>()) {
@ -290,6 +288,13 @@ void HistoryItem::destroy() {
delete this; delete this;
} }
void HistoryItem::refreshMainView() {
if (const auto view = mainView()) {
Auth().data().notifyHistoryChangeDelayed(_history);
view->refreshInBlock();
}
}
void HistoryItem::removeMainView() { void HistoryItem::removeMainView() {
if (const auto view = mainView()) { if (const auto view = mainView()) {
if (const auto channelHistory = _history->asChannelHistory()) { if (const auto channelHistory = _history->asChannelHistory()) {
@ -297,7 +302,6 @@ void HistoryItem::removeMainView() {
} }
Auth().data().notifyHistoryChangeDelayed(_history); Auth().data().notifyHistoryChangeDelayed(_history);
view->removeFromBlock(); view->removeFromBlock();
_mainView = nullptr;
} }
} }
@ -677,10 +681,12 @@ HistoryItem *HistoryItem::nextItem() const {
QString HistoryItem::notificationText() const { QString HistoryItem::notificationText() const {
auto getText = [this]() { auto getText = [this]() {
if (emptyText()) { if (_media) {
return _media ? _media->notificationText() : QString(); return _media->notificationText();
} } else if (!emptyText()) {
return _text.originalText(); return _text.originalText();
}
return QString();
}; };
auto result = getText(); auto result = getText();
@ -692,10 +698,12 @@ QString HistoryItem::notificationText() const {
QString HistoryItem::inDialogsText(DrawInDialog way) const { QString HistoryItem::inDialogsText(DrawInDialog way) const {
auto getText = [this]() { auto getText = [this]() {
if (emptyText()) { if (_media) {
return _media ? _media->chatsListText() : QString(); return _media->chatsListText();
} } else if (!emptyText()) {
return TextUtilities::Clean(_text.originalText()); return TextUtilities::Clean(_text.originalText());
}
return QString();
}; };
const auto plainText = getText(); const auto plainText = getText();
const auto sender = [&]() -> PeerData* { const auto sender = [&]() -> PeerData* {

View File

@ -95,6 +95,7 @@ public:
void setMainView(HistoryView::Element *view) { void setMainView(HistoryView::Element *view) {
_mainView = view; _mainView = view;
} }
void refreshMainView();
void clearMainView(); void clearMainView();
void removeMainView(); void removeMainView();
@ -196,6 +197,9 @@ public:
bool emptyText() const { bool emptyText() const {
return _text.isEmpty(); return _text.isEmpty();
} }
Text cloneText() const {
return _text;
}
bool isPinned() const; bool isPinned() const;
bool canPin() const; bool canPin() const;

View File

@ -271,7 +271,7 @@ void HistoryMessageReply::paint(
auto replyToAsMsg = replyToMsg->toHistoryMessage(); auto replyToAsMsg = replyToMsg->toHistoryMessage();
if (!(flags & PaintFlag::InBubble)) { 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)); p.setPen(outbg ? (selected ? st::msgOutDateFgSelected : st::msgOutDateFg) : (selected ? st::msgInDateFgSelected : st::msgInDateFg));
} else { } else {
p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg)); p.setPen(outbg ? (selected ? st::historyTextOutFgSelected : st::historyTextOutFg) : (selected ? st::historyTextInFgSelected : st::historyTextInFg));

View File

@ -74,6 +74,9 @@ public:
virtual bool hasTextForCopy() const { virtual bool hasTextForCopy() const {
return false; return false;
} }
virtual bool hideMessageText() const {
return true;
}
virtual bool allowsFastShare() const { virtual bool allowsFastShare() const {
return false; return false;
} }

View File

@ -367,29 +367,20 @@ HistoryMessageEdited *HistoryGroupedMedia::displayedEditBadge() const {
} }
void HistoryGroupedMedia::updateNeedBubbleState() { void HistoryGroupedMedia::updateNeedBubbleState() {
const auto getItemCaption = [](const Part &part) { const auto hasCaption = [&] {
if (const auto media = part.item->media()) { if (_parts.front().item->emptyText()) {
return TextWithEntities{ media->caption(), EntitiesInText() }; return false;
// #TODO group caption
}
return part.content->getCaption();
};
const auto captionText = [&] {
auto result = getItemCaption(_parts.front());
if (result.text.isEmpty()) {
return result;
} }
for (auto i = 1, count = int(_parts.size()); i != count; ++i) { for (auto i = 1, count = int(_parts.size()); i != count; ++i) {
if (!getItemCaption(_parts[i]).text.isEmpty()) { if (!_parts[i].item->emptyText()) {
return TextWithEntities(); return false;
} }
} }
return result; return true;
}(); }();
_caption.setText( if (hasCaption) {
st::messageTextStyle, _caption = _parts.front().item->cloneText();
captionText.text + _parent->skipBlock(), }
Ui::ItemTextNoMonoOptions(_parent->data()));
_needBubble = computeNeedBubble(); _needBubble = computeNeedBubble();
} }

View File

@ -72,25 +72,21 @@ std::unique_ptr<HistoryMedia> CreateAttach(
} else if (document->isAnimation()) { } else if (document->isAnimation()) {
return std::make_unique<HistoryGif>( return std::make_unique<HistoryGif>(
parent, parent,
document, document);
QString());
} else if (document->isVideoFile()) { } else if (document->isVideoFile()) {
return std::make_unique<HistoryVideo>( return std::make_unique<HistoryVideo>(
parent, parent,
parent->data(), parent->data(),
document, document);
QString());
} }
return std::make_unique<HistoryDocument>( return std::make_unique<HistoryDocument>(
parent, parent,
document, document);
QString());
} else if (photo) { } else if (photo) {
return std::make_unique<HistoryPhoto>( return std::make_unique<HistoryPhoto>(
parent, parent,
parent->data(), parent->data(),
photo, photo);
QString());
} }
return nullptr; return nullptr;
} }
@ -223,8 +219,7 @@ HistoryFileMedia::~HistoryFileMedia() = default;
HistoryPhoto::HistoryPhoto( HistoryPhoto::HistoryPhoto(
not_null<Element*> parent, not_null<Element*> parent,
not_null<HistoryItem*> realParent, not_null<HistoryItem*> realParent,
not_null<PhotoData*> photo, not_null<PhotoData*> photo)
const QString &caption)
: HistoryFileMedia(parent) : HistoryFileMedia(parent)
, _data(photo) , _data(photo)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
@ -233,12 +228,7 @@ HistoryPhoto::HistoryPhoto(
std::make_shared<PhotoOpenClickHandler>(_data, fullId), std::make_shared<PhotoOpenClickHandler>(_data, fullId),
std::make_shared<PhotoSaveClickHandler>(_data, fullId), std::make_shared<PhotoSaveClickHandler>(_data, fullId),
std::make_shared<PhotoCancelClickHandler>(_data, fullId)); std::make_shared<PhotoCancelClickHandler>(_data, fullId));
if (!caption.isEmpty()) { _caption = realParent->cloneText();
_caption.setText(
st::messageTextStyle,
caption + _parent->skipBlock(),
Ui::ItemTextNoMonoOptions(_parent->data()));
}
create(realParent->fullId()); create(realParent->fullId());
} }
@ -263,7 +253,9 @@ void HistoryPhoto::create(FullMsgId contextId, PeerData *chat) {
} }
QSize HistoryPhoto::countOptimalSize() { QSize HistoryPhoto::countOptimalSize() {
if (_caption.hasSkipBlock()) { if (_parent->media() != this) {
_caption = Text();
} else if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
_parent->skipBlockHeight()); _parent->skipBlockHeight());
@ -733,19 +725,13 @@ DocumentViewRegister::~DocumentViewRegister() {
HistoryVideo::HistoryVideo( HistoryVideo::HistoryVideo(
not_null<Element*> parent, not_null<Element*> parent,
not_null<HistoryItem*> realParent, not_null<HistoryItem*> realParent,
not_null<DocumentData*> document, not_null<DocumentData*> document)
const QString &caption)
: HistoryFileMedia(parent) : HistoryFileMedia(parent)
, DocumentViewRegister(parent, document) , DocumentViewRegister(parent, document)
, _data(document) , _data(document)
, _thumbw(1) , _thumbw(1)
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) { , _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
if (!caption.isEmpty()) { _caption = realParent->cloneText();
_caption.setText(
st::messageTextStyle,
caption + _parent->skipBlock(),
Ui::ItemTextNoMonoOptions(_parent->data()));
}
setDocumentLinks(_data, realParent); setDocumentLinks(_data, realParent);
@ -755,7 +741,9 @@ HistoryVideo::HistoryVideo(
} }
QSize HistoryVideo::countOptimalSize() { QSize HistoryVideo::countOptimalSize() {
if (_caption.hasSkipBlock()) { if (_parent->media() != this) {
_caption = Text();
} else if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
_parent->skipBlockHeight()); _parent->skipBlockHeight());
@ -1206,12 +1194,12 @@ ImagePtr HistoryVideo::replyPreview() {
HistoryDocument::HistoryDocument( HistoryDocument::HistoryDocument(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document)
const QString &caption)
: HistoryFileMedia(parent) : HistoryFileMedia(parent)
, DocumentViewRegister(parent, document) , DocumentViewRegister(parent, document)
, _data(document) { , _data(document) {
const auto item = parent->data(); const auto item = parent->data();
auto caption = item->cloneText();
createComponents(!caption.isEmpty()); createComponents(!caption.isEmpty());
if (auto named = Get<HistoryDocumentNamed>()) { if (auto named = Get<HistoryDocumentNamed>()) {
@ -1223,10 +1211,7 @@ HistoryDocument::HistoryDocument(
setStatusSize(FileStatusSizeReady); setStatusSize(FileStatusSizeReady);
if (auto captioned = Get<HistoryDocumentCaptioned>()) { if (auto captioned = Get<HistoryDocumentCaptioned>()) {
captioned->_caption.setText( captioned->_caption = std::move(caption);
st::messageTextStyle,
caption + _parent->skipBlock(),
Ui::ItemTextNoMonoOptions(item));
} }
} }
@ -1284,12 +1269,16 @@ QSize HistoryDocument::countOptimalSize() {
const auto item = _parent->data(); const auto item = _parent->data();
auto captioned = Get<HistoryDocumentCaptioned>(); 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( captioned->_caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
_parent->skipBlockHeight()); _parent->skipBlockHeight());
} }
auto thumbed = Get<HistoryDocumentThumbed>(); auto thumbed = Get<HistoryDocumentThumbed>();
if (thumbed) { if (thumbed) {
_data->thumb->load(); _data->thumb->load();
@ -1953,8 +1942,7 @@ ImagePtr HistoryDocument::replyPreview() {
HistoryGif::HistoryGif( HistoryGif::HistoryGif(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document)
const QString &caption)
: HistoryFileMedia(parent) : HistoryFileMedia(parent)
, DocumentViewRegister(parent, document) , DocumentViewRegister(parent, document)
, _data(document) , _data(document)
@ -1964,18 +1952,14 @@ HistoryGif::HistoryGif(
setStatusSize(FileStatusSizeReady); setStatusSize(FileStatusSizeReady);
if (!caption.isEmpty() && !_data->isVideoMessage()) { _caption = item->cloneText();
_caption.setText(
st::messageTextStyle,
caption + _parent->skipBlock(),
Ui::ItemTextNoMonoOptions(item));
}
_data->thumb->load(); _data->thumb->load();
} }
QSize HistoryGif::countOptimalSize() { QSize HistoryGif::countOptimalSize() {
if (_caption.hasSkipBlock()) { if (_parent->media() != this) {
_caption = Text();
} else if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
_parent->skipBlockHeight()); _parent->skipBlockHeight());

View File

@ -130,8 +130,7 @@ public:
HistoryPhoto( HistoryPhoto(
not_null<Element*> parent, not_null<Element*> parent,
not_null<HistoryItem*> realParent, not_null<HistoryItem*> realParent,
not_null<PhotoData*> photo, not_null<PhotoData*> photo);
const QString &caption);
HistoryPhoto( HistoryPhoto(
not_null<Element*> parent, not_null<Element*> parent,
not_null<PeerData*> chat, not_null<PeerData*> chat,
@ -243,8 +242,7 @@ public:
HistoryVideo( HistoryVideo(
not_null<Element*> parent, not_null<Element*> parent,
not_null<HistoryItem*> realParent, not_null<HistoryItem*> realParent,
not_null<DocumentData*> document, not_null<DocumentData*> document);
const QString &caption);
HistoryMediaType type() const override { HistoryMediaType type() const override {
return MediaTypeVideo; return MediaTypeVideo;
@ -336,8 +334,7 @@ class HistoryDocument
public: public:
HistoryDocument( HistoryDocument(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document);
const QString &caption);
HistoryMediaType type() const override { HistoryMediaType type() const override {
return _data->isVoiceMessage() return _data->isVoiceMessage()
@ -420,8 +417,7 @@ class HistoryGif : public HistoryFileMedia, public DocumentViewRegister {
public: public:
HistoryGif( HistoryGif(
not_null<Element*> parent, not_null<Element*> parent,
not_null<DocumentData*> document, not_null<DocumentData*> document);
const QString &caption);
HistoryMediaType type() const override { HistoryMediaType type() const override {
return MediaTypeGif; return MediaTypeGif;
@ -703,6 +699,10 @@ public:
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override; void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override; HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;
bool hideMessageText() const override {
return false;
}
[[nodiscard]] TextSelection adjustSelection( [[nodiscard]] TextSelection adjustSelection(
TextSelection selection, TextSelection selection,
TextSelectType type) const override; TextSelectType type) const override;
@ -918,6 +918,10 @@ public:
} }
static QString fillAmountAndCurrency(uint64 amount, const QString &currency); static QString fillAmountAndCurrency(uint64 amount, const QString &currency);
bool hideMessageText() const override {
return false;
}
void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override; void draw(Painter &p, const QRect &r, TextSelection selection, TimeMs ms) const override;
HistoryTextState getState(QPoint point, HistoryStateRequest request) const override; HistoryTextState getState(QPoint point, HistoryStateRequest request) const override;

View File

@ -308,9 +308,6 @@ HistoryMessage::HistoryMessage(
if (msg.has_reply_markup()) config.mtpMarkup = &msg.vreply_markup; if (msg.has_reply_markup()) config.mtpMarkup = &msg.vreply_markup;
if (msg.has_edit_date()) config.editDate = ::date(msg.vedit_date); 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_post_author()) config.author = qs(msg.vpost_author);
if (msg.has_grouped_id()) {
setGroupId(MessageGroupId::FromRaw(msg.vgrouped_id.v));
}
createComponents(config); createComponents(config);
@ -323,6 +320,10 @@ HistoryMessage::HistoryMessage(
? TextUtilities::EntitiesFromMTP(msg.ventities.v) ? TextUtilities::EntitiesFromMTP(msg.ventities.v)
: EntitiesInText(); : EntitiesInText();
setText({ text, entities }); setText({ text, entities });
if (msg.has_grouped_id()) {
setGroupId(MessageGroupId::FromRaw(msg.vgrouped_id.v));
}
} }
HistoryMessage::HistoryMessage( HistoryMessage::HistoryMessage(
@ -444,13 +445,13 @@ HistoryMessage::HistoryMessage(
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) const MTPReplyMarkup &markup)
: HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { : HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
createComponentsHelper(flags, replyTo, viaBotId, postAuthor, markup); createComponentsHelper(flags, replyTo, viaBotId, postAuthor, markup);
_media = std::make_unique<Data::MediaFile>(this, document, caption); _media = std::make_unique<Data::MediaFile>(this, document);
setText(TextWithEntities()); setText(caption);
} }
HistoryMessage::HistoryMessage( HistoryMessage::HistoryMessage(
@ -463,13 +464,13 @@ HistoryMessage::HistoryMessage(
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) const MTPReplyMarkup &markup)
: HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { : HistoryItem(history, msgId, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
createComponentsHelper(flags, replyTo, viaBotId, postAuthor, markup); createComponentsHelper(flags, replyTo, viaBotId, postAuthor, markup);
_media = std::make_unique<Data::MediaPhoto>(this, photo, caption); _media = std::make_unique<Data::MediaPhoto>(this, photo);
setText(TextWithEntities()); setText(caption);
} }
HistoryMessage::HistoryMessage( HistoryMessage::HistoryMessage(
@ -705,11 +706,15 @@ QString FormatViewsCount(int views) {
} }
void HistoryMessage::refreshMedia(const MTPMessageMedia *media) { void HistoryMessage::refreshMedia(const MTPMessageMedia *media) {
const auto wasGrouped = Auth().data().groups().isGrouped(this);
_media = nullptr; _media = nullptr;
if (media) { if (media) {
setMedia(*media); setMedia(*media);
} }
}
void HistoryMessage::refreshSentMedia(const MTPMessageMedia *media) {
const auto wasGrouped = Auth().data().groups().isGrouped(this);
refreshMedia(media);
if (wasGrouped) { if (wasGrouped) {
Auth().data().groups().refreshMessage(this); 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) { } else if (data.has_photo() && data.vphoto.type() == mtpc_photo) {
return std::make_unique<Data::MediaPhoto>( return std::make_unique<Data::MediaPhoto>(
item, item,
Auth().data().photo(data.vphoto.c_photo()), Auth().data().photo(data.vphoto.c_photo()));
/*data.has_caption() ? qs(data.vcaption) : */QString()); // #TODO l76 caption
} else { } else {
LOG(("API Error: " LOG(("API Error: "
"Got MTPMessageMediaPhoto " "Got MTPMessageMediaPhoto "
@ -790,8 +794,7 @@ std::unique_ptr<Data::Media> HistoryMessage::CreateMedia(
&& data.vdocument.type() == mtpc_document) { && data.vdocument.type() == mtpc_document) {
return std::make_unique<Data::MediaFile>( return std::make_unique<Data::MediaFile>(
item, item,
Auth().data().document(data.vdocument.c_document()), Auth().data().document(data.vdocument.c_document()));
/*data.has_caption() ? qs(data.vcaption) :*/ QString()); // #TODO l76 caption
} else { } else {
LOG(("API Error: " LOG(("API Error: "
"Got MTPMessageMediaDocument " "Got MTPMessageMediaDocument "
@ -900,12 +903,12 @@ void HistoryMessage::applyEditionToEmpty() {
void HistoryMessage::updateSentMedia(const MTPMessageMedia *media) { void HistoryMessage::updateSentMedia(const MTPMessageMedia *media) {
if (_flags & MTPDmessage_ClientFlag::f_from_inline_bot) { if (_flags & MTPDmessage_ClientFlag::f_from_inline_bot) {
if (!media || !_media || !_media->updateInlineResultMedia(*media)) { if (!media || !_media || !_media->updateInlineResultMedia(*media)) {
refreshMedia(media); refreshSentMedia(media);
} }
_flags &= ~MTPDmessage_ClientFlag::f_from_inline_bot; _flags &= ~MTPDmessage_ClientFlag::f_from_inline_bot;
} else { } else {
if (!media || !_media || !_media->updateSentMedia(*media)) { if (!media || !_media || !_media->updateSentMedia(*media)) {
refreshMedia(media); refreshSentMedia(media);
} }
} }
Auth().data().requestItemResize(this); Auth().data().requestItemResize(this);

View File

@ -79,7 +79,7 @@ public:
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
return _create( return _create(
history, history,
@ -104,7 +104,7 @@ public:
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
return _create( return _create(
history, history,
@ -144,6 +144,7 @@ public:
} }
void refreshMedia(const MTPMessageMedia *media); void refreshMedia(const MTPMessageMedia *media);
void refreshSentMedia(const MTPMessageMedia *media);
void setMedia(const MTPMessageMedia &media); void setMedia(const MTPMessageMedia &media);
static std::unique_ptr<Data::Media> CreateMedia( static std::unique_ptr<Data::Media> CreateMedia(
not_null<HistoryMessage*> item, not_null<HistoryMessage*> item,
@ -234,7 +235,7 @@ private:
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
not_null<DocumentData*> document, not_null<DocumentData*> document,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup); // local document const MTPReplyMarkup &markup); // local document
HistoryMessage( HistoryMessage(
not_null<History*> history, not_null<History*> history,
@ -246,7 +247,7 @@ private:
UserId from, UserId from,
const QString &postAuthor, const QString &postAuthor,
not_null<PhotoData*> photo, not_null<PhotoData*> photo,
const QString &caption, const TextWithEntities &caption,
const MTPReplyMarkup &markup); // local photo const MTPReplyMarkup &markup); // local photo
HistoryMessage( HistoryMessage(
not_null<History*> history, not_null<History*> history,

View File

@ -571,10 +571,8 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
}, lifetime()); }, lifetime());
Auth().data().itemViewRefreshRequest( Auth().data().itemViewRefreshRequest(
) | rpl::start_with_next([this](auto item) { ) | rpl::start_with_next([this](auto item) {
if (const auto view = item->mainView()) { item->refreshMainView();
updateHistoryGeometry(); }, lifetime());
}
});
subscribe(Auth().data().contactsLoaded(), [this](bool) { subscribe(Auth().data().contactsLoaded(), [this](bool) {
if (_peer) { if (_peer) {
updateReportSpamStatus(); updateReportSpamStatus();
@ -4288,7 +4286,7 @@ void HistoryWidget::sendFileConfirmed(
MTP_string(file->caption), MTP_string(file->caption),
photo, photo,
MTPnullMarkup, MTPnullMarkup,
MTPnullEntities,// #TODO l76 entities MTPnullEntities, // #TODO caption entities
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
@ -4313,7 +4311,7 @@ void HistoryWidget::sendFileConfirmed(
MTP_string(file->caption), MTP_string(file->caption),
document, document,
MTPnullMarkup, MTPnullMarkup,
MTPnullEntities, // #TODO l76 entities MTPnullEntities, // #TODO caption entities
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
@ -4341,7 +4339,7 @@ void HistoryWidget::sendFileConfirmed(
MTP_string(file->caption), MTP_string(file->caption),
document, document,
MTPnullMarkup, MTPnullMarkup,
MTPnullEntities,// #TODO l76 entities MTPnullEntities, // #TODO caption entities
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
MTP_string(messagePostAuthor), MTP_string(messagePostAuthor),
@ -5143,7 +5141,7 @@ bool HistoryWidget::onStickerSend(DocumentData *sticker) {
return false; return false;
} }
} }
return sendExistingDocument(sticker, QString()); return sendExistingDocument(sticker, TextWithEntities());
} }
void HistoryWidget::onPhotoSend(PhotoData *photo) { void HistoryWidget::onPhotoSend(PhotoData *photo) {
@ -5155,7 +5153,7 @@ void HistoryWidget::onPhotoSend(PhotoData *photo) {
return; return;
} }
} }
sendExistingPhoto(photo, QString()); sendExistingPhoto(photo, TextWithEntities());
} }
void HistoryWidget::onInlineResultSend( void HistoryWidget::onInlineResultSend(
@ -5368,7 +5366,7 @@ void HistoryWidget::destroyPinnedBar() {
bool HistoryWidget::sendExistingDocument( bool HistoryWidget::sendExistingDocument(
DocumentData *doc, DocumentData *doc,
const QString &caption) { TextWithEntities caption) {
if (!_peer || !_peer->canWrite() || !doc) { if (!_peer || !_peer->canWrite() || !doc) {
return false; return false;
} }
@ -5409,6 +5407,15 @@ bool HistoryWidget::sendExistingDocument(
} }
auto messageFromId = channelPost ? 0 : Auth().userId(); auto messageFromId = channelPost ? 0 : Auth().userId();
auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString(); 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( _history->addNewDocument(
newId.msg, newId.msg,
flags, flags,
@ -5420,7 +5427,6 @@ bool HistoryWidget::sendExistingDocument(
doc, doc,
caption, caption,
MTPnullMarkup); MTPnullMarkup);
_history->sendRequestId = MTP::send( _history->sendRequestId = MTP::send(
MTPmessages_SendMedia( MTPmessages_SendMedia(
MTP_flags(sendFlags), MTP_flags(sendFlags),
@ -5430,10 +5436,10 @@ bool HistoryWidget::sendExistingDocument(
MTP_flags(0), MTP_flags(0),
mtpInput, mtpInput,
MTPint()), MTPint()),
MTP_string(caption), MTP_string(caption.text),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPnullMarkup,
MTPnullEntities), // #TODO l76 entities sentEntities),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail), App::main()->rpcFail(&MainWidget::sendMessageFail),
0, 0,
@ -5461,7 +5467,7 @@ bool HistoryWidget::sendExistingDocument(
void HistoryWidget::sendExistingPhoto( void HistoryWidget::sendExistingPhoto(
PhotoData *photo, PhotoData *photo,
const QString &caption) { TextWithEntities caption) {
if (!_peer || !_peer->canWrite() || !photo) { if (!_peer || !_peer->canWrite() || !photo) {
return; return;
} }
@ -5497,6 +5503,15 @@ void HistoryWidget::sendExistingPhoto(
} }
auto messageFromId = channelPost ? 0 : Auth().userId(); auto messageFromId = channelPost ? 0 : Auth().userId();
auto messagePostAuthor = channelPost ? (Auth().user()->firstName + ' ' + Auth().user()->lastName) : QString(); 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( _history->addNewPhoto(
newId.msg, newId.msg,
flags, flags,
@ -5518,10 +5533,10 @@ void HistoryWidget::sendExistingPhoto(
MTP_flags(0), MTP_flags(0),
MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)), MTP_inputPhoto(MTP_long(photo->id), MTP_long(photo->access)),
MTPint()), MTPint()),
MTP_string(caption), MTP_string(caption.text),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPnullMarkup,
MTPnullEntities), // #TODO l76 entities sentEntities),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail), App::main()->rpcFail(&MainWidget::sendMessageFail),
0, 0,
@ -5627,7 +5642,7 @@ void HistoryWidget::editMessage(FullMsgId itemId) {
void HistoryWidget::editMessage(not_null<HistoryItem*> item) { void HistoryWidget::editMessage(not_null<HistoryItem*> item) {
if (const auto media = item->media()) { if (const auto media = item->media()) {
if (media->allowsEditCaption()) { if (media->allowsEditCaption()) {
Ui::show(Box<EditCaptionBox>(media, item->fullId())); Ui::show(Box<EditCaptionBox>(item));
return; return;
} }
} }
@ -6391,7 +6406,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
} else { } else {
_replyToName.drawElided(p, replyLeft, backy + st::msgReplyPadding.top(), width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right()); _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()); _replyEditMsgText.drawElided(p, replyLeft, backy + st::msgReplyPadding.top() + st::msgServiceNameFont->height, width() - replyLeft - _fieldBarCancel->width() - st::msgReplyPadding.right());
} else { } else {
p.setFont(st::msgDateFont); p.setFont(st::msgDateFont);
@ -6552,7 +6567,7 @@ void HistoryWidget::drawPinnedBar(Painter &p) {
p.setFont(st::msgServiceNameFont); p.setFont(st::msgServiceNameFont);
p.drawText(left, top + st::msgServiceNameFont->ascent, lang(lng_pinned_message)); 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()); _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
} else { } else {
p.setFont(st::msgDateFont); p.setFont(st::msgDateFont);

View File

@ -593,8 +593,8 @@ private:
void destroyPinnedBar(); void destroyPinnedBar();
void unpinDone(const MTPUpdates &updates); void unpinDone(const MTPUpdates &updates);
bool sendExistingDocument(DocumentData *doc, const QString &caption); bool sendExistingDocument(DocumentData *doc, TextWithEntities caption);
void sendExistingPhoto(PhotoData *photo, const QString &caption); void sendExistingPhoto(PhotoData *photo, TextWithEntities caption);
void drawField(Painter &p, const QRect &rect); void drawField(Painter &p, const QRect &rect);
void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const; void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const;

View File

@ -470,6 +470,10 @@ QDateTime Element::displayedEditDate() const {
return QDateTime(); return QDateTime();
} }
bool Element::hasVisibleText() const {
return false;
}
HistoryBlock *Element::block() { HistoryBlock *Element::block() {
return _block; return _block;
} }
@ -495,6 +499,12 @@ void Element::removeFromBlock() {
_block->remove(this); _block->remove(this);
} }
void Element::refreshInBlock() {
Expects(_block != nullptr);
_block->refreshView(this);
}
void Element::setIndexInBlock(int index) { void Element::setIndexInBlock(int index) {
Expects(_block != nullptr); Expects(_block != nullptr);
Expects(index >= 0); Expects(index >= 0);

View File

@ -173,12 +173,14 @@ public:
virtual ClickHandlerPtr rightActionLink() const; virtual ClickHandlerPtr rightActionLink() const;
virtual bool displayEditedBadge() const; virtual bool displayEditedBadge() const;
virtual QDateTime displayedEditDate() const; virtual QDateTime displayedEditDate() const;
virtual bool hasVisibleText() const;
// Legacy blocks structure. // Legacy blocks structure.
HistoryBlock *block(); HistoryBlock *block();
const HistoryBlock *block() const; const HistoryBlock *block() const;
void attachToBlock(not_null<HistoryBlock*> block, int index); void attachToBlock(not_null<HistoryBlock*> block, int index);
void removeFromBlock(); void removeFromBlock();
void refreshInBlock();
void setIndexInBlock(int index); void setIndexInBlock(int index);
int indexInBlock() const; int indexInBlock() const;
Element *previousInBlocks() const; Element *previousInBlocks() const;

View File

@ -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), [=] { _menu->addAction(lang(lng_context_copy_text), [=] {
copyContextText(itemId); copyContextText(itemId);
})->setEnabled(true); })->setEnabled(true);

View File

@ -258,7 +258,7 @@ QSize Message::performCountOptimalSize() {
} }
maxWidth = item->plainMaxWidth(); maxWidth = item->plainMaxWidth();
minHeight = item->emptyText() ? 0 : item->_text.minHeight(); minHeight = hasVisibleText() ? item->_text.minHeight() : 0;
if (!mediaOnBottom) { if (!mediaOnBottom) {
minHeight += st::msgPadding.bottom(); minHeight += st::msgPadding.bottom();
if (mediaDisplayed) minHeight += st::mediaInBubbleSkip; 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 // 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 // but if we have only media we don't do that
if (!item->emptyText()) { if (hasVisibleText()) {
accumulate_max(maxWidth, markup->inlineKeyboard->naturalWidth()); accumulate_max(maxWidth, markup->inlineKeyboard->naturalWidth());
} }
} }
@ -1278,7 +1278,7 @@ bool Message::drawBubble() const {
} }
const auto media = this->media(); const auto media = this->media();
return media return media
? (!item->emptyText() || media->needsBubble()) ? (hasVisibleText() || media->needsBubble())
: !item->isEmpty(); : !item->isEmpty();
} }
@ -1401,7 +1401,7 @@ void Message::updateMediaInBubbleState() {
mediaHasSomethingBelow = true; mediaHasSomethingBelow = true;
mediaHasSomethingAbove = getMediaHasSomethingAbove(); mediaHasSomethingAbove = getMediaHasSomethingAbove();
auto entryState = (mediaHasSomethingAbove auto entryState = (mediaHasSomethingAbove
|| !item->emptyText() || hasVisibleText()
|| (media && media->isDisplayed())) || (media && media->isDisplayed()))
? MediaInBubbleState::Bottom ? MediaInBubbleState::Bottom
: MediaInBubbleState::None; : MediaInBubbleState::None;
@ -1420,7 +1420,7 @@ void Message::updateMediaInBubbleState() {
if (!entry) { if (!entry) {
mediaHasSomethingAbove = getMediaHasSomethingAbove(); mediaHasSomethingAbove = getMediaHasSomethingAbove();
} }
if (!item->emptyText()) { if (hasVisibleText()) {
if (media->isAboveMessage()) { if (media->isAboveMessage()) {
mediaHasSomethingBelow = true; mediaHasSomethingBelow = true;
} else { } else {
@ -1554,15 +1554,15 @@ int Message::resizeContentGetHeight(int newWidth) {
entry->resizeGetHeight(countGeometry().width()); entry->resizeGetHeight(countGeometry().width());
} }
} else { } else {
if (item->emptyText()) { if (hasVisibleText()) {
newHeight = 0;
} else {
auto textWidth = qMax(contentWidth - st::msgPadding.left() - st::msgPadding.right(), 1); auto textWidth = qMax(contentWidth - st::msgPadding.left() - st::msgPadding.right(), 1);
if (textWidth != item->_textWidth) { if (textWidth != item->_textWidth) {
item->_textWidth = textWidth; item->_textWidth = textWidth;
item->_textHeight = item->_text.countHeight(textWidth); item->_textHeight = item->_text.countHeight(textWidth);
} }
newHeight = item->_textHeight; newHeight = item->_textHeight;
} else {
newHeight = 0;
} }
if (!mediaOnBottom) { if (!mediaOnBottom) {
newHeight += st::msgPadding.bottom(); newHeight += st::msgPadding.bottom();
@ -1616,6 +1616,14 @@ int Message::resizeContentGetHeight(int newWidth) {
return newHeight; 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) { QSize Message::performCountCurrentSize(int newWidth) {
const auto item = message(); const auto item = message();
const auto newHeight = resizeContentGetHeight(newWidth); const auto newHeight = resizeContentGetHeight(newWidth);

View File

@ -128,6 +128,7 @@ private:
int resizeContentGetHeight(int newWidth); int resizeContentGetHeight(int newWidth);
QSize performCountOptimalSize() override; QSize performCountOptimalSize() override;
QSize performCountCurrentSize(int newWidth) override; QSize performCountCurrentSize(int newWidth) override;
bool hasVisibleText() const override;
bool displayFastShare() const; bool displayFastShare() const;
bool displayGoToOriginal() const; bool displayGoToOriginal() const;

View File

@ -135,8 +135,7 @@ void SendPhoto::addToHistory(
fromId, fromId,
postAuthor, postAuthor,
_photo, _photo,
_message, { _message, _entities },
//_entities,
markup); markup);
} }
@ -171,8 +170,7 @@ void SendFile::addToHistory(
fromId, fromId,
postAuthor, postAuthor,
_document, _document,
_message, { _message, _entities },
//_entities,
markup); markup);
} }

View File

@ -1237,14 +1237,11 @@ void MediaView::refreshMediaViewer() {
void MediaView::refreshCaption(HistoryItem *item) { void MediaView::refreshCaption(HistoryItem *item) {
_caption = Text(); _caption = Text();
if (!item) {
const auto media = item ? item->media() : nullptr;
if (!media) {
return; return;
} }
const auto caption = item->originalText();
const auto caption = media->caption(); if (caption.text.isEmpty()) {
if (caption.isEmpty()) {
return; return;
} }
const auto asBot = [&] { const auto asBot = [&] {
@ -1256,7 +1253,7 @@ void MediaView::refreshCaption(HistoryItem *item) {
_caption = Text(st::msgMinWidth); _caption = Text(st::msgMinWidth);
_caption.setMarkedText( _caption.setMarkedText(
st::mediaviewCaptionStyle, st::mediaviewCaptionStyle,
{ caption, EntitiesInText() }, // #TODO caption entities parse caption,
Ui::ItemTextOptions(item)); Ui::ItemTextOptions(item));
} }