Handle fwd_from without a link to the account.

This commit is contained in:
John Preston 2019-03-15 19:15:56 +04:00
parent 6d1193a751
commit a34e998c42
36 changed files with 503 additions and 192 deletions

View File

@ -1010,6 +1010,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_forwarded_via" = "Forwarded from {user} via {inline_bot}"; "lng_forwarded_via" = "Forwarded from {user} via {inline_bot}";
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}"; "lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
"lng_forwarded_signed" = "{channel} ({user})"; "lng_forwarded_signed" = "{channel} ({user})";
"lng_forwarded_hidden" = "The account was hidden by the user.";
"lng_signed_author" = "Author: {user}"; "lng_signed_author" = "Author: {user}";
"lng_in_reply_to" = "In reply to"; "lng_in_reply_to" = "In reply to";
"lng_edited" = "edited"; "lng_edited" = "edited";

View File

@ -3407,7 +3407,7 @@ void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
d.vdate, d.vdate,
d.vmessage, d.vmessage,
MTP_messageMediaEmpty(), MTP_messageMediaEmpty(),
MTPnullMarkup, MTPReplyMarkup(),
d.has_entities() ? d.ventities : MTPnullEntities, d.has_entities() ? d.ventities : MTPnullEntities,
MTPint(), MTPint(),
MTPint(), MTPint(),
@ -3431,7 +3431,7 @@ void ApiWrap::applyUpdatesNoPtsCheck(const MTPUpdates &updates) {
d.vdate, d.vdate,
d.vmessage, d.vmessage,
MTP_messageMediaEmpty(), MTP_messageMediaEmpty(),
MTPnullMarkup, MTPReplyMarkup(),
d.has_entities() ? d.ventities : MTPnullEntities, d.has_entities() ? d.ventities : MTPnullEntities,
MTPint(), MTPint(),
MTPint(), MTPint(),
@ -4366,7 +4366,7 @@ void ApiWrap::sendSharedContact(
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), MTP_int(messageFromId),
peerToMTP(peer->id), peerToMTP(peer->id),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(options.replyTo), MTP_int(options.replyTo),
MTP_int(unixtime()), MTP_int(unixtime()),
@ -4377,7 +4377,7 @@ void ApiWrap::sendSharedContact(
MTP_string(lastName), MTP_string(lastName),
MTP_string(vcard), MTP_string(vcard),
MTP_int(userId)), MTP_int(userId)),
MTPnullMarkup, MTPReplyMarkup(),
MTPnullEntities, MTPnullEntities,
MTP_int(views), MTP_int(views),
MTPint(), MTPint(),
@ -4636,13 +4636,13 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), MTP_int(messageFromId),
peerToMTP(peer->id), peerToMTP(peer->id),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(message.replyTo), MTP_int(message.replyTo),
MTP_int(unixtime()), MTP_int(unixtime()),
msgText, msgText,
media, media,
MTPnullMarkup, MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
@ -4655,7 +4655,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) {
MTP_int(message.replyTo), MTP_int(message.replyTo),
msgText, msgText,
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPReplyMarkup(),
sentEntities sentEntities
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
applyUpdates(result, randomId); applyUpdates(result, randomId);
@ -4847,7 +4847,7 @@ void ApiWrap::sendExistingDocument(
messagePostAuthor, messagePostAuthor,
document, document,
caption, caption,
MTPnullMarkup); MTPReplyMarkup());
auto failHandler = std::make_shared<Fn<void(const RPCError&)>>(); auto failHandler = std::make_shared<Fn<void(const RPCError&)>>();
auto performRequest = [=] { auto performRequest = [=] {
@ -4861,7 +4861,7 @@ void ApiWrap::sendExistingDocument(
MTPint()), MTPint()),
MTP_string(captionText), MTP_string(captionText),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPReplyMarkup(),
sentEntities sentEntities
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
applyUpdates(result, randomId); applyUpdates(result, randomId);
@ -5011,7 +5011,7 @@ void ApiWrap::sendMediaWithRandomId(
media, media,
MTP_string(caption.text), MTP_string(caption.text),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPReplyMarkup(),
sentEntities 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);

View File

@ -145,6 +145,9 @@ namespace App {
existing->updateReplyMarkup(m.has_reply_markup() existing->updateReplyMarkup(m.has_reply_markup()
? (&m.vreply_markup) ? (&m.vreply_markup)
: nullptr); : nullptr);
existing->updateForwardedInfo(m.has_fwd_from()
? &m.vfwd_from
: nullptr);
existing->setViewsCount(m.has_views() ? m.vviews.v : -1); existing->setViewsCount(m.has_views() ? m.vviews.v : -1);
existing->indexAsNewItem(); existing->indexAsNewItem();
Auth().data().requestItemTextRefresh(existing); Auth().data().requestItemTextRefresh(existing);

View File

@ -529,7 +529,7 @@ void EditCaptionBox::save() {
MTP_int(item->id), MTP_int(item->id),
MTP_string(sending.text), MTP_string(sending.text),
MTPInputMedia(), MTPInputMedia(),
MTPnullMarkup, MTPReplyMarkup(),
sentEntities), sentEntities),
rpcDone(&EditCaptionBox::saveDone), rpcDone(&EditCaptionBox::saveDone),
rpcFail(&EditCaptionBox::saveFail)); rpcFail(&EditCaptionBox::saveFail));

View File

@ -39,7 +39,7 @@ void ShareBotGame(not_null<UserData*> bot, not_null<PeerData*> chat) {
MTP_string(bot->botInfo->shareGameShortName))), MTP_string(bot->botInfo->shareGameShortName))),
MTP_string(""), MTP_string(""),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPReplyMarkup(),
MTPnullEntities), MTPnullEntities),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail), App::main()->rpcFail(&MainWidget::sendMessageFail),

View File

@ -63,6 +63,12 @@ style::color PeerUserpicColor(PeerId peerId) {
return colors[PeerColorIndex(peerId)]; return colors[PeerColorIndex(peerId)];
} }
PeerId FakePeerIdForJustName(const QString &name) {
return peerFromUser(name.isEmpty()
? 777
: hashCrc32(name.constData(), name.size() * sizeof(QChar)));
}
} // namespace Data } // namespace Data
PeerClickHandler::PeerClickHandler(not_null<PeerData*> peer) PeerClickHandler::PeerClickHandler(not_null<PeerData*> peer)

View File

@ -31,6 +31,7 @@ class Session;
int PeerColorIndex(PeerId peerId); int PeerColorIndex(PeerId peerId);
int PeerColorIndex(int32 bareId); int PeerColorIndex(int32 bareId);
style::color PeerUserpicColor(PeerId peerId); style::color PeerUserpicColor(PeerId peerId);
PeerId FakePeerIdForJustName(const QString &name);
} // namespace Data } // namespace Data

View File

