Display correctly forwards of forwards in sublists.

This commit is contained in:
John Preston 2023-12-31 13:07:06 +04:00
parent 9392550c01
commit 2a8a74b5b1
16 changed files with 166 additions and 65 deletions

View File

@ -897,7 +897,9 @@ void RowPainter::Paint(
if (const auto peer = searchChat.peer()) {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
if (peer->isSelf() || forwarded->imported) {
return forwarded->hiddenSenderInfo.get();
return forwarded->savedFromHiddenSenderInfo.get()
? forwarded->savedFromHiddenSenderInfo.get()
: forwarded->originalHiddenSenderInfo.get();
}
}
}

View File

@ -1218,7 +1218,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
width(),
st::msgPhotoSize,
context.paused);
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info = item->displayHiddenSenderInfo()) {
if (info->customUserpic.empty()) {
info->emptyUserpic.paintCircle(
p,

View File

@ -153,6 +153,10 @@ struct HistoryItem::CreateConfig {
PeerId savedFromPeer = 0;
MsgId savedFromMsgId = 0;
PeerId savedFromSenderId = 0;
QString savedFromSenderName;
bool savedFromOutgoing = false;
TimeId editDate = 0;
HistoryMessageMarkupData markup;
HistoryMessageRepliesData replies;
@ -179,6 +183,13 @@ void HistoryItem::FillForwardedInfo(
config.savedFromPeer = peerFromMTP(*savedFromPeer);
config.savedFromMsgId = savedFromMsgId->v;
}
config.savedFromSenderId = data.vsaved_from_id()
? peerFromMTP(*data.vsaved_from_id())
: PeerId();
config.savedFromSenderName = qs(
data.vsaved_from_name().value_or_empty());
config.savedFromOutgoing = data.is_saved_out();
config.imported = data.is_imported();
}
@ -476,7 +487,7 @@ HistoryItem::HistoryItem(
}
if (!dropForwardInfo) {
config.originalDate = original->originalDate();
if (const auto info = original->hiddenSenderInfo()) {
if (const auto info = original->originalHiddenSenderInfo()) {
config.originalSenderName = info->name;
} else if (const auto originalSender = original->originalSender()) {
config.originalSenderId = originalSender->id;
@ -500,6 +511,11 @@ HistoryItem::HistoryItem(
config.savedFromPeer = original->history()->peer->id;
config.savedFromMsgId = original->id;
//}
config.savedFromOutgoing = original->out();
config.savedFromSenderId = original->Get<HistoryMessageForwarded>()
? original->author()->id
: PeerId();
}
if (flags & MessageFlag::HasPostAuthor) {
config.postAuthor = postAuthor;
@ -1193,10 +1209,10 @@ PeerData *HistoryItem::computeDisplayFrom() const {
if (const auto sender = discussionPostOriginalSender()) {
return sender;
} else if (const auto forwarded = Get<HistoryMessageForwarded>()) {
if (_history->peer->isSelf()
|| _history->peer->isRepliesChat()
|| forwarded->imported) {
return forwarded->originalSender;
if (showForwardsFromSender(forwarded)) {
return forwarded->forwardOfForward()
? forwarded->savedFromSender
: forwarded->originalSender;
}
}
return author().get();
@ -1213,10 +1229,10 @@ PeerData *HistoryItem::displayFrom() const {
uint8 HistoryItem::colorIndex() const {
if (const auto from = displayFrom()) {
return from->colorIndex();
} else if (const auto info = hiddenSenderInfo()) {
} else if (const auto info = displayHiddenSenderInfo()) {
return info->colorIndex;
}
Unexpected("No displayFrom and no hiddenSenderInfo.");
Unexpected("No displayFrom and no displayHiddenSenderInfo.");
}
std::unique_ptr<HistoryView::Element> HistoryItem::createView(
@ -2493,16 +2509,32 @@ PeerData *HistoryItem::originalSender() const {
return forwarded->originalSender;
}
const auto peer = _history->peer;
return (peer->isChannel() && !peer->isMegagroup()) ? peer : from();
return peer->isBroadcast() ? peer : from();
}
const HiddenSenderInfo *HistoryItem::hiddenSenderInfo() const {
const HiddenSenderInfo *HistoryItem::originalHiddenSenderInfo() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->hiddenSenderInfo.get();
return forwarded->originalHiddenSenderInfo.get();
}
return nullptr;
}
const HiddenSenderInfo *HistoryItem::displayHiddenSenderInfo() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->savedFromHiddenSenderInfo
? forwarded->savedFromHiddenSenderInfo.get()
: forwarded->originalHiddenSenderInfo.get();
}
return nullptr;
}
bool HistoryItem::showForwardsFromSender(
not_null<const HistoryMessageForwarded*> forwarded) const {
const auto peer = history()->peer;
return !forwarded->story
&& (peer->isSelf() || peer->isRepliesChat() || forwarded->imported);
}
not_null<PeerData*> HistoryItem::fromOriginal() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
if (forwarded->originalSender) {
@ -3055,6 +3087,20 @@ PeerData *HistoryItem::savedSublistPeer() const {
return nullptr;
}
PeerData *HistoryItem::savedFromSender() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->savedFromSender;
}
return nullptr;
}
const HiddenSenderInfo *HistoryItem::savedFromHiddenSenderInfo() const {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->savedFromHiddenSenderInfo.get();
}
return nullptr;
}
TextWithEntities HistoryItem::notificationText(
NotificationTextOptions options) const {
auto result = [&] {
@ -3107,16 +3153,25 @@ ItemPreview HistoryItem::toPreview(ToPreviewOptions options) const {
? tr::lng_from_you(tr::now)
: sender->shortName();
};
result.icon = (Get<HistoryMessageForwarded>() != nullptr)
const auto forwarded = Get<HistoryMessageForwarded>();
const auto forwardFromSender = forwarded
&& showForwardsFromSender(forwarded);
result.icon = (forwarded
&& (!forwardFromSender || forwarded->forwardOfForward()))
? ItemPreview::Icon::ForwardedMessage
: replyToStory().valid()
? ItemPreview::Icon::ReplyToStory
: ItemPreview::Icon::None;
const auto fromForwarded = [&]() -> std::optional<QString> {
if (const auto forwarded = Get<HistoryMessageForwarded>()) {
return forwarded->originalSender
? fromSender(forwarded->originalSender)
: forwarded->hiddenSenderInfo->name;
if (forwarded) {
const auto sender = forwarded->forwardOfForward()
? forwarded->savedFromSender
: forwarded->originalSender;
return sender
? fromSender(sender)
: forwarded->savedFromHiddenSenderInfo
? forwarded->savedFromHiddenSenderInfo->name
: forwarded->originalHiddenSenderInfo->name;
}
return {};
};
@ -3313,9 +3368,10 @@ void HistoryItem::setupForwardedComponent(const CreateConfig &config) {
? _history->owner().peer(originalSender).get()
: nullptr;
if (!forwarded->originalSender) {
forwarded->hiddenSenderInfo = std::make_unique<HiddenSenderInfo>(
config.originalSenderName,
config.imported);
forwarded->originalHiddenSenderInfo
= std::make_unique<HiddenSenderInfo>(
config.originalSenderName,
config.imported);
}
forwarded->originalId = config.originalId;
forwarded->originalPostAuthor = config.originalPostAuthor;
@ -3323,6 +3379,14 @@ void HistoryItem::setupForwardedComponent(const CreateConfig &config) {
forwarded->savedFromPeer = _history->owner().peerLoaded(
config.savedFromPeer);
forwarded->savedFromMsgId = config.savedFromMsgId;
forwarded->savedFromSender = _history->owner().peerLoaded(
config.savedFromSenderId);
forwarded->savedFromOutgoing = config.savedFromOutgoing;
if (!forwarded->savedFromSender
&& !config.savedFromSenderName.isEmpty()) {
forwarded->savedFromHiddenSenderInfo
= std::make_unique<HiddenSenderInfo>(config.savedFromSenderName, false);
}
forwarded->imported = config.imported;
}

View File

@ -20,6 +20,7 @@ struct HistoryMessageViews;
struct HistoryMessageMarkupData;
struct HistoryMessageReplyMarkup;
struct HistoryMessageTranslation;
struct HistoryMessageForwarded;
struct HistoryServiceDependentData;
enum class HistorySelfDestructType;
struct PreparedServiceText;
@ -481,13 +482,20 @@ public:
[[nodiscard]] TimeId originalDate() const;
[[nodiscard]] PeerData *originalSender() const;
[[nodiscard]] const HiddenSenderInfo *hiddenSenderInfo() const;
[[nodiscard]] const HiddenSenderInfo *originalHiddenSenderInfo() const;
[[nodiscard]] not_null<PeerData*> fromOriginal() const;
[[nodiscard]] QString originalPostAuthor() const;
[[nodiscard]] MsgId originalId() const;
[[nodiscard]] Data::SavedSublist *savedSublist() const;
[[nodiscard]] PeerData *savedSublistPeer() const;
[[nodiscard]] PeerData *savedFromSender() const;
[[nodiscard]] const HiddenSenderInfo *savedFromHiddenSenderInfo() const;
[[nodiscard]] const HiddenSenderInfo *displayHiddenSenderInfo() const;
[[nodiscard]] bool showForwardsFromSender(
not_null<const HistoryMessageForwarded*> forwarded) const;
[[nodiscard]] bool isEmpty() const;

View File

@ -190,7 +190,7 @@ void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
const auto name = TextWithEntities{
.text = (originalSender
? originalSender->name()
: hiddenSenderInfo->name)
: originalHiddenSenderInfo->name)
};
if (!originalPostAuthor.isEmpty()) {
phrase = tr::lng_forwarded_signed(

View File

@ -126,9 +126,13 @@ private:
struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded, HistoryItem> {
void create(const HistoryMessageVia *via) const;
[[nodiscard]] bool forwardOfForward() const {
return savedFromSender || savedFromHiddenSenderInfo;
}
TimeId originalDate = 0;
PeerData *originalSender = nullptr;
std::unique_ptr<HiddenSenderInfo> hiddenSenderInfo;
std::unique_ptr<HiddenSenderInfo> originalHiddenSenderInfo;
QString originalPostAuthor;
QString psaType;
MsgId originalId = 0;
@ -136,6 +140,11 @@ struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded
PeerData *savedFromPeer = nullptr;
MsgId savedFromMsgId = 0;
PeerData *savedFromSender = nullptr;
std::unique_ptr<HiddenSenderInfo> savedFromHiddenSenderInfo;
bool savedFromOutgoing = false;
bool imported = false;
bool story = false;
};

View File

@ -376,7 +376,7 @@ void PreviewWrap::paintEvent(QPaintEvent *e) {
userpicTop,
width(),
st::msgPhotoSize);
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info = item->originalHiddenSenderInfo()) {
if (info->customUserpic.empty()) {
info->emptyUserpic.paintCircle(
p,

View File

@ -127,7 +127,7 @@ void ForwardPanel::checkTexts() {
for (const auto item : _data.items) {
if (const auto from = item->originalSender()) {
version += from->nameVersion();
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info = item->originalHiddenSenderInfo()) {
++version;
} else {
Unexpected("Corrupt forwarded information in message.");
@ -168,7 +168,7 @@ void ForwardPanel::updateTexts() {
names.push_back(from->shortName());
fullname = from->name();
}
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info = item->originalHiddenSenderInfo()) {
if (!insertedNames.contains(info->name)) {
insertedNames.emplace(info->name);
names.push_back(info->firstName);

View File

@ -64,16 +64,20 @@ Element *MousedElement/* = nullptr*/;
HistoryMessageForwarded *prevForwarded,
not_null<HistoryItem*> item,
HistoryMessageForwarded *forwarded) {
const auto sender = previous->originalSender();
const auto sender = previous->displayFrom();
if ((prevForwarded != nullptr) != (forwarded != nullptr)) {
return false;
} else if (sender != item->originalSender()) {
} else if (sender != item->displayFrom()) {
return false;
} else if (!prevForwarded || sender) {
return true;
}
const auto previousInfo = prevForwarded->hiddenSenderInfo.get();
const auto itemInfo = forwarded->hiddenSenderInfo.get();
const auto previousInfo = prevForwarded->savedFromHiddenSenderInfo
? prevForwarded->savedFromHiddenSenderInfo.get()
: prevForwarded->originalHiddenSenderInfo.get();
const auto itemInfo = forwarded->savedFromHiddenSenderInfo
? forwarded->savedFromHiddenSenderInfo.get()
: forwarded->originalHiddenSenderInfo.get();
Assert(previousInfo != nullptr);
Assert(itemInfo != nullptr);
return (*previousInfo == *itemInfo);

View File

@ -56,7 +56,8 @@ enum class Context : char {
Replies,
Pinned,
AdminLog,
ContactPreview
ContactPreview,
SavedSublist,
};
enum class OnlyEmojiAndSpaces : char {

View File

@ -2181,7 +2181,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
userpicTop,
view->width(),
st::msgPhotoSize);
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info = item->displayHiddenSenderInfo()) {
if (info->customUserpic.empty()) {
info->emptyUserpic.paintCircle(
p,

View File

@ -738,7 +738,7 @@ QSize Message::performCountOptimalSize() {
validateFromNameText(from);
const auto &name = from
? _fromName
: item->hiddenSenderInfo()->nameText();
: item->displayHiddenSenderInfo()->nameText();
auto namew = st::msgPadding.left()
+ name.maxWidth()
+ (_fromNameStatus
@ -1389,7 +1389,7 @@ void Message::paintFromName(
const auto stm = context.messageStyle();
const auto from = item->displayFrom();
const auto info = from ? nullptr : item->hiddenSenderInfo();
const auto info = from ? nullptr : item->displayHiddenSenderInfo();
Assert(from || info);
const auto nameFg = !context.outbg
? FromNameFg(context, colorIndex())
@ -1974,13 +1974,6 @@ void Message::unloadHeavyPart() {
}
}
bool Message::showForwardsFromSender(
not_null<HistoryMessageForwarded*> forwarded) const {
const auto peer = data()->history()->peer;
return !forwarded->story
&& (peer->isSelf() || peer->isRepliesChat() || forwarded->imported);
}
bool Message::hasFromPhoto() const {
if (isHidden()) {
return false;
@ -1990,7 +1983,8 @@ bool Message::hasFromPhoto() const {
return true;
case Context::History:
case Context::Pinned:
case Context::Replies: {
case Context::Replies:
case Context::SavedSublist: {
const auto item = data();
if (item->isPost()) {
return false;
@ -2328,7 +2322,7 @@ bool Message::getStateFromName(
if (from) {
validateFromNameText(from);
return &_fromName;
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info = item->displayHiddenSenderInfo()) {
return &info->nameText();
} else {
Unexpected("Corrupt forwarded information in message.");
@ -3017,7 +3011,9 @@ void Message::validateFromNameText(PeerData *from) const {
Ui::NameTextOptions());
}
if (from->isPremium()
|| (from->isChannel() && from != history()->peer)) {
|| (from->isChannel()
&& from->emojiStatusId()
&& from != history()->peer)) {
if (!_fromNameStatus) {
_fromNameStatus = std::make_unique<FromNameStatus>();
const auto size = st::emojiSize;
@ -3162,10 +3158,17 @@ bool Message::hasFromName() const {
return true;
case Context::History:
case Context::Pinned:
case Context::Replies: {
case Context::Replies:
case Context::SavedSublist: {
const auto item = data();
const auto peer = item->history()->peer;
if (hasOutLayout() && !item->from()->isChannel()) {
if (peer->isSelf()) {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
return forwarded->savedFromSender
&& forwarded->savedFromSender->isChannel();
}
}
return false;
} else if (!peer->isUser()) {
if (const auto media = this->media()) {
@ -3177,7 +3180,7 @@ bool Message::hasFromName() const {
if (forwarded->imported
&& peer.get() == forwarded->originalSender) {
return false;
} else if (showForwardsFromSender(forwarded)) {
} else if (item->showForwardsFromSender(forwarded)) {
return true;
}
}
@ -3201,8 +3204,9 @@ bool Message::displayForwardedFrom() const {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
if (forwarded->story) {
return true;
} else if (showForwardsFromSender(forwarded)) {
return false;
} else if (item->showForwardsFromSender(forwarded)) {
return forwarded->savedFromSender
&& (forwarded->savedFromSender != forwarded->originalSender);
}
if (const auto sender = item->discussionPostOriginalSender()) {
if (sender == forwarded->originalSender) {
@ -3218,12 +3222,20 @@ bool Message::displayForwardedFrom() const {
bool Message::hasOutLayout() const {
const auto item = data();
if (item->history()->peer->isSelf()) {
return !item->Has<HistoryMessageForwarded>();
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
return (context() == Context::SavedSublist)
&& (!forwarded->forwardOfForward()
? forwarded->originalSender->isSelf()
: ((forwarded->savedFromSender
&& forwarded->savedFromSender->isSelf())
|| forwarded->savedFromOutgoing));
}
return true;
} else if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
if (!forwarded->imported
|| !forwarded->originalSender
|| !forwarded->originalSender->isSelf()) {
if (showForwardsFromSender(forwarded)) {
if (item->showForwardsFromSender(forwarded)) {
return false;
}
}
@ -3325,6 +3337,7 @@ bool Message::displayFastReply() const {
bool Message::displayRightActionComments() const {
return !isPinnedContext()
&& (context() != Context::SavedSublist)
&& data()->repliesAreComments()
&& media()
&& media()->isDisplayed()
@ -3359,11 +3372,10 @@ bool Message::displayFastShare() const {
return !peer->isMegagroup();
} else if (const auto user = peer->asUser()) {
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
return !showForwardsFromSender(forwarded)
&& !item->out()
return !item->out()
&& forwarded->originalSender
&& forwarded->originalSender->isChannel()
&& !forwarded->originalSender->isMegagroup();
&& forwarded->originalSender->isBroadcast()
&& !item->showForwardsFromSender(forwarded);
} else if (user->isBot() && !item->out()) {
if (const auto media = this->media()) {
return media->allowsFastShare();
@ -3382,7 +3394,7 @@ bool Message::displayGoToOriginal() const {
return forwarded->savedFromPeer
&& forwarded->savedFromMsgId
&& (!item->externalReply() || !hasBubble())
&& !(context() == Context::Replies);
&& (context() != Context::Replies);
}
return false;
}
@ -3451,7 +3463,9 @@ void Message::drawRightAction(
} else {
const auto &icon = data()->isSponsored()
? st->historyFastCloseIcon()
: (displayFastShare() && !isPinnedContext())
: (displayFastShare()
&& !isPinnedContext()
&& this->context() != Context::SavedSublist)
? st->historyFastShareIcon()
: st->historyGoToOriginalIcon();
icon.paintInCenter(p, { left, top, size->width(), size->height() });
@ -3483,7 +3497,8 @@ ClickHandlerPtr Message::prepareRightActionLink() const {
return HideSponsoredClickHandler();
} else if (isPinnedContext()) {
return JumpToMessageClickHandler(data());
} else if (displayRightActionComments()) {
} else if ((context() != Context::SavedSublist)
&& displayRightActionComments()) {
return createGoToCommentsLink();
}
const auto sessionId = data()->history()->session().uniqueId();
@ -3655,7 +3670,7 @@ void Message::fromNameUpdated(int width) const {
const auto nameText = [&]() -> const Ui::Text::String * {
if (from) {
return &_fromName;
} else if (const auto info = item->hiddenSenderInfo()) {
} else if (const auto info= item->originalHiddenSenderInfo()) {
return &info->nameText();
} else {
Unexpected("Corrupted forwarded information in message.");

View File

@ -173,8 +173,6 @@ private:
void initPsa();
void fromNameUpdated(int width) const;
[[nodiscard]] bool showForwardsFromSender(
not_null<HistoryMessageForwarded*> forwarded) const;
[[nodiscard]] TextSelection skipTextSelection(
TextSelection selection) const;
[[nodiscard]] TextSelection unskipTextSelection(

View File

@ -208,7 +208,7 @@ void Reply::update(
? _externalSender
: nullptr;
_hiddenSenderColorIndexPlusOne = (!_colorPeer && message)
? (message->hiddenSenderInfo()->colorIndex + 1)
? (message->originalHiddenSenderInfo()->colorIndex + 1)
: 0;
const auto hasPreview = (story && story->hasReplyPreview())
@ -376,8 +376,8 @@ QString Reply::senderName(
const auto forwarded
= data->resolvedMessage->Get<HistoryMessageForwarded>();
if (forwarded) {
Assert(forwarded->hiddenSenderInfo != nullptr);
return forwarded->hiddenSenderInfo->name;
Assert(forwarded->originalHiddenSenderInfo != nullptr);
return forwarded->originalHiddenSenderInfo->name;
}
}
return QString();

View File

@ -432,7 +432,7 @@ QRect SublistWidget::floatPlayerAvailableRect() {
}
Context SublistWidget::listContext() {
return Context::Pinned;
return Context::SavedSublist;
}
bool SublistWidget::listScrollTo(int top, bool syntetic) {

View File

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