Fix unsupported filtering in monoforum export.

Fixes #29545.
This commit is contained in:
John Preston 2025-07-14 11:21:14 +04:00
parent 1c41e01f0d
commit a285c1abec
3 changed files with 53 additions and 14 deletions

View file

@ -1167,8 +1167,15 @@ Chat ParseChat(const MTPChat &data) {
result.colorIndex = (color && color->data().vcolor())
? color->data().vcolor()->v
: PeerColorIndex(result.bareId);
result.isMonoforum = data.is_monoforum();
result.isBroadcast = data.is_broadcast();
result.isSupergroup = data.is_megagroup();
result.hasMonoforumAdminRights = data.is_broadcast()
&& (data.is_creator()
|| (data.vadmin_rights()
&& data.vadmin_rights()->data().is_manage_direct_messages()));
result.monoforumLinkId
= data.vlinked_monoforum_id().value_or_empty();
result.title = ParseString(data.vtitle());
if (const auto username = data.vusername()) {
result.username = ParseString(*username);
@ -1188,15 +1195,6 @@ Chat ParseChat(const MTPChat &data) {
return result;
}
std::map<PeerId, Chat> ParseChatsList(const MTPVector<MTPChat> &data) {
auto result = std::map<PeerId, Chat>();
for (const auto &chat : data.v) {
auto parsed = ParseChat(chat);
result.emplace(parsed.id(), std::move(parsed));
}
return result;
}
Utf8String ContactInfo::name() const {
return firstName.isEmpty()
? (lastName.isEmpty()
@ -1273,6 +1271,20 @@ std::map<PeerId, Peer> ParsePeersLists(
auto parsed = ParseChat(chat);
result.emplace(parsed.id(), Peer{ std::move(parsed) });
}
for (auto &[peerId, parsed] : result) {
if (const auto chat = std::get_if<Chat>(&parsed.data)) {
if (chat->isMonoforum) {
const auto i = result.find(
PeerId(ChannelId(chat->monoforumLinkId)));
if (i != end(result)) {
chat->isMonoforumAdmin
= i->second.chat()->hasMonoforumAdminRights;
chat->isMonoforumOfPublicBroadcast
= !i->second.chat()->username.isEmpty();
}
}
}
}
return result;
}
@ -2191,7 +2203,13 @@ const DialogInfo *DialogsInfo::item(int index) const {
DialogInfo::Type DialogTypeFromChat(const Chat &chat) {
using Type = DialogInfo::Type;
return chat.username.isEmpty()
return (chat.isMonoforum && !chat.isMonoforumAdmin)
? Type::Personal
: (chat.isMonoforumAdmin && chat.isMonoforumOfPublicBroadcast)
? Type::PublicSupergroup
: chat.isMonoforumAdmin
? Type::PrivateSupergroup
: chat.username.isEmpty()
? (chat.isBroadcast
? Type::PrivateChannel
: chat.isSupergroup
@ -2252,6 +2270,11 @@ DialogsInfo ParseDialogsInfo(const MTPmessages_Dialogs &data) {
info.migratedToChannelId = peer.chat()
? peer.chat()->migratedToChannelId
: 0;
info.isMonoforum = peer.chat()
&& peer.chat()->isMonoforum;
info.monoforumBroadcastInput = peer.chat()
? peer.chat()->monoforumBroadcastInput
: MTPInputPeer(MTP_inputPeerEmpty());
}
info.topMessageId = fields.vtop_message().v;
const auto messageIt = messages.find(MessageId{
@ -2290,6 +2313,10 @@ DialogInfo DialogInfoFromChat(const Chat &data) {
result.topMessageId = 0;
result.type = DialogTypeFromChat(data);
result.migratedToChannelId = data.migratedToChannelId;
result.isMonoforum = data.isMonoforum;
if (data.isMonoforumAdmin) {
result.monoforumBroadcastInput = data.monoforumBroadcastInput;
}
return result;
}
@ -2424,7 +2451,8 @@ void FinalizeDialogsInfo(DialogsInfo &info, const Settings &settings) {
}
Unexpected("Type in ApiWrap::onlyMyMessages.");
}();
dialog.onlyMyMessages = ((settings.fullChats & setting) != setting);
dialog.onlyMyMessages = (dialog.type != DialogType::Personal)
&& ((settings.fullChats & setting) != setting);
ranges::sort(dialog.splits);
}

View file

@ -319,14 +319,19 @@ struct Chat {
Utf8String title;
Utf8String username;
uint8 colorIndex = 0;
bool isMonoforum = false;
bool isBroadcast = false;
bool isSupergroup = false;
bool isMonoforumAdmin = false;
bool hasMonoforumAdminRights = false;
bool isMonoforumOfPublicBroadcast = false;
BareId monoforumLinkId = 0;
MTPInputPeer input = MTP_inputPeerEmpty();
MTPInputPeer monoforumBroadcastInput = MTP_inputPeerEmpty();
};
Chat ParseChat(const MTPChat &data);
std::map<PeerId, Chat> ParseChatsList(const MTPVector<MTPChat> &data);
struct Peer {
PeerId id() const;
@ -952,12 +957,15 @@ struct DialogInfo {
MTPInputPeer migratedFromInput = MTP_inputPeerEmpty();
ChannelId migratedToChannelId = 0;
MTPInputPeer monoforumBroadcastInput = MTP_inputPeerEmpty();
// User messages splits which contained that dialog.
std::vector<int> splits;
// Filled after the whole dialogs list is accumulated.
bool onlyMyMessages = false;
bool isLeftChannel = false;
bool isMonoforum = false;
QString relativePath;
// Filled when requesting dialog messages.

View file

@ -1370,7 +1370,7 @@ void ApiWrap::appendSinglePeerDialogs(Data::DialogsInfo &&info) {
if (isSupergroupType(info.type) && !migratedRequestId) {
migratedRequestId = requestSinglePeerMigrated(info);
continue;
} else if (isChannelType(info.type)) {
} else if (isChannelType(info.type) || info.isMonoforum) {
continue;
}
for (auto i = last; i != 0; --i) {
@ -1642,6 +1642,9 @@ void ApiWrap::requestChatMessages(
const auto realPeerInput = (splitIndex >= 0)
? _chatProcess->info.input
: _chatProcess->info.migratedFromInput;
const auto outgoingInput = _chatProcess->info.isMonoforum
? _chatProcess->info.monoforumBroadcastInput
: MTP_inputPeerSelf();
const auto realSplitIndex = (splitIndex >= 0)
? splitIndex
: (splitsCount + splitIndex);
@ -1650,7 +1653,7 @@ void ApiWrap::requestChatMessages(
MTP_flags(MTPmessages_Search::Flag::f_from_id),
realPeerInput,
MTP_string(), // query
MTP_inputPeerSelf(),
outgoingInput,
MTPInputPeer(), // saved_peer_id
MTPVector<MTPReaction>(), // saved_reaction
MTPint(), // top_msg_id