Update API scheme on layer 204.

This commit is contained in:
John Preston 2025-05-16 12:58:49 +04:00
parent 76db55ff19
commit b91a040a32
9 changed files with 108 additions and 53 deletions

View file

@ -185,6 +185,9 @@ void ChannelData::setAccessHash(uint64 accessHash) {
}
void ChannelData::setFlags(ChannelDataFlags which) {
if (which & Flag::MonoforumAdmin) {
which |= Flag::Monoforum;
}
if (which & (Flag::Forum | Flag::Monoforum)) {
which |= Flag::Megagroup;
}
@ -202,15 +205,15 @@ void ChannelData::setFlags(ChannelDataFlags which) {
const auto takenForum = ((diff & Flag::Forum) && !(which & Flag::Forum))
? mgInfo->takeForumData()
: nullptr;
const auto takenMonoforum = ((diff & Flag::Monoforum)
&& !(which & Flag::Monoforum))
const auto takenMonoforum = ((diff & Flag::MonoforumAdmin)
&& !(which & Flag::MonoforumAdmin))
? mgInfo->takeMonoforumData()
: nullptr;
const auto wasIn = amIn();
if ((diff & Flag::Forum) && (which & Flag::Forum)) {
mgInfo->ensureForum(this);
} else if ((diff & Flag::Monoforum) && (which & Flag::Monoforum)) {
if ((diff & Flag::MonoforumAdmin) && (which & Flag::MonoforumAdmin)) {
mgInfo->ensureMonoforum(this);
} else if ((diff & Flag::Forum) && (which & Flag::Forum)) {
mgInfo->ensureForum(this);
}
_flags.set(which);
if (diff & (Flag::Left | Flag::Forbidden)) {
@ -228,7 +231,7 @@ void ChannelData::setFlags(ChannelDataFlags which) {
}
}
if (diff & (Flag::Forum
| Flag::Monoforum
| Flag::MonoforumAdmin
| Flag::CallNotEmpty
| Flag::SimilarExpanded
| Flag::Signatures
@ -237,7 +240,7 @@ void ChannelData::setFlags(ChannelDataFlags which) {
if (diff & Flag::CallNotEmpty) {
history->updateChatListEntry();
}
if (diff & (Flag::Forum | Flag::Monoforum)) {
if (diff & (Flag::Forum | Flag::MonoforumAdmin)) {
Core::App().notifications().clearFromHistory(history);
history->updateChatListEntryHeight();
if (history->inChatList()) {
@ -334,9 +337,14 @@ bool ChannelData::discussionLinkKnown() const {
}
void ChannelData::setMonoforumLink(ChannelData *link) {
if (_monoforumLink != link) {
_monoforumLink = link;
session().changes().peerUpdated(this, UpdateFlag::MonoforumLink);
if (_monoforumLink || !link) {
return;
}
_monoforumLink = link;
link->setMonoforumLink(this);
session().changes().peerUpdated(this, UpdateFlag::MonoforumLink);
if (isMegagroup() && (link->amCreator() || link->hasAdminRights())) {
setFlags(flags() | Flag::MonoforumAdmin);
}
}
@ -826,6 +834,12 @@ void ChannelData::setAdminRights(ChatAdminRights rights) {
session().changes().peerUpdated(
this,
UpdateFlag::Rights | UpdateFlag::Admins | UpdateFlag::BannedUsers);
if (isBroadcast() && _monoforumLink) {
const auto flags = _monoforumLink->flags();
const auto admin = (amCreator() || hasAdminRights());
_monoforumLink->setFlags((flags & ~Flag::MonoforumAdmin)
| (admin ? Flag::MonoforumAdmin : Flag()));
}
}
void ChannelData::setRestrictions(ChatRestrictionsInfo rights) {
@ -1291,11 +1305,6 @@ void ApplyChannelUpdate(
} else {
channel->setDiscussionLink(nullptr);
}
if (const auto chat = update.vlinked_monoforum_id()) {
channel->setMonoforumLink(channel->owner().channelLoaded(chat->v));
} else {
channel->setMonoforumLink(nullptr);
}
if (const auto history = channel->owner().historyLoaded(channel)) {
if (const auto available = update.vavailable_min_id()) {
history->clearUpTill(available->v);

View file

@ -80,6 +80,7 @@ enum class ChannelDataFlag : uint64 {
PaidMessagesAvailable = (1ULL << 37),
AutoTranslation = (1ULL << 38),
Monoforum = (1ULL << 39),
MonoforumAdmin = (1ULL << 40),
};
inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
using ChannelDataFlags = base::flags<ChannelDataFlag>;

View file

@ -1604,9 +1604,10 @@ bool PeerData::canManageGroupCall() const {
}
bool PeerData::amMonoforumAdmin() const {
const auto broadcast = monoforumBroadcast();
return broadcast
&& (broadcast->amCreator() || broadcast->hasAdminRights());
if (const auto channel = asChannel()) {
return channel->flags() & ChannelDataFlag::MonoforumAdmin;
}
return false;
}
int PeerData::starsPerMessage() const {

View file

@ -264,21 +264,35 @@ void SavedMessages::apply(
auto offsetPeer = (PeerData*)nullptr;
const auto selfId = _owner->session().userPeerId();
for (const auto &dialog : *list) {
const auto &data = dialog.data();
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
const auto topId = MsgId(data.vtop_message().v);
if (const auto item = _owner->message(selfId, topId)) {
offsetPeer = peer;
offsetDate = item->date();
offsetId = topId;
lastValid = true;
const auto entry = sublist(peer);
const auto entryPinned = pinned || data.is_pinned();
entry->applyMaybeLast(item);
_owner->setPinnedFromEntryList(entry, entryPinned);
} else {
lastValid = false;
}
dialog.match([&](const MTPDsavedDialog &data) {
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
const auto topId = MsgId(data.vtop_message().v);
if (const auto item = _owner->message(selfId, topId)) {
offsetPeer = peer;
offsetDate = item->date();
offsetId = topId;
lastValid = true;
const auto entry = sublist(peer);
const auto entryPinned = pinned || data.is_pinned();
entry->applyMaybeLast(item);
_owner->setPinnedFromEntryList(entry, entryPinned);
} else {
lastValid = false;
}
}, [&](const MTPDmonoForumDialog &data) {
const auto peer = _owner->peer(peerFromMTP(data.vpeer()));
const auto topId = MsgId(data.vtop_message().v);
if (const auto item = _owner->message(selfId, topId)) {
offsetPeer = peer;
offsetDate = item->date();
offsetId = topId;
lastValid = true;
const auto entry = sublist(peer);
entry->applyMaybeLast(item);
} else {
lastValid = false;
}
});
}
if (pinned) {
} else if (!lastValid) {
@ -359,8 +373,8 @@ rpl::producer<> SavedMessages::destroyed() const {
return _parentChat->flagsValue(
) | rpl::filter([=](const ChannelData::Flags::Change &update) {
using Flag = ChannelData::Flag;
return (update.diff & Flag::Monoforum)
&& !(update.value & Flag::Monoforum);
return (update.diff & Flag::MonoforumAdmin)
&& !(update.value & Flag::MonoforumAdmin);
}) | rpl::take(1) | rpl::to_empty;
}

View file

@ -377,14 +377,14 @@ void Session::clear() {
auto forums = base::flat_set<not_null<ChannelData*>>();
for (const auto &[peerId, peer] : _peers) {
if (const auto channel = peer->asChannel()) {
if (channel->isForum() || channel->isMonoforum()) {
if (channel->isForum() || channel->amMonoforumAdmin()) {
forums.emplace(channel);
}
}
}
for (const auto &channel : forums) {
channel->setFlags(channel->flags()
& ~(ChannelDataFlag::Forum | ChannelDataFlag::Monoforum));
& ~(ChannelDataFlag::Forum | ChannelDataFlag::MonoforumAdmin));
}
_sendActionManager->clear();
@ -1026,6 +1026,16 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
channel->setStarsPerMessage(
data.vsend_paid_messages_stars().value_or_empty());
if (const auto monoforum = data.vlinked_monoforum_id()) {
if (const auto linked = channelLoaded(monoforum->v)) {
channel->setMonoforumLink(linked);
} else {
channel->updateFull();
}
} else {
channel->setMonoforumLink(nullptr);
}
if (wasInChannel != channel->amIn()) {
flags |= UpdateFlag::ChannelAmIn;
}
@ -4659,9 +4669,10 @@ void Session::refreshChatListEntry(Dialogs::Key key) {
} else if (const auto monoforum = history->peer->monoforum()) {
monoforum->preloadSublists();
}
if (history->peer->isMonoforum()
&& !history->peer->monoforumBroadcast()) {
history->peer->updateFull();
if (const auto broadcast = history->peer->monoforumBroadcast()) {
if (!broadcast->isFullLoaded()) {
broadcast->updateFull();
}
}
}
}

View file

@ -790,7 +790,14 @@ HistoryItem::~HistoryItem() {
reply->clearData(this);
}
if (const auto saved = Get<HistoryMessageSaved>()) {
saved->sublist->removeOne(this);
if (saved->savedMessagesSublist) {
saved->savedMessagesSublist->removeOne(this);
} else if (const auto monoforum = _history->peer->monoforum()) {
const auto peer = _history->owner().peer(saved->sublistPeerId);
if (const auto sublist = monoforum->sublistLoaded(peer)) {
sublist->removeOne(this);
}
}
}
clearDependencyMessage();
applyTTL(0);
@ -3436,7 +3443,7 @@ FullStoryId HistoryItem::replyToStory() const {
}
FullReplyTo HistoryItem::replyTo() const {
const auto monoforumPeer = _history->peer->isMonoforum()
const auto monoforumPeer = _history->peer->amMonoforumAdmin()
? savedSublistPeer()
: nullptr;
auto result = FullReplyTo{
@ -3560,19 +3567,26 @@ bool HistoryItem::isEmpty() const {
Data::SavedSublist *HistoryItem::savedSublist() const {
if (const auto saved = Get<HistoryMessageSaved>()) {
return saved->sublist;
if (saved->savedMessagesSublist) {
return saved->savedMessagesSublist;
} else if (const auto monoforum = _history->peer->monoforum()) {
const auto peer = _history->owner().peer(saved->sublistPeerId);
return monoforum->sublist(peer).get();
}
} else if (_history->peer->isSelf()) {
const auto sublist = _history->owner().savedMessages().sublist(
_history->peer);
const auto that = const_cast<HistoryItem*>(this);
that->AddComponents(HistoryMessageSaved::Bit());
that->Get<HistoryMessageSaved>()->sublist = sublist;
const auto saved = that->Get<HistoryMessageSaved>();
saved->sublistPeerId = _history->peer->id;
saved->savedMessagesSublist = sublist;
return sublist;
} else if (const auto monoforum = _history->peer->monoforum()) {
const auto sublist = monoforum->sublist(_from);
const auto that = const_cast<HistoryItem*>(this);
that->AddComponents(HistoryMessageSaved::Bit());
that->Get<HistoryMessageSaved>()->sublist = sublist;
that->Get<HistoryMessageSaved>()->sublistPeerId = _from->id;
return sublist;
}
return nullptr;
@ -3802,10 +3816,7 @@ void HistoryItem::createComponents(CreateConfig &&config) {
config.savedSublistPeer = _history->session().userPeerId();
}
}
const auto peer = _history->owner().peer(config.savedSublistPeer);
saved->sublist = _history->peer->isSelf()
? _history->owner().savedMessages().sublist(peer)
: _history->peer->monoforum()->sublist(peer);
saved->sublistPeerId = config.savedSublistPeer;
}
if (const auto reply = Get<HistoryMessageReply>()) {

View file

@ -174,7 +174,11 @@ struct HistoryMessageSavedMediaData
struct HistoryMessageSaved
: RuntimeComponent<HistoryMessageSaved, HistoryItem> {
Data::SavedSublist *sublist = nullptr;
PeerId sublistPeerId = 0;
// This can't change after the message is created, but is required
// frequently in reactions, so we cache the value here.
Data::SavedSublist *savedMessagesSublist = nullptr;
};
class ReplyToMessagePointer final {

View file

@ -99,11 +99,11 @@ userStatusLastMonth#65899777 flags:# by_me:flags.0?true = UserStatus;
chatEmpty#29562865 id:long = Chat;
chat#41cbf256 flags:# creator:flags.0?true left:flags.2?true deactivated:flags.5?true call_active:flags.23?true call_not_empty:flags.24?true noforwards:flags.25?true id:long title:string photo:ChatPhoto participants_count:int date:int version:int migrated_to:flags.6?InputChannel admin_rights:flags.14?ChatAdminRights default_banned_rights:flags.18?ChatBannedRights = Chat;
chatForbidden#6592a1a7 id:long title:string = Chat;
channel#7482147e flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long = Chat;
channel#fe685355 flags:# creator:flags.0?true left:flags.2?true broadcast:flags.5?true verified:flags.7?true megagroup:flags.8?true restricted:flags.9?true signatures:flags.11?true min:flags.12?true scam:flags.19?true has_link:flags.20?true has_geo:flags.21?true slowmode_enabled:flags.22?true call_active:flags.23?true call_not_empty:flags.24?true fake:flags.25?true gigagroup:flags.26?true noforwards:flags.27?true join_to_send:flags.28?true join_request:flags.29?true forum:flags.30?true flags2:# stories_hidden:flags2.1?true stories_hidden_min:flags2.2?true stories_unavailable:flags2.3?true signature_profiles:flags2.12?true autotranslation:flags2.15?true broadcast_messages_allowed:flags2.16?true monoforum:flags2.17?true id:long access_hash:flags.13?long title:string username:flags.6?string photo:ChatPhoto date:int restriction_reason:flags.9?Vector<RestrictionReason> admin_rights:flags.14?ChatAdminRights banned_rights:flags.15?ChatBannedRights default_banned_rights:flags.18?ChatBannedRights participants_count:flags.17?int usernames:flags2.0?Vector<Username> stories_max_id:flags2.4?int color:flags2.7?PeerColor profile_color:flags2.8?PeerColor emoji_status:flags2.9?EmojiStatus level:flags2.10?int subscription_until_date:flags2.11?int bot_verification_icon:flags2.13?long send_paid_messages_stars:flags2.14?long linked_monoforum_id:flags2.18?long = 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#2633421b 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 reactions_limit:flags.20?int = ChatFull;
channelFull#7fc3facc 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 restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true paid_messages_available:flags2.20?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 reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int linked_monoforum_id:flags2.21?long = ChatFull;
channelFull#52d6806b 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 restricted_sponsored:flags2.11?true can_view_revenue:flags2.12?true paid_media_allowed:flags2.14?true can_view_stars_revenue:flags2.15?true paid_reactions_available:flags2.16?true stargifts_available:flags2.19?true paid_messages_available:flags2.20?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 reactions_limit:flags2.13?int stories:flags2.4?PeerStories wallpaper:flags2.7?WallPaper boosts_applied:flags2.8?int boosts_unrestrict:flags2.9?int emojiset:flags2.10?StickerSet bot_verification:flags2.17?BotVerification stargifts_count:flags2.18?int = ChatFull;
chatParticipant#c02d4007 user_id:long inviter_id:long date:int = ChatParticipant;
chatParticipantCreator#e46bcee4 user_id:long = ChatParticipant;
@ -433,6 +433,8 @@ updateBotPurchasedPaidMedia#283bd312 user_id:long payload:string qts:int = Updat
updatePaidReactionPrivacy#8b725fce private:PaidReactionPrivacy = Update;
updateSentPhoneCode#504aa18f sent_code:auth.SentCode = Update;
updateGroupCallChainBlocks#a477288f call:InputGroupCall sub_chain_id:int blocks:Vector<bytes> next_offset:int = Update;
updateReadMonoForumInbox#bcf34712 flags:# channel_id:long saved_peer_id:Peer read_max_id:int = Update;
updateReadMonoForumOutbox#a4a79376 channel_id:long saved_peer_id:Peer read_max_id:int = Update;
updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State;
@ -1713,6 +1715,7 @@ storyReactionPublicRepost#cfcd0f13 peer_id:Peer story:StoryItem = StoryReaction;
stories.storyReactionsList#aa5f789c flags:# count:int reactions:Vector<StoryReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
savedDialog#bd87cb6c flags:# pinned:flags.2?true peer:Peer top_message:int = SavedDialog;
monoForumDialog#31ac5089 peer:Peer top_message:int read_inbox_max_id:int read_outbox_max_id:int unread_count:int = SavedDialog;
messages.savedDialogs#f83ae221 dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
messages.savedDialogsSlice#44ba9dd9 count:int dialogs:Vector<SavedDialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.SavedDialogs;
@ -2392,6 +2395,7 @@ messages.savePreparedInlineMessage#f21f7f2f flags:# result:InputBotInlineResult
messages.getPreparedInlineMessage#857ebdb8 bot:InputUser id:string = messages.PreparedInlineMessage;
messages.searchStickers#29b1c66a flags:# emojis:flags.0?true q:string emoticon:string lang_code:Vector<string> offset:int limit:int hash:long = messages.FoundStickers;
messages.reportMessagesDelivery#5a6d7395 flags:# push:flags.0?true peer:InputPeer id:Vector<int> = Bool;
messages.readSavedHistory#baab7bd6 parent_peer:InputPeer peer:InputPeer max_id:int = messages.Messages;
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;

View file

@ -603,7 +603,7 @@ void SessionNavigation::showPeerByLinkResolved(
showPeerInfo(peer, params);
} else if (resolveType == ResolveType::HashtagSearch) {
searchMessages(info.text, peer->owner().history(peer));
} else if ((peer->isForum() || peer->isMonoforum())
} else if ((peer->isForum() || peer->amMonoforumAdmin())
&& resolveType != ResolveType::Boost) {
const auto itemId = info.messageId;
if (!itemId) {