Rewrite sponsored to use fake sender names.

This commit is contained in:
John Preston 2021-12-31 15:47:23 +03:00
parent 68886e1b61
commit 611be90880
19 changed files with 250 additions and 125 deletions

View File

@ -42,6 +42,8 @@ class CloudImageView;
int PeerColorIndex(PeerId peerId);
int PeerColorIndex(BareId bareId);
style::color PeerUserpicColor(PeerId peerId);
// Must be used only for PeerColor-s.
PeerId FakePeerIdForJustName(const QString &name);
class RestrictionCheckResult {

View File

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_text_entities.h"
#include "apiwrap.h"
#include "base/unixtime.h"
#include "data/data_user.h"
#include "data/data_channel.h"
#include "data/data_peer_id.h"
#include "data/data_session.h"
@ -71,23 +72,10 @@ bool SponsoredMessages::append(not_null<History*> history) {
return false;
}
const auto flags = MessageFlags(0)
| (history->peer->isChannel() ? MessageFlag::Post : MessageFlags(0))
| MessageFlag::HasFromId
| MessageFlag::IsSponsored
| MessageFlag::Local;
auto local = history->addNewLocalMessage(
entryIt->item.reset(history->addNewLocalMessage(
_session->data().nextLocalMessageId(),
flags,
UserId(0),
MsgId(0),
HistoryItem::NewMessageDate(0),
entryIt->sponsored.fromId,
QString(),
entryIt->sponsored.textWithEntities,
MTP_messageMediaEmpty(),
HistoryMessageMarkupData());
entryIt->item.reset(std::move(local));
entryIt->sponsored.from,
entryIt->sponsored.textWithEntities));
return true;
}
@ -163,36 +151,49 @@ void SponsoredMessages::append(
});
const auto randomId = data.vrandom_id().v;
const auto hash = qs(data.vchat_invite_hash().value_or_empty());
const auto fromId = [&] {
const auto makeFrom = [](not_null<PeerData*> peer) {
const auto channel = peer->asChannel();
return SponsoredFrom{
.peer = peer,
.title = peer->name,
.isBroadcast = (channel && channel->isBroadcast()),
.isMegagroup = (channel && channel->isMegagroup()),
.isChannel = (channel != nullptr),
.isPublic = (channel && channel->isPublic()),
.isBot = (peer->isUser() && peer->asUser()->isBot()),
};
};
const auto from = [&]() -> SponsoredFrom {
if (data.vfrom_id()) {
return peerFromMTP(*data.vfrom_id());
return makeFrom(
_session->data().peer(peerFromMTP(*data.vfrom_id())));
}
Assert(data.vchat_invite());
return data.vchat_invite()->match([](const MTPDchatInvite &data) {
return Data::FakePeerIdForJustName(qs(data.vtitle()));
return SponsoredFrom{
.title = qs(data.vtitle()),
.isBroadcast = data.is_broadcast(),
.isMegagroup = data.is_megagroup(),
.isChannel = data.is_channel(),
.isPublic = data.is_public(),
};
}, [&](const MTPDchatInviteAlready &data) {
const auto chat = _session->data().processChat(data.vchat());
if (!chat) {
return PeerId(0);
}
if (const auto channel = chat->asChannel()) {
channel->clearInvitePeek();
}
return chat->id;
return makeFrom(chat);
}, [&](const MTPDchatInvitePeek &data) {
const auto chat = _session->data().processChat(data.vchat());
if (!chat) {
return PeerId(0);
}
if (const auto channel = chat->asChannel()) {
channel->setInvitePeek(hash, data.vexpires().v);
}
return chat->id;
return makeFrom(chat);
});
}();
auto sharedMessage = SponsoredMessage{
.randomId = randomId,
.fromId = fromId,
.from = from,
.textWithEntities = {
.text = qs(data.vmessage()),
.entities = Api::EntitiesFromMTP(
@ -263,17 +264,17 @@ void SponsoredMessages::view(const FullMsgId &fullId) {
}).send();
}
SponsoredMessages::ChannelPost SponsoredMessages::channelPost(
SponsoredMessages::Details SponsoredMessages::lookupDetails(
const FullMsgId &fullId) const {
const auto entryPtr = find(fullId);
if (!entryPtr) {
return { .msgId = ShowAtUnreadMsgId, .hash = std::nullopt };
return {};
}
const auto msgId = entryPtr->sponsored.msgId;
const auto hash = entryPtr->sponsored.chatInviteHash;
const auto &hash = entryPtr->sponsored.chatInviteHash;
return {
.msgId = msgId ? msgId : ShowAtUnreadMsgId,
.hash = hash.isEmpty() ? std::nullopt : std::make_optional(hash),
.peer = entryPtr->sponsored.from.peer,
.msgId = entryPtr->sponsored.msgId,
};
}

View File

@ -20,9 +20,19 @@ namespace Data {
class Session;
struct SponsoredMessage final {
struct SponsoredFrom {
PeerData *peer = nullptr;
QString title;
bool isBroadcast = false;
bool isMegagroup = false;
bool isChannel = false;
bool isPublic = false;
bool isBot = false;
};
struct SponsoredMessage {
QByteArray randomId;
PeerId fromId;
SponsoredFrom from;
TextWithEntities textWithEntities;
History *history = nullptr;
MsgId msgId;
@ -31,9 +41,10 @@ struct SponsoredMessage final {
class SponsoredMessages final {
public:
struct ChannelPost {
MsgId msgId;
struct Details {
std::optional<QString> hash;
PeerData *peer = nullptr;
MsgId msgId;
};
using RandomId = QByteArray;
explicit SponsoredMessages(not_null<Session*> owner);
@ -45,7 +56,7 @@ public:
void request(not_null<History*> history);
[[nodiscard]] bool append(not_null<History*> history);
void clearItems(not_null<History*> history);
[[nodiscard]] ChannelPost channelPost(const FullMsgId &fullId) const;
[[nodiscard]] Details lookupDetails(const FullMsgId &fullId) const;
void view(const FullMsgId &fullId);

View File

@ -280,9 +280,6 @@ enum class MessageFlag : uint32 {
// Contact sign-up message, notification should be skipped for Silent.
IsContactSignUp = (1U << 30),
// In channels.
IsSponsored = (1U << 31),
};
inline constexpr bool is_flag_type(MessageFlag) { return true; }
using MessageFlags = base::flags<MessageFlag>;

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "data/data_chat_filters.h"
#include "data/data_scheduled_messages.h"
#include "data/data_sponsored_messages.h"
#include "data/data_send_action.h"
#include "data/data_folder.h"
#include "data/data_photo.h"
@ -673,6 +674,18 @@ not_null<HistoryItem*> History::addNewLocalMessage(
true);
}
not_null<HistoryItem*> History::addNewLocalMessage(
MsgId id,
Data::SponsoredFrom from,
const TextWithEntities &textWithEntities) {
return addNewItem(
makeMessage(
id,
from,
textWithEntities),
true);
}
void History::setUnreadMentionsCount(int count) {
const auto had = _unreadMentionsCount && (*_unreadMentionsCount > 0);
if (_unreadMentions.size() > count) {

View File

@ -35,6 +35,7 @@ struct Draft;
class Session;
class Folder;
class ChatFilter;
struct SponsoredFrom;
enum class ForwardOptions {
PreserveInfo,
@ -190,6 +191,10 @@ public:
const QString &postAuthor,
not_null<GameData*> game,
HistoryMessageMarkupData &&markup);
not_null<HistoryItem*> addNewLocalMessage(
MsgId id,
Data::SponsoredFrom from,
const TextWithEntities &textWithEntities); // sponsored
// Used only internally and for channel admin log.
not_null<HistoryItem*> createItem(

View File

@ -896,7 +896,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
userpicTop,
width(),
st::msgPhotoSize);
} else if (const auto info = view->data()->hiddenForwardedInfo()) {
} else if (const auto info = view->data()->hiddenSenderInfo()) {
info->userpic.paint(
p,
st::historyPhotoLeft,

View File

@ -45,6 +45,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_user.h"
#include "data/data_sponsored_messages.h"
#include "styles/style_dialogs.h"
#include "styles/style_chat.h"
@ -294,6 +295,10 @@ HistoryItem *HistoryItem::lookupDiscussionPostOriginal() const {
PeerData *HistoryItem::displayFrom() const {
if (const auto sender = discussionPostOriginalSender()) {
return sender;
} else if (const auto sponsored = Get<HistoryMessageSponsored>()) {
if (sponsored->sender) {
return nullptr;
}
} else if (const auto forwarded = Get<HistoryMessageForwarded>()) {
if (history()->peer->isSelf() || history()->peer->isRepliesChat() || forwarded->imported) {
return forwarded->originalSender;
@ -484,7 +489,7 @@ bool HistoryItem::isScheduled() const {
}
bool HistoryItem::isSponsored() const {
return (_flags & MessageFlag::IsSponsored);
return Has<HistoryMessageSponsored>();
}
bool HistoryItem::skipNotification() const {
@ -900,8 +905,10 @@ PeerData *HistoryItem::senderOriginal() const {
return (peer->isChannel() && !peer->isMegagroup()) ? peer : from();
}
const HiddenSenderInfo *HistoryItem::hiddenForwardedInfo() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
const HiddenSenderInfo *HistoryItem::hiddenSenderInfo() const {
if (const auto sponsored = Get<HistoryMessageSponsored>()) {
return sponsored->sender.get();
} else if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->hiddenSenderInfo.get();
}
return nullptr;
@ -1118,6 +1125,8 @@ ItemPreview HistoryItem::toPreview(ToPreviewOptions options) const {
const auto sender = [&]() -> std::optional<QString> {
if (options.hideSender || isPost() || isEmpty()) {
return {};
} else if (const auto sponsored = Get<HistoryMessageSponsored>()) {
return sponsored->sender->name;
} else if (!_history->peer->isUser()) {
if (const auto from = displayFrom()) {
return fromSender(from);

View File

@ -387,7 +387,7 @@ public:
[[nodiscard]] TimeId dateOriginal() const;
[[nodiscard]] PeerData *senderOriginal() const;
[[nodiscard]] const HiddenSenderInfo *hiddenForwardedInfo() const;
[[nodiscard]] const HiddenSenderInfo *hiddenSenderInfo() const;
[[nodiscard]] not_null<PeerData*> fromOriginal() const;
[[nodiscard]] QString authorOriginal() const;
[[nodiscard]] MsgId idOriginal() const;

View File

@ -102,6 +102,17 @@ struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded
bool imported = false;
};
struct HistoryMessageSponsored : public RuntimeComponent<HistoryMessageSponsored, HistoryItem> {
enum class Type : uchar {
User,
Group,
Broadcast,
Bot,
};
std::unique_ptr<HiddenSenderInfo> sender;
Type type = Type::User;
};
struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, HistoryItem> {
HistoryMessageReply() = default;
HistoryMessageReply(const HistoryMessageReply &other) = delete;

View File

@ -47,6 +47,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_histories.h"
#include "data/data_web_page.h"
#include "data/data_sponsored_messages.h"
#include "styles/style_dialogs.h"
#include "styles/style_widgets.h"
#include "styles/style_chat.h"
@ -582,7 +583,7 @@ HistoryMessage::HistoryMessage(
&& (!originalMedia || !originalMedia->forceForwardedInfo()));
if (!dropForwardInfo) {
config.originalDate = original->dateOriginal();
if (const auto info = original->hiddenForwardedInfo()) {
if (const auto info = original->hiddenSenderInfo()) {
config.senderNameOriginal = info->name;
} else if (const auto senderOriginal = original->senderOriginal()) {
config.senderOriginal = senderOriginal->id;
@ -768,6 +769,29 @@ HistoryMessage::HistoryMessage(
setEmptyText();
}
HistoryMessage::HistoryMessage(
not_null<History*> history,
MsgId id,
Data::SponsoredFrom from,
const TextWithEntities &textWithEntities)
: HistoryItem(
history,
id,
((history->peer->isChannel() ? MessageFlag::Post : MessageFlag(0))
//| (from.peer ? MessageFlag::HasFromId : MessageFlag(0))
| MessageFlag::Local),
HistoryItem::NewMessageDate(0),
/*from.peer ? from.peer->id : */PeerId(0)) {
createComponentsHelper(
_flags,
MsgId(0), // replyTo
UserId(0), // viaBotId
QString(), // postAuthor
HistoryMessageMarkupData());
setText(textWithEntities);
setSponsoredFrom(from);
}
void HistoryMessage::createComponentsHelper(
MessageFlags flags,
MsgId replyTo,
@ -1915,6 +1939,23 @@ void HistoryMessage::setUnreadRepliesCount(
Data::MessageUpdate::Flag::RepliesUnreadCount);
}
void HistoryMessage::setSponsoredFrom(const Data::SponsoredFrom &from) {
AddComponents(HistoryMessageSponsored::Bit());
const auto sponsored = Get<HistoryMessageSponsored>();
sponsored->sender = std::make_unique<HiddenSenderInfo>(
from.title,
false);
using Type = HistoryMessageSponsored::Type;
sponsored->type = from.isBot
? Type::Bot
: from.isBroadcast
? Type::Broadcast
: (from.peer && from.peer->isUser())
? Type::User
: Type::Group;
}
void HistoryMessage::setReplyToTop(MsgId replyToTop) {
const auto reply = Get<HistoryMessageReply>();
if (!reply

View File

@ -14,6 +14,10 @@ struct SendAction;
struct SendOptions;
} // namespace Api
namespace Data {
struct SponsoredFrom;
} // namespace Data
namespace HistoryView {
class Message;
} // namespace HistoryView
@ -115,6 +119,11 @@ public:
const QString &postAuthor,
not_null<GameData*> game,
HistoryMessageMarkupData &&markup); // local game
HistoryMessage(
not_null<History*> history,
MsgId id,
Data::SponsoredFrom from,
const TextWithEntities &textWithEntities); // sponsored
void refreshMedia(const MTPMessageMedia *media);
void refreshSentMedia(const MTPMessageMedia *media);
@ -251,6 +260,7 @@ private:
void setUnreadRepliesCount(
not_null<HistoryMessageViews*> views,
int count);
void setSponsoredFrom(const Data::SponsoredFrom &from);
static void FillForwardedInfo(
CreateConfig &config,

View File

@ -7006,7 +7006,7 @@ void HistoryWidget::updateForwardingTexts() {
fullname = from->name;
}
version += from->nameVersion;
} else if (const auto info = item->hiddenForwardedInfo()) {
} else if (const auto info = item->hiddenSenderInfo()) {
if (!insertedNames.contains(info->name)) {
insertedNames.emplace(info->name);
names.push_back(info->firstName);
@ -7058,7 +7058,7 @@ void HistoryWidget::checkForwardingInfo() {
for (const auto item : _toForward.items) {
if (const auto from = item->senderOriginal()) {
version += from->nameVersion;
} else if (const auto info = item->hiddenForwardedInfo()) {
} else if (const auto info = item->hiddenSenderInfo()) {
++version;
} else {
Unexpected("Corrupt forwarded information in message.");

View File

@ -45,7 +45,7 @@ namespace {
// A new message from the same sender is attached to previous within 15 minutes.
constexpr int kAttachMessageToPreviousSecondsDelta = 900;
bool IsAttachedToPreviousInSavedMessages(
[[nodiscard]] bool IsAttachedToPreviousInSavedMessages(
not_null<HistoryItem*> previous,
HistoryMessageForwarded *prevForwarded,
not_null<HistoryItem*> item,
@ -65,6 +65,22 @@ bool IsAttachedToPreviousInSavedMessages(
return (*previousInfo == *itemInfo);
}
[[nodiscard]] Window::SessionController *ContextOrSessionWindow(
const ClickHandlerContext &context,
not_null<Main::Session*> session) {
if (const auto controller = context.sessionWindow.get()) {
return controller;
}
const auto &windows = session->windows();
if (windows.empty()) {
session->domain().activate(&session->account());
if (windows.empty()) {
return nullptr;
}
}
return windows.front();
}
} // namespace
std::unique_ptr<Ui::PathShiftGradient> MakePathShiftGradient(
@ -599,7 +615,26 @@ ClickHandlerPtr Element::fromLink() const {
return _fromLink;
}
const auto item = data();
if (const auto from = item->displayFrom()) {
if (item->isSponsored()) {
const auto session = &item->history()->session();
_fromLink = std::make_shared<LambdaClickHandler>([=](
ClickContext context) {
if (context.button != Qt::LeftButton) {
return;
}
const auto my = context.other.value<ClickHandlerContext>();
if (const auto window = ContextOrSessionWindow(my, session)) {
auto &sponsored = session->data().sponsoredMessages();
const auto details = sponsored.lookupDetails(my.itemId);
if (const auto &hash = details.hash) {
Api::CheckChatInvite(window, *hash);
} else if (const auto peer = details.peer) {
window->showPeerInfo(peer);
}
}
});
return _fromLink;
} else if (const auto from = item->displayFrom()) {
_fromLink = std::make_shared<LambdaClickHandler>([=](
ClickContext context) {
if (context.button != Qt::LeftButton) {
@ -607,29 +642,8 @@ ClickHandlerPtr Element::fromLink() const {
}
const auto my = context.other.value<ClickHandlerContext>();
const auto session = &from->session();
const auto window = [&]() -> Window::SessionController* {
if (const auto controller = my.sessionWindow.get()) {
return controller;
}
const auto &windows = session->windows();
if (windows.empty()) {
session->domain().activate(&session->account());
if (windows.empty()) {
return nullptr;
}
}
return windows.front();
}();
if (window) {
const auto inviteHash = item->isSponsored()
? session->data().sponsoredMessages().channelPost(
my.itemId).hash
: std::nullopt;
if (inviteHash) {
Api::CheckChatInvite(window, *inviteHash);
} else {
window->showPeerInfo(from);
}
if (const auto window = ContextOrSessionWindow(my, session)) {
window->showPeerInfo(from);
}
});
_fromLink->setProperty(kPeerLinkPeerIdProperty, from->id.value);

View File

@ -1753,7 +1753,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
userpicTop,
view->width(),
st::msgPhotoSize);
} else if (const auto info = view->data()->hiddenForwardedInfo()) {
} else if (const auto info = view->data()->hiddenSenderInfo()) {
info->userpic.paint(
p,
st::historyPhotoLeft,

View File

@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_user.h"
#include "data/data_channel.h"
#include "data/data_message_reactions.h"
#include "data/data_sponsored_messages.h"
#include "lang/lang_keys.h"
#include "mainwidget.h"
#include "main/main_session.h"
@ -415,7 +416,7 @@ QSize Message::performCountOptimalSize() {
const auto from = item->displayFrom();
const auto &name = from
? from->nameText()
: item->hiddenForwardedInfo()->nameText;
: item->hiddenSenderInfo()->nameText;
auto namew = st::msgPadding.left()
+ name.maxWidth()
+ st::msgPadding.right();
@ -935,17 +936,19 @@ void Message::paintFromName(
const auto nameText = [&]() -> const Ui::Text::String * {
const auto from = item->displayFrom();
if (context.outbg || item->isPost()) {
p.setPen(stm->msgServiceFg);
const auto service = (context.outbg || item->isPost());
if (from) {
p.setPen(service
? stm->msgServiceFg
: FromNameFg(context, from->id));
return &from->nameText();
} else if (from) {
p.setPen(FromNameFg(context, from->id));
return &from->nameText();
} else if (const auto info = item->hiddenForwardedInfo()) {
p.setPen(FromNameFg(context, info->colorPeerId));
} else if (const auto info = item->hiddenSenderInfo()) {
p.setPen(service
? stm->msgServiceFg
: FromNameFg(context, info->colorPeerId));
return &info->nameText;
} else {
Unexpected("Corrupt forwarded information in message.");
Unexpected("Corrupt sender information in message.");
}
}();
nameText->drawElided(p, availableLeft, trect.top(), availableWidth);
@ -1524,7 +1527,7 @@ bool Message::getStateFromName(
const auto nameText = [&]() -> const Ui::Text::String * {
if (from) {
return &from->nameText();
} else if (const auto info = item->hiddenForwardedInfo()) {
} else if (const auto info = item->hiddenSenderInfo()) {
return &info->nameText;
} else {
Unexpected("Corrupt forwarded information in message.");
@ -2076,14 +2079,11 @@ int Message::viewButtonHeight() const {
}
void Message::updateViewButtonExistence() {
const auto has = [&] {
const auto item = data();
if (item->isSponsored()) {
return true;
}
const auto media = item->media();
return media && ViewButton::MediaHasViewButton(media);
}();
const auto item = data();
const auto sponsored = item->Get<HistoryMessageSponsored>();
const auto media = sponsored ? nullptr : item->media();
const auto has = sponsored
|| (media && ViewButton::MediaHasViewButton(media));
if (!has) {
_viewButton = nullptr;
return;
@ -2091,13 +2091,9 @@ void Message::updateViewButtonExistence() {
return;
}
auto callback = [=] { history()->owner().requestViewRepaint(this); };
_viewButton = data()->isSponsored()
? std::make_unique<ViewButton>(
data()->displayFrom(),
std::move(callback))
: std::make_unique<ViewButton>(
data()->media(),
std::move(callback));
_viewButton = sponsored
? std::make_unique<ViewButton>(sponsored, std::move(callback))
: std::make_unique<ViewButton>(media, std::move(callback));
}
void Message::initLogEntryOriginal() {
@ -2572,7 +2568,7 @@ void Message::fromNameUpdated(int width) const {
const auto nameText = [&]() -> const Ui::Text::String * {
if (from) {
return &from->nameText();
} else if (const auto info = item->hiddenForwardedInfo()) {
} else if (const auto info = item->hiddenSenderInfo()) {
return &info->nameText;
} else {
Unexpected("Corrupted forwarded information in message.");

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_sponsored_messages.h"
#include "data/data_user.h"
#include "data/data_web_page.h"
#include "history/history_item_components.h"
#include "history/view/history_view_cursor_state.h"
#include "lang/lang_keys.h"
#include "main/main_session.h"
@ -30,20 +31,19 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView {
namespace {
inline auto PeerToPhrase(not_null<PeerData*> peer) {
using SponsoredType = HistoryMessageSponsored::Type;
inline auto SponsoredPhrase(SponsoredType type) {
const auto phrase = [&] {
if (const auto user = peer->asUser()) {
return user->isBot()
? tr::lng_view_button_bot
: tr::lng_view_button_user;
} else if (peer->isChat()) {
return tr::lng_view_button_group;
} else if (peer->isChannel()) {
return tr::lng_view_button_channel;
switch (type) {
case SponsoredType::Bot: return tr::lng_view_button_bot;
case SponsoredType::Group: return tr::lng_view_button_group;
case SponsoredType::Broadcast: return tr::lng_view_button_channel;
case SponsoredType::User: return tr::lng_view_button_user;
}
Unexpected("Invalid peer in ViewButton.");
}()(tr::now);
return Ui::Text::Upper(phrase);
Unexpected("SponsoredType in SponsoredPhrase.");
}();
return Ui::Text::Upper(phrase(tr::now));
}
inline auto WebPageToPhrase(not_null<WebPageData*> webpage) {
@ -75,8 +75,11 @@ inline auto WebPageToPhrase(not_null<WebPageData*> webpage) {
} // namespace
struct ViewButton::Inner {
Inner(not_null<PeerData*> peer, Fn<void()> updateCallback);
Inner(
not_null<HistoryMessageSponsored*> sponsored,
Fn<void()> updateCallback);
Inner(not_null<Data::Media*> media, Fn<void()> updateCallback);
void updateMask(int height);
void toggleRipple(bool pressed);
@ -114,22 +117,28 @@ bool ViewButton::MediaHasViewButton(
&& webpage->document->isWallPaper());
}
ViewButton::Inner::Inner(not_null<PeerData*> peer, Fn<void()> updateCallback)
ViewButton::Inner::Inner(
not_null<HistoryMessageSponsored*> sponsored,
Fn<void()> updateCallback)
: margins(st::historyViewButtonMargins)
, link(std::make_shared<LambdaClickHandler>([=](ClickContext context) {
const auto my = context.other.value<ClickHandlerContext>();
if (const auto controller = my.sessionWindow.get()) {
const auto &data = controller->session().data();
const auto link = data.sponsoredMessages().channelPost(my.itemId);
if (link.hash) {
Api::CheckChatInvite(controller, *link.hash);
} else {
controller->showPeer(peer, link.msgId);
const auto itemId = my.itemId;
const auto details = data.sponsoredMessages().lookupDetails(itemId);
if (details.hash) {
Api::CheckChatInvite(controller, *details.hash);
} else if (details.peer) {
controller->showPeerHistory(
details.peer,
Window::SectionShow::Way::Forward,
details.msgId);
}
}
}))
, updateCallback(std::move(updateCallback))
, text(st::historyViewButtonTextStyle, PeerToPhrase(peer)) {
, text(st::historyViewButtonTextStyle, SponsoredPhrase(sponsored->type)) {
}
ViewButton::Inner::Inner(
@ -170,8 +179,10 @@ void ViewButton::Inner::toggleRipple(bool pressed) {
}
}
ViewButton::ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback)
: _inner(std::make_unique<Inner>(peer, std::move(updateCallback))) {
ViewButton::ViewButton(
not_null<HistoryMessageSponsored*> sponsored,
Fn<void()> updateCallback)
: _inner(std::make_unique<Inner>(sponsored, std::move(updateCallback))) {
}
ViewButton::ViewButton(

View File

@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/chat_style.h"
struct HistoryMessageSponsored;
namespace Data {
class Media;
} // namespace Data
@ -21,7 +23,9 @@ struct TextState;
class ViewButton {
public:
ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback);
ViewButton(
not_null<HistoryMessageSponsored*> sponsored,
Fn<void()> updateCallback);
ViewButton(not_null<Data::Media*> media, Fn<void()> updateCallback);
~ViewButton();

View File

@ -2130,7 +2130,7 @@ void OverlayWidget::refreshMediaViewer() {
void OverlayWidget::refreshFromLabel() {
if (_message) {
_from = _message->senderOriginal();
if (const auto info = _message->hiddenForwardedInfo()) {
if (const auto info = _message->hiddenSenderInfo()) {
_fromName = info->name;
} else {
Assert(_from != nullptr);