mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-03 21:54:05 +02:00
Update API scheme to layer 167.
Support quote offset passing to API. Support simple phrases in giveaway results message.
This commit is contained in:
parent
f442d69cb6
commit
dcc326e17f
44 changed files with 389 additions and 303 deletions
|
@ -1667,6 +1667,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_action_story_mention_me_unavailable" = "The story where you mentioned {user} is no longer available.";
|
"lng_action_story_mention_me_unavailable" = "The story where you mentioned {user} is no longer available.";
|
||||||
"lng_action_story_mention_unavailable" = "The story where {user} mentioned you is no longer available.";
|
"lng_action_story_mention_unavailable" = "The story where {user} mentioned you is no longer available.";
|
||||||
"lng_action_giveaway_started" = "{from} just started a giveaway of Telegram Premium subscriptions to its followers.";
|
"lng_action_giveaway_started" = "{from} just started a giveaway of Telegram Premium subscriptions to its followers.";
|
||||||
|
"lng_action_giveaway_results#one" = "{count} winner of the giveaway was randomly selected by Telegram and received private messages with giftcodes.";
|
||||||
|
"lng_action_giveaway_results#other" = "{count} winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes.";
|
||||||
|
"lng_action_giveaway_results_some" = "Some winners of the giveaway was randomly selected by Telegram and received private messages with giftcodes.";
|
||||||
|
"lng_action_giveaway_results_none" = "No winners of the giveaway could be selected.";
|
||||||
|
|
||||||
"lng_premium_gift_duration_months#one" = "for {count} month";
|
"lng_premium_gift_duration_months#one" = "for {count} month";
|
||||||
"lng_premium_gift_duration_months#other" = "for {count} months";
|
"lng_premium_gift_duration_months#other" = "for {count} months";
|
||||||
|
|
|
@ -72,7 +72,7 @@ MTPInputReplyTo ReplyToForMTP(
|
||||||
| (external ? Flag::f_reply_to_peer_id : Flag())
|
| (external ? Flag::f_reply_to_peer_id : Flag())
|
||||||
| (replyTo.quote.text.isEmpty()
|
| (replyTo.quote.text.isEmpty()
|
||||||
? Flag()
|
? Flag()
|
||||||
: Flag::f_quote_text)
|
: (Flag::f_quote_text | Flag::f_quote_offset))
|
||||||
| (quoteEntities.v.isEmpty()
|
| (quoteEntities.v.isEmpty()
|
||||||
? Flag()
|
? Flag()
|
||||||
: Flag::f_quote_entities)),
|
: Flag::f_quote_entities)),
|
||||||
|
@ -82,7 +82,8 @@ MTPInputReplyTo ReplyToForMTP(
|
||||||
? owner->peer(replyTo.messageId.peer)->input
|
? owner->peer(replyTo.messageId.peer)->input
|
||||||
: MTPInputPeer()),
|
: MTPInputPeer()),
|
||||||
MTP_string(replyTo.quote.text),
|
MTP_string(replyTo.quote.text),
|
||||||
quoteEntities);
|
quoteEntities,
|
||||||
|
MTP_int(replyTo.quoteOffset));
|
||||||
}
|
}
|
||||||
return MTPInputReplyTo();
|
return MTPInputReplyTo();
|
||||||
}
|
}
|
||||||
|
@ -983,6 +984,7 @@ int Histories::sendPreparedMessage(
|
||||||
.quote = replyTo.quote,
|
.quote = replyTo.quote,
|
||||||
.storyId = replyTo.storyId,
|
.storyId = replyTo.storyId,
|
||||||
.topicRootId = convertTopicReplyToId(history, replyTo.topicRootId),
|
.topicRootId = convertTopicReplyToId(history, replyTo.topicRootId),
|
||||||
|
.quoteOffset = replyTo.quoteOffset,
|
||||||
};
|
};
|
||||||
return v::match(message(history, realReplyTo), [&](const auto &request) {
|
return v::match(message(history, realReplyTo), [&](const auto &request) {
|
||||||
const auto type = RequestType::Send;
|
const auto type = RequestType::Send;
|
||||||
|
|
|
@ -161,6 +161,7 @@ struct FullReplyTo {
|
||||||
TextWithEntities quote;
|
TextWithEntities quote;
|
||||||
FullStoryId storyId;
|
FullStoryId storyId;
|
||||||
MsgId topicRootId = 0;
|
MsgId topicRootId = 0;
|
||||||
|
int quoteOffset = 0;
|
||||||
|
|
||||||
[[nodiscard]] bool valid() const {
|
[[nodiscard]] bool valid() const {
|
||||||
return messageId || (storyId && peerIsUser(storyId.peer));
|
return messageId || (storyId && peerIsUser(storyId.peer));
|
||||||
|
|
|
@ -1316,9 +1316,9 @@ ServiceAction ParseServiceAction(
|
||||||
}, [&](const MTPDmessageActionSetChatWallPaper &data) {
|
}, [&](const MTPDmessageActionSetChatWallPaper &data) {
|
||||||
auto content = ActionSetChatWallPaper();
|
auto content = ActionSetChatWallPaper();
|
||||||
// #TODO wallpapers
|
// #TODO wallpapers
|
||||||
|
content.same = data.is_same();
|
||||||
|
content.both = data.is_for_both();
|
||||||
result.content = content;
|
result.content = content;
|
||||||
}, [&](const MTPDmessageActionSetSameChatWallPaper &data) {
|
|
||||||
result.content = ActionSetSameChatWallPaper();
|
|
||||||
}, [&](const MTPDmessageActionRequestedPeer &data) {
|
}, [&](const MTPDmessageActionRequestedPeer &data) {
|
||||||
auto content = ActionRequestedPeer();
|
auto content = ActionRequestedPeer();
|
||||||
content.peerId = ParsePeerId(data.vpeer());
|
content.peerId = ParsePeerId(data.vpeer());
|
||||||
|
@ -1334,9 +1334,14 @@ ServiceAction ParseServiceAction(
|
||||||
content.months = data.vmonths().v;
|
content.months = data.vmonths().v;
|
||||||
content.code = data.vslug().v;
|
content.code = data.vslug().v;
|
||||||
result.content = content;
|
result.content = content;
|
||||||
}, [&](const MTPDmessageActionGiveawayLaunch &) {
|
}, [&](const MTPDmessageActionGiveawayLaunch &data) {
|
||||||
auto content = ActionGiveawayLaunch();
|
auto content = ActionGiveawayLaunch();
|
||||||
result.content = content;
|
result.content = content;
|
||||||
|
}, [&](const MTPDmessageActionGiveawayResults &data) {
|
||||||
|
auto content = ActionGiveawayResults();
|
||||||
|
content.winners = data.vwinners_count().v;
|
||||||
|
content.unclaimed = data.vunclaimed_count().v;
|
||||||
|
result.content = content;
|
||||||
}, [](const MTPDmessageActionEmpty &data) {});
|
}, [](const MTPDmessageActionEmpty &data) {});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,12 +533,11 @@ struct ActionSuggestProfilePhoto {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ActionSetChatWallPaper {
|
struct ActionSetChatWallPaper {
|
||||||
|
bool same = false;
|
||||||
|
bool both = false;
|
||||||
// #TODO wallpapers
|
// #TODO wallpapers
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ActionSetSameChatWallPaper {
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ActionGiftCode {
|
struct ActionGiftCode {
|
||||||
QByteArray code;
|
QByteArray code;
|
||||||
PeerId boostPeerId = 0;
|
PeerId boostPeerId = 0;
|
||||||
|
@ -555,6 +554,11 @@ struct ActionRequestedPeer {
|
||||||
struct ActionGiveawayLaunch {
|
struct ActionGiveawayLaunch {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ActionGiveawayResults {
|
||||||
|
int winners = 0;
|
||||||
|
int unclaimed = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct ServiceAction {
|
struct ServiceAction {
|
||||||
std::variant<
|
std::variant<
|
||||||
v::null_t,
|
v::null_t,
|
||||||
|
@ -593,9 +597,9 @@ struct ServiceAction {
|
||||||
ActionSuggestProfilePhoto,
|
ActionSuggestProfilePhoto,
|
||||||
ActionRequestedPeer,
|
ActionRequestedPeer,
|
||||||
ActionSetChatWallPaper,
|
ActionSetChatWallPaper,
|
||||||
ActionSetSameChatWallPaper,
|
|
||||||
ActionGiftCode,
|
ActionGiftCode,
|
||||||
ActionGiveawayLaunch> content;
|
ActionGiveawayLaunch,
|
||||||
|
ActionGiveawayResults> content;
|
||||||
};
|
};
|
||||||
|
|
||||||
ServiceAction ParseServiceAction(
|
ServiceAction ParseServiceAction(
|
||||||
|
|
|
@ -1273,12 +1273,12 @@ auto HtmlWriter::Wrap::pushMessage(
|
||||||
}, [&](const ActionRequestedPeer &data) {
|
}, [&](const ActionRequestedPeer &data) {
|
||||||
return "requested: "_q/* + data.peerId*/;
|
return "requested: "_q/* + data.peerId*/;
|
||||||
}, [&](const ActionSetChatWallPaper &data) {
|
}, [&](const ActionSetChatWallPaper &data) {
|
||||||
return serviceFrom + " set a new background for this chat";
|
|
||||||
}, [&](const ActionSetSameChatWallPaper &data) {
|
|
||||||
return serviceFrom
|
return serviceFrom
|
||||||
+ " set "
|
+ (data.same
|
||||||
+ wrapReplyToLink("the same background")
|
? (" set "
|
||||||
+ " for this chat";
|
+ wrapReplyToLink("the same background")
|
||||||
|
+ " for this chat")
|
||||||
|
: " set a new background for this chat");
|
||||||
}, [&](const ActionGiftCode &data) {
|
}, [&](const ActionGiftCode &data) {
|
||||||
return data.unclaimed
|
return data.unclaimed
|
||||||
? ("This is an unclaimed Telegram Premium for "
|
? ("This is an unclaimed Telegram Premium for "
|
||||||
|
@ -1297,6 +1297,10 @@ auto HtmlWriter::Wrap::pushMessage(
|
||||||
}, [&](const ActionGiveawayLaunch &data) {
|
}, [&](const ActionGiveawayLaunch &data) {
|
||||||
return serviceFrom + " just started a giveaway "
|
return serviceFrom + " just started a giveaway "
|
||||||
"of Telegram Premium subscriptions to its followers.";
|
"of Telegram Premium subscriptions to its followers.";
|
||||||
|
}, [&](const ActionGiveawayResults &data) {
|
||||||
|
return QByteArray::number(data.winners)
|
||||||
|
+ " of the giveaway were randomly selected by Telegram "
|
||||||
|
"and received private messages with giftcodes.";
|
||||||
}, [](v::null_t) { return QByteArray(); });
|
}, [](v::null_t) { return QByteArray(); });
|
||||||
|
|
||||||
if (!serviceText.isEmpty()) {
|
if (!serviceText.isEmpty()) {
|
||||||
|
|
|
@ -604,12 +604,15 @@ QByteArray SerializeMessage(
|
||||||
push("via_giveaway", data.viaGiveaway);
|
push("via_giveaway", data.viaGiveaway);
|
||||||
}, [&](const ActionGiveawayLaunch &data) {
|
}, [&](const ActionGiveawayLaunch &data) {
|
||||||
pushAction("giveaway_launch");
|
pushAction("giveaway_launch");
|
||||||
|
}, [&](const ActionGiveawayResults &data) {
|
||||||
|
pushAction("giveaway_results");
|
||||||
|
push("winners", data.winners);
|
||||||
|
push("unclaimed", data.unclaimed);
|
||||||
}, [&](const ActionSetChatWallPaper &data) {
|
}, [&](const ActionSetChatWallPaper &data) {
|
||||||
pushActor();
|
pushActor();
|
||||||
pushAction("set_chat_wallpaper");
|
pushAction(data.same
|
||||||
}, [&](const ActionSetSameChatWallPaper &data) {
|
? "set_same_chat_wallpaper"
|
||||||
pushActor();
|
: "set_chat_wallpaper");
|
||||||
pushAction("set_same_chat_wallpaper");
|
|
||||||
pushReplyToMsgId("message_id");
|
pushReplyToMsgId("message_id");
|
||||||
}, [](v::null_t) {});
|
}, [](v::null_t) {});
|
||||||
|
|
||||||
|
|
|
@ -1144,7 +1144,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
} else if (item->isUnreadMention()
|
} else if (item->isUnreadMention()
|
||||||
&& !item->isUnreadMedia()) {
|
&& !item->isUnreadMedia()) {
|
||||||
readContents.insert(item);
|
readContents.insert(item);
|
||||||
_widget->enqueueMessageHighlight(view, {});
|
_widget->enqueueMessageHighlight({ item });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session().data().reactions().poll(item, context.now);
|
session().data().reactions().poll(item, context.now);
|
||||||
|
@ -2410,17 +2410,25 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
const auto replyToItem = selected.item ? selected.item : item;
|
const auto replyToItem = selected.item ? selected.item : item;
|
||||||
const auto itemId = replyToItem->fullId();
|
const auto itemId = replyToItem->fullId();
|
||||||
const auto quote = selected.text;
|
const auto quote = selected.text;
|
||||||
|
const auto quoteOffset = selected.offset;
|
||||||
text.replace('&', u"&&"_q);
|
text.replace('&', u"&&"_q);
|
||||||
_menu->addAction(text, [=] {
|
_menu->addAction(text, [=] {
|
||||||
if (canSendReply) {
|
if (canSendReply) {
|
||||||
_widget->replyToMessage({ itemId, quote });
|
_widget->replyToMessage({
|
||||||
|
.messageId = itemId,
|
||||||
|
.quote = quote,
|
||||||
|
.quoteOffset = quoteOffset,
|
||||||
|
});
|
||||||
if (!quote.empty()) {
|
if (!quote.empty()) {
|
||||||
_widget->clearSelected();
|
_widget->clearSelected();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
HistoryView::Controls::ShowReplyToChatBox(
|
const auto show = controller->uiShow();
|
||||||
controller->uiShow(),
|
HistoryView::Controls::ShowReplyToChatBox(show, {
|
||||||
{ itemId, quote });
|
.messageId = itemId,
|
||||||
|
.quote = quote,
|
||||||
|
.quoteOffset = quoteOffset,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, &st::menuIconReply);
|
}, &st::menuIconReply);
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,20 @@ constexpr auto kPinnedMessageTextLimit = 16;
|
||||||
|
|
||||||
using ItemPreview = HistoryView::ItemPreview;
|
using ItemPreview = HistoryView::ItemPreview;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] PreparedServiceText PrepareEmptyText(const T &) {
|
||||||
|
return PreparedServiceText();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
[[nodiscard]] PreparedServiceText PrepareErrorText(const T &data) {
|
||||||
|
if constexpr (!std::is_same_v<T, MTPDmessageActionEmpty>) {
|
||||||
|
const auto name = QString::fromUtf8(typeid(data).name());
|
||||||
|
LOG(("API Error: %1 received.").arg(name));
|
||||||
|
}
|
||||||
|
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] TextWithEntities SpoilerLoginCode(TextWithEntities text) {
|
[[nodiscard]] TextWithEntities SpoilerLoginCode(TextWithEntities text) {
|
||||||
const auto r = QRegularExpression(u"([\\d\\-]{5,7})"_q);
|
const auto r = QRegularExpression(u"([\\d\\-]{5,7})"_q);
|
||||||
const auto m = r.match(text.text);
|
const auto m = r.match(text.text);
|
||||||
|
@ -449,7 +463,7 @@ HistoryItem::HistoryItem(
|
||||||
const auto originalMedia = original->media();
|
const auto originalMedia = original->media();
|
||||||
const auto dropForwardInfo = original->computeDropForwardedInfo();
|
const auto dropForwardInfo = original->computeDropForwardedInfo();
|
||||||
config.reply.messageId = config.reply.topMessageId = topicRootId;
|
config.reply.messageId = config.reply.topMessageId = topicRootId;
|
||||||
config.reply.topicPost = (topicRootId != 0);
|
config.reply.topicPost = (topicRootId != 0) ? 1 : 0;
|
||||||
if (const auto originalReply = original->Get<HistoryMessageReply>()) {
|
if (const auto originalReply = original->Get<HistoryMessageReply>()) {
|
||||||
if (originalReply->external()) {
|
if (originalReply->external()) {
|
||||||
config.reply = originalReply->fields().clone(this);
|
config.reply = originalReply->fields().clone(this);
|
||||||
|
@ -3371,13 +3385,15 @@ void HistoryItem::createComponentsHelper(
|
||||||
&& topic->rootId() != to->topicRootId()) {
|
&& topic->rootId() != to->topicRootId()) {
|
||||||
config.reply.externalPeerId = replyTo.messageId.peer;
|
config.reply.externalPeerId = replyTo.messageId.peer;
|
||||||
}
|
}
|
||||||
config.reply.topicPost = config.reply.externalPeerId
|
const auto topicPost = config.reply.externalPeerId
|
||||||
? (replyTo.topicRootId
|
? (replyTo.topicRootId
|
||||||
&& (replyTo.topicRootId != Data::ForumTopic::kGeneralId))
|
&& (replyTo.topicRootId != Data::ForumTopic::kGeneralId))
|
||||||
: (LookupReplyIsTopicPost(to)
|
: (LookupReplyIsTopicPost(to)
|
||||||
|| (to && to->Has<HistoryServiceTopicInfo>())
|
|| (to && to->Has<HistoryServiceTopicInfo>())
|
||||||
|| (forum && forum->creating(config.reply.topMessageId)));
|
|| (forum && forum->creating(config.reply.topMessageId)));
|
||||||
config.reply.manualQuote = !replyTo.quote.empty();
|
config.reply.topicPost = topicPost ? 1 : 0;
|
||||||
|
config.reply.manualQuote = replyTo.quote.empty() ? 0 : 1;
|
||||||
|
config.reply.quoteOffset = replyTo.quoteOffset;
|
||||||
config.reply.quote = std::move(replyTo.quote);
|
config.reply.quote = std::move(replyTo.quote);
|
||||||
}
|
}
|
||||||
config.markup = std::move(markup);
|
config.markup = std::move(markup);
|
||||||
|
@ -3696,8 +3712,12 @@ void HistoryItem::createServiceFromMtp(const MTPDmessageService &message) {
|
||||||
}
|
}
|
||||||
}, call->lifetime);
|
}, call->lifetime);
|
||||||
}
|
}
|
||||||
} else if (type == mtpc_messageActionSetSameChatWallPaper) {
|
} else if (type == mtpc_messageActionSetChatWallPaper) {
|
||||||
UpdateComponents(HistoryServiceSameBackground::Bit());
|
if (action.c_messageActionSetChatWallPaper().is_same()) {
|
||||||
|
UpdateComponents(HistoryServiceSameBackground::Bit());
|
||||||
|
} else {
|
||||||
|
RemoveComponents(HistoryServiceSameBackground::Bit());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (const auto replyTo = message.vreply_to()) {
|
if (const auto replyTo = message.vreply_to()) {
|
||||||
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
||||||
|
@ -3877,7 +3897,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto prepareChatDeletePhoto = [this] {
|
auto prepareChatDeletePhoto = [&](const MTPDmessageActionChatDeletePhoto &action) {
|
||||||
auto result = PreparedServiceText();
|
auto result = PreparedServiceText();
|
||||||
if (isPost()) {
|
if (isPost()) {
|
||||||
result.text = tr::lng_action_removed_photo_channel(
|
result.text = tr::lng_action_removed_photo_channel(
|
||||||
|
@ -3956,7 +3976,23 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto prepareScreenshotTaken = [this] {
|
auto preparePinMessage = [&](const MTPDmessageActionPinMessage &) {
|
||||||
|
return preparePinnedText();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto prepareGameScore = [&](const MTPDmessageActionGameScore &) {
|
||||||
|
return prepareGameScoreText();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto preparePhoneCall = [&](const MTPDmessageActionPhoneCall &) -> PreparedServiceText {
|
||||||
|
Unexpected("PhoneCall type in setServiceMessageFromMtp.");
|
||||||
|
};
|
||||||
|
|
||||||
|
auto preparePaymentSent = [&](const MTPDmessageActionPaymentSent &) {
|
||||||
|
return preparePaymentSentText();
|
||||||
|
};
|
||||||
|
|
||||||
|
auto prepareScreenshotTaken = [this](const MTPDmessageActionScreenshotTaken &) {
|
||||||
auto result = PreparedServiceText();
|
auto result = PreparedServiceText();
|
||||||
if (out()) {
|
if (out()) {
|
||||||
result.text = tr::lng_action_you_took_screenshot(
|
result.text = tr::lng_action_you_took_screenshot(
|
||||||
|
@ -4055,7 +4091,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto prepareContactSignUp = [this] {
|
auto prepareContactSignUp = [this](const MTPDmessageActionContactSignUp &data) {
|
||||||
auto result = PreparedServiceText();
|
auto result = PreparedServiceText();
|
||||||
result.links.push_back(fromLink());
|
result.links.push_back(fromLink());
|
||||||
result.text = tr::lng_action_user_registered(
|
result.text = tr::lng_action_user_registered(
|
||||||
|
@ -4258,6 +4294,10 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto prepareGroupCallScheduled = [&](const MTPDmessageActionGroupCallScheduled &data) {
|
||||||
|
return prepareCallScheduledText(data.vschedule_date().v);
|
||||||
|
};
|
||||||
|
|
||||||
auto prepareSetChatTheme = [this](const MTPDmessageActionSetChatTheme &action) {
|
auto prepareSetChatTheme = [this](const MTPDmessageActionSetChatTheme &action) {
|
||||||
auto result = PreparedServiceText();
|
auto result = PreparedServiceText();
|
||||||
const auto text = qs(action.vemoticon());
|
const auto text = qs(action.vemoticon());
|
||||||
|
@ -4459,28 +4499,7 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
auto prepareSetChatWallPaper = [&](
|
auto prepareSetChatWallPaper = [&](
|
||||||
const MTPDmessageActionSetChatWallPaper &action) {
|
const MTPDmessageActionSetChatWallPaper &action) {
|
||||||
const auto isSelf = (_from->id == _from->session().userPeerId());
|
const auto isSelf = (_from->id == _from->session().userPeerId());
|
||||||
const auto peer = isSelf ? history()->peer : _from;
|
const auto same = action.is_same();
|
||||||
const auto user = peer->asUser();
|
|
||||||
const auto name = (user && !user->firstName.isEmpty())
|
|
||||||
? user->firstName
|
|
||||||
: peer->name();
|
|
||||||
auto result = PreparedServiceText{};
|
|
||||||
result.links.push_back(peer->createOpenLink());
|
|
||||||
result.text = isSelf
|
|
||||||
? tr::lng_action_set_wallpaper_me(
|
|
||||||
tr::now,
|
|
||||||
Ui::Text::WithEntities)
|
|
||||||
: tr::lng_action_set_wallpaper(
|
|
||||||
tr::now,
|
|
||||||
lt_user,
|
|
||||||
Ui::Text::Link(name, 1), // Link 1.
|
|
||||||
Ui::Text::WithEntities);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto prepareSetSameChatWallPaper = [&](
|
|
||||||
const MTPDmessageActionSetSameChatWallPaper &action) {
|
|
||||||
const auto isSelf = (_from->id == _from->session().userPeerId());
|
|
||||||
const auto peer = isSelf ? history()->peer : _from;
|
const auto peer = isSelf ? history()->peer : _from;
|
||||||
const auto user = peer->asUser();
|
const auto user = peer->asUser();
|
||||||
const auto name = (user && !user->firstName.isEmpty())
|
const auto name = (user && !user->firstName.isEmpty())
|
||||||
|
@ -4491,14 +4510,18 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
result.links.push_back(peer->createOpenLink());
|
result.links.push_back(peer->createOpenLink());
|
||||||
}
|
}
|
||||||
result.text = isSelf
|
result.text = isSelf
|
||||||
? tr::lng_action_set_same_wallpaper_me(
|
? (same
|
||||||
tr::now,
|
? tr::lng_action_set_same_wallpaper_me
|
||||||
Ui::Text::WithEntities)
|
: tr::lng_action_set_wallpaper_me)(
|
||||||
: tr::lng_action_set_same_wallpaper(
|
tr::now,
|
||||||
tr::now,
|
Ui::Text::WithEntities)
|
||||||
lt_user,
|
: (same
|
||||||
Ui::Text::Link(name, 1), // Link 1.
|
? tr::lng_action_set_same_wallpaper
|
||||||
Ui::Text::WithEntities);
|
: tr::lng_action_set_wallpaper)(
|
||||||
|
tr::now,
|
||||||
|
lt_user,
|
||||||
|
Ui::Text::Link(name, 1), // Link 1.
|
||||||
|
Ui::Text::WithEntities);
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4532,93 +4555,65 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
setServiceText(action.match([&](
|
auto prepareGiveawayResults = [&](const MTPDmessageActionGiveawayResults &action) {
|
||||||
const MTPDmessageActionChatAddUser &data) {
|
auto result = PreparedServiceText();
|
||||||
return prepareChatAddUserText(data);
|
const auto winners = action.vwinners_count().v;
|
||||||
}, [&](const MTPDmessageActionChatJoinedByLink &data) {
|
const auto unclaimed = action.vunclaimed_count().v;
|
||||||
return prepareChatJoinedByLink(data);
|
result.text = {
|
||||||
}, [&](const MTPDmessageActionChatCreate &data) {
|
(!winners
|
||||||
return prepareChatCreate(data);
|
? tr::lng_action_giveaway_results_none(tr::now)
|
||||||
}, [](const MTPDmessageActionChatMigrateTo &) {
|
: unclaimed
|
||||||
return PreparedServiceText();
|
? tr::lng_action_giveaway_results_some(tr::now)
|
||||||
}, [](const MTPDmessageActionChannelMigrateFrom &) {
|
: tr::lng_action_giveaway_results(
|
||||||
return PreparedServiceText();
|
tr::now,
|
||||||
}, [](const MTPDmessageActionHistoryClear &) {
|
lt_count,
|
||||||
return PreparedServiceText();
|
winners))
|
||||||
}, [&](const MTPDmessageActionChannelCreate &data) {
|
};
|
||||||
return prepareChannelCreate(data);
|
return result;
|
||||||
}, [&](const MTPDmessageActionChatDeletePhoto &) {
|
};
|
||||||
return prepareChatDeletePhoto();
|
|
||||||
}, [&](const MTPDmessageActionChatDeleteUser &data) {
|
setServiceText(action.match(
|
||||||
return prepareChatDeleteUser(data);
|
prepareChatAddUserText,
|
||||||
}, [&](const MTPDmessageActionChatEditPhoto &data) {
|
prepareChatJoinedByLink,
|
||||||
return prepareChatEditPhoto(data);
|
prepareChatCreate,
|
||||||
}, [&](const MTPDmessageActionChatEditTitle &data) {
|
PrepareEmptyText<MTPDmessageActionChatMigrateTo>,
|
||||||
return prepareChatEditTitle(data);
|
PrepareEmptyText<MTPDmessageActionChannelMigrateFrom>,
|
||||||
}, [&](const MTPDmessageActionPinMessage &) {
|
PrepareEmptyText<MTPDmessageActionHistoryClear>,
|
||||||
return preparePinnedText();
|
prepareChannelCreate,
|
||||||
}, [&](const MTPDmessageActionGameScore &) {
|
prepareChatDeletePhoto,
|
||||||
return prepareGameScoreText();
|
prepareChatDeleteUser,
|
||||||
}, [&](const MTPDmessageActionPhoneCall &) -> PreparedServiceText {
|
prepareChatEditPhoto,
|
||||||
Unexpected("PhoneCall type in setServiceMessageFromMtp.");
|
prepareChatEditTitle,
|
||||||
}, [&](const MTPDmessageActionPaymentSent &) {
|
preparePinMessage,
|
||||||
return preparePaymentSentText();
|
prepareGameScore,
|
||||||
}, [&](const MTPDmessageActionScreenshotTaken &) {
|
preparePhoneCall,
|
||||||
return prepareScreenshotTaken();
|
preparePaymentSent,
|
||||||
}, [&](const MTPDmessageActionCustomAction &data) {
|
prepareScreenshotTaken,
|
||||||
return prepareCustomAction(data);
|
prepareCustomAction,
|
||||||
}, [&](const MTPDmessageActionBotAllowed &data) {
|
prepareBotAllowed,
|
||||||
return prepareBotAllowed(data);
|
prepareSecureValuesSent,
|
||||||
}, [&](const MTPDmessageActionSecureValuesSent &data) {
|
prepareContactSignUp,
|
||||||
return prepareSecureValuesSent(data);
|
prepareProximityReached,
|
||||||
}, [&](const MTPDmessageActionContactSignUp &data) {
|
PrepareErrorText<MTPDmessageActionPaymentSentMe>,
|
||||||
return prepareContactSignUp();
|
PrepareErrorText<MTPDmessageActionSecureValuesSentMe>,
|
||||||
}, [&](const MTPDmessageActionGeoProximityReached &data) {
|
prepareGroupCall,
|
||||||
return prepareProximityReached(data);
|
prepareInviteToGroupCall,
|
||||||
}, [](const MTPDmessageActionPaymentSentMe &) {
|
prepareSetMessagesTTL,
|
||||||
LOG(("API Error: messageActionPaymentSentMe received."));
|
prepareGroupCallScheduled,
|
||||||
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
prepareSetChatTheme,
|
||||||
}, [](const MTPDmessageActionSecureValuesSentMe &) {
|
prepareChatJoinedByRequest,
|
||||||
LOG(("API Error: messageActionSecureValuesSentMe received."));
|
prepareWebViewDataSent,
|
||||||
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
prepareGiftPremium,
|
||||||
}, [&](const MTPDmessageActionGroupCall &data) {
|
prepareTopicCreate,
|
||||||
return prepareGroupCall(data);
|
prepareTopicEdit,
|
||||||
}, [&](const MTPDmessageActionInviteToGroupCall &data) {
|
PrepareErrorText<MTPDmessageActionWebViewDataSentMe>,
|
||||||
return prepareInviteToGroupCall(data);
|
prepareSuggestProfilePhoto,
|
||||||
}, [&](const MTPDmessageActionSetMessagesTTL &data) {
|
prepareRequestedPeer,
|
||||||
return prepareSetMessagesTTL(data);
|
prepareSetChatWallPaper,
|
||||||
}, [&](const MTPDmessageActionGroupCallScheduled &data) {
|
prepareGiftCode,
|
||||||
return prepareCallScheduledText(data.vschedule_date().v);
|
prepareGiveawayLaunch,
|
||||||
}, [&](const MTPDmessageActionSetChatTheme &data) {
|
prepareGiveawayResults,
|
||||||
return prepareSetChatTheme(data);
|
PrepareErrorText<MTPDmessageActionEmpty>));
|
||||||
}, [&](const MTPDmessageActionChatJoinedByRequest &data) {
|
|
||||||
return prepareChatJoinedByRequest(data);
|
|
||||||
}, [&](const MTPDmessageActionWebViewDataSent &data) {
|
|
||||||
return prepareWebViewDataSent(data);
|
|
||||||
}, [&](const MTPDmessageActionGiftPremium &data) {
|
|
||||||
return prepareGiftPremium(data);
|
|
||||||
}, [&](const MTPDmessageActionTopicCreate &data) {
|
|
||||||
return prepareTopicCreate(data);
|
|
||||||
}, [&](const MTPDmessageActionTopicEdit &data) {
|
|
||||||
return prepareTopicEdit(data);
|
|
||||||
}, [&](const MTPDmessageActionWebViewDataSentMe &data) {
|
|
||||||
LOG(("API Error: messageActionWebViewDataSentMe received."));
|
|
||||||
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
|
||||||
}, [&](const MTPDmessageActionSuggestProfilePhoto &data) {
|
|
||||||
return prepareSuggestProfilePhoto(data);
|
|
||||||
}, [&](const MTPDmessageActionRequestedPeer &data) {
|
|
||||||
return prepareRequestedPeer(data);
|
|
||||||
}, [&](const MTPDmessageActionSetChatWallPaper &data) {
|
|
||||||
return prepareSetChatWallPaper(data);
|
|
||||||
}, [&](const MTPDmessageActionSetSameChatWallPaper &data) {
|
|
||||||
return prepareSetSameChatWallPaper(data);
|
|
||||||
}, [&](const MTPDmessageActionGiftCode &data) {
|
|
||||||
return prepareGiftCode(data);
|
|
||||||
}, [&](const MTPDmessageActionGiveawayLaunch &data) {
|
|
||||||
return prepareGiveawayLaunch(data);
|
|
||||||
}, [](const MTPDmessageActionEmpty &) {
|
|
||||||
return PreparedServiceText{ { tr::lng_message_empty(tr::now) } };
|
|
||||||
}));
|
|
||||||
|
|
||||||
// Additional information.
|
// Additional information.
|
||||||
applyAction(action);
|
applyAction(action);
|
||||||
|
@ -4680,10 +4675,13 @@ void HistoryItem::applyAction(const MTPMessageAction &action) {
|
||||||
}, [](const MTPDphotoEmpty &) {
|
}, [](const MTPDphotoEmpty &) {
|
||||||
});
|
});
|
||||||
}, [&](const MTPDmessageActionSetChatWallPaper &data) {
|
}, [&](const MTPDmessageActionSetChatWallPaper &data) {
|
||||||
const auto session = &history()->session();
|
if (!data.is_same()) {
|
||||||
const auto &attached = data.vwallpaper();
|
using namespace Data;
|
||||||
if (const auto paper = Data::WallPaper::Create(session, attached)) {
|
const auto session = &history()->session();
|
||||||
_media = std::make_unique<Data::MediaWallPaper>(this, *paper);
|
const auto &attached = data.vwallpaper();
|
||||||
|
if (const auto paper = WallPaper::Create(session, attached)) {
|
||||||
|
_media = std::make_unique<MediaWallPaper>(this, *paper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [&](const MTPDmessageActionGiftCode &data) {
|
}, [&](const MTPDmessageActionGiftCode &data) {
|
||||||
const auto boostedId = data.vboost_peer()
|
const auto boostedId = data.vboost_peer()
|
||||||
|
|
|
@ -283,8 +283,9 @@ ReplyFields ReplyFields::clone(not_null<HistoryItem*> parent) const {
|
||||||
.messageId = messageId,
|
.messageId = messageId,
|
||||||
.topMessageId = topMessageId,
|
.topMessageId = topMessageId,
|
||||||
.storyId = storyId,
|
.storyId = storyId,
|
||||||
.topicPost = topicPost,
|
.quoteOffset = quoteOffset,
|
||||||
.manualQuote = manualQuote,
|
.manualQuote = manualQuote,
|
||||||
|
.topicPost = topicPost,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +304,7 @@ ReplyFields ReplyFieldsFromMTP(
|
||||||
: id;
|
: id;
|
||||||
result.topMessageId
|
result.topMessageId
|
||||||
= data.vreply_to_top_id().value_or(id);
|
= data.vreply_to_top_id().value_or(id);
|
||||||
result.topicPost = data.is_forum_topic();
|
result.topicPost = data.is_forum_topic() ? 1 : 0;
|
||||||
}
|
}
|
||||||
if (const auto header = data.vreply_from()) {
|
if (const auto header = data.vreply_from()) {
|
||||||
const auto &data = header->data();
|
const auto &data = header->data();
|
||||||
|
@ -324,7 +325,8 @@ ReplyFields ReplyFieldsFromMTP(
|
||||||
&owner->session(),
|
&owner->session(),
|
||||||
data.vquote_entities().value_or_empty()),
|
data.vquote_entities().value_or_empty()),
|
||||||
};
|
};
|
||||||
result.manualQuote = data.is_quote();
|
result.quoteOffset = data.vquote_offset().value_or_empty();
|
||||||
|
result.manualQuote = data.is_quote() ? 1 : 0;
|
||||||
return result;
|
return result;
|
||||||
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
}, [&](const MTPDmessageReplyStoryHeader &data) {
|
||||||
return ReplyFields{
|
return ReplyFields{
|
||||||
|
@ -357,6 +359,7 @@ FullReplyTo ReplyToFromMTP(
|
||||||
&history->session(),
|
&history->session(),
|
||||||
data.vquote_entities().value_or_empty()),
|
data.vquote_entities().value_or_empty()),
|
||||||
};
|
};
|
||||||
|
result.quoteOffset = data.vquote_offset().value_or_empty();
|
||||||
return result;
|
return result;
|
||||||
}, [&](const MTPDinputReplyToStory &data) {
|
}, [&](const MTPDinputReplyToStory &data) {
|
||||||
if (const auto parsed = Data::UserFromInputMTP(
|
if (const auto parsed = Data::UserFromInputMTP(
|
||||||
|
@ -461,7 +464,7 @@ void HistoryMessageReply::updateFields(
|
||||||
MsgId messageId,
|
MsgId messageId,
|
||||||
MsgId topMessageId,
|
MsgId topMessageId,
|
||||||
bool topicPost) {
|
bool topicPost) {
|
||||||
_fields.topicPost = topicPost;
|
_fields.topicPost = topicPost ? 1 : 0;
|
||||||
if ((_fields.messageId != messageId)
|
if ((_fields.messageId != messageId)
|
||||||
&& !IsServerMsgId(_fields.messageId)) {
|
&& !IsServerMsgId(_fields.messageId)) {
|
||||||
_fields.messageId = messageId;
|
_fields.messageId = messageId;
|
||||||
|
|
|
@ -233,7 +233,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReplyFields {
|
struct ReplyFields {
|
||||||
ReplyFields clone(not_null<HistoryItem*> parent) const;
|
[[nodiscard]] ReplyFields clone(not_null<HistoryItem*> parent) const;
|
||||||
|
|
||||||
TextWithEntities quote;
|
TextWithEntities quote;
|
||||||
std::unique_ptr<Data::Media> externalMedia;
|
std::unique_ptr<Data::Media> externalMedia;
|
||||||
|
@ -244,8 +244,9 @@ struct ReplyFields {
|
||||||
MsgId messageId = 0;
|
MsgId messageId = 0;
|
||||||
MsgId topMessageId = 0;
|
MsgId topMessageId = 0;
|
||||||
StoryId storyId = 0;
|
StoryId storyId = 0;
|
||||||
bool topicPost = false;
|
uint32 quoteOffset : 30 = 0;
|
||||||
bool manualQuote = false;
|
uint32 manualQuote : 1 = 0;
|
||||||
|
uint32 topicPost : 1 = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] ReplyFields ReplyFieldsFromMTP(
|
[[nodiscard]] ReplyFields ReplyFieldsFromMTP(
|
||||||
|
|
|
@ -270,19 +270,22 @@ bool IsItemScheduledUntilOnline(not_null<const HistoryItem*> item) {
|
||||||
ClickHandlerPtr JumpToMessageClickHandler(
|
ClickHandlerPtr JumpToMessageClickHandler(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
FullMsgId returnToId,
|
FullMsgId returnToId,
|
||||||
TextWithEntities highlightPart) {
|
TextWithEntities highlightPart,
|
||||||
|
int highlightPartOffsetHint) {
|
||||||
return JumpToMessageClickHandler(
|
return JumpToMessageClickHandler(
|
||||||
item->history()->peer,
|
item->history()->peer,
|
||||||
item->id,
|
item->id,
|
||||||
returnToId,
|
returnToId,
|
||||||
std::move(highlightPart));
|
std::move(highlightPart),
|
||||||
|
highlightPartOffsetHint);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClickHandlerPtr JumpToMessageClickHandler(
|
ClickHandlerPtr JumpToMessageClickHandler(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
FullMsgId returnToId,
|
FullMsgId returnToId,
|
||||||
TextWithEntities highlightPart) {
|
TextWithEntities highlightPart,
|
||||||
|
int highlightPartOffsetHint) {
|
||||||
return std::make_shared<LambdaClickHandler>([=] {
|
return std::make_shared<LambdaClickHandler>([=] {
|
||||||
const auto separate = Core::App().separateWindowForPeer(peer);
|
const auto separate = Core::App().separateWindowForPeer(peer);
|
||||||
const auto controller = separate
|
const auto controller = separate
|
||||||
|
@ -293,6 +296,7 @@ ClickHandlerPtr JumpToMessageClickHandler(
|
||||||
Window::SectionShow::Way::Forward
|
Window::SectionShow::Way::Forward
|
||||||
};
|
};
|
||||||
params.highlightPart = highlightPart;
|
params.highlightPart = highlightPart;
|
||||||
|
params.highlightPartOffsetHint = highlightPartOffsetHint;
|
||||||
params.origin = Window::SectionShow::OriginMessage{
|
params.origin = Window::SectionShow::OriginMessage{
|
||||||
returnToId
|
returnToId
|
||||||
};
|
};
|
||||||
|
@ -392,8 +396,11 @@ MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) {
|
||||||
MTP_flags(Flag::f_reply_to_msg_id
|
MTP_flags(Flag::f_reply_to_msg_id
|
||||||
| (replyToTop ? Flag::f_reply_to_top_id : Flag())
|
| (replyToTop ? Flag::f_reply_to_top_id : Flag())
|
||||||
| (externalPeerId ? Flag::f_reply_to_peer_id : Flag())
|
| (externalPeerId ? Flag::f_reply_to_peer_id : Flag())
|
||||||
| (replyTo.quote.empty() ? Flag() : Flag::f_quote)
|
| (replyTo.quote.empty()
|
||||||
| (replyTo.quote.empty() ? Flag() : Flag::f_quote_text)
|
? Flag()
|
||||||
|
: (Flag::f_quote
|
||||||
|
| Flag::f_quote_text
|
||||||
|
| Flag::f_quote_offset))
|
||||||
| (quoteEntities.v.empty()
|
| (quoteEntities.v.empty()
|
||||||
? Flag()
|
? Flag()
|
||||||
: Flag::f_quote_entities)),
|
: Flag::f_quote_entities)),
|
||||||
|
@ -403,7 +410,8 @@ MTPMessageReplyHeader NewMessageReplyHeader(const Api::SendAction &action) {
|
||||||
MTPMessageMedia(), // reply_media
|
MTPMessageMedia(), // reply_media
|
||||||
MTP_int(replyToTop),
|
MTP_int(replyToTop),
|
||||||
MTP_string(replyTo.quote.text),
|
MTP_string(replyTo.quote.text),
|
||||||
quoteEntities);
|
quoteEntities,
|
||||||
|
MTP_int(replyTo.quoteOffset));
|
||||||
}
|
}
|
||||||
return MTPMessageReplyHeader();
|
return MTPMessageReplyHeader();
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,11 +124,13 @@ struct SendingErrorRequest {
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
MsgId msgId,
|
MsgId msgId,
|
||||||
FullMsgId returnToId = FullMsgId(),
|
FullMsgId returnToId = FullMsgId(),
|
||||||
TextWithEntities highlightPart = {});
|
TextWithEntities highlightPart = {},
|
||||||
|
int highlightPartOffsetHint = 0);
|
||||||
[[nodiscard]] ClickHandlerPtr JumpToMessageClickHandler(
|
[[nodiscard]] ClickHandlerPtr JumpToMessageClickHandler(
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
FullMsgId returnToId = FullMsgId(),
|
FullMsgId returnToId = FullMsgId(),
|
||||||
TextWithEntities highlightPart = {});
|
TextWithEntities highlightPart = {},
|
||||||
|
int highlightPartOffsetHint = 0);
|
||||||
[[nodiscard]] ClickHandlerPtr JumpToStoryClickHandler(
|
[[nodiscard]] ClickHandlerPtr JumpToStoryClickHandler(
|
||||||
not_null<Data::Story*> story);
|
not_null<Data::Story*> story);
|
||||||
ClickHandlerPtr JumpToStoryClickHandler(
|
ClickHandlerPtr JumpToStoryClickHandler(
|
||||||
|
|
|
@ -25,10 +25,8 @@ ElementHighlighter::ElementHighlighter(
|
||||||
, _animation(*this) {
|
, _animation(*this) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElementHighlighter::enqueue(
|
void ElementHighlighter::enqueue(const SelectedQuote "e) {
|
||||||
not_null<Element*> view,
|
const auto data = computeHighlight(quote);
|
||||||
const TextWithEntities &part) {
|
|
||||||
const auto data = computeHighlight(view, part);
|
|
||||||
if (_queue.empty() && !_animation.animating()) {
|
if (_queue.empty() && !_animation.animating()) {
|
||||||
highlight(data);
|
highlight(data);
|
||||||
} else if (_highlighted != data && !base::contains(_queue, data)) {
|
} else if (_highlighted != data && !base::contains(_queue, data)) {
|
||||||
|
@ -37,10 +35,8 @@ void ElementHighlighter::enqueue(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElementHighlighter::highlight(
|
void ElementHighlighter::highlight(const SelectedQuote "e) {
|
||||||
not_null<Element*> view,
|
highlight(computeHighlight(quote));
|
||||||
const TextWithEntities &part) {
|
|
||||||
highlight(computeHighlight(view, part));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElementHighlighter::checkNextHighlight() {
|
void ElementHighlighter::checkNextHighlight() {
|
||||||
|
@ -75,9 +71,10 @@ Ui::ChatPaintHighlight ElementHighlighter::state(
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementHighlighter::Highlight ElementHighlighter::computeHighlight(
|
ElementHighlighter::Highlight ElementHighlighter::computeHighlight(
|
||||||
not_null<const Element*> view,
|
const SelectedQuote "e) {
|
||||||
const TextWithEntities &part) {
|
Assert(quote.item != nullptr);
|
||||||
const auto item = view->data();
|
|
||||||
|
const auto item = not_null(quote.item);
|
||||||
const auto owner = &item->history()->owner();
|
const auto owner = &item->history()->owner();
|
||||||
if (const auto group = owner->groups().find(item)) {
|
if (const auto group = owner->groups().find(item)) {
|
||||||
const auto leader = group->items.front();
|
const auto leader = group->items.front();
|
||||||
|
@ -85,20 +82,19 @@ ElementHighlighter::Highlight ElementHighlighter::computeHighlight(
|
||||||
const auto i = ranges::find(group->items, item);
|
const auto i = ranges::find(group->items, item);
|
||||||
if (i != end(group->items)) {
|
if (i != end(group->items)) {
|
||||||
const auto index = int(i - begin(group->items));
|
const auto index = int(i - begin(group->items));
|
||||||
if (part.empty()) {
|
if (quote.text.empty()) {
|
||||||
return { leaderId, AddGroupItemSelection({}, index) };
|
return { leaderId, AddGroupItemSelection({}, index) };
|
||||||
} else if (const auto leaderView = _viewForItem(leader)) {
|
} else if (const auto leaderView = _viewForItem(leader)) {
|
||||||
return {
|
return { leaderId, leaderView->selectionFromQuote(quote) };
|
||||||
leaderId,
|
|
||||||
leaderView->selectionFromQuote(item, part),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { leaderId };
|
return { leaderId };
|
||||||
} else if (part.empty()) {
|
} else if (quote.text.empty()) {
|
||||||
return { item->fullId() };
|
return { item->fullId() };
|
||||||
|
} else if (const auto view = _viewForItem(item)) {
|
||||||
|
return { item->fullId(), view->selectionFromQuote(quote) };
|
||||||
}
|
}
|
||||||
return { item->fullId(), view->selectionFromQuote(item, part) };
|
return { item->fullId() };
|
||||||
}
|
}
|
||||||
|
|
||||||
void ElementHighlighter::highlight(Highlight data) {
|
void ElementHighlighter::highlight(Highlight data) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct ChatPaintHighlight;
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
class Element;
|
class Element;
|
||||||
|
struct SelectedQuote;
|
||||||
|
|
||||||
class ElementHighlighter final {
|
class ElementHighlighter final {
|
||||||
public:
|
public:
|
||||||
|
@ -33,8 +34,8 @@ public:
|
||||||
ViewForItem viewForItem,
|
ViewForItem viewForItem,
|
||||||
RepaintView repaintView);
|
RepaintView repaintView);
|
||||||
|
|
||||||
void enqueue(not_null<Element*> view, const TextWithEntities &part);
|
void enqueue(const SelectedQuote "e);
|
||||||
void highlight(not_null<Element*> view, const TextWithEntities &part);
|
void highlight(const SelectedQuote "e);
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
[[nodiscard]] Ui::ChatPaintHighlight state(
|
[[nodiscard]] Ui::ChatPaintHighlight state(
|
||||||
|
@ -71,9 +72,7 @@ private:
|
||||||
friend inline bool operator==(Highlight, Highlight) = default;
|
friend inline bool operator==(Highlight, Highlight) = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] Highlight computeHighlight(
|
[[nodiscard]] Highlight computeHighlight(const SelectedQuote "e);
|
||||||
not_null<const Element*> view,
|
|
||||||
const TextWithEntities &part);
|
|
||||||
void highlight(Highlight data);
|
void highlight(Highlight data);
|
||||||
void checkNextHighlight();
|
void checkNextHighlight();
|
||||||
void repaintHighlightedItem(not_null<const Element*> view);
|
void repaintHighlightedItem(not_null<const Element*> view);
|
||||||
|
|
|
@ -1075,7 +1075,7 @@ void HistoryWidget::initTabbedSelector() {
|
||||||
if (!data.recipientOverride) {
|
if (!data.recipientOverride) {
|
||||||
return true;
|
return true;
|
||||||
} else if (data.recipientOverride != _peer) {
|
} else if (data.recipientOverride != _peer) {
|
||||||
showHistory(data.recipientOverride->id, ShowAtTheEndMsgId, {});
|
showHistory(data.recipientOverride->id, ShowAtTheEndMsgId);
|
||||||
}
|
}
|
||||||
return (data.recipientOverride == _peer);
|
return (data.recipientOverride == _peer);
|
||||||
}) | rpl::start_with_next([=](ChatHelpers::InlineChosen data) {
|
}) | rpl::start_with_next([=](ChatHelpers::InlineChosen data) {
|
||||||
|
@ -1270,9 +1270,8 @@ void HistoryWidget::scrollToAnimationCallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::enqueueMessageHighlight(
|
void HistoryWidget::enqueueMessageHighlight(
|
||||||
not_null<HistoryView::Element*> view,
|
const HistoryView::SelectedQuote "e) {
|
||||||
const TextWithEntities &part) {
|
_highlighter.enqueue(quote);
|
||||||
_highlighter.enqueue(view, part);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui::ChatPaintHighlight HistoryWidget::itemHighlight(
|
Ui::ChatPaintHighlight HistoryWidget::itemHighlight(
|
||||||
|
@ -1973,10 +1972,12 @@ bool HistoryWidget::insideJumpToEndInsteadOfToUnread() const {
|
||||||
void HistoryWidget::showHistory(
|
void HistoryWidget::showHistory(
|
||||||
const PeerId &peerId,
|
const PeerId &peerId,
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart) {
|
const TextWithEntities &highlightPart,
|
||||||
|
int highlightPartOffsetHint) {
|
||||||
_pinnedClickedId = FullMsgId();
|
_pinnedClickedId = FullMsgId();
|
||||||
_minPinnedId = std::nullopt;
|
_minPinnedId = std::nullopt;
|
||||||
_showAtMsgHighlightPart = {};
|
_showAtMsgHighlightPart = {};
|
||||||
|
_showAtMsgHighlightPartOffsetHint = 0;
|
||||||
|
|
||||||
const auto wasDialogsEntryState = computeDialogsEntryState();
|
const auto wasDialogsEntryState = computeDialogsEntryState();
|
||||||
const auto startBot = (showAtMsgId == ShowAndStartBotMsgId);
|
const auto startBot = (showAtMsgId == ShowAndStartBotMsgId);
|
||||||
|
@ -2024,10 +2025,16 @@ void HistoryWidget::showHistory(
|
||||||
).arg(_history->inboxReadTillId().bare
|
).arg(_history->inboxReadTillId().bare
|
||||||
).arg(Logs::b(_history->loadedAtBottom())
|
).arg(Logs::b(_history->loadedAtBottom())
|
||||||
).arg(showAtMsgId.bare));
|
).arg(showAtMsgId.bare));
|
||||||
delayedShowAt(showAtMsgId, highlightPart);
|
delayedShowAt(
|
||||||
|
showAtMsgId,
|
||||||
|
highlightPart,
|
||||||
|
highlightPartOffsetHint);
|
||||||
} else if (_showAtMsgId != showAtMsgId) {
|
} else if (_showAtMsgId != showAtMsgId) {
|
||||||
clearAllLoadRequests();
|
clearAllLoadRequests();
|
||||||
setMsgId(showAtMsgId, highlightPart);
|
setMsgId(
|
||||||
|
showAtMsgId,
|
||||||
|
highlightPart,
|
||||||
|
highlightPartOffsetHint);
|
||||||
firstLoadMessages();
|
firstLoadMessages();
|
||||||
doneShow();
|
doneShow();
|
||||||
}
|
}
|
||||||
|
@ -2047,7 +2054,10 @@ void HistoryWidget::showHistory(
|
||||||
_cornerButtons.skipReplyReturn(skipId);
|
_cornerButtons.skipReplyReturn(skipId);
|
||||||
}
|
}
|
||||||
|
|
||||||
setMsgId(showAtMsgId, highlightPart);
|
setMsgId(
|
||||||
|
showAtMsgId,
|
||||||
|
highlightPart,
|
||||||
|
highlightPartOffsetHint);
|
||||||
if (_historyInited) {
|
if (_historyInited) {
|
||||||
DEBUG_LOG(("JumpToEnd(%1, %2, %3): "
|
DEBUG_LOG(("JumpToEnd(%1, %2, %3): "
|
||||||
"Showing instant at %4."
|
"Showing instant at %4."
|
||||||
|
@ -2151,6 +2161,7 @@ void HistoryWidget::showHistory(
|
||||||
|
|
||||||
_showAtMsgId = showAtMsgId;
|
_showAtMsgId = showAtMsgId;
|
||||||
_showAtMsgHighlightPart = highlightPart;
|
_showAtMsgHighlightPart = highlightPart;
|
||||||
|
_showAtMsgHighlightPartOffsetHint = highlightPartOffsetHint;
|
||||||
_historyInited = false;
|
_historyInited = false;
|
||||||
_contactStatus = nullptr;
|
_contactStatus = nullptr;
|
||||||
|
|
||||||
|
@ -3305,7 +3316,10 @@ void HistoryWidget::messagesReceived(
|
||||||
}
|
}
|
||||||
|
|
||||||
_delayedShowAtRequest = 0;
|
_delayedShowAtRequest = 0;
|
||||||
setMsgId(_delayedShowAtMsgId, _delayedShowAtMsgHighlightPart);
|
setMsgId(
|
||||||
|
_delayedShowAtMsgId,
|
||||||
|
_delayedShowAtMsgHighlightPart,
|
||||||
|
_delayedShowAtMsgHighlightPartOffsetHint);
|
||||||
historyLoaded();
|
historyLoaded();
|
||||||
}
|
}
|
||||||
if (session().supportMode()) {
|
if (session().supportMode()) {
|
||||||
|
@ -3529,13 +3543,15 @@ void HistoryWidget::loadMessagesDown() {
|
||||||
|
|
||||||
void HistoryWidget::delayedShowAt(
|
void HistoryWidget::delayedShowAt(
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart) {
|
const TextWithEntities &highlightPart,
|
||||||
|
int highlightPartOffsetHint) {
|
||||||
if (!_history) {
|
if (!_history) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_delayedShowAtMsgHighlightPart != highlightPart) {
|
if (_delayedShowAtMsgHighlightPart != highlightPart) {
|
||||||
_delayedShowAtMsgHighlightPart = highlightPart;
|
_delayedShowAtMsgHighlightPart = highlightPart;
|
||||||
}
|
}
|
||||||
|
_delayedShowAtMsgHighlightPartOffsetHint = highlightPartOffsetHint;
|
||||||
if (_delayedShowAtRequest && _delayedShowAtMsgId == showAtMsgId) {
|
if (_delayedShowAtRequest && _delayedShowAtMsgId == showAtMsgId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4120,10 +4136,12 @@ PeerData *HistoryWidget::peer() const {
|
||||||
// Sometimes _showAtMsgId is set directly.
|
// Sometimes _showAtMsgId is set directly.
|
||||||
void HistoryWidget::setMsgId(
|
void HistoryWidget::setMsgId(
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart) {
|
const TextWithEntities &highlightPart,
|
||||||
|
int highlightPartOffsetHint) {
|
||||||
if (_showAtMsgHighlightPart != highlightPart) {
|
if (_showAtMsgHighlightPart != highlightPart) {
|
||||||
_showAtMsgHighlightPart = highlightPart;
|
_showAtMsgHighlightPart = highlightPart;
|
||||||
}
|
}
|
||||||
|
_showAtMsgHighlightPartOffsetHint = highlightPartOffsetHint;
|
||||||
if (_showAtMsgId != showAtMsgId) {
|
if (_showAtMsgId != showAtMsgId) {
|
||||||
_showAtMsgId = showAtMsgId;
|
_showAtMsgId = showAtMsgId;
|
||||||
if (_history) {
|
if (_history) {
|
||||||
|
@ -4244,11 +4262,11 @@ void HistoryWidget::cornerButtonsShowAtPosition(
|
||||||
).arg(_history->peer->name()
|
).arg(_history->peer->name()
|
||||||
).arg(_history->inboxReadTillId().bare
|
).arg(_history->inboxReadTillId().bare
|
||||||
).arg(Logs::b(_history->loadedAtBottom())));
|
).arg(Logs::b(_history->loadedAtBottom())));
|
||||||
showHistory(_peer->id, ShowAtUnreadMsgId, {});
|
showHistory(_peer->id, ShowAtUnreadMsgId);
|
||||||
} else if (_peer && position.fullId.peer == _peer->id) {
|
} else if (_peer && position.fullId.peer == _peer->id) {
|
||||||
showHistory(_peer->id, position.fullId.msg, {});
|
showHistory(_peer->id, position.fullId.msg);
|
||||||
} else if (_migrated && position.fullId.peer == _migrated->peer->id) {
|
} else if (_migrated && position.fullId.peer == _migrated->peer->id) {
|
||||||
showHistory(_peer->id, -position.fullId.msg, {});
|
showHistory(_peer->id, -position.fullId.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5700,9 +5718,11 @@ int HistoryWidget::countInitialScrollTop() {
|
||||||
const auto view = item->mainView();
|
const auto view = item->mainView();
|
||||||
Assert(view != nullptr);
|
Assert(view != nullptr);
|
||||||
|
|
||||||
enqueueMessageHighlight(
|
enqueueMessageHighlight({
|
||||||
view,
|
item,
|
||||||
base::take(_showAtMsgHighlightPart));
|
base::take(_showAtMsgHighlightPart),
|
||||||
|
base::take(_showAtMsgHighlightPartOffsetHint),
|
||||||
|
});
|
||||||
const auto result = itemTopForHighlight(view);
|
const auto result = itemTopForHighlight(view);
|
||||||
createUnreadBarIfBelowVisibleArea(result);
|
createUnreadBarIfBelowVisibleArea(result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -6386,8 +6406,7 @@ void HistoryWidget::handlePeerMigration() {
|
||||||
if (_peer != channel) {
|
if (_peer != channel) {
|
||||||
showHistory(
|
showHistory(
|
||||||
channel->id,
|
channel->id,
|
||||||
(_showAtMsgId > 0) ? (-_showAtMsgId) : _showAtMsgId,
|
(_showAtMsgId > 0) ? (-_showAtMsgId) : _showAtMsgId);
|
||||||
{});
|
|
||||||
channel->session().api().chatParticipants().requestCountDelayed(
|
channel->session().api().chatParticipants().requestCountDelayed(
|
||||||
channel);
|
channel);
|
||||||
} else {
|
} else {
|
||||||
|
@ -6483,7 +6502,7 @@ bool HistoryWidget::showSlowmodeError() {
|
||||||
if (const auto item = _history->latestSendingMessage()) {
|
if (const auto item = _history->latestSendingMessage()) {
|
||||||
if (const auto view = item->mainView()) {
|
if (const auto view = item->mainView()) {
|
||||||
animatedScrollToItem(item->id);
|
animatedScrollToItem(item->id);
|
||||||
enqueueMessageHighlight(view, {});
|
enqueueMessageHighlight({ item });
|
||||||
}
|
}
|
||||||
return tr::lng_slowmode_no_many(tr::now);
|
return tr::lng_slowmode_no_many(tr::now);
|
||||||
}
|
}
|
||||||
|
@ -7149,7 +7168,7 @@ void HistoryWidget::replyToMessage(
|
||||||
if (isJoinChannel()) {
|
if (isJoinChannel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_processingReplyTo = { .messageId = item->fullId(), .quote = quote};
|
_processingReplyTo = { .messageId = item->fullId(), .quote = quote };
|
||||||
_processingReplyItem = item;
|
_processingReplyItem = item;
|
||||||
processReply();
|
processReply();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ class Element;
|
||||||
class PinnedTracker;
|
class PinnedTracker;
|
||||||
class TranslateBar;
|
class TranslateBar;
|
||||||
class ComposeSearch;
|
class ComposeSearch;
|
||||||
|
struct SelectedQuote;
|
||||||
} // namespace HistoryView
|
} // namespace HistoryView
|
||||||
|
|
||||||
namespace HistoryView::Controls {
|
namespace HistoryView::Controls {
|
||||||
|
@ -149,7 +150,8 @@ public:
|
||||||
void firstLoadMessages();
|
void firstLoadMessages();
|
||||||
void delayedShowAt(
|
void delayedShowAt(
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart);
|
const TextWithEntities &highlightPart,
|
||||||
|
int highlightPartOffsetHint);
|
||||||
|
|
||||||
bool updateReplaceMediaButton();
|
bool updateReplaceMediaButton();
|
||||||
void updateFieldPlaceholder();
|
void updateFieldPlaceholder();
|
||||||
|
@ -165,7 +167,8 @@ public:
|
||||||
PeerData *peer() const;
|
PeerData *peer() const;
|
||||||
void setMsgId(
|
void setMsgId(
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart = {});
|
const TextWithEntities &highlightPart = {},
|
||||||
|
int highlightPartOffsetHint = 0);
|
||||||
MsgId msgId() const;
|
MsgId msgId() const;
|
||||||
|
|
||||||
bool hasTopBarShadow() const {
|
bool hasTopBarShadow() const {
|
||||||
|
@ -182,9 +185,7 @@ public:
|
||||||
|
|
||||||
bool touchScroll(const QPoint &delta);
|
bool touchScroll(const QPoint &delta);
|
||||||
|
|
||||||
void enqueueMessageHighlight(
|
void enqueueMessageHighlight(const HistoryView::SelectedQuote "e);
|
||||||
not_null<HistoryView::Element*> view,
|
|
||||||
const TextWithEntities &part);
|
|
||||||
[[nodiscard]] Ui::ChatPaintHighlight itemHighlight(
|
[[nodiscard]] Ui::ChatPaintHighlight itemHighlight(
|
||||||
not_null<const HistoryItem*> item) const;
|
not_null<const HistoryItem*> item) const;
|
||||||
|
|
||||||
|
@ -228,7 +229,8 @@ public:
|
||||||
void showHistory(
|
void showHistory(
|
||||||
const PeerId &peer,
|
const PeerId &peer,
|
||||||
MsgId showAtMsgId,
|
MsgId showAtMsgId,
|
||||||
const TextWithEntities &highlightPart);
|
const TextWithEntities &highlightPart = {},
|
||||||
|
int highlightPartOffsetHint = 0);
|
||||||
void setChooseReportMessagesDetails(
|
void setChooseReportMessagesDetails(
|
||||||
Ui::ReportReason reason,
|
Ui::ReportReason reason,
|
||||||
Fn<void(MessageIdsList)> callback);
|
Fn<void(MessageIdsList)> callback);
|
||||||
|
@ -693,6 +695,7 @@ private:
|
||||||
bool _canSendTexts = false;
|
bool _canSendTexts = false;
|
||||||
MsgId _showAtMsgId = ShowAtUnreadMsgId;
|
MsgId _showAtMsgId = ShowAtUnreadMsgId;
|
||||||
TextWithEntities _showAtMsgHighlightPart;
|
TextWithEntities _showAtMsgHighlightPart;
|
||||||
|
int _showAtMsgHighlightPartOffsetHint = 0;
|
||||||
|
|
||||||
int _firstLoadRequest = 0; // Not real mtpRequestId.
|
int _firstLoadRequest = 0; // Not real mtpRequestId.
|
||||||
int _preloadRequest = 0; // Not real mtpRequestId.
|
int _preloadRequest = 0; // Not real mtpRequestId.
|
||||||
|
@ -700,6 +703,7 @@ private:
|
||||||
|
|
||||||
MsgId _delayedShowAtMsgId = -1;
|
MsgId _delayedShowAtMsgId = -1;
|
||||||
TextWithEntities _delayedShowAtMsgHighlightPart;
|
TextWithEntities _delayedShowAtMsgHighlightPart;
|
||||||
|
int _delayedShowAtMsgHighlightPartOffsetHint = 0;
|
||||||
int _delayedShowAtRequest = 0; // Not real mtpRequestId.
|
int _delayedShowAtRequest = 0; // Not real mtpRequestId.
|
||||||
|
|
||||||
History *_supportPreloadHistory = nullptr;
|
History *_supportPreloadHistory = nullptr;
|
||||||
|
|
|
@ -235,7 +235,7 @@ rpl::producer<SelectedQuote> PreviewWrap::showQuoteSelector(
|
||||||
|
|
||||||
initElement();
|
initElement();
|
||||||
|
|
||||||
_selection = _element->selectionFromQuote(item, quote.text);
|
_selection = _element->selectionFromQuote(quote);
|
||||||
return _selection.value(
|
return _selection.value(
|
||||||
) | rpl::map([=](TextSelection selection) {
|
) | rpl::map([=](TextSelection selection) {
|
||||||
if (const auto result = _element->selectedQuote(selection)) {
|
if (const auto result = _element->selectedQuote(selection)) {
|
||||||
|
@ -643,6 +643,7 @@ void DraftOptionsBox(
|
||||||
if (const auto current = state->quote.current()) {
|
if (const auto current = state->quote.current()) {
|
||||||
result.messageId = current.item->fullId();
|
result.messageId = current.item->fullId();
|
||||||
result.quote = current.text;
|
result.quote = current.text;
|
||||||
|
result.quoteOffset = current.offset;
|
||||||
} else {
|
} else {
|
||||||
result.quote = {};
|
result.quote = {};
|
||||||
}
|
}
|
||||||
|
|
|
@ -581,7 +581,9 @@ bool AddReplyToMessageAction(
|
||||||
const ContextMenuRequest &request,
|
const ContextMenuRequest &request,
|
||||||
not_null<ListWidget*> list) {
|
not_null<ListWidget*> list) {
|
||||||
const auto context = list->elementContext();
|
const auto context = list->elementContext();
|
||||||
const auto item = request.quoteItem ? request.quoteItem : request.item;
|
const auto item = request.quote.item
|
||||||
|
? request.quote.item
|
||||||
|
: request.item;
|
||||||
const auto topic = item ? item->topic() : nullptr;
|
const auto topic = item ? item->topic() : nullptr;
|
||||||
const auto peer = item ? item->history()->peer.get() : nullptr;
|
const auto peer = item ? item->history()->peer.get() : nullptr;
|
||||||
if (!item
|
if (!item
|
||||||
|
@ -598,7 +600,7 @@ bool AddReplyToMessageAction(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto "e = request.quote;
|
const auto "e = request.quote;
|
||||||
auto text = quote.empty()
|
auto text = quote.text.empty()
|
||||||
? tr::lng_context_reply_msg(tr::now)
|
? tr::lng_context_reply_msg(tr::now)
|
||||||
: tr::lng_context_quote_and_reply(tr::now);
|
: tr::lng_context_quote_and_reply(tr::now);
|
||||||
text.replace('&', u"&&"_q);
|
text.replace('&', u"&&"_q);
|
||||||
|
@ -607,7 +609,11 @@ bool AddReplyToMessageAction(
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
list->replyToMessageRequestNotify({ itemId, quote });
|
list->replyToMessageRequestNotify({
|
||||||
|
.messageId = itemId,
|
||||||
|
.quote = quote.text,
|
||||||
|
.quoteOffset = quote.offset,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, &st::menuIconReply);
|
}, &st::menuIconReply);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/unique_qptr.h"
|
#include "base/unique_qptr.h"
|
||||||
|
#include "history/view/history_view_element.h"
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
struct ReactionId;
|
struct ReactionId;
|
||||||
|
@ -47,8 +48,7 @@ struct ContextMenuRequest {
|
||||||
HistoryItem *item = nullptr;
|
HistoryItem *item = nullptr;
|
||||||
SelectedItems selectedItems;
|
SelectedItems selectedItems;
|
||||||
TextForMimeData selectedText;
|
TextForMimeData selectedText;
|
||||||
TextWithEntities quote;
|
SelectedQuote quote;
|
||||||
HistoryItem *quoteItem = nullptr;
|
|
||||||
bool overSelection = false;
|
bool overSelection = false;
|
||||||
PointState pointState = PointState();
|
PointState pointState = PointState();
|
||||||
};
|
};
|
||||||
|
|
|
@ -1647,29 +1647,30 @@ SelectedQuote Element::FindSelectedQuote(
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { item, result };
|
return { item, result, modified.from };
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection Element::FindSelectionFromQuote(
|
TextSelection Element::FindSelectionFromQuote(
|
||||||
const Ui::Text::String &text,
|
const Ui::Text::String &text,
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) {
|
||||||
const TextWithEntities "e) {
|
Expects(quote.item != nullptr);
|
||||||
if (quote.empty()) {
|
|
||||||
|
if (quote.text.empty()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto &original = item->originalText();
|
const auto &original = quote.item->originalText();
|
||||||
auto result = TextSelection();
|
auto result = TextSelection();
|
||||||
auto offset = 0;
|
auto offset = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
const auto i = original.text.indexOf(quote.text, offset);
|
const auto i = original.text.indexOf(quote.text.text, offset);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
auto selection = TextSelection{
|
auto selection = TextSelection{
|
||||||
uint16(i),
|
uint16(i),
|
||||||
uint16(i + quote.text.size()),
|
uint16(i + quote.text.text.size()),
|
||||||
};
|
};
|
||||||
if (CheckQuoteEntities(quote.entities, original, selection)) {
|
if (CheckQuoteEntities(quote.text.entities, original, selection)) {
|
||||||
result = selection;
|
result = selection;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -270,6 +270,7 @@ struct TopicButton {
|
||||||
struct SelectedQuote {
|
struct SelectedQuote {
|
||||||
HistoryItem *item = nullptr;
|
HistoryItem *item = nullptr;
|
||||||
TextWithEntities text;
|
TextWithEntities text;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
explicit operator bool() const {
|
explicit operator bool() const {
|
||||||
return item && !text.empty();
|
return item && !text.empty();
|
||||||
|
@ -401,8 +402,7 @@ public:
|
||||||
virtual SelectedQuote selectedQuote(
|
virtual SelectedQuote selectedQuote(
|
||||||
TextSelection selection) const = 0;
|
TextSelection selection) const = 0;
|
||||||
virtual TextSelection selectionFromQuote(
|
virtual TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const = 0;
|
||||||
const TextWithEntities "e) const = 0;
|
|
||||||
[[nodiscard]] virtual TextSelection adjustSelection(
|
[[nodiscard]] virtual TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TextSelectType type) const;
|
TextSelectType type) const;
|
||||||
|
@ -413,8 +413,7 @@ public:
|
||||||
not_null<HistoryItem*> item);
|
not_null<HistoryItem*> item);
|
||||||
[[nodiscard]] static TextSelection FindSelectionFromQuote(
|
[[nodiscard]] static TextSelection FindSelectionFromQuote(
|
||||||
const Ui::Text::String &text,
|
const Ui::Text::String &text,
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e);
|
||||||
const TextWithEntities "e);
|
|
||||||
|
|
||||||
[[nodiscard]] virtual auto reactionButtonParameters(
|
[[nodiscard]] virtual auto reactionButtonParameters(
|
||||||
QPoint position,
|
QPoint position,
|
||||||
|
|
|
@ -709,9 +709,10 @@ bool ListWidget::isBelowPosition(Data::MessagePosition position) const {
|
||||||
|
|
||||||
void ListWidget::highlightMessage(
|
void ListWidget::highlightMessage(
|
||||||
FullMsgId itemId,
|
FullMsgId itemId,
|
||||||
const TextWithEntities &part) {
|
const TextWithEntities &part,
|
||||||
|
int partOffsetHint) {
|
||||||
if (const auto view = viewForItem(itemId)) {
|
if (const auto view = viewForItem(itemId)) {
|
||||||
_highlighter.highlight(view, part);
|
_highlighter.highlight({ view->data(), part, partOffsetHint });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -787,7 +788,10 @@ bool ListWidget::showAtPositionNow(
|
||||||
computeScrollTo(*scrollTop, position, params.animated);
|
computeScrollTo(*scrollTop, position, params.animated);
|
||||||
if (position != Data::MaxMessagePosition
|
if (position != Data::MaxMessagePosition
|
||||||
&& position != Data::UnreadMessagePosition) {
|
&& position != Data::UnreadMessagePosition) {
|
||||||
highlightMessage(position.fullId, params.highlightPart);
|
highlightMessage(
|
||||||
|
position.fullId,
|
||||||
|
params.highlightPart,
|
||||||
|
params.highlightPartOffsetHint);
|
||||||
}
|
}
|
||||||
if (done) {
|
if (done) {
|
||||||
const auto found = !position.fullId.peer
|
const auto found = !position.fullId.peer
|
||||||
|
@ -2143,7 +2147,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
||||||
} else if (item->isUnreadMention()
|
} else if (item->isUnreadMention()
|
||||||
&& !item->isUnreadMedia()) {
|
&& !item->isUnreadMedia()) {
|
||||||
readContents.insert(item);
|
readContents.insert(item);
|
||||||
_highlighter.enqueue(view, {});
|
_highlighter.enqueue({ item });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session->data().reactions().poll(item, context.now);
|
session->data().reactions().poll(item, context.now);
|
||||||
|
@ -2603,12 +2607,10 @@ void ListWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
request.view = _overElement;
|
request.view = _overElement;
|
||||||
request.item = overItem;
|
request.item = overItem;
|
||||||
request.pointState = _overState.pointState;
|
request.pointState = _overState.pointState;
|
||||||
const auto quote = (_overElement
|
request.quote = (_overElement
|
||||||
&& _selectedTextItem == _overElement->data())
|
&& _selectedTextItem == _overElement->data())
|
||||||
? _overElement->selectedQuote(_selectedTextRange)
|
? _overElement->selectedQuote(_selectedTextRange)
|
||||||
: SelectedQuote();
|
: SelectedQuote();
|
||||||
request.quote = quote.text;
|
|
||||||
request.quoteItem = quote.item;
|
|
||||||
request.selectedText = _selectedText;
|
request.selectedText = _selectedText;
|
||||||
request.selectedItems = collectSelectedItems();
|
request.selectedItems = collectSelectedItems();
|
||||||
const auto hasSelection = !request.selectedItems.empty()
|
const auto hasSelection = !request.selectedItems.empty()
|
||||||
|
|
|
@ -233,7 +233,8 @@ public:
|
||||||
bool isBelowPosition(Data::MessagePosition position) const;
|
bool isBelowPosition(Data::MessagePosition position) const;
|
||||||
void highlightMessage(
|
void highlightMessage(
|
||||||
FullMsgId itemId,
|
FullMsgId itemId,
|
||||||
const TextWithEntities &part);
|
const TextWithEntities &part,
|
||||||
|
int partOffsetHint);
|
||||||
|
|
||||||
void showAtPosition(
|
void showAtPosition(
|
||||||
Data::MessagePosition position,
|
Data::MessagePosition position,
|
||||||
|
|
|
@ -2684,11 +2684,13 @@ SelectedQuote Message::selectedQuote(TextSelection selection) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection Message::selectionFromQuote(
|
TextSelection Message::selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const {
|
||||||
const TextWithEntities "e) const {
|
Expects(quote.item != nullptr);
|
||||||
if (quote.empty()) {
|
|
||||||
|
if (quote.text.empty()) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
const auto item = quote.item;
|
||||||
const auto &translated = item->translatedText();
|
const auto &translated = item->translatedText();
|
||||||
const auto &original = item->originalText();
|
const auto &original = item->originalText();
|
||||||
if (&translated != &original) {
|
if (&translated != &original) {
|
||||||
|
@ -2697,11 +2699,11 @@ TextSelection Message::selectionFromQuote(
|
||||||
const auto media = this->media();
|
const auto media = this->media();
|
||||||
const auto mediaDisplayed = media && media->isDisplayed();
|
const auto mediaDisplayed = media && media->isDisplayed();
|
||||||
const auto mediaBefore = mediaDisplayed && invertMedia();
|
const auto mediaBefore = mediaDisplayed && invertMedia();
|
||||||
const auto result = FindSelectionFromQuote(text(), item, quote);
|
const auto result = FindSelectionFromQuote(text(), quote);
|
||||||
return mediaBefore ? media->unskipSelection(result) : result;
|
return mediaBefore ? media->unskipSelection(result) : result;
|
||||||
} else if (const auto media = this->media()) {
|
} else if (const auto media = this->media()) {
|
||||||
if (media->isDisplayed() || isHiddenByGroup()) {
|
if (media->isDisplayed() || isHiddenByGroup()) {
|
||||||
return media->selectionFromQuote(item, quote);
|
return media->selectionFromQuote(quote);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -97,8 +97,7 @@ public:
|
||||||
TextForMimeData selectedText(TextSelection selection) const override;
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
SelectedQuote selectedQuote(TextSelection selection) const override;
|
SelectedQuote selectedQuote(TextSelection selection) const override;
|
||||||
TextSelection selectionFromQuote(
|
TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const override;
|
||||||
const TextWithEntities "e) const override;
|
|
||||||
TextSelection adjustSelection(
|
TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TextSelectType type) const override;
|
TextSelectType type) const override;
|
||||||
|
|
|
@ -130,11 +130,13 @@ RepliesMemento::RepliesMemento(
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
MsgId rootId,
|
MsgId rootId,
|
||||||
MsgId highlightId,
|
MsgId highlightId,
|
||||||
const TextWithEntities &highlightPart)
|
const TextWithEntities &highlightPart,
|
||||||
|
int highlightPartOffsetHint)
|
||||||
: _history(history)
|
: _history(history)
|
||||||
, _rootId(rootId)
|
, _rootId(rootId)
|
||||||
, _highlightId(highlightId)
|
, _highlightPart(highlightPart)
|
||||||
, _highlightPart(highlightPart) {
|
, _highlightPartOffsetHint(highlightPartOffsetHint)
|
||||||
|
, _highlightId(highlightId) {
|
||||||
if (highlightId) {
|
if (highlightId) {
|
||||||
_list.setAroundPosition({
|
_list.setAroundPosition({
|
||||||
.fullId = FullMsgId(_history->peer->id, highlightId),
|
.fullId = FullMsgId(_history->peer->id, highlightId),
|
||||||
|
@ -2149,6 +2151,7 @@ void RepliesWidget::restoreState(not_null<RepliesMemento*> memento) {
|
||||||
Window::SectionShow::Way::Forward,
|
Window::SectionShow::Way::Forward,
|
||||||
anim::type::instant);
|
anim::type::instant);
|
||||||
params.highlightPart = memento->highlightPart();
|
params.highlightPart = memento->highlightPart();
|
||||||
|
params.highlightPartOffsetHint = memento->highlightPartOffsetHint();
|
||||||
showAtPosition(Data::MessagePosition{
|
showAtPosition(Data::MessagePosition{
|
||||||
.fullId = FullMsgId(_history->peer->id, highlight),
|
.fullId = FullMsgId(_history->peer->id, highlight),
|
||||||
.date = TimeId(0),
|
.date = TimeId(0),
|
||||||
|
|
|
@ -381,7 +381,8 @@ public:
|
||||||
not_null<History*> history,
|
not_null<History*> history,
|
||||||
MsgId rootId,
|
MsgId rootId,
|
||||||
MsgId highlightId = 0,
|
MsgId highlightId = 0,
|
||||||
const TextWithEntities &highlightPart = {});
|
const TextWithEntities &highlightPart = {},
|
||||||
|
int highlightPartOffsetHint = 0);
|
||||||
explicit RepliesMemento(
|
explicit RepliesMemento(
|
||||||
not_null<HistoryItem*> commentsItem,
|
not_null<HistoryItem*> commentsItem,
|
||||||
MsgId commentId = 0);
|
MsgId commentId = 0);
|
||||||
|
@ -431,14 +432,18 @@ public:
|
||||||
[[nodiscard]] const TextWithEntities &highlightPart() const {
|
[[nodiscard]] const TextWithEntities &highlightPart() const {
|
||||||
return _highlightPart;
|
return _highlightPart;
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] int highlightPartOffsetHint() const {
|
||||||
|
return _highlightPartOffsetHint;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setupTopicViewer();
|
void setupTopicViewer();
|
||||||
|
|
||||||
const not_null<History*> _history;
|
const not_null<History*> _history;
|
||||||
MsgId _rootId = 0;
|
MsgId _rootId = 0;
|
||||||
const MsgId _highlightId = 0;
|
|
||||||
const TextWithEntities _highlightPart;
|
const TextWithEntities _highlightPart;
|
||||||
|
const int _highlightPartOffsetHint = 0;
|
||||||
|
const MsgId _highlightId = 0;
|
||||||
ListMemento _list;
|
ListMemento _list;
|
||||||
std::shared_ptr<Data::RepliesList> _replies;
|
std::shared_ptr<Data::RepliesList> _replies;
|
||||||
QVector<FullMsgId> _replyReturns;
|
QVector<FullMsgId> _replyReturns;
|
||||||
|
|
|
@ -674,8 +674,7 @@ SelectedQuote Service::selectedQuote(TextSelection selection) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection Service::selectionFromQuote(
|
TextSelection Service::selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const {
|
||||||
const TextWithEntities "e) const {
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,7 @@ public:
|
||||||
TextForMimeData selectedText(TextSelection selection) const override;
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
SelectedQuote selectedQuote(TextSelection selection) const override;
|
SelectedQuote selectedQuote(TextSelection selection) const override;
|
||||||
TextSelection selectionFromQuote(
|
TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const override;
|
||||||
const TextWithEntities "e) const override;
|
|
||||||
TextSelection adjustSelection(
|
TextSelection adjustSelection(
|
||||||
TextSelection selection,
|
TextSelection selection,
|
||||||
TextSelectType type) const override;
|
TextSelectType type) const override;
|
||||||
|
|
|
@ -1232,12 +1232,10 @@ SelectedQuote Document::selectedQuote(TextSelection selection) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection Document::selectionFromQuote(
|
TextSelection Document::selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const {
|
||||||
const TextWithEntities "e) const {
|
|
||||||
if (const auto captioned = Get<HistoryDocumentCaptioned>()) {
|
if (const auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
const auto result = Element::FindSelectionFromQuote(
|
const auto result = Element::FindSelectionFromQuote(
|
||||||
captioned->caption,
|
captioned->caption,
|
||||||
item,
|
|
||||||
quote);
|
quote);
|
||||||
if (result.empty()) {
|
if (result.empty()) {
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -48,8 +48,7 @@ public:
|
||||||
TextForMimeData selectedText(TextSelection selection) const override;
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
SelectedQuote selectedQuote(TextSelection selection) const override;
|
SelectedQuote selectedQuote(TextSelection selection) const override;
|
||||||
TextSelection selectionFromQuote(
|
TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const override;
|
||||||
const TextWithEntities "e) const override;
|
|
||||||
|
|
||||||
bool uploading() const override;
|
bool uploading() const override;
|
||||||
|
|
||||||
|
|
|
@ -1205,10 +1205,8 @@ SelectedQuote Gif::selectedQuote(TextSelection selection) const {
|
||||||
return Element::FindSelectedQuote(_caption, selection, _realParent);
|
return Element::FindSelectedQuote(_caption, selection, _realParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection Gif::selectionFromQuote(
|
TextSelection Gif::selectionFromQuote(const SelectedQuote "e) const {
|
||||||
not_null<HistoryItem*> item,
|
return Element::FindSelectionFromQuote(_caption, quote);
|
||||||
const TextWithEntities "e) const {
|
|
||||||
return Element::FindSelectionFromQuote(_caption, item, quote);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gif::fullFeaturedGrouped(RectParts sides) const {
|
bool Gif::fullFeaturedGrouped(RectParts sides) const {
|
||||||
|
|
|
@ -71,8 +71,7 @@ public:
|
||||||
TextForMimeData selectedText(TextSelection selection) const override;
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
SelectedQuote selectedQuote(TextSelection selection) const override;
|
SelectedQuote selectedQuote(TextSelection selection) const override;
|
||||||
TextSelection selectionFromQuote(
|
TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const override;
|
||||||
const TextWithEntities "e) const override;
|
|
||||||
|
|
||||||
bool uploading() const override;
|
bool uploading() const override;
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,7 @@ public:
|
||||||
[[nodiscard]] virtual SelectedQuote selectedQuote(
|
[[nodiscard]] virtual SelectedQuote selectedQuote(
|
||||||
TextSelection selection) const;
|
TextSelection selection) const;
|
||||||
[[nodiscard]] virtual TextSelection selectionFromQuote(
|
[[nodiscard]] virtual TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const {
|
||||||
const TextWithEntities "e) const {
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -622,19 +622,20 @@ SelectedQuote GroupedMedia::selectedQuote(TextSelection selection) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection GroupedMedia::selectionFromQuote(
|
TextSelection GroupedMedia::selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const {
|
||||||
const TextWithEntities "e) const {
|
Expects(quote.item != nullptr);
|
||||||
|
|
||||||
if (_mode != Mode::Column) {
|
if (_mode != Mode::Column) {
|
||||||
return (_captionItem == item)
|
return (_captionItem == quote.item)
|
||||||
? Element::FindSelectionFromQuote(_caption, item, quote)
|
? Element::FindSelectionFromQuote(_caption, quote)
|
||||||
: TextSelection();
|
: TextSelection();
|
||||||
}
|
}
|
||||||
const auto i = ranges::find(_parts, item, &Part::item);
|
const auto i = ranges::find(_parts, not_null(quote.item), &Part::item);
|
||||||
if (i == end(_parts)) {
|
if (i == end(_parts)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
const auto index = int(i - begin(_parts));
|
const auto index = int(i - begin(_parts));
|
||||||
auto result = i->content->selectionFromQuote(item, quote);
|
auto result = i->content->selectionFromQuote(quote);
|
||||||
if (result.empty()) {
|
if (result.empty()) {
|
||||||
return AddGroupItemSelection({}, index);
|
return AddGroupItemSelection({}, index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,7 @@ public:
|
||||||
TextForMimeData selectedText(TextSelection selection) const override;
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
SelectedQuote selectedQuote(TextSelection selection) const override;
|
SelectedQuote selectedQuote(TextSelection selection) const override;
|
||||||
TextSelection selectionFromQuote(
|
TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const override;
|
||||||
const TextWithEntities "e) const override;
|
|
||||||
|
|
||||||
std::vector<Ui::BubbleSelectionInterval> getBubbleSelectionIntervals(
|
std::vector<Ui::BubbleSelectionInterval> getBubbleSelectionIntervals(
|
||||||
TextSelection selection) const override;
|
TextSelection selection) const override;
|
||||||
|
|
|
@ -1098,10 +1098,8 @@ SelectedQuote Photo::selectedQuote(TextSelection selection) const {
|
||||||
return Element::FindSelectedQuote(_caption, selection, _realParent);
|
return Element::FindSelectedQuote(_caption, selection, _realParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextSelection Photo::selectionFromQuote(
|
TextSelection Photo::selectionFromQuote(const SelectedQuote "e) const {
|
||||||
not_null<HistoryItem*> item,
|
return Element::FindSelectionFromQuote(_caption, quote);
|
||||||
const TextWithEntities "e) const {
|
|
||||||
return Element::FindSelectionFromQuote(_caption, item, quote);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Photo::hideSpoilers() {
|
void Photo::hideSpoilers() {
|
||||||
|
|
|
@ -59,8 +59,7 @@ public:
|
||||||
TextForMimeData selectedText(TextSelection selection) const override;
|
TextForMimeData selectedText(TextSelection selection) const override;
|
||||||
SelectedQuote selectedQuote(TextSelection selection) const override;
|
SelectedQuote selectedQuote(TextSelection selection) const override;
|
||||||
TextSelection selectionFromQuote(
|
TextSelection selectionFromQuote(
|
||||||
not_null<HistoryItem*> item,
|
const SelectedQuote "e) const override;
|
||||||
const TextWithEntities "e) const override;
|
|
||||||
|
|
||||||
PhotoData *getPhoto() const override {
|
PhotoData *getPhoto() const override {
|
||||||
return _data;
|
return _data;
|
||||||
|
|
|
@ -1411,7 +1411,11 @@ void MainWidget::showHistory(
|
||||||
&& way != Way::Forward) {
|
&& way != Way::Forward) {
|
||||||
clearBotStartToken(_history->peer());
|
clearBotStartToken(_history->peer());
|
||||||
}
|
}
|
||||||
_history->showHistory(peerId, showAtMsgId, params.highlightPart);
|
_history->showHistory(
|
||||||
|
peerId,
|
||||||
|
showAtMsgId,
|
||||||
|
params.highlightPart,
|
||||||
|
params.highlightPartOffsetHint);
|
||||||
if (alreadyThatPeer && params.reapplyLocalDraft) {
|
if (alreadyThatPeer && params.reapplyLocalDraft) {
|
||||||
_history->applyDraft(HistoryWidget::FieldHistoryAction::NewEntry);
|
_history->applyDraft(HistoryWidget::FieldHistoryAction::NewEntry);
|
||||||
}
|
}
|
||||||
|
@ -1772,7 +1776,7 @@ void MainWidget::showNewSection(
|
||||||
} else {
|
} else {
|
||||||
_mainSection = std::move(newMainSection);
|
_mainSection = std::move(newMainSection);
|
||||||
_history->finishAnimating();
|
_history->finishAnimating();
|
||||||
_history->showHistory(0, 0, {});
|
_history->showHistory(PeerId(), MsgId());
|
||||||
|
|
||||||
if (const auto entry = _mainSection->activeChat(); entry.key) {
|
if (const auto entry = _mainSection->activeChat(); entry.key) {
|
||||||
_controller->setActiveChatEntry(entry);
|
_controller->setActiveChatEntry(entry);
|
||||||
|
|
|
@ -101,7 +101,7 @@ channel#1981ea7e flags:# creator:flags.0?true left:flags.2?true broadcast:flags.
|
||||||
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
channelForbidden#17d493d5 flags:# broadcast:flags.5?true megagroup:flags.8?true id:long access_hash:long title:string until_date:flags.16?int = Chat;
|
||||||
|
|
||||||
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
chatFull#c9d31138 flags:# can_set_username:flags.7?true has_scheduled:flags.8?true translations_disabled:flags.19?true id:long about:string participants:ChatParticipants chat_photo:flags.2?Photo notify_settings:PeerNotifySettings exported_invite:flags.13?ExportedChatInvite bot_info:flags.3?Vector<BotInfo> pinned_msg_id:flags.6?int folder_id:flags.11?int call:flags.12?InputGroupCall ttl_period:flags.14?int groupcall_default_join_as:flags.15?Peer theme_emoticon:flags.16?string requests_pending:flags.17?int recent_requesters:flags.17?Vector<long> available_reactions:flags.18?ChatReactions = ChatFull;
|
||||||
channelFull#723027bd flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories = ChatFull;
|
channelFull#723027bd flags:# can_view_participants:flags.3?true can_set_username:flags.6?true can_set_stickers:flags.7?true hidden_prehistory:flags.10?true can_set_location:flags.16?true has_scheduled:flags.19?true can_view_stats:flags.20?true blocked:flags.22?true flags2:# can_delete_channel:flags2.0?true antispam:flags2.1?true participants_hidden:flags2.2?true translations_disabled:flags2.3?true stories_pinned_available:flags2.5?true view_forum_as_messages:flags2.6?true id:long about:string participants_count:flags.0?int admins_count:flags.1?int kicked_count:flags.2?int banned_count:flags.2?int online_count:flags.13?int read_inbox_max_id:int read_outbox_max_id:int unread_count:int chat_photo:Photo notify_settings:PeerNotifySettings exported_invite:flags.23?ExportedChatInvite bot_info:Vector<BotInfo> migrated_from_chat_id:flags.4?long migrated_from_max_id:flags.4?int pinned_msg_id:flags.5?int stickerset:flags.8?StickerSet available_min_id:flags.9?int folder_id:flags.11?int linked_chat_id:flags.14?long location:flags.15?ChannelLocation slowmode_seconds:flags.17?int slowmode_next_send_date:flags.18?int stats_dc:flags.12?int pts:int call:flags.21?InputGroupCall ttl_period:flags.24?int pending_suggestions:flags.25?Vector<string> groupcall_default_join_as:flags.26?Peer theme_emoticon:flags.27?string requests_pending:flags.28?int recent_requesters:flags.28?Vector<long> default_send_as:flags.29?Peer available_reactions:flags.30?ChatReactions stories:flags2.4?PeerStories = ChatFull;
|
||||||
|
|
||||||
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
|
||||||
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
|
||||||
|
@ -170,12 +170,12 @@ messageActionTopicCreate#d999256 flags:# title:string icon_color:int icon_emoji_
|
||||||
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
|
messageActionTopicEdit#c0944820 flags:# title:flags.0?string icon_emoji_id:flags.1?long closed:flags.2?Bool hidden:flags.3?Bool = MessageAction;
|
||||||
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
|
messageActionSuggestProfilePhoto#57de635e photo:Photo = MessageAction;
|
||||||
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction;
|
messageActionRequestedPeer#fe77345d button_id:int peer:Peer = MessageAction;
|
||||||
messageActionSetChatWallPaper#bc44a927 wallpaper:WallPaper = MessageAction;
|
messageActionSetChatWallPaper#5060a3f4 flags:# same:flags.0?true for_both:flags.1?true wallpaper:WallPaper = MessageAction;
|
||||||
messageActionSetSameChatWallPaper#c0787d6d wallpaper:WallPaper = MessageAction;
|
|
||||||
messageActionGiftCode#d2cfdb0e flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string = MessageAction;
|
messageActionGiftCode#d2cfdb0e flags:# via_giveaway:flags.0?true unclaimed:flags.2?true boost_peer:flags.1?Peer months:int slug:string = MessageAction;
|
||||||
messageActionGiveawayLaunch#332ba9ed = MessageAction;
|
messageActionGiveawayLaunch#332ba9ed = MessageAction;
|
||||||
|
messageActionGiveawayResults#2a9fadc5 winners_count:int unclaimed_count:int = MessageAction;
|
||||||
|
|
||||||
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
dialog#d58a08c6 flags:# pinned:flags.2?true unread_mark:flags.3?true view_forum_as_messages:flags.6?true peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int unread_mentions_count:int unread_reactions_count:int notify_settings:PeerNotifySettings pts:flags.0?int draft:flags.1?DraftMessage folder_id:flags.4?int ttl_period:flags.5?int = Dialog;
|
||||||
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
dialogFolder#71bd134c flags:# pinned:flags.2?true folder:Folder peer:Peer top_message:int unread_muted_peers_count:int unread_unmuted_peers_count:int unread_muted_messages_count:int unread_unmuted_messages_count:int = Dialog;
|
||||||
|
|
||||||
photoEmpty#2331b22d id:long = Photo;
|
photoEmpty#2331b22d id:long = Photo;
|
||||||
|
@ -392,6 +392,9 @@ updateReadStories#f74e932b peer:Peer max_id:int = Update;
|
||||||
updateStoryID#1bf335b9 id:int random_id:long = Update;
|
updateStoryID#1bf335b9 id:int random_id:long = Update;
|
||||||
updateStoriesStealthMode#2c084dc1 stealth_mode:StoriesStealthMode = Update;
|
updateStoriesStealthMode#2c084dc1 stealth_mode:StoriesStealthMode = Update;
|
||||||
updateSentStoryReaction#7d627683 peer:Peer story_id:int reaction:Reaction = Update;
|
updateSentStoryReaction#7d627683 peer:Peer story_id:int reaction:Reaction = Update;
|
||||||
|
updateBotChatBoost#904dd49c peer:Peer boost:Boost qts:int = Update;
|
||||||
|
updateChannelViewForumAsMessages#7b68920 channel_id:long enabled:Bool = Update;
|
||||||
|
updatePeerWallpaper#ae3f101d flags:# peer:Peer wallpaper:flags.0?WallPaper = Update;
|
||||||
|
|
||||||
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
|
||||||
|
|
||||||
|
@ -1232,7 +1235,7 @@ statsGraph#8ea464b6 flags:# json:DataJSON zoom_token:flags.0?string = StatsGraph
|
||||||
|
|
||||||
messageInteractionCounters#ad4fc9bd msg_id:int views:int forwards:int = MessageInteractionCounters;
|
messageInteractionCounters#ad4fc9bd msg_id:int views:int forwards:int = MessageInteractionCounters;
|
||||||
|
|
||||||
stats.broadcastStats#bdf78394 period:StatsDateRangeDays followers:StatsAbsValueAndPrev views_per_post:StatsAbsValueAndPrev shares_per_post:StatsAbsValueAndPrev enabled_notifications:StatsPercentValue growth_graph:StatsGraph followers_graph:StatsGraph mute_graph:StatsGraph top_hours_graph:StatsGraph interactions_graph:StatsGraph iv_interactions_graph:StatsGraph views_by_source_graph:StatsGraph new_followers_by_source_graph:StatsGraph languages_graph:StatsGraph recent_message_interactions:Vector<MessageInteractionCounters> = stats.BroadcastStats;
|
stats.broadcastStats#cb303962 period:StatsDateRangeDays followers:StatsAbsValueAndPrev views_per_post:StatsAbsValueAndPrev shares_per_post:StatsAbsValueAndPrev enabled_notifications:StatsPercentValue growth_graph:StatsGraph followers_graph:StatsGraph mute_graph:StatsGraph top_hours_graph:StatsGraph interactions_graph:StatsGraph iv_interactions_graph:StatsGraph views_by_source_graph:StatsGraph new_followers_by_source_graph:StatsGraph languages_graph:StatsGraph reactions_by_emotion_graph:StatsGraph story_interactions_graph:StatsGraph story_reactions_by_emotion_graph:StatsGraph recent_message_interactions:Vector<MessageInteractionCounters> = stats.BroadcastStats;
|
||||||
|
|
||||||
help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
|
help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
|
||||||
help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
|
help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
|
||||||
|
@ -1264,14 +1267,14 @@ messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> use
|
||||||
|
|
||||||
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
messages.discussionMessage#a6341782 flags:# messages:Vector<Message> max_id:flags.0?int read_inbox_max_id:flags.1?int read_outbox_max_id:flags.2?int unread_count:int chats:Vector<Chat> users:Vector<User> = messages.DiscussionMessage;
|
||||||
|
|
||||||
messageReplyHeader#6eebcabd flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector<MessageEntity> = MessageReplyHeader;
|
messageReplyHeader#afbc09db flags:# reply_to_scheduled:flags.2?true forum_topic:flags.3?true quote:flags.9?true reply_to_msg_id:flags.4?int reply_to_peer_id:flags.0?Peer reply_from:flags.5?MessageFwdHeader reply_media:flags.8?MessageMedia reply_to_top_id:flags.1?int quote_text:flags.6?string quote_entities:flags.7?Vector<MessageEntity> quote_offset:flags.10?int = MessageReplyHeader;
|
||||||
messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader;
|
messageReplyStoryHeader#9c98bfc1 user_id:long story_id:int = MessageReplyHeader;
|
||||||
|
|
||||||
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
messageReplies#83d60fc2 flags:# comments:flags.0?true replies:int replies_pts:int recent_repliers:flags.1?Vector<Peer> channel_id:flags.0?long max_id:flags.2?int read_max_id:flags.3?int = MessageReplies;
|
||||||
|
|
||||||
peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
|
peerBlocked#e8fd8014 peer_id:Peer date:int = PeerBlocked;
|
||||||
|
|
||||||
stats.messageStats#8999f295 views_graph:StatsGraph = stats.MessageStats;
|
stats.messageStats#7fe91c14 views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.MessageStats;
|
||||||
|
|
||||||
groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall;
|
groupCallDiscarded#7780bcb4 id:long access_hash:long duration:int = GroupCall;
|
||||||
groupCall#d597650c flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int = GroupCall;
|
groupCall#d597650c flags:# join_muted:flags.1?true can_change_join_muted:flags.2?true join_date_asc:flags.6?true schedule_start_subscribed:flags.8?true can_start_video:flags.9?true record_video_active:flags.11?true rtmp_stream:flags.12?true listeners_hidden:flags.13?true id:long access_hash:long participants_count:int title:flags.3?string stream_dc_id:flags.4?int record_start_date:flags.5?int schedule_date:flags.7?int unmuted_video_count:flags.10?int unmuted_video_limit:int version:int = GroupCall;
|
||||||
|
@ -1334,7 +1337,7 @@ account.resetPasswordFailedWait#e3779861 retry_date:int = account.ResetPasswordR
|
||||||
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
|
account.resetPasswordRequestedWait#e9effc7d until_date:int = account.ResetPasswordResult;
|
||||||
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
|
account.resetPasswordOk#e926d63e = account.ResetPasswordResult;
|
||||||
|
|
||||||
sponsoredMessage#daafff6b flags:# recommended:flags.5?true show_peer_photo:flags.6?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string webpage:flags.9?SponsoredWebPage message:string entities:flags.1?Vector<MessageEntity> sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage;
|
sponsoredMessage#ed5383f7 flags:# recommended:flags.5?true show_peer_photo:flags.6?true random_id:bytes from_id:flags.3?Peer chat_invite:flags.4?ChatInvite chat_invite_hash:flags.4?string channel_post:flags.2?int start_param:flags.0?string webpage:flags.9?SponsoredWebPage app:flags.10?BotApp message:string entities:flags.1?Vector<MessageEntity> button_text:flags.11?string sponsor_info:flags.7?string additional_info:flags.8?string = SponsoredMessage;
|
||||||
|
|
||||||
messages.sponsoredMessages#c9ee1d87 flags:# posts_between:flags.0?int messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
|
messages.sponsoredMessages#c9ee1d87 flags:# posts_between:flags.0?int messages:Vector<SponsoredMessage> chats:Vector<Chat> users:Vector<User> = messages.SponsoredMessages;
|
||||||
messages.sponsoredMessagesEmpty#1839490f = messages.SponsoredMessages;
|
messages.sponsoredMessagesEmpty#1839490f = messages.SponsoredMessages;
|
||||||
|
@ -1544,7 +1547,7 @@ storyViews#8d595cd6 flags:# has_viewers:flags.1?true views_count:int forwards_co
|
||||||
|
|
||||||
storyItemDeleted#51e6ee4f id:int = StoryItem;
|
storyItemDeleted#51e6ee4f id:int = StoryItem;
|
||||||
storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem;
|
storyItemSkipped#ffadc913 flags:# close_friends:flags.8?true id:int date:int expire_date:int = StoryItem;
|
||||||
storyItem#44c457ce flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
|
storyItem#af6365a1 flags:# pinned:flags.5?true public:flags.7?true close_friends:flags.8?true min:flags.9?true noforwards:flags.10?true edited:flags.11?true contacts:flags.12?true selected_contacts:flags.13?true out:flags.16?true id:int date:int fwd_from:flags.17?StoryFwdHeader expire_date:int caption:flags.0?string entities:flags.1?Vector<MessageEntity> media:MessageMedia media_areas:flags.14?Vector<MediaArea> privacy:flags.2?Vector<PrivacyRule> views:flags.3?StoryViews sent_reaction:flags.15?Reaction = StoryItem;
|
||||||
|
|
||||||
stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:StoriesStealthMode = stories.AllStories;
|
stories.allStoriesNotModified#1158fe3e flags:# state:string stealth_mode:StoriesStealthMode = stories.AllStories;
|
||||||
stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector<PeerStories> chats:Vector<Chat> users:Vector<User> stealth_mode:StoriesStealthMode = stories.AllStories;
|
stories.allStories#6efc5e81 flags:# has_more:flags.0?true count:int state:string peer_stories:Vector<PeerStories> chats:Vector<Chat> users:Vector<User> stealth_mode:StoriesStealthMode = stories.AllStories;
|
||||||
|
@ -1557,7 +1560,7 @@ stories.storyViewsList#46e9b9ec flags:# count:int reactions_count:int views:Vect
|
||||||
|
|
||||||
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
stories.storyViews#de9eed1d views:Vector<StoryViews> users:Vector<User> = stories.StoryViews;
|
||||||
|
|
||||||
inputReplyToMessage#73ec805 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> = InputReplyTo;
|
inputReplyToMessage#22c0f6d5 flags:# reply_to_msg_id:int top_msg_id:flags.0?int reply_to_peer_id:flags.1?InputPeer quote_text:flags.2?string quote_entities:flags.3?Vector<MessageEntity> quote_offset:flags.4?int = InputReplyTo;
|
||||||
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
|
inputReplyToStory#15b0f283 user_id:InputUser story_id:int = InputReplyTo;
|
||||||
|
|
||||||
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
exportedStoryLink#3fc9053b link:string = ExportedStoryLink;
|
||||||
|
@ -1596,6 +1599,10 @@ premium.myBoosts#9ae228e2 my_boosts:Vector<MyBoost> chats:Vector<Chat> users:Vec
|
||||||
|
|
||||||
premium.boostsStatus#4959427a flags:# my_boost:flags.2?true level:int current_level_boosts:int boosts:int gift_boosts:flags.4?int next_level_boosts:flags.0?int premium_audience:flags.1?StatsPercentValue boost_url:string prepaid_giveaways:flags.3?Vector<PrepaidGiveaway> my_boost_slots:flags.2?Vector<int> = premium.BoostsStatus;
|
premium.boostsStatus#4959427a flags:# my_boost:flags.2?true level:int current_level_boosts:int boosts:int gift_boosts:flags.4?int next_level_boosts:flags.0?int premium_audience:flags.1?StatsPercentValue boost_url:string prepaid_giveaways:flags.3?Vector<PrepaidGiveaway> my_boost_slots:flags.2?Vector<int> = premium.BoostsStatus;
|
||||||
|
|
||||||
|
storyFwdHeader#b826e150 flags:# from:flags.0?Peer from_name:flags.1?string story_id:flags.2?int = StoryFwdHeader;
|
||||||
|
|
||||||
|
stats.storyStats#50cd067c views_graph:StatsGraph reactions_by_emotion_graph:StatsGraph = stats.StoryStats;
|
||||||
|
|
||||||
---functions---
|
---functions---
|
||||||
|
|
||||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||||
|
@ -1936,7 +1943,8 @@ messages.searchCustomEmoji#2c11c0d7 emoticon:string hash:long = EmojiList;
|
||||||
messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool;
|
messages.togglePeerTranslations#e47cb579 flags:# disabled:flags.0?true peer:InputPeer = Bool;
|
||||||
messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
|
messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
|
||||||
messages.requestAppWebView#8c5a3b3c flags:# write_allowed:flags.0?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = AppWebViewResult;
|
messages.requestAppWebView#8c5a3b3c flags:# write_allowed:flags.0?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = AppWebViewResult;
|
||||||
messages.setChatWallPaper#8ffacae1 flags:# peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates;
|
messages.setChatWallPaper#8ffacae1 flags:# for_both:flags.3?true revert:flags.4?true peer:InputPeer wallpaper:flags.0?InputWallPaper settings:flags.2?WallPaperSettings id:flags.1?int = Updates;
|
||||||
|
messages.searchEmojiStickerSets#92b4494c flags:# exclude_featured:flags.0?true q:string hash:long = messages.FoundStickerSets;
|
||||||
|
|
||||||
updates.getState#edd4882a = updates.State;
|
updates.getState#edd4882a = updates.State;
|
||||||
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
|
updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference;
|
||||||
|
@ -2038,6 +2046,8 @@ channels.reportAntiSpamFalsePositive#a850a693 channel:InputChannel msg_id:int =
|
||||||
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
|
channels.toggleParticipantsHidden#6a6e7854 channel:InputChannel enabled:Bool = Updates;
|
||||||
channels.clickSponsoredMessage#18afbc93 channel:InputChannel random_id:bytes = Bool;
|
channels.clickSponsoredMessage#18afbc93 channel:InputChannel random_id:bytes = Bool;
|
||||||
channels.updateColor#621a201f flags:# channel:InputChannel color:int background_emoji_id:flags.0?long = Updates;
|
channels.updateColor#621a201f flags:# channel:InputChannel color:int background_emoji_id:flags.0?long = Updates;
|
||||||
|
channels.toggleViewForumAsMessages#9738bb15 channel:InputChannel enabled:Bool = Updates;
|
||||||
|
channels.getChannelRecommendations#83b70d97 channel:InputChannel = messages.Chats;
|
||||||
|
|
||||||
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON;
|
||||||
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool;
|
||||||
|
@ -2129,6 +2139,7 @@ stats.loadAsyncGraph#621d5fa0 flags:# token:string x:flags.0?long = StatsGraph;
|
||||||
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
|
stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
|
||||||
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
|
||||||
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
stats.getMessageStats#b6e0a3f5 flags:# dark:flags.0?true channel:InputChannel msg_id:int = stats.MessageStats;
|
||||||
|
stats.getStoryStats#374fef40 flags:# dark:flags.0?true peer:InputPeer id:int = stats.StoryStats;
|
||||||
|
|
||||||
chatlists.exportChatlistInvite#8472478e chatlist:InputChatlist title:string peers:Vector<InputPeer> = chatlists.ExportedChatlistInvite;
|
chatlists.exportChatlistInvite#8472478e chatlist:InputChatlist title:string peers:Vector<InputPeer> = chatlists.ExportedChatlistInvite;
|
||||||
chatlists.deleteExportedInvite#719c5c5e chatlist:InputChatlist slug:string = Bool;
|
chatlists.deleteExportedInvite#719c5c5e chatlist:InputChatlist slug:string = Bool;
|
||||||
|
@ -2143,7 +2154,7 @@ chatlists.getLeaveChatlistSuggestions#fdbcd714 chatlist:InputChatlist = Vector<P
|
||||||
chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector<InputPeer> = Updates;
|
chatlists.leaveChatlist#74fae13a chatlist:InputChatlist peers:Vector<InputPeer> = Updates;
|
||||||
|
|
||||||
stories.canSendStory#c7dfdfdd peer:InputPeer = Bool;
|
stories.canSendStory#c7dfdfdd peer:InputPeer = Bool;
|
||||||
stories.sendStory#bcb73644 flags:# pinned:flags.2?true noforwards:flags.4?true peer:InputPeer media:InputMedia media_areas:flags.5?Vector<MediaArea> caption:flags.0?string entities:flags.1?Vector<MessageEntity> privacy_rules:Vector<InputPrivacyRule> random_id:long period:flags.3?int = Updates;
|
stories.sendStory#e4e6694b flags:# pinned:flags.2?true noforwards:flags.4?true peer:InputPeer media:InputMedia media_areas:flags.5?Vector<MediaArea> caption:flags.0?string entities:flags.1?Vector<MessageEntity> privacy_rules:Vector<InputPrivacyRule> random_id:long period:flags.3?int fwd_from_id:flags.6?InputPeer fwd_from_story:flags.6?int = Updates;
|
||||||
stories.editStory#b583ba46 flags:# peer:InputPeer id:int media:flags.0?InputMedia media_areas:flags.3?Vector<MediaArea> caption:flags.1?string entities:flags.1?Vector<MessageEntity> privacy_rules:flags.2?Vector<InputPrivacyRule> = Updates;
|
stories.editStory#b583ba46 flags:# peer:InputPeer id:int media:flags.0?InputMedia media_areas:flags.3?Vector<MediaArea> caption:flags.1?string entities:flags.1?Vector<MessageEntity> privacy_rules:flags.2?Vector<InputPrivacyRule> = Updates;
|
||||||
stories.deleteStories#ae59db5f peer:InputPeer id:Vector<int> = Vector<int>;
|
stories.deleteStories#ae59db5f peer:InputPeer id:Vector<int> = Vector<int>;
|
||||||
stories.togglePinned#9a75a1ef peer:InputPeer id:Vector<int> pinned:Bool = Vector<int>;
|
stories.togglePinned#9a75a1ef peer:InputPeer id:Vector<int> pinned:Bool = Vector<int>;
|
||||||
|
@ -2170,3 +2181,4 @@ premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:
|
||||||
premium.getMyBoosts#be77b4a = premium.MyBoosts;
|
premium.getMyBoosts#be77b4a = premium.MyBoosts;
|
||||||
premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector<int> peer:InputPeer = premium.MyBoosts;
|
premium.applyBoost#6b7da746 flags:# slots:flags.0?Vector<int> peer:InputPeer = premium.MyBoosts;
|
||||||
premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus;
|
premium.getBoostsStatus#42f1f61 peer:InputPeer = premium.BoostsStatus;
|
||||||
|
premium.getUserBoosts#39854d1f peer:InputPeer user_id:InputUser = premium.BoostsList;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
// LAYER 166
|
// LAYER 167
|
||||||
|
|
|
@ -806,7 +806,8 @@ void SessionNavigation::showRepliesForMessage(
|
||||||
history,
|
history,
|
||||||
rootId,
|
rootId,
|
||||||
commentId,
|
commentId,
|
||||||
params.highlightPart);
|
params.highlightPart,
|
||||||
|
params.highlightPartOffsetHint);
|
||||||
memento->setFromTopic(topic);
|
memento->setFromTopic(topic);
|
||||||
showSection(std::move(memento), params);
|
showSection(std::move(memento), params);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -168,6 +168,7 @@ struct SectionShow {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextWithEntities highlightPart;
|
TextWithEntities highlightPart;
|
||||||
|
int highlightPartOffsetHint = 0;
|
||||||
Way way = Way::Forward;
|
Way way = Way::Forward;
|
||||||
anim::type animated = anim::type::normal;
|
anim::type animated = anim::type::normal;
|
||||||
anim::activation activation = anim::activation::normal;
|
anim::activation activation = anim::activation::normal;
|
||||||
|
|
Loading…
Add table
Reference in a new issue