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_channel_via" = "Forwarded from {channel} via {inline_bot}";
"lng_forwarded_signed" = "{channel} ({user})";
"lng_forwarded_hidden" = "The account was hidden by the user.";
"lng_signed_author" = "Author: {user}";
"lng_in_reply_to" = "In reply to";
"lng_edited" = "edited";

View File

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

View File

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

View File

@ -529,7 +529,7 @@ void EditCaptionBox::save() {
MTP_int(item->id),
MTP_string(sending.text),
MTPInputMedia(),
MTPnullMarkup,
MTPReplyMarkup(),
sentEntities),
rpcDone(&EditCaptionBox::saveDone),
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(""),
MTP_long(randomId),
MTPnullMarkup,
MTPReplyMarkup(),
MTPnullEntities),
App::main()->rpcDone(&MainWidget::sentUpdatesReceived),
App::main()->rpcFail(&MainWidget::sendMessageFail),

View File

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

View File

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

View File

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

View File

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

View File

@ -1156,6 +1156,12 @@ Message ParseMessage(
}
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(
[](const MTPDmessageFwdHeader &data) {
return data.vdate.v;
@ -1167,6 +1173,8 @@ Message ParseMessage(
}
return PeerId(0);
});
result.forwarded = result.forwardedFromId
|| !result.forwardedFromName.isEmpty();
}
if (data.has_post_author()) {
result.signature = ParseString(data.vpost_author);

View File

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

View File

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

View File

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

View File

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

View File

@ -342,6 +342,8 @@ QByteArray SerializeMessage(
push("Author", message.signature);
if (message.forwardedFromId) {
push("Forwarded from", wrapPeerName(message.forwardedFromId));
} else if (!message.forwardedFromName.isEmpty()) {
push("Forwarded from", message.forwardedFromName);
}
if (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 "ui/widgets/popup_menu.h"
#include "ui/image/image.h"
#include "ui/toast/toast.h"
#include "ui/text_options.h"
#include "window/window_controller.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
if (userpicTop + st::msgPhotoSize > clip.top()) {
const auto message = view->data()->toHistoryMessage();
message->displayFrom()->paintUserpicLeft(
p,
st::historyPhotoLeft,
userpicTop,
width(),
st::msgPhotoSize);
if (const auto from = message->displayFrom()) {
from->paintUserpicLeft(
p,
st::historyPhotoLeft,
userpicTop,
width(),
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;
});
@ -2535,9 +2547,10 @@ void HistoryInner::mouseActionUpdate() {
const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr);
dragState = TextState(
nullptr,
message->displayFrom()->openLink());
const auto from = message->displayFrom();
dragState = TextState(nullptr, from
? from->openLink()
: hiddenUserpicLink(message->fullId()));
_dragStateItem = App::histItemById(dragState.itemId);
lnkhost = view;
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) {
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
return;
@ -3066,7 +3086,9 @@ QString HistoryInner::tooltipText() const {
if (media->hidesForwardedInfo()) {
dateText += "\n" + lng_forwarded(
lt_user,
forwarded->originalSender->shortName());
(forwarded->originalSender
? forwarded->originalSender->shortName()
: forwarded->hiddenSenderInfo->firstName));
}
}
}

View File

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

View File

@ -603,7 +603,7 @@ TimeId HistoryItem::dateOriginal() const {
return date();
}
not_null<PeerData*> HistoryItem::senderOriginal() const {
PeerData *HistoryItem::senderOriginal() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->originalSender;
}
@ -611,10 +611,19 @@ not_null<PeerData*> HistoryItem::senderOriginal() const {
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 {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
if (const auto user = forwarded->originalSender->asUser()) {
return user;
if (forwarded->originalSender) {
if (const auto user = forwarded->originalSender->asUser()) {
return user;
}
}
}
return from();

View File

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

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h"
#include "ui/effects/ripple_animation.h"
#include "ui/image/image.h"
#include "ui/toast/toast.h"
#include "ui/text_options.h"
#include "history/history.h"
#include "history/history_message.h"
@ -77,17 +78,37 @@ int HistoryMessageEdited::maxWidth() const {
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 {
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()) {
phrase = lng_forwarded_signed(
lt_channel,
App::peerName(originalSender),
name,
lt_user,
originalAuthor);
} else {
phrase = App::peerName(originalSender);
phrase = name;
}
if (via) {
if (fromChannel) {
@ -121,9 +142,15 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
Qt::LayoutDirectionAuto
};
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
? goToMessageClickHandler(originalSender, originalId)
: originalSender->openLink());
: originalSender
? originalSender->openLink()
: hidden);
if (via) {
text.setLink(2, via->link);
}

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "history/history_item.h"
#include "ui/empty_userpic.h"
class HistoryDocument;
struct WebPageData;
@ -50,11 +51,30 @@ struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited, Hist
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> {
void create(const HistoryMessageVia *via) const;
TimeId originalDate = 0;
PeerData *originalSender = nullptr;
std::unique_ptr<HiddenSenderInfo> hiddenSenderInfo;
QString originalAuthor;
MsgId originalId = 0;
mutable Text text = { 1 };

View File

@ -277,6 +277,7 @@ struct HistoryMessage::CreateConfig {
int viewsCount = -1;
QString author;
PeerId senderOriginal = 0;
QString senderNameOriginal;
MsgId originalId = 0;
PeerId savedFromPeer = 0;
MsgId savedFromMsgId = 0;
@ -291,6 +292,24 @@ struct HistoryMessage::CreateConfig {
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(
not_null<History*> history,
const MTPDmessage &data)
@ -300,22 +319,12 @@ HistoryMessage::HistoryMessage(
data.vflags.v,
data.vdate.v,
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) {
auto &f = data.vfwd_from.c_messageFwdHeader();
config.originalDate = f.vdate.v;
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_fwd_from()) {
data.vfwd_from.match([&](const MTPDmessageFwdHeader &data) {
FillForwardedInfo(config, data);
});
}
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;
@ -350,7 +359,7 @@ HistoryMessage::HistoryMessage(
mtpCastFlags(data.vflags.v),
data.vdate.v,
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;
@ -385,17 +394,22 @@ HistoryMessage::HistoryMessage(
from) {
const auto peer = history->peer;
CreateConfig config;
auto config = CreateConfig();
if (original->Has<HistoryMessageForwarded>() || !original->history()->peer->isSelf()) {
// Server doesn't add "fwd_from" to non-forwarded messages from chat with yourself.
config.originalDate = original->dateOriginal();
auto senderOriginal = original->senderOriginal();
config.senderOriginal = senderOriginal->id;
config.authorOriginal = original->authorOriginal();
if (senderOriginal->isChannel()) {
config.originalId = original->idOriginal();
if (const auto info = original->hiddenForwardedInfo()) {
config.senderNameOriginal = info->name;
} else if (const auto senderOriginal = original->senderOriginal()) {
config.senderOriginal = senderOriginal->id;
if (senderOriginal->isChannel()) {
config.originalId = original->idOriginal();
}
} else {
Unexpected("Corrupt forwarded information in message.");
}
config.authorOriginal = original->authorOriginal();
}
if (peer->isSelf()) {
//
@ -455,7 +469,7 @@ HistoryMessage::HistoryMessage(
const QString &postAuthor,
const TextWithEntities &textWithEntities)
: 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);
}
@ -522,7 +536,7 @@ void HistoryMessage::createComponentsHelper(
UserId viaBotId,
const QString &postAuthor,
const MTPReplyMarkup &markup) {
CreateConfig config;
auto config = CreateConfig();
if (flags & MTPDmessage::Flag::f_via_bot_id) config.viaBotId = viaBotId;
if (flags & MTPDmessage::Flag::f_reply_to_msg_id) config.replyTo = replyTo;
@ -540,10 +554,10 @@ int HistoryMessage::viewsCount() const {
return HistoryItem::viewsCount();
}
not_null<PeerData*> HistoryMessage::displayFrom() const {
PeerData *HistoryMessage::displayFrom() const {
return history()->peer->isSelf()
? senderOriginal()
: author();
: author().get();
}
bool HistoryMessage::updateDependencyItem() {
@ -636,7 +650,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (config.editDate != TimeId(0)) {
mask |= HistoryMessageEdited::Bit();
}
if (config.senderOriginal) {
if (config.originalDate != 0) {
mask |= HistoryMessageForwarded::Bit();
}
if (config.mtpMarkup) {
@ -672,16 +686,7 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
if (const auto msgsigned = Get<HistoryMessageSigned>()) {
msgsigned->author = config.author;
}
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
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;
}
setupForwardedComponent(config);
if (const auto markup = Get<HistoryMessageReplyMarkup>()) {
if (config.mtpMarkup) {
markup->create(*config.mtpMarkup);
@ -692,7 +697,28 @@ void HistoryMessage::createComponents(const CreateConfig &config) {
_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) {
@ -923,6 +949,25 @@ void HistoryMessage::updateSentMedia(const MTPMessageMedia *media) {
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) {
if (IsServerMsgId(id) && isUnreadMention()) {
if (history()->addToUnreadMentions(id, type)) {

View File

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

View File

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

View File

@ -99,9 +99,12 @@ QSize HistoryContact::countOptimalSize() {
if (_contact) {
_contact->loadUserpic();
} else {
const auto full = _name.originalText();
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(
Data::PeerUserpicColor(_userId ? _userId : _parent->data()->id),
_name.originalText());
Data::PeerUserpicColor(_userId
? peerFromUser(_userId)
: Data::FakePeerIdForJustName(full)),
full);
}
if (_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.
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
TextSelection UnshiftItemSelection(
@ -312,8 +331,7 @@ bool Element::computeIsAttachToPrevious(not_null<Element*> previous) {
|| (!item->isPost() && !prev->isPost()));
if (possible) {
if (item->history()->peer->isSelf()) {
return prev->senderOriginal() == item->senderOriginal()
&& (prev->Has<HistoryMessageForwarded>() == item->Has<HistoryMessageForwarded>());
return IsAttachedToPreviousInSavedMessages(prev, item);
} else {
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 "auth_session.h"
#include "ui/widgets/popup_menu.h"
#include "ui/toast/toast.h"
#include "lang/lang_keys.h"
#include "boxes/peers/edit_participant_box.h"
#include "data/data_session.h"
@ -1303,12 +1304,23 @@ void ListWidget::paintEvent(QPaintEvent *e) {
const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr);
message->from()->paintUserpicLeft(
p,
st::historyPhotoLeft,
userpicTop,
view->width(),
st::msgPhotoSize);
if (const auto from = message->displayFrom()) {
from->paintUserpicLeft(
p,
st::historyPhotoLeft,
userpicTop,
view->width(),
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;
});
@ -2147,9 +2159,10 @@ void ListWidget::mouseActionUpdate() {
const auto message = view->data()->toHistoryMessage();
Assert(message != nullptr);
dragState = TextState(
nullptr,
message->displayFrom()->openLink());
const auto from = message->displayFrom();
dragState = TextState(nullptr, from
? from->openLink()
: hiddenUserpicLink(message->fullId()));
_overItemExact = App::histItemById(dragState.itemId);
lnkhost = view;
return false;
@ -2221,6 +2234,13 @@ void ListWidget::mouseActionUpdate() {
//} // #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 {
if (ClickHandler::getPressed() || ClickHandler::getActive()) {
return style::cur_pointer;

View File

@ -409,6 +409,8 @@ private:
template <typename Method>
void enumerateDates(Method method);
ClickHandlerPtr hiddenUserpicLink(FullMsgId id);
static constexpr auto kMinimalIdsLimit = 24;
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_web_page.h"
#include "history/history.h"
#include "ui/toast/toast.h"
#include "data/data_session.h"
#include "data/data_user.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);
}
style::color FromNameFg(not_null<PeerData*> peer, bool selected) {
style::color FromNameFg(PeerId peerId, bool selected) {
if (selected) {
const style::color colors[] = {
st::historyPeer1NameFgSelected,
@ -161,7 +162,7 @@ style::color FromNameFg(not_null<PeerData*> peer, bool selected) {
st::historyPeer7NameFgSelected,
st::historyPeer8NameFgSelected,
};
return colors[Data::PeerColorIndex(peer->id)];
return colors[Data::PeerColorIndex(peerId)];
} else {
const style::color colors[] = {
st::historyPeer1NameFg,
@ -173,7 +174,7 @@ style::color FromNameFg(not_null<PeerData*> peer, bool selected) {
st::historyPeer7NameFg,
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().
// They will be added in resizeGetHeight() anyway.
if (displayFromName()) {
const auto from = item->displayFrom();
const auto &name = from
? from->nameText
: item->hiddenForwardedInfo()->nameText;
auto namew = st::msgPadding.left()
+ item->displayFrom()->nameText.maxWidth()
+ name.maxWidth()
+ st::msgPadding.right();
if (via && !displayForwardedFrom()) {
namew += st::msgServiceFont->spacew + via->maxWidth;
@ -421,7 +426,9 @@ void Message::draw(
}
if (bubble) {
if (displayFromName() && item->displayFrom()->nameVersion > item->_fromNameVersion) {
if (displayFromName()
&& item->displayFrom()
&& item->displayFrom()->nameVersion > item->_fromNameVersion) {
fromNameUpdated(g.width());
}
@ -531,13 +538,23 @@ void Message::paintFromName(
}
p.setFont(st::msgNameFont);
if (item->isPost()) {
p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg);
} else {
p.setPen(FromNameFg(item->displayFrom(), selected));
}
item->displayFrom()->nameText.drawElided(p, availableLeft, trect.top(), availableWidth);
auto skipWidth = item->displayFrom()->nameText.maxWidth() + st::msgServiceFont->spacew;
const auto nameText = [&]() -> const Text* {
const auto from = item->displayFrom();
if (item->isPost()) {
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 {
Unexpected("Corrupt forwarded information in message.");
}
}();
nameText->drawElided(p, availableLeft, trect.top(), availableWidth);
const auto skipWidth = nameText->maxWidth() + st::msgServiceFont->spacew;
availableLeft += skipWidth;
availableWidth -= skipWidth;
@ -861,19 +878,31 @@ bool Message::getStateFromName(
if (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
&& point.x() < availableLeft + availableWidth
&& point.x() < availableLeft + user->nameText.maxWidth()) {
outResult->link = user->openLink();
&& point.x() < availableLeft + nameText->maxWidth()) {
static const auto hidden = std::make_shared<LambdaClickHandler>([] {
Ui::Toast::Show(lang(lng_forwarded_hidden));
});
outResult->link = from ? from->openLink() : hidden;
return true;
}
auto via = item->Get<HistoryMessageVia>();
if (via
&& !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 + user->nameText.maxWidth() + st::msgServiceFont->spacew + via->width) {
&& point.x() < availableLeft + nameText->maxWidth() + st::msgServiceFont->spacew + via->width) {
outResult->link = via->link;
return true;
}
@ -1316,7 +1345,8 @@ bool Message::displayForwardedFrom() const {
|| !media
|| !media->isDisplayed()
|| !media->hideForwardedFrom()
|| forwarded->originalSender->isChannel();
|| (forwarded->originalSender
&& forwarded->originalSender->isChannel());
}
return false;
}
@ -1376,6 +1406,7 @@ bool Message::displayFastShare() const {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
return !peer->isSelf()
&& !item->out()
&& forwarded->originalSender
&& forwarded->originalSender->isChannel()
&& !forwarded->originalSender->isMegagroup();
} else if (user->botInfo && !item->out()) {
@ -1521,13 +1552,23 @@ void Message::fromNameUpdated(int width) const {
} else if (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 (!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
- st::msgPadding.left()
- st::msgPadding.right()
- item->displayFrom()->nameText.maxWidth()
- nameText->maxWidth()
- 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 {
flags |= MTPDmessage_ClientFlag::f_from_inline_bot;
MTPReplyMarkup markup = MTPnullMarkup;
auto markup = MTPReplyMarkup();
if (_mtpKeyboard) {
flags |= MTPDmessage::Flag::f_reply_markup;
markup = *_mtpKeyboard;

View File

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

View File

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

View File

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

View File

@ -217,6 +217,7 @@ private:
Data::FileOrigin fileOrigin() const;
void refreshFromLabel(HistoryItem *item);
void refreshCaption(HistoryItem *item);
void refreshMediaViewer();
void refreshNavVisibility();
@ -387,7 +388,8 @@ private:
bool _firstOpenedPeerPhoto = false;
PeerData *_from = nullptr;
Text _fromName;
QString _fromName;
Text _fromNameLabel;
std::optional<int> _index; // Index in current _sharedMedia data.
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"
const MTPReplyMarkup MTPnullMarkup = MTP_replyKeyboardMarkup(
MTP_flags(0),
MTP_vector<MTPKeyboardButtonRow>(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)
extern const MTPReplyMarkup MTPnullMarkup;
extern const MTPVector<MTPMessageEntity> MTPnullEntities;
extern const MTPMessageFwdHeader MTPnullFwdHeader;