@ -3019,13 +3019,13 @@ void Session::insertCheckedServiceNotification(
MTP_int(clientMsgId()), MTP_int(clientMsgId()),
MTP_int(peerToUser(PeerData::kServiceNotificationsId)), MTP_int(peerToUser(PeerData::kServiceNotificationsId)),
MTP_peerUser(MTP_int(_session->userId())), MTP_peerUser(MTP_int(_session->userId())),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTPint(), MTPint(),
MTP_int(date), MTP_int(date),
MTP_string(sending.text), MTP_string(sending.text),
media, media,
MTPnullMarkup, MTPReplyMarkup(),
TextUtilities::EntitiesToMTP(sending.entities), TextUtilities::EntitiesToMTP(sending.entities),
MTPint(), MTPint(),
MTPint(), MTPint(),

View File

@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text_options.h" #include "ui/text_options.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "support/support_helper.h" #include "support/support_helper.h"
#include "history/history_item_components.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "history/history.h" #include "history/history.h"
#include "data/data_channel.h" #include "data/data_channel.h"
@ -175,6 +176,7 @@ void paintRow(
not_null<Entry*> entry, not_null<Entry*> entry,
Dialogs::Key chat, Dialogs::Key chat,
PeerData *from, PeerData *from,
const HiddenSenderInfo *hiddenSenderInfo,
HistoryItem *item, HistoryItem *item,
const Data::Draft *draft, const Data::Draft *draft,
QDateTime date, QDateTime date,
@ -220,6 +222,13 @@ void paintRow(
st::dialogsPadding.y(), st::dialogsPadding.y(),
fullWidth, fullWidth,
st::dialogsPhotoSize); st::dialogsPhotoSize);
} else if (hiddenSenderInfo) {
hiddenSenderInfo->userpic.paint(
p,
st::dialogsPadding.x(),
st::dialogsPadding.y(),
fullWidth,
st::dialogsPhotoSize);
} else { } else {
entry->paintUserpicLeft( entry->paintUserpicLeft(
p, p,
@ -382,6 +391,8 @@ void paintRow(
icon->paint(p, rectForName.topLeft() + QPoint(qMin(from->dialogName().maxWidth(), rectForName.width()), 0), fullWidth); icon->paint(p, rectForName.topLeft() + QPoint(qMin(from->dialogName().maxWidth(), rectForName.width()), 0), fullWidth);
} }
from->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width()); from->dialogName().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
} else if (hiddenSenderInfo) {
hiddenSenderInfo->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
} else { } else {
p.setFont(st::msgNameFont); p.setFont(st::msgNameFont);
auto text = entry->chatListName(); // TODO feed name with emoji auto text = entry->chatListName(); // TODO feed name with emoji
@ -658,6 +669,7 @@ void RowPainter::paint(
entry, entry,
row->key(), row->key(),
from, from,
nullptr,
item, item,
cloudDraft, cloudDraft,
displayDate, displayDate,
@ -684,7 +696,7 @@ void RowPainter::paint(
if (const auto searchChat = row->searchInChat()) { if (const auto searchChat = row->searchInChat()) {
if (const auto peer = searchChat.peer()) { if (const auto peer = searchChat.peer()) {
if (peer->isSelf()) { if (peer->isSelf()) {
return item->senderOriginal().get(); return item->senderOriginal();
} else if (!peer->isChannel() || peer->isMegagroup()) { } else if (!peer->isChannel() || peer->isMegagroup()) {
return item->from().get(); return item->from().get();
} }
@ -694,6 +706,16 @@ void RowPainter::paint(
? history->peer->migrateTo() ? history->peer->migrateTo()
: history->peer.get(); : history->peer.get();
}(); }();
const auto hiddenSenderInfo = [&]() -> const HiddenSenderInfo* {
if (const auto searchChat = row->searchInChat()) {
if (const auto peer = searchChat.peer()) {
if (peer->isSelf()) {
return item->hiddenForwardedInfo();
}
}
}
return nullptr;
}();
const auto drawInDialogWay = [&] { const auto drawInDialogWay = [&] {
if (const auto searchChat = row->searchInChat()) { if (const auto searchChat = row->searchInChat()) {
if (const auto peer = searchChat.peer()) { if (const auto peer = searchChat.peer()) {
@ -775,6 +797,7 @@ void RowPainter::paint(
history, history,
history, history,
from, from,
hiddenSenderInfo,
item, item,
cloudDraft, cloudDraft,
ItemDateTime(item), ItemDateTime(item),

View File

@ -1156,6 +1156,12 @@ Message ParseMessage(
} }
return PeerId(0); return PeerId(0);
}); });
result.forwardedFromName = data.vfwd_from.match(
[](const MTPDmessageFwdHeader &data) {
return data.has_from_name()
? data.vfrom_name.v
: QByteArray();
});
result.forwardedDate = data.vfwd_from.match( result.forwardedDate = data.vfwd_from.match(
[](const MTPDmessageFwdHeader &data) { [](const MTPDmessageFwdHeader &data) {
return data.vdate.v; return data.vdate.v;
@ -1167,6 +1173,8 @@ Message ParseMessage(
} }
return PeerId(0); return PeerId(0);
}); });
result.forwarded = result.forwardedFromId
|| !result.forwardedFromName.isEmpty();
} }
if (data.has_post_author()) { if (data.has_post_author()) {
result.signature = ParseString(data.vpost_author); result.signature = ParseString(data.vpost_author);

View File

@ -501,7 +501,9 @@ struct Message {
int32 fromId = 0; int32 fromId = 0;
PeerId toId = 0; PeerId toId = 0;
PeerId forwardedFromId = 0; PeerId forwardedFromId = 0;
Utf8String forwardedFromName;
TimeId forwardedDate = 0; TimeId forwardedDate = 0;
bool forwarded = false;
PeerId savedFromChatId = 0; PeerId savedFromChatId = 0;
Utf8String signature; Utf8String signature;
int32 viaBotId = 0; int32 viaBotId = 0;

View File

@ -203,6 +203,9 @@ Stats AbstractWriter::produceTestExample(
if (++count % 3 == 0) { if (++count % 3 == 0) {
message.forwardedFromId = Data::UserPeerId(user.info.userId); message.forwardedFromId = Data::UserPeerId(user.info.userId);
message.forwardedDate = date(); message.forwardedDate = date();
} else if (count % 3 == 2) {
message.forwardedFromName = "Test hidden forward";
message.forwardedDate = date();
} }
message.fromId = user.info.userId; message.fromId = user.info.userId;
message.replyToMsgId = counter(); message.replyToMsgId = counter();

View File

@ -513,6 +513,8 @@ struct HtmlWriter::MessageInfo {
int32 fromId = 0; int32 fromId = 0;
TimeId date = 0; TimeId date = 0;
Data::PeerId forwardedFromId = 0; Data::PeerId forwardedFromId = 0;
QString forwardedFromName;
bool forwarded = false;
TimeId forwardedDate = 0; TimeId forwardedDate = 0;
}; };
@ -648,6 +650,20 @@ void FillUserpicNames(UserpicData &data, const Data::Peer &peer) {
} }
} }
void FillUserpicNames(UserpicData &data, const QByteArray &full) {
const auto names = full.split(' ');
data.firstName = names[0];
for (auto i = 1; i != names.size(); ++i) {
if (names[i].isEmpty()) {
continue;
}
if (!data.lastName.isEmpty()) {
data.lastName.append(' ');
}
data.lastName.append(names[i]);
}
}
QByteArray ComposeName(const UserpicData &data, const QByteArray &empty) { QByteArray ComposeName(const UserpicData &data, const QByteArray &empty) {
return ((data.firstName.isEmpty() && data.lastName.isEmpty()) return ((data.firstName.isEmpty() && data.lastName.isEmpty())
? empty ? empty
@ -948,7 +964,9 @@ auto HtmlWriter::Wrap::pushMessage(
info.fromId = message.fromId; info.fromId = message.fromId;
info.date = message.date; info.date = message.date;
info.forwardedFromId = message.forwardedFromId; info.forwardedFromId = message.forwardedFromId;
info.forwardedFromName = message.forwardedFromName;
info.forwardedDate = message.forwardedDate; info.forwardedDate = message.forwardedDate;
info.forwarded = message.forwarded;
if (message.media.content.is<UnsupportedMedia>()) { if (message.media.content.is<UnsupportedMedia>()) {
return { info, pushServiceMessage( return { info, pushServiceMessage(
message.id, message.id,
@ -1122,19 +1140,24 @@ auto HtmlWriter::Wrap::pushMessage(
block.append(pushDiv("from_name")); block.append(pushDiv("from_name"));
block.append(SerializeString( block.append(SerializeString(
ComposeName(userpic, "Deleted Account"))); ComposeName(userpic, "Deleted Account")));
if (!via.isEmpty() && !message.forwardedFromId) { if (!via.isEmpty() && !message.forwarded) {
block.append(" via @" + via); block.append(" via @" + via);
} }
block.append(popTag()); block.append(popTag());
} }
if (message.forwardedFromId) { if (message.forwarded) {
auto forwardedUserpic = UserpicData(); auto forwardedUserpic = UserpicData();
forwardedUserpic.colorIndex = PeerColorIndex( forwardedUserpic.colorIndex = message.forwardedFromId
BarePeerId(message.forwardedFromId)); ? PeerColorIndex(BarePeerId(message.forwardedFromId))
: PeerColorIndex(message.id);
forwardedUserpic.pixelSize = kHistoryUserpicSize; forwardedUserpic.pixelSize = kHistoryUserpicSize;
if (message.forwardedFromId) {
FillUserpicNames( FillUserpicNames(
forwardedUserpic, forwardedUserpic,
peers.peer(message.forwardedFromId)); peers.peer(message.forwardedFromId));
} else {
FillUserpicNames(forwardedUserpic, message.forwardedFromName);
}
const auto forwardedWrap = forwardedNeedsWrap(message, previous); const auto forwardedWrap = forwardedNeedsWrap(message, previous);
if (forwardedWrap) { if (forwardedWrap) {
@ -1179,7 +1202,7 @@ auto HtmlWriter::Wrap::pushMessage(
block.append(SerializeString(message.signature)); block.append(SerializeString(message.signature));
block.append(popTag()); block.append(popTag());
} }
if (message.forwardedFromId) { if (message.forwarded) {
block.append(popTag()); block.append(popTag());
} }
block.append(popTag()); block.append(popTag());
@ -1200,10 +1223,12 @@ bool HtmlWriter::Wrap::messageNeedsWrap(
} else if (QDateTime::fromTime_t(previous->date).date() } else if (QDateTime::fromTime_t(previous->date).date()
!= QDateTime::fromTime_t(message.date).date()) { != QDateTime::fromTime_t(message.date).date()) {
return true; return true;
} else if (!message.forwardedFromId != !previous->forwardedFromId) { } else if (message.forwarded != previous->forwarded) {
return true; return true;
} else if (std::abs(message.date - previous->date) } else if (std::abs(message.date - previous->date)
> (message.forwardedFromId ? 1 : kJoinWithinSeconds)) { > ((message.forwardedFromId || !message.forwardedFromName.isEmpty())
? 1
: kJoinWithinSeconds)) {
return true; return true;
} }
return false; return false;
@ -1725,11 +1750,12 @@ MediaData HtmlWriter::Wrap::prepareMediaData(
bool HtmlWriter::Wrap::forwardedNeedsWrap( bool HtmlWriter::Wrap::forwardedNeedsWrap(
const Data::Message &message, const Data::Message &message,
const MessageInfo *previous) const { const MessageInfo *previous) const {
Expects(message.forwardedFromId != 0); Expects(message.forwarded);
if (messageNeedsWrap(message, previous)) { if (messageNeedsWrap(message, previous)) {
return true; return true;
} else if (message.forwardedFromId != previous->forwardedFromId) { } else if (!message.forwardedFromId
|| message.forwardedFromId != previous->forwardedFromId) {
return true; return true;
} else if (Data::IsChatPeerId(message.forwardedFromId)) { } else if (Data::IsChatPeerId(message.forwardedFromId)) {
return true; return true;

View File

@ -471,6 +471,10 @@ QByteArray SerializeMessage(
pushBare( pushBare(
"forwarded_from", "forwarded_from",
wrapPeerName(message.forwardedFromId)); wrapPeerName(message.forwardedFromId));
} else if (!message.forwardedFromName.isEmpty()) {
pushBare(
"forwarded_from",
StringAllowNull(message.forwardedFromName));
} }
if (message.savedFromChatId) { if (message.savedFromChatId) {
pushBare("saved_from", wrapPeerName(message.savedFromChatId)); pushBare("saved_from", wrapPeerName(message.savedFromChatId));

View File

@ -342,6 +342,8 @@ QByteArray SerializeMessage(
push("Author", message.signature); push("Author", message.signature);
if (message.forwardedFromId) { if (message.forwardedFromId) {
push("Forwarded from", wrapPeerName(message.forwardedFromId)); push("Forwarded from", wrapPeerName(message.forwardedFromId));
} else if (!message.forwardedFromName.isEmpty()) {
push("Forwarded from", message.forwardedFromName);
} }
if (message.savedFromChatId) { if (message.savedFromChatId) {
push("Saved from", wrapPeerName(message.savedFromChatId)); push("Saved from", wrapPeerName(message.savedFromChatId));

View File

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_context_menu.h" #include "history/view/history_view_context_menu.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/toast/toast.h"
#include "ui/text_options.h" #include "ui/text_options.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_peer_menu.h" #include "window/window_peer_menu.h"
@ -686,12 +687,23 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
// paint the userpic if it intersects the painted rect // paint the userpic if it intersects the painted rect
if (userpicTop + st::msgPhotoSize > clip.top()) { if (userpicTop + st::msgPhotoSize > clip.top()) {
const auto message = view->data()->toHistoryMessage(); const auto message = view->data()->toHistoryMessage();
message->displayFrom()->paintUserpicLeft( if (const auto from = message->displayFrom()) {
from->paintUserpicLeft(
p, p,
st::historyPhotoLeft, st::historyPhotoLeft,
userpicTop, userpicTop,
width(), width(),
st::msgPhotoSize); st::msgPhotoSize);
} else if (const auto info = message->hiddenForwardedInfo()) {
info->userpic.paint(
p,
st::historyPhotoLeft,
userpicTop,
width(),
st::msgPhotoSize);
} else {
Unexpected("Corrupt forwarded information in message.");
}
} }
return true; return true;
}); });
@ -2535,9 +2547,10 @@ void HistoryInner::mouseActionUpdate() {
const auto message = view->data()->toHistoryMessage(); const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr); Assert(message != nullptr);
dragState = TextState( const auto from = message->displayFrom();
nullptr, dragState = TextState(nullptr, from
message->displayFrom()->openLink()); ? from->openLink()
: hiddenUserpicLink(message->fullId()));
_dragStateItem = App::histItemById(dragState.itemId); _dragStateItem = App::histItemById(dragState.itemId);
lnkhost = view; lnkhost = view;
return false; return false;
@ -2678,6 +2691,13 @@ void HistoryInner::mouseActionUpdate() {
} }
} }
ClickHandlerPtr HistoryInner::hiddenUserpicLink(FullMsgId id) {
static const auto result = std::make_shared<LambdaClickHandler>([] {
Ui::Toast::Show(lang(lng_forwarded_hidden));
});
return result;
}
void HistoryInner::updateDragSelection(Element *dragSelFrom, Element *dragSelTo, bool dragSelecting) { void HistoryInner::updateDragSelection(Element *dragSelFrom, Element *dragSelTo, bool dragSelecting) {
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) { if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
return; return;
@ -3066,7 +3086,9 @@ QString HistoryInner::tooltipText() const {
if (media->hidesForwardedInfo()) { if (media->hidesForwardedInfo()) {
dateText += "\n" + lng_forwarded( dateText += "\n" + lng_forwarded(
lt_user, lt_user,
forwarded->originalSender->shortName()); (forwarded->originalSender
? forwarded->originalSender->shortName()
: forwarded->hiddenSenderInfo->firstName));
} }
} }
} }

View File

@ -189,6 +189,8 @@ private:
template <typename Method> template <typename Method>
void enumerateDates(Method method); void enumerateDates(Method method);
ClickHandlerPtr hiddenUserpicLink(FullMsgId id);
void scrollDateCheck(); void scrollDateCheck();
void scrollDateHideByTimer(); void scrollDateHideByTimer();
bool canHaveFromUserpics() const; bool canHaveFromUserpics() const;

View File

@ -603,7 +603,7 @@ TimeId HistoryItem::dateOriginal() const {
return date(); return date();
} }
not_null<PeerData*> HistoryItem::senderOriginal() const { PeerData *HistoryItem::senderOriginal() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) { if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->originalSender; return forwarded->originalSender;
} }
@ -611,12 +611,21 @@ not_null<PeerData*> HistoryItem::senderOriginal() const {
return (peer->isChannel() && !peer->isMegagroup()) ? peer : from(); return (peer->isChannel() && !peer->isMegagroup()) ? peer : from();
} }
const HiddenSenderInfo *HistoryItem::hiddenForwardedInfo() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->hiddenSenderInfo.get();
}
return nullptr;
}
not_null<PeerData*> HistoryItem::fromOriginal() const { not_null<PeerData*> HistoryItem::fromOriginal() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) { if (const auto forwarded = Get<HistoryMessageForwarded>()) {
if (forwarded->originalSender) {
if (const auto user = forwarded->originalSender->asUser()) { if (const auto user = forwarded->originalSender->asUser()) {
return user; return user;
} }
} }
}
return from(); return from();
} }

View File

@ -54,6 +54,8 @@ enum class Context : char;
class ElementDelegate; class ElementDelegate;
} // namespace HistoryView } // namespace HistoryView
struct HiddenSenderInfo;
class HistoryItem : public RuntimeComposer<HistoryItem> { class HistoryItem : public RuntimeComposer<HistoryItem> {
public: public:
static not_null<HistoryItem*> Create( static not_null<HistoryItem*> Create(
@ -166,6 +168,8 @@ public:
} }
virtual void updateReplyMarkup(const MTPReplyMarkup *markup) { virtual void updateReplyMarkup(const MTPReplyMarkup *markup) {
} }
virtual void updateForwardedInfo(const MTPMessageFwdHeader *fwd) {
}
virtual void addToUnreadMentions(UnreadMentionType type); virtual void addToUnreadMentions(UnreadMentionType type);
virtual void eraseFromUnreadMentions() { virtual void eraseFromUnreadMentions() {
@ -257,7 +261,8 @@ public:
not_null<PeerData*> author() const; not_null<PeerData*> author() const;
TimeId dateOriginal() const; TimeId dateOriginal() const;
not_null<PeerData*> senderOriginal() const; PeerData *senderOriginal() const;
const HiddenSenderInfo *hiddenForwardedInfo() const;
not_null<PeerData*> fromOriginal() const; not_null<PeerData*> fromOriginal() const;
QString authorOriginal() const; QString authorOriginal() const;
MsgId idOriginal() const; MsgId idOriginal() const;

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "ui/effects/ripple_animation.h" #include "ui/effects/ripple_animation.h"
#include "ui/image/image.h" #include "ui/image/image.h"
#include "ui/toast/toast.h"
#include "ui/text_options.h" #include "ui/text_options.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_message.h" #include "history/history_message.h"
@ -77,17 +78,37 @@ int HistoryMessageEdited::maxWidth() const {
return text.maxWidth(); return text.maxWidth();
} }
HiddenSenderInfo::HiddenSenderInfo(const QString &name)
: name(name)
, colorPeerId(Data::FakePeerIdForJustName(name))
, userpic(Data::PeerUserpicColor(colorPeerId), name) {
nameText.setText(st::msgNameStyle, name, Ui::NameTextOptions());
const auto parts = name.trimmed().split(' ', QString::SkipEmptyParts);
firstName = parts[0];
for (const auto &part : parts.mid(1)) {
if (!lastName.isEmpty()) {
lastName.append(' ');
}
lastName.append(part);
}
}
void HistoryMessageForwarded::create(const HistoryMessageVia *via) const { void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
auto phrase = QString(); auto phrase = QString();
auto fromChannel = (originalSender->isChannel() && !originalSender->isMegagroup()); const auto fromChannel = originalSender
&& originalSender->isChannel()
&& !originalSender->isMegagroup();
const auto name = originalSender
? App::peerName(originalSender)
: hiddenSenderInfo->name;
if (!originalAuthor.isEmpty()) { if (!originalAuthor.isEmpty()) {
phrase = lng_forwarded_signed( phrase = lng_forwarded_signed(
lt_channel, lt_channel,
App::peerName(originalSender), name,
lt_user, lt_user,
originalAuthor); originalAuthor);
} else { } else {
phrase = App::peerName(originalSender); phrase = name;
} }
if (via) { if (via) {
if (fromChannel) { if (fromChannel) {
@ -121,9 +142,15 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
Qt::LayoutDirectionAuto Qt::LayoutDirectionAuto
}; };
text.setText(st::fwdTextStyle, phrase, opts); text.setText(st::fwdTextStyle, phrase, opts);
static const auto hidden = std::make_shared<LambdaClickHandler>([] {
Ui::Toast::Show(lang(lng_forwarded_hidden));
});
text.setLink(1, fromChannel text.setLink(1, fromChannel
? goToMessageClickHandler(originalSender, originalId) ? goToMessageClickHandler(originalSender, originalId)
: originalSender->openLink()); : originalSender
? originalSender->openLink()
: hidden);
if (via) { if (via) {
text.setLink(2, via->link); text.setLink(2, via->link);
} }

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "history/history_item.h" #include "history/history_item.h"
#include "ui/empty_userpic.h"
class HistoryDocument; class HistoryDocument;
struct WebPageData; struct WebPageData;
@ -50,11 +51,30 @@ struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited, Hist
Text text; Text text;
}; };
struct HiddenSenderInfo {
explicit HiddenSenderInfo(const QString &name);
QString name;
QString firstName;
QString lastName;
PeerId colorPeerId = 0;
Ui::EmptyUserpic userpic;
Text nameText;
inline bool operator==(const HiddenSenderInfo &other) const {
return name == other.name;
}
inline bool operator!=(const HiddenSenderInfo &other) const {
return !(*this == other);
}
};
struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded, HistoryItem> { struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded, HistoryItem> {
void create(const HistoryMessageVia *via) const; void create(const HistoryMessageVia *via) const;
TimeId originalDate = 0; TimeId originalDate = 0;
PeerData *originalSender = nullptr; PeerData *originalSender = nullptr;
std::unique_ptr<HiddenSenderInfo> hiddenSenderInfo;
QString originalAuthor; QString originalAuthor;
MsgId originalId = 0; MsgId originalId = 0;
mutable Text text = { 1 }; mutable Text text = { 1 };

View File

@ -277,6 +277,7 @@ struct HistoryMessage::CreateConfig {
int viewsCount = -1; int viewsCount = -1;
QString author; QString author;
PeerId senderOriginal = 0; PeerId senderOriginal = 0;
QString senderNameOriginal;
MsgId originalId = 0; MsgId originalId = 0;
PeerId savedFromPeer = 0; PeerId savedFromPeer = 0;
MsgId savedFromMsgId = 0; MsgId savedFromMsgId = 0;
@ -291,6 +292,24 @@ struct HistoryMessage::CreateConfig {
const HistoryMessageReplyMarkup *inlineMarkup = nullptr; const HistoryMessageReplyMarkup *inlineMarkup = nullptr;
}; };
void HistoryMessage::FillForwardedInfo(
CreateConfig &config,
const MTPDmessageFwdHeader &data) {
config.originalDate = data.vdate.v;
if (data.has_from_id() || data.has_channel_id()) {
config.senderOriginal = data.has_channel_id()
? peerFromChannel(data.vchannel_id)
: peerFromUser(data.vfrom_id);
}
if (data.has_from_name()) config.senderNameOriginal = qs(data.vfrom_name);
if (data.has_channel_post()) config.originalId = data.vchannel_post.v;
if (data.has_post_author()) config.authorOriginal = qs(data.vpost_author);
if (data.has_saved_from_peer() && data.has_saved_from_msg_id()) {
config.savedFromPeer = peerFromMTP(data.vsaved_from_peer);
config.savedFromMsgId = data.vsaved_from_msg_id.v;
}
}
HistoryMessage::HistoryMessage( HistoryMessage::HistoryMessage(
not_null<History*> history, not_null<History*> history,
const MTPDmessage &data) const MTPDmessage &data)
@ -300,22 +319,12 @@ HistoryMessage::HistoryMessage(
data.vflags.v, data.vflags.v,
data.vdate.v, data.vdate.v,
data.has_from_id() ? data.vfrom_id.v : UserId(0)) { data.has_from_id() ? data.vfrom_id.v : UserId(0)) {
CreateConfig config; auto config = CreateConfig();
if (data.has_fwd_from() && data.vfwd_from.type() == mtpc_messageFwdHeader) { if (data.has_fwd_from()) {
auto &f = data.vfwd_from.c_messageFwdHeader(); data.vfwd_from.match([&](const MTPDmessageFwdHeader &data) {
config.originalDate = f.vdate.v; FillForwardedInfo(config, data);
if (f.has_from_id() || f.has_channel_id()) { });
config.senderOriginal = f.has_channel_id()
? peerFromChannel(f.vchannel_id)
: peerFromUser(f.vfrom_id);
if (f.has_channel_post()) config.originalId = f.vchannel_post.v;
if (f.has_post_author()) config.authorOriginal = qs(f.vpost_author);
if (f.has_saved_from_peer() && f.has_saved_from_msg_id()) {
config.savedFromPeer = peerFromMTP(f.vsaved_from_peer);
config.savedFromMsgId = f.vsaved_from_msg_id.v;
}
}
} }
if (data.has_reply_to_msg_id()) config.replyTo = data.vreply_to_msg_id.v; if (data.has_reply_to_msg_id()) config.replyTo = data.vreply_to_msg_id.v;
if (data.has_via_bot_id()) config.viaBotId = data.vvia_bot_id.v; if (data.has_via_bot_id()) config.viaBotId = data.vvia_bot_id.v;
@ -350,7 +359,7 @@ HistoryMessage::HistoryMessage(
mtpCastFlags(data.vflags.v), mtpCastFlags(data.vflags.v),
data.vdate.v, data.vdate.v,
data.has_from_id() ? data.vfrom_id.v : UserId(0)) { data.has_from_id() ? data.vfrom_id.v : UserId(0)) {
CreateConfig config; auto config = CreateConfig();
if (data.has_reply_to_msg_id()) config.replyTo = data.vreply_to_msg_id.v; if (data.has_reply_to_msg_id()) config.replyTo = data.vreply_to_msg_id.v;
@ -385,17 +394,22 @@ HistoryMessage::HistoryMessage(
from) { from) {
const auto peer = history->peer; const auto peer = history->peer;
CreateConfig config; auto config = CreateConfig();
if (original->Has<HistoryMessageForwarded>() || !original->history()->peer->isSelf()) { if (original->Has<HistoryMessageForwarded>() || !original->history()->peer->isSelf()) {
// Server doesn't add "fwd_from" to non-forwarded messages from chat with yourself. // Server doesn't add "fwd_from" to non-forwarded messages from chat with yourself.
config.originalDate = original->dateOriginal(); config.originalDate = original->dateOriginal();
auto senderOriginal = original->senderOriginal(); if (const auto info = original->hiddenForwardedInfo()) {
config.senderNameOriginal = info->name;
} else if (const auto senderOriginal = original->senderOriginal()) {
config.senderOriginal = senderOriginal->id; config.senderOriginal = senderOriginal->id;
config.authorOriginal = original->authorOriginal();
if (senderOriginal->isChannel()) { if (senderOriginal->isChannel()) {
config.originalId = original->idOriginal(); config.originalId = original->idOriginal();
} }
} else {
Unexpected("Corrupt forwarded information in message.");
}
config.authorOriginal = original->authorOriginal();
} }
if (peer->isSelf()) { if (peer->isSelf()) {
// //
@ -455,7 +469,7 @@ HistoryMessage::HistoryMessage(
const QString &postAuthor, const QString &postAuthor,
const TextWithEntities &textWithEntities) const TextWithEntities &textWithEntities)
: HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) { : HistoryItem(history, id, flags, date, (flags & MTPDmessage::Flag::f_from_id) ? from : 0) {
createComponentsHelper(flags, replyTo, viaBotId, postAuthor, MTPnullMarkup); createComponentsHelper(flags, replyTo, viaBotId, postAuthor, MTPReplyMarkup());
setText(textWithEntities); setText(textWithEntities);
} }
@ -522,7 +536,7 @@ void HistoryMessage::createComponentsHelper(
UserId viaBotId, UserId viaBotId,
const QString &postAuthor, const QString &postAuthor,
const MTPReplyMarkup &markup) { const MTPReplyMarkup &markup) {
CreateConfig config; auto config = CreateConfig();
if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId; if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId;
if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo; if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo;
@ -540,10 +554,10 @@ int HistoryMessage::viewsCount() const {
return HistoryItem::viewsCount(); return HistoryItem::viewsCount();
} }
not_null<PeerData*> HistoryMessage::displayFrom() const { PeerData *HistoryMessage::displayFrom() const {
return history()->peer->isSelf() return history()->peer->isSelf()
? senderOriginal() ? senderOriginal()
: author(); : author().get();
} }
bool HistoryMessage::updateDependencyItem() { bool HistoryMessage::updateDependencyItem() {
@ -636,7 +650,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (config.editDate != TimeId(0)) { if (config.editDate != TimeId(0)) {
mask |= HistoryMessageEdited::Bit(); mask |= HistoryMessageEdited::Bit();
} }
if (config.senderOriginal) { if (config.originalDate != 0) {
mask |= HistoryMessageForwarded::Bit(); mask |= HistoryMessageForwarded::Bit();
} }
if (config.mtpMarkup) { if (config.mtpMarkup) {
@ -672,16 +686,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (const auto msgsigned = Get<HistoryMessageSigned>()) { if (const auto msgsigned = Get<HistoryMessageSigned>()) {
msgsigned->author = config.author; msgsigned->author = config.author;
} }
if (const auto forwarded = Get<HistoryMessageForwarded>()) { setupForwardedComponent(config);
forwarded->originalDate = config.originalDate;
forwarded->originalSender = history()->owner().peer(
config.senderOriginal);
forwarded->originalId = config.originalId;
forwarded->originalAuthor = config.authorOriginal;
forwarded->savedFromPeer = history()->owner().peerLoaded(
config.savedFromPeer);
forwarded->savedFromMsgId = config.savedFromMsgId;
}
if (const auto markup = Get<HistoryMessageReplyMarkup>()) { if (const auto markup = Get<HistoryMessageReplyMarkup>()) {
if (config.mtpMarkup) { if (config.mtpMarkup) {
markup->create(*config.mtpMarkup); markup->create(*config.mtpMarkup);
@ -692,7 +697,28 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
_flags |= MTPDmessage_ClientFlag::f_has_switch_inline_button; _flags |= MTPDmessage_ClientFlag::f_has_switch_inline_button;
} }
} }
_fromNameVersion = displayFrom()->nameVersion; const auto from = displayFrom();
_fromNameVersion = from ? from->nameVersion : 1;
}
void HistoryMessage::setupForwardedComponent(const CreateConfig &config) {
const auto forwarded = Get<HistoryMessageForwarded>();
if (!forwarded) {
return;
}
forwarded->originalDate = config.originalDate;
forwarded->originalSender = config.senderOriginal
? history()->owner().peer(config.senderOriginal).get()
: nullptr;
if (!forwarded->originalSender) {
forwarded->hiddenSenderInfo = std::make_unique<HiddenSenderInfo>(
config.senderNameOriginal);
}
forwarded->originalId = config.originalId;
forwarded->originalAuthor = config.authorOriginal;
forwarded->savedFromPeer = history()->owner().peerLoaded(
config.savedFromPeer);
forwarded->savedFromMsgId = config.savedFromMsgId;
} }
QString FormatViewsCount(int views) { QString FormatViewsCount(int views) {
@ -923,6 +949,25 @@ void HistoryMessage::updateSentMedia(const MTPMessageMedia *media) {
history()->owner().requestItemResize(this); history()->owner().requestItemResize(this);
} }
void HistoryMessage::updateForwardedInfo(const MTPMessageFwdHeader *fwd) {
const auto forwarded = Get<HistoryMessageForwarded>();
if (!fwd) {
if (forwarded) {
LOG(("API Error: Server removed forwarded information."));
}
return;
} else if (!forwarded) {
LOG(("API Error: Server added forwarded information."));
return;
}
fwd->match([&](const MTPDmessageFwdHeader &data) {
auto config = CreateConfig();
FillForwardedInfo(config, data);
setupForwardedComponent(config);
history()->owner().requestItemResize(this);
});
}
void HistoryMessage::addToUnreadMentions(UnreadMentionType type) { void HistoryMessage::addToUnreadMentions(UnreadMentionType type) {
if (IsServerMsgId(id) && isUnreadMention()) { if (IsServerMsgId(id) && isUnreadMention()) {
if (history()->addToUnreadMentions(id, type)) { if (history()->addToUnreadMentions(id, type)) {

View File

@ -114,6 +114,7 @@ public:
void updateReplyMarkup(const MTPReplyMarkup *markup) override { void updateReplyMarkup(const MTPReplyMarkup *markup) override {
setReplyMarkup(markup); setReplyMarkup(markup);
} }
void updateForwardedInfo(const MTPMessageFwdHeader *fwd) override;
void addToUnreadMentions(UnreadMentionType type) override; void addToUnreadMentions(UnreadMentionType type) override;
void eraseFromUnreadMentions() override; void eraseFromUnreadMentions() override;
@ -125,7 +126,7 @@ public:
bool textHasLinks() const override; bool textHasLinks() const override;
int viewsCount() const override; int viewsCount() const override;
not_null<PeerData*> displayFrom() const; PeerData *displayFrom() const;
bool updateDependencyItem() override; bool updateDependencyItem() override;
MsgId dependencyMsgId() const override { MsgId dependencyMsgId() const override {
return replyToId(); return replyToId();
@ -164,6 +165,11 @@ private:
struct CreateConfig; struct CreateConfig;
void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, UserId viaBotId, const QString &postAuthor, const MTPReplyMarkup &markup); void createComponentsHelper(MTPDmessage::Flags flags, MsgId replyTo, UserId viaBotId, const QString &postAuthor, const MTPReplyMarkup &markup);
void createComponents(const CreateConfig &config); void createComponents(const CreateConfig &config);
void setupForwardedComponent(const CreateConfig &config);
static void FillForwardedInfo(
CreateConfig &config,
const MTPDmessageFwdHeader &data);
void updateAdminBadgeState(); void updateAdminBadgeState();
ClickHandlerPtr fastReplyLink() const; ClickHandlerPtr fastReplyLink() const;

View File

@ -2753,7 +2753,7 @@ void HistoryWidget::saveEditMsg() {
MTP_int(_editMsgId), MTP_int(_editMsgId),
MTP_string(sending.text), MTP_string(sending.text),
MTPInputMedia(), MTPInputMedia(),
MTPnullMarkup, MTPReplyMarkup(),
sentEntities), sentEntities),
rpcDone(&HistoryWidget::saveEditMsgDone, _history), rpcDone(&HistoryWidget::saveEditMsgDone, _history),
rpcFail(&HistoryWidget::saveEditMsgFail, _history)); rpcFail(&HistoryWidget::saveEditMsgFail, _history));
@ -4268,13 +4268,13 @@ void HistoryWidget::sendFileConfirmed(
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), MTP_int(messageFromId),
peerToMTP(file->to.peer), peerToMTP(file->to.peer),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(file->to.replyTo), MTP_int(file->to.replyTo),
MTP_int(unixtime()), MTP_int(unixtime()),
MTP_string(caption.text), MTP_string(caption.text),
photo, photo,
MTPnullMarkup, MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
@ -4293,13 +4293,13 @@ void HistoryWidget::sendFileConfirmed(
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), MTP_int(messageFromId),
peerToMTP(file->to.peer), peerToMTP(file->to.peer),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(file->to.replyTo), MTP_int(file->to.replyTo),
MTP_int(unixtime()), MTP_int(unixtime()),
MTP_string(caption.text), MTP_string(caption.text),
document, document,
MTPnullMarkup, MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
@ -4321,13 +4321,13 @@ void HistoryWidget::sendFileConfirmed(
MTP_int(newId.msg), MTP_int(newId.msg),
MTP_int(messageFromId), MTP_int(messageFromId),
peerToMTP(file->to.peer), peerToMTP(file->to.peer),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTPint(), MTPint(),
MTP_int(file->to.replyTo), MTP_int(file->to.replyTo),
MTP_int(unixtime()), MTP_int(unixtime()),
MTP_string(caption.text), MTP_string(caption.text),
document, document,
MTPnullMarkup, MTPReplyMarkup(),
localEntities, localEntities,
MTP_int(1), MTP_int(1),
MTPint(), MTPint(),
@ -5476,7 +5476,7 @@ bool HistoryWidget::sendExistingPhoto(
messagePostAuthor, messagePostAuthor,
photo, photo,
caption, caption,
MTPnullMarkup); MTPReplyMarkup());
_history->sendRequestId = MTP::send( _history->sendRequestId = MTP::send(
MTPmessages_SendMedia( MTPmessages_SendMedia(
@ -5489,7 +5489,7 @@ bool HistoryWidget::sendExistingPhoto(
MTPint()), MTPint()),
MTP_string(caption.text), MTP_string(caption.text),
MTP_long(randomId), MTP_long(randomId),
MTPnullMarkup, MTPReplyMarkup(),
sentEntities), sentEntities),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived), App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail), App::main()->rpcFail(&MainWidget::sendMessageFail),
@ -6229,23 +6229,36 @@ void HistoryWidget::updateForwardingTexts() {
int32 version = 0; int32 version = 0;
QString from, text; QString from, text;
if (const auto count = int(_toForward.size())) { if (const auto count = int(_toForward.size())) {
QMap<PeerData*, bool> fromUsersMap; auto insertedPeers = base::flat_set<not_null<PeerData*>>();
QVector<PeerData*> fromUsers; auto insertedNames = base::flat_set<QString>();
fromUsers.reserve(_toForward.size()); auto fullname = QString();
auto names = std::vector<QString>();
names.reserve(_toForward.size());
for (const auto item : _toForward) { for (const auto item : _toForward) {
const auto from = item->senderOriginal(); if (const auto from = item->senderOriginal()) {
if (!fromUsersMap.contains(from)) { if (!insertedPeers.contains(from)) {
fromUsersMap.insert(from, true); insertedPeers.emplace(from);
fromUsers.push_back(from); names.push_back(from->shortName());
fullname = App::peerName(from);
} }
version += from->nameVersion; version += from->nameVersion;
} else if (const auto info = item->hiddenForwardedInfo()) {
if (!insertedNames.contains(info->name)) {
insertedNames.emplace(info->name);
names.push_back(info->firstName);
fullname = info->name;
} }
if (fromUsers.size() > 2) { ++version;
from = lng_forwarding_from(lt_count, fromUsers.size() - 1, lt_user, fromUsers.at(0)->shortName());
} else if (fromUsers.size() < 2) {
from = fromUsers.at(0)->name;
} else { } else {
from = lng_forwarding_from_two(lt_user, fromUsers.at(0)->shortName(), lt_second_user, fromUsers.at(1)->shortName()); Unexpected("Corrupt forwarded information in message.");
}
}
if (names.size() > 2) {
from = lng_forwarding_from(lt_count, names.size() - 1, lt_user, names[0]);
} else if (names.size() < 2) {
from = fullname;
} else {
from = lng_forwarding_from_two(lt_user, names[0], lt_second_user, names[1]);
} }
if (count < 2) { if (count < 2) {
@ -6266,7 +6279,13 @@ void HistoryWidget::checkForwardingInfo() {
if (!_toForward.empty()) { if (!_toForward.empty()) {
auto version = 0; auto version = 0;
for (const auto item : _toForward) { for (const auto item : _toForward) {
version += item->senderOriginal()->nameVersion; if (const auto from = item->senderOriginal()) {
version += from->nameVersion;
} else if (const auto info = item->hiddenForwardedInfo()) {
++version;
} else {
Unexpected("Corrupt forwarded information in message.");
}
} }
if (version != _toForwardNameVersion) { if (version != _toForwardNameVersion) {
updateForwardingTexts(); updateForwardingTexts();

View File

@ -99,9 +99,12 @@ QSize HistoryContact::countOptimalSize() {
if (_contact) { if (_contact) {
_contact->loadUserpic(); _contact->loadUserpic();
} else { } else {
const auto full = _name.originalText();
_photoEmpty = std::make_unique<Ui::EmptyUserpic>( _photoEmpty = std::make_unique<Ui::EmptyUserpic>(
Data::PeerUserpicColor(_userId ? _userId : _parent->data()->id), Data::PeerUserpicColor(_userId
_name.originalText()); ? peerFromUser(_userId)
: Data::FakePeerIdForJustName(full)),
full);
} }
if (_contact if (_contact
&& _contact->contactStatus() == UserData::ContactStatus::Contact) { && _contact->contactStatus() == UserData::ContactStatus::Contact) {

View File

@ -26,6 +26,25 @@ namespace {
// A new message from the same sender is attached to previous within 15 minutes. // A new message from the same sender is attached to previous within 15 minutes.
constexpr int kAttachMessageToPreviousSecondsDelta = 900; constexpr int kAttachMessageToPreviousSecondsDelta = 900;
bool IsAttachedToPreviousInSavedMessages(
not_null<HistoryItem*> previous,
not_null<HistoryItem*> item) {
const auto forwarded = previous->Has<HistoryMessageForwarded>();
const auto sender = previous->senderOriginal();
if (forwarded != item->Has<HistoryMessageForwarded>()) {
return false;
} else if (sender != item->senderOriginal()) {
return false;
} else if (!forwarded || sender) {
return true;
}
const auto previousInfo = previous->hiddenForwardedInfo();
const auto itemInfo = item->hiddenForwardedInfo();
Assert(previousInfo != nullptr);
Assert(itemInfo != nullptr);
return (*previousInfo == *itemInfo);
}
} // namespace } // namespace
TextSelection UnshiftItemSelection( TextSelection UnshiftItemSelection(
@ -312,8 +331,7 @@ bool Element::computeIsAttachToPrevious(not_null<Element*> previous) {
|| (!item->isPost() && !prev->isPost())); || (!item->isPost() && !prev->isPost()));
if (possible) { if (possible) {
if (item->history()->peer->isSelf()) { if (item->history()->peer->isSelf()) {
return prev->senderOriginal() == item->senderOriginal() return IsAttachedToPreviousInSavedMessages(prev, item);
&& (prev->Has<HistoryMessageForwarded>() == item->Has<HistoryMessageForwarded>());
} else { } else {
return prev->from() == item->from(); return prev->from() == item->from();
} }

View File

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/window_peer_menu.h" #include "window/window_peer_menu.h"
#include "auth_session.h" #include "auth_session.h"
#include "ui/widgets/popup_menu.h" #include "ui/widgets/popup_menu.h"
#include "ui/toast/toast.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "boxes/peers/edit_participant_box.h" #include "boxes/peers/edit_participant_box.h"
#include "data/data_session.h" #include "data/data_session.h"
@ -1303,12 +1304,23 @@ void ListWidget::paintEvent(QPaintEvent *e) {
const auto message = view->data()->toHistoryMessage(); const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr); Assert(message != nullptr);
message->from()->paintUserpicLeft( if (const auto from = message->displayFrom()) {
from->paintUserpicLeft(
p, p,
st::historyPhotoLeft, st::historyPhotoLeft,
userpicTop, userpicTop,
view->width(), view->width(),
st::msgPhotoSize); st::msgPhotoSize);
} else if (const auto info = message->hiddenForwardedInfo()) {
info->userpic.paint(
p,
st::historyPhotoLeft,
userpicTop,
view->width(),
st::msgPhotoSize);
} else {
Unexpected("Corrupt forwarded information in message.");
}
} }
return true; return true;
}); });
@ -2147,9 +2159,10 @@ void ListWidget::mouseActionUpdate() {
const auto message = view->data()->toHistoryMessage(); const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr); Assert(message != nullptr);
dragState = TextState( const auto from = message->displayFrom();
nullptr, dragState = TextState(nullptr, from
message->displayFrom()->openLink()); ? from->openLink()
: hiddenUserpicLink(message->fullId()));
_overItemExact = App::histItemById(dragState.itemId); _overItemExact = App::histItemById(dragState.itemId);
lnkhost = view; lnkhost = view;
return false; return false;
@ -2221,6 +2234,13 @@ void ListWidget::mouseActionUpdate() {
//} // #TODO select scroll //} // #TODO select scroll
} }
ClickHandlerPtr ListWidget::hiddenUserpicLink(FullMsgId id) {
static const auto result = std::make_shared<LambdaClickHandler>([] {
Ui::Toast::Show(lang(lng_forwarded_hidden));
});
return result;
}
style::cursor ListWidget::computeMouseCursor() const { style::cursor ListWidget::computeMouseCursor() const {
if (ClickHandler::getPressed() || ClickHandler::getActive()) { if (ClickHandler::getPressed() || ClickHandler::getActive()) {
return style::cur_pointer; return style::cur_pointer;

View File

@ -409,6 +409,8 @@ private:
template <typename Method> template <typename Method>
void enumerateDates(Method method); void enumerateDates(Method method);
ClickHandlerPtr hiddenUserpicLink(FullMsgId id);
static constexpr auto kMinimalIdsLimit = 24; static constexpr auto kMinimalIdsLimit = 24;
not_null<ListDelegate*> _delegate; not_null<ListDelegate*> _delegate;

View File

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/media/history_media.h" #include "history/media/history_media.h"
#include "history/media/history_media_web_page.h" #include "history/media/history_media_web_page.h"
#include "history/history.h" #include "history/history.h"
#include "ui/toast/toast.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
@ -149,7 +150,7 @@ void PaintBubble(Painter &p, QRect rect, int outerWidth, bool selected, bool out
App::roundRect(p, rect, bg, cors, &sh, parts); App::roundRect(p, rect, bg, cors, &sh, parts);
} }
style::color FromNameFg(not_null<PeerData*> peer, bool selected) { style::color FromNameFg(PeerId peerId, bool selected) {
if (selected) { if (selected) {
const style::color colors[] = { const style::color colors[] = {
st::historyPeer1NameFgSelected, st::historyPeer1NameFgSelected,
@ -161,7 +162,7 @@ style::color FromNameFg(not_null<PeerData*> peer, bool selected) {
st::historyPeer7NameFgSelected, st::historyPeer7NameFgSelected,
st::historyPeer8NameFgSelected, st::historyPeer8NameFgSelected,
}; };
return colors[Data::PeerColorIndex(peer->id)]; return colors[Data::PeerColorIndex(peerId)];
} else { } else {
const style::color colors[] = { const style::color colors[] = {
st::historyPeer1NameFg, st::historyPeer1NameFg,
@ -173,7 +174,7 @@ style::color FromNameFg(not_null<PeerData*> peer, bool selected) {
st::historyPeer7NameFg, st::historyPeer7NameFg,
st::historyPeer8NameFg, st::historyPeer8NameFg,
}; };
return colors[Data::PeerColorIndex(peer->id)]; return colors[Data::PeerColorIndex(peerId)];
} }
} }
@ -286,8 +287,12 @@ QSize Message::performCountOptimalSize() {
// Count parts in maxWidth(), don't count them in minHeight(). // Count parts in maxWidth(), don't count them in minHeight().
// They will be added in resizeGetHeight() anyway. // They will be added in resizeGetHeight() anyway.
if (displayFromName()) { if (displayFromName()) {
const auto from = item->displayFrom();
const auto &name = from
? from->nameText
: item->hiddenForwardedInfo()->nameText;
auto namew = st::msgPadding.left() auto namew = st::msgPadding.left()
+ item->displayFrom()->nameText.maxWidth() + name.maxWidth()
+ st::msgPadding.right(); + st::msgPadding.right();
if (via && !displayForwardedFrom()) { if (via && !displayForwardedFrom()) {
namew += st::msgServiceFont->spacew + via->maxWidth; namew += st::msgServiceFont->spacew + via->maxWidth;
@ -421,7 +426,9 @@ void Message::draw(
} }
if (bubble) { if (bubble) {
if (displayFromName() && item->displayFrom()->nameVersion > item->_fromNameVersion) { if (displayFromName()
&& item->displayFrom()
&& item->displayFrom()->nameVersion > item->_fromNameVersion) {
fromNameUpdated(g.width()); fromNameUpdated(g.width());
} }
@ -531,13 +538,23 @@ void Message::paintFromName(
} }
p.setFont(st::msgNameFont); p.setFont(st::msgNameFont);
const auto nameText = [&]() -> const Text* {
const auto from = item->displayFrom();
if (item->isPost()) { if (item->isPost()) {
p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg); p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg);
return &from->nameText;
} else if (from) {
p.setPen(FromNameFg(from->id, selected));
return &from->nameText;
} else if (const auto info = item->hiddenForwardedInfo()) {
p.setPen(FromNameFg(info->colorPeerId, selected));
return &info->nameText;
} else { } else {
p.setPen(FromNameFg(item->displayFrom(), selected)); Unexpected("Corrupt forwarded information in message.");
} }
item->displayFrom()->nameText.drawElided(p, availableLeft, trect.top(), availableWidth); }();
auto skipWidth = item->displayFrom()->nameText.maxWidth() + st::msgServiceFont->spacew; nameText->drawElided(p, availableLeft, trect.top(), availableWidth);
const auto skipWidth = nameText->maxWidth() + st::msgServiceFont->spacew;
availableLeft += skipWidth; availableLeft += skipWidth;
availableWidth -= skipWidth; availableWidth -= skipWidth;
@ -861,19 +878,31 @@ bool Message::getStateFromName(
if (replyWidth) { if (replyWidth) {
availableWidth -= st::msgPadding.right() + replyWidth; availableWidth -= st::msgPadding.right() + replyWidth;
} }
auto user = item->displayFrom(); const auto from = item->displayFrom();
const auto nameText = [&]() -> const Text* {
if (from) {
return &from->nameText;
} else if (const auto info = item->hiddenForwardedInfo()) {
return &info->nameText;
} else {
Unexpected("Corrupt forwarded information in message.");
}
}();
if (point.x() >= availableLeft if (point.x() >= availableLeft
&& point.x() < availableLeft + availableWidth && point.x() < availableLeft + availableWidth
&& point.x() < availableLeft + user->nameText.maxWidth()) { && point.x() < availableLeft + nameText->maxWidth()) {
outResult->link = user->openLink(); static const auto hidden = std::make_shared<LambdaClickHandler>([] {
Ui::Toast::Show(lang(lng_forwarded_hidden));
});
outResult->link = from ? from->openLink() : hidden;
return true; return true;
} }
auto via = item->Get<HistoryMessageVia>(); auto via = item->Get<HistoryMessageVia>();
if (via if (via
&& !displayForwardedFrom() && !displayForwardedFrom()
&& point.x() >= availableLeft + item->displayFrom()->nameText.maxWidth() + st::msgServiceFont->spacew && point.x() >= availableLeft + nameText->maxWidth() + st::msgServiceFont->spacew
&& point.x() < availableLeft + availableWidth && point.x() < availableLeft + availableWidth
&& point.x() < availableLeft + user->nameText.maxWidth() + st::msgServiceFont->spacew + via->width) { && point.x() < availableLeft + nameText->maxWidth() + st::msgServiceFont->spacew + via->width) {
outResult->link = via->link; outResult->link = via->link;
return true; return true;
} }
@ -1316,7 +1345,8 @@ bool Message::displayForwardedFrom() const {
|| !media || !media
|| !media->isDisplayed() || !media->isDisplayed()
|| !media->hideForwardedFrom() || !media->hideForwardedFrom()
|| forwarded->originalSender->isChannel(); || (forwarded->originalSender
&& forwarded->originalSender->isChannel());
} }
return false; return false;
} }
@ -1376,6 +1406,7 @@ bool Message::displayFastShare() const {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) { if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
return !peer->isSelf() return !peer->isSelf()
&& !item->out() && !item->out()
&& forwarded->originalSender
&& forwarded->originalSender->isChannel() && forwarded->originalSender->isChannel()
&& !forwarded->originalSender->isMegagroup(); && !forwarded->originalSender->isMegagroup();
} else if (user->botInfo && !item->out()) { } else if (user->botInfo && !item->out()) {
@ -1521,13 +1552,23 @@ void Message::fromNameUpdated(int width) const {
} else if (replyWidth) { } else if (replyWidth) {
width -= st::msgPadding.right() + replyWidth; width -= st::msgPadding.right() + replyWidth;
} }
item->_fromNameVersion = item->displayFrom()->nameVersion; const auto from = item->displayFrom();
item->_fromNameVersion = from ? from->nameVersion : 1;
if (const auto via = item->Get<HistoryMessageVia>()) { if (const auto via = item->Get<HistoryMessageVia>()) {
if (!displayForwardedFrom()) { if (!displayForwardedFrom()) {
const auto nameText = [&]() -> const Text* {
if (from) {
return &from->nameText;
} else if (const auto info = item->hiddenForwardedInfo()) {
return &info->nameText;
} else {
Unexpected("Corrupted forwarded information in message.");
}
}();
via->resize(width via->resize(width
- st::msgPadding.left() - st::msgPadding.left()
- st::msgPadding.right() - st::msgPadding.right()
- item->displayFrom()->nameText.maxWidth() - nameText->maxWidth()
- st::msgServiceFont->spacew); - st::msgServiceFont->spacew);
} }
} }

View File

@ -317,7 +317,7 @@ bool Result::hasThumbDisplay() const {
void Result::addToHistory(History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId, const QString &postAuthor) const { void Result::addToHistory(History *history, MTPDmessage::Flags flags, MsgId msgId, UserId fromId, MTPint mtpDate, UserId viaBotId, MsgId replyToId, const QString &postAuthor) const {
flags |= MTPDmessage_ClientFlag::f_from_inline_bot; flags |= MTPDmessage_ClientFlag::f_from_inline_bot;
MTPReplyMarkup markup = MTPnullMarkup; auto markup = MTPReplyMarkup();
if (_mtpKeyboard) { if (_mtpKeyboard) {
flags |= MTPDmessage::Flag::f_reply_markup; flags |= MTPDmessage::Flag::f_reply_markup;
markup = *_mtpKeyboard; markup = *_mtpKeyboard;

View File

@ -46,7 +46,7 @@ void SendDataCommon::addToHistory(
MTP_int(msgId), MTP_int(msgId),
MTP_int(fromId), MTP_int(fromId),
peerToMTP(history->peer->id), peerToMTP(history->peer->id),
MTPnullFwdHeader, MTPMessageFwdHeader(),
MTP_int(viaBotId), MTP_int(viaBotId),
MTP_int(replyToId), MTP_int(replyToId),
mtpDate, mtpDate,

View File

@ -157,32 +157,29 @@ bool HasForceLogoutNotification(const MTPUpdates &updates) {
bool ForwardedInfoDataLoaded( bool ForwardedInfoDataLoaded(
not_null<AuthSession*> session, not_null<AuthSession*> session,
const MTPMessageFwdHeader &header) { const MTPMessageFwdHeader &header) {
if (header.type() != mtpc_messageFwdHeader) { return header.match([&](const MTPDmessageFwdHeader &data) {
return true; if (data.has_channel_id()) {
} if (!session->data().channelLoaded(data.vchannel_id.v)) {
auto &info = header.c_messageFwdHeader();
if (info.has_channel_id()) {
if (!session->data().channelLoaded(info.vchannel_id.v)) {
return false; return false;
} }
if (info.has_from_id()) { if (data.has_from_id()) {
const auto from = session->data().user(info.vfrom_id.v); const auto from = session->data().user(data.vfrom_id.v);
if (from->loadedStatus == PeerData::NotLoaded) { if (from->loadedStatus == PeerData::NotLoaded) {
return false; return false;
} }
} }
} else { } else if (data.has_from_id()
if (info.has_from_id() && !session->data().userLoaded(info.vfrom_id.v)) { && !session->data().userLoaded(data.vfrom_id.v)) {
return false; return false;
} }
}
return true; return true;
});
} }
bool MentionUsersLoaded( bool MentionUsersLoaded(
not_null<AuthSession*> session, not_null<AuthSession*> session,
const MTPVector<MTPMessageEntity> &entities) { const MTPVector<MTPMessageEntity> &entities) {
for_const (auto &entity, entities.v) { for (const auto &entity : entities.v) {
auto type = entity.type(); auto type = entity.type();
if (type == mtpc_messageEntityMentionName) { if (type == mtpc_messageEntityMentionName) {
if (!session->data().userLoaded(entity.c_messageEntityMentionName().vuser_id.v)) { if (!session->data().userLoaded(entity.c_messageEntityMentionName().vuser_id.v)) {

View File

@ -521,9 +521,9 @@ void OverlayWidget::updateControls() {
} else { } else {
_dateText = lng_mediaview_date_time(lt_date, d.date().toString(qsl("dd.MM.yy")), lt_time, d.time().toString(cTimeFormat())); _dateText = lng_mediaview_date_time(lt_date, d.date().toString(qsl("dd.MM.yy")), lt_time, d.time().toString(cTimeFormat()));
} }
if (_from) { if (!_fromName.isEmpty()) {
_fromName.setText(st::mediaviewTextStyle, (_from->migrateTo() ? _from->migrateTo() : _from)->name, Ui::NameTextOptions()); _fromNameLabel.setText(st::mediaviewTextStyle, _fromName, Ui::NameTextOptions());
_nameNav = myrtlrect(st::mediaviewTextLeft, height() - st::mediaviewTextTop, qMin(_fromName.maxWidth(), width() / 3), st::mediaviewFont->height); _nameNav = myrtlrect(st::mediaviewTextLeft, height() - st::mediaviewTextTop, qMin(_fromNameLabel.maxWidth(), width() / 3), st::mediaviewFont->height);
_dateNav = myrtlrect(st::mediaviewTextLeft + _nameNav.width() + st::mediaviewTextSkip, height() - st::mediaviewTextTop, st::mediaviewFont->width(_dateText), st::mediaviewFont->height); _dateNav = myrtlrect(st::mediaviewTextLeft + _nameNav.width() + st::mediaviewTextSkip, height() - st::mediaviewTextTop, st::mediaviewFont->width(_dateText), st::mediaviewFont->height);
} else { } else {
_nameNav = QRect(); _nameNav = QRect();
@ -920,6 +920,7 @@ void OverlayWidget::clearData() {
_menu = nullptr; _menu = nullptr;
setContext(std::nullopt); setContext(std::nullopt);
_from = nullptr; _from = nullptr;
_fromName = QString();
_photo = nullptr; _photo = nullptr;
_doc = nullptr; _doc = nullptr;
_fullScreenVideo = false; _fullScreenVideo = false;
@ -1523,6 +1524,22 @@ void OverlayWidget::refreshMediaViewer() {
preloadData(0); preloadData(0);
} }
void OverlayWidget::refreshFromLabel(HistoryItem *item) {
if (_msgid && item) {
_from = item->senderOriginal();
if (const auto info = item->hiddenForwardedInfo()) {
_fromName = info->name;
} else {
Assert(_from != nullptr);
_fromName = App::peerName(
_from->migrateTo() ? _from->migrateTo() : _from);
}
} else {
_from = _user;
_fromName = _user ? App::peerName(_user) : QString();
}
}
void OverlayWidget::refreshCaption(HistoryItem *item) { void OverlayWidget::refreshCaption(HistoryItem *item) {
_caption = Text(); _caption = Text();
if (!item) { if (!item) {
@ -1720,11 +1737,7 @@ void OverlayWidget::displayPhoto(not_null<PhotoData*> photo, HistoryItem *item)
_w = ConvertScale(photo->width()); _w = ConvertScale(photo->width());
_h = ConvertScale(photo->height()); _h = ConvertScale(photo->height());
contentSizeChanged(); contentSizeChanged();
if (_msgid && item) { refreshFromLabel(item);
_from = item->senderOriginal();
} else {
_from = _user;
}
_photo->download(fileOrigin()); _photo->download(fileOrigin());
displayFinished(); displayFinished();
} }
@ -1860,11 +1873,7 @@ void OverlayWidget::displayDocument(DocumentData *doc, HistoryItem *item) {
_h = contentSize.height(); _h = contentSize.height();
} }
contentSizeChanged(); contentSizeChanged();
if (_msgid && item) { refreshFromLabel(item);
_from = item->senderOriginal();
} else {
_from = _user;
}
_blurred = false; _blurred = false;
displayFinished(); displayFinished();
} }
@ -2614,10 +2623,10 @@ void OverlayWidget::paintEvent(QPaintEvent *e) {
p.setFont(st::mediaviewFont); p.setFont(st::mediaviewFont);
// name // name
if (_from && _nameNav.intersects(r)) { if (_nameNav.isValid() && _nameNav.intersects(r)) {
float64 o = overLevel(OverName); float64 o = _from ? overLevel(OverName) : 0.;
p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co); p.setOpacity((o * st::mediaviewIconOverOpacity + (1 - o) * st::mediaviewIconOpacity) * co);
_fromName.drawElided(p, _nameNav.left(), _nameNav.top(), _nameNav.width()); _fromNameLabel.drawElided(p, _nameNav.left(), _nameNav.top(), _nameNav.width());
if (o > 0) { if (o > 0) {
p.setOpacity(o * co); p.setOpacity(o * co);
@ -3330,7 +3339,7 @@ void OverlayWidget::updateOver(QPoint pos) {
updateOverState(OverLeftNav); updateOverState(OverLeftNav);
} else if (_rightNavVisible && _rightNav.contains(pos)) { } else if (_rightNavVisible && _rightNav.contains(pos)) {
updateOverState(OverRightNav); updateOverState(OverRightNav);
} else if (_nameNav.contains(pos)) { } else if (_from && _nameNav.contains(pos)) {
updateOverState(OverName); updateOverState(OverName);
} else if (IsServerMsgId(_msgid.msg) && _dateNav.contains(pos)) { } else if (IsServerMsgId(_msgid.msg) && _dateNav.contains(pos)) {
updateOverState(OverDate); updateOverState(OverDate);

View File

@ -217,6 +217,7 @@ private:
Data::FileOrigin fileOrigin() const; Data::FileOrigin fileOrigin() const;
void refreshFromLabel(HistoryItem *item);
void refreshCaption(HistoryItem *item); void refreshCaption(HistoryItem *item);
void refreshMediaViewer(); void refreshMediaViewer();
void refreshNavVisibility(); void refreshNavVisibility();
@ -387,7 +388,8 @@ private:
bool _firstOpenedPeerPhoto = false; bool _firstOpenedPeerPhoto = false;
PeerData *_from = nullptr; PeerData *_from = nullptr;
Text _fromName; QString _fromName;
Text _fromNameLabel;
std::optional<int> _index; // Index in current _sharedMedia data. std::optional<int> _index; // Index in current _sharedMedia data.
std::optional<int> _fullIndex; // Index in full shared media. std::optional<int> _fullIndex; // Index in full shared media.

View File

@ -7,17 +7,4 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#include "mtproto/type_utils.h" #include "mtproto/type_utils.h"
const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(
MTP_flags(0),
MTP_vector<MTPKeyboardButtonRow>(0));
const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0); const MTPVector<MTPMessageEntity> MTPnullEntities = MTP_vector<MTPMessageEntity>(0);
const MTPMessageFwdHeader MTPnullFwdHeader = MTP_messageFwdHeader(
MTP_flags(0),
MTPint(),
MTPstring(),
MTPint(),
MTPint(),
MTPint(),
MTPstring(),
MTPPeer(),
MTPint());

View File

@ -142,6 +142,4 @@ enum class MTPDchannel_ClientFlag : uint32 {
}; };
DEFINE_MTP_CLIENT_FLAGS(MTPDchannel) DEFINE_MTP_CLIENT_FLAGS(MTPDchannel)
extern const MTPReplyMarkup MTPnullMarkup;
extern const MTPVector<MTPMessageEntity> MTPnullEntities; extern const MTPVector<MTPMessageEntity> MTPnullEntities;
extern const MTPMessageFwdHeader MTPnullFwdHeader;