Replaced use of raw MTP* bot commands with new transitional classes.

This commit is contained in:
23rd 2022-05-15 00:27:21 +03:00 committed by John Preston
parent 5f8608ed90
commit 13146e9c06
14 changed files with 136 additions and 145 deletions

View File

@ -486,6 +486,8 @@ PRIVATE
data/data_peer.h
data/data_peer_bot_command.cpp
data/data_peer_bot_command.h
data/data_peer_bot_commands.cpp
data/data_peer_bot_commands.h
data/data_peer_id.cpp
data/data_peer_id.h
data/data_peer_values.cpp

View File

@ -20,7 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "mtproto/mtproto_config.h"
#include "mtproto/mtproto_dc_options.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_peer_bot_command.h"
#include "data/stickers/data_stickers.h"
#include "data/data_session.h"
#include "data/data_user.h"
@ -1988,16 +1987,29 @@ void Updates::feedUpdate(const MTPUpdate &update) {
const auto &d = update.c_updateBotCommands();
if (const auto peer = session().data().peerLoaded(peerFromMTP(d.vpeer()))) {
const auto botId = UserId(d.vbot_id().v);
const auto commands = Data::BotCommands{
.userId = UserId(d.vbot_id().v),
.commands = ranges::views::all(
d.vcommands().v
) | ranges::views::transform(
Data::BotCommandFromTL
) | ranges::to_vector,
};
if (const auto user = peer->asUser()) {
if (user->isBot() && user->id == peerFromUser(botId)) {
if (Data::UpdateBotCommands(user->botInfo->commands, &d.vcommands())) {
const auto equal = ranges::equal(
user->botInfo->commands,
commands.commands);
user->botInfo->commands = commands.commands;
if (!equal) {
session().data().botCommandsChanged(user);
}
}
} else if (const auto chat = peer->asChat()) {
chat->setBotCommands(botId, d.vcommands());
chat->setBotCommands({ commands });
} else if (const auto megagroup = peer->asMegagroup()) {
if (megagroup->mgInfo->updateBotCommands(botId, d.vcommands())) {
if (megagroup->mgInfo->setBotCommands({ commands })) {
session().data().botCommandsChanged(megagroup);
}
}

View File

@ -16,7 +16,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_file_origin.h"
#include "data/data_session.h"
#include "data/stickers/data_stickers.h"
#include "data/data_peer_bot_command.h"
#include "menu/menu_send.h" // SendMenu::FillSendMenu
#include "chat_helpers/stickers_lottie.h"
#include "chat_helpers/message_field.h" // PrepareMentionTag.

View File

@ -50,14 +50,9 @@ void MegagroupInfo::setLocation(const ChannelLocation &location) {
_location = location;
}
bool MegagroupInfo::updateBotCommands(const MTPVector<MTPBotInfo> &data) {
return Data::UpdateBotCommands(_botCommands, data);
}
bool MegagroupInfo::updateBotCommands(
UserId botId,
const MTPVector<MTPBotCommand> &data) {
return Data::UpdateBotCommands(_botCommands, botId, &data);
Data::ChatBotCommands::Changed MegagroupInfo::setBotCommands(
const std::vector<Data::BotCommands> &list) {
return _botCommands.update(list);
}
ChannelData::ChannelData(not_null<Data::Session*> owner, PeerId id)
@ -908,7 +903,13 @@ void ApplyChannelUpdate(
SetTopPinnedMessageId(channel, pinned->v);
}
if (channel->isMegagroup()) {
if (channel->mgInfo->updateBotCommands(update.vbot_info())) {
auto commands = ranges::views::all(
update.vbot_info().v
) | ranges::views::transform(
Data::BotCommandsFromTL
) | ranges::to_vector;
if (channel->mgInfo->setBotCommands(std::move(commands))) {
channel->owner().botCommandsChanged(channel);
}
const auto stickerSet = update.vstickerset();

View File

@ -11,10 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_pts_waiter.h"
#include "data/data_location.h"
#include "data/data_chat_participant_status.h"
namespace Data {
struct BotCommand;
} // namespace Data
#include "data/data_peer_bot_commands.h"
struct ChannelLocation {
QString address;
@ -89,12 +86,9 @@ public:
const ChannelLocation *getLocation() const;
void setLocation(const ChannelLocation &location);
bool updateBotCommands(const MTPVector<MTPBotInfo> &data);
bool updateBotCommands(
UserId botId,
const MTPVector<MTPBotCommand> &data);
[[nodiscard]] auto botCommands() const
-> const base::flat_map<UserId, std::vector<Data::BotCommand>> & {
Data::ChatBotCommands::Changed setBotCommands(
const std::vector<Data::BotCommands> &commands);
[[nodiscard]] const Data::ChatBotCommands &botCommands() const {
return _botCommands;
}
@ -124,7 +118,7 @@ public:
private:
ChatData *_migratedFrom = nullptr;
ChannelLocation _location;
base::flat_map<UserId, std::vector<Data::BotCommand>> _botCommands;
Data::ChatBotCommands _botCommands;
};

View File

@ -13,7 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "data/data_group_call.h"
#include "data/data_message_reactions.h"
#include "data/data_peer_bot_command.h"
#include "history/history.h"
#include "main/main_session.h"
#include "apiwrap.h"
@ -258,16 +257,8 @@ PeerId ChatData::groupCallDefaultJoinAs() const {
return _callDefaultJoinAs;
}
void ChatData::setBotCommands(const MTPVector<MTPBotInfo> &data) {
if (Data::UpdateBotCommands(_botCommands, data)) {
owner().botCommandsChanged(this);
}
}
void ChatData::setBotCommands(
UserId botId,
const MTPVector<MTPBotCommand> &data) {
if (Data::UpdateBotCommands(_botCommands, botId, &data)) {
void ChatData::setBotCommands(const std::vector<Data::BotCommands> &list) {
if (_botCommands.update(list)) {
owner().botCommandsChanged(this);
}
}
@ -458,9 +449,12 @@ void ApplyChatUpdate(not_null<ChatData*> chat, const MTPDchatFull &update) {
chat->setMessagesTTL(update.vttl_period().value_or_empty());
if (const auto info = update.vbot_info()) {
chat->setBotCommands(*info);
auto &&commands = ranges::views::all(
info->v
) | ranges::views::transform(Data::BotCommandsFromTL);
chat->setBotCommands(std::move(commands) | ranges::to_vector);
} else {
chat->setBotCommands(MTP_vector<MTPBotInfo>());
chat->setBotCommands({});
}
using Flag = ChatDataFlag;
const auto mask = Flag::CanSetUsername;

View File

@ -9,10 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_peer.h"
#include "data/data_chat_participant_status.h"
namespace Data {
struct BotCommand;
} // namespace Data
#include "data/data_peer_bot_commands.h"
enum class ChatAdminRight;
@ -152,12 +149,8 @@ public:
void setGroupCallDefaultJoinAs(PeerId peerId);
[[nodiscard]] PeerId groupCallDefaultJoinAs() const;
void setBotCommands(const MTPVector<MTPBotInfo> &data);
void setBotCommands(
UserId botId,
const MTPVector<MTPBotCommand> &data);
[[nodiscard]] auto botCommands() const
-> const base::flat_map<UserId, std::vector<Data::BotCommand>> & {
void setBotCommands(const std::vector<Data::BotCommands> &commands);
[[nodiscard]] const Data::ChatBotCommands &botCommands() const {
return _botCommands;
}
@ -205,7 +198,7 @@ private:
std::unique_ptr<Data::GroupCall> _call;
PeerId _callDefaultJoinAs = 0;
base::flat_map<UserId, std::vector<Data::BotCommand>> _botCommands;
Data::ChatBotCommands _botCommands;
ChannelData *_migratedTo = nullptr;
rpl::lifetime _lifetime;

View File

@ -7,90 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/data_peer_bot_command.h"
#include "data/data_user.h"
namespace Data {
bool UpdateBotCommands(
std::vector<Data::BotCommand> &commands,
const MTPVector<MTPBotCommand> *data) {
if (!data) {
const auto changed = !commands.empty();
commands.clear();
return changed;
}
const auto &v = data->v;
commands.reserve(v.size());
auto result = false;
auto index = 0;
for (const auto &command : v) {
command.match([&](const MTPDbotCommand &data) {
const auto command = qs(data.vcommand());
const auto description = qs(data.vdescription());
if (commands.size() <= index) {
commands.push_back({
.command = command,
.description = description,
});
result = true;
} else {
auto &entry = commands[index];
if (entry.command != command
|| entry.description != description) {
entry.command = command;
entry.description = description;
result = true;
}
}
++index;
});
}
if (index < commands.size()) {
result = true;
}
commands.resize(index);
return result;
}
bool UpdateBotCommands(
base::flat_map<UserId, std::vector<Data::BotCommand>> &commands,
UserId botId,
const MTPVector<MTPBotCommand> *data) {
return (!data || data->v.isEmpty())
? commands.remove(botId)
: UpdateBotCommands(commands[botId], data);
}
bool UpdateBotCommands(
base::flat_map<UserId, std::vector<Data::BotCommand>> &commands,
const MTPVector<MTPBotInfo> &data) {
auto result = false;
auto filled = base::flat_set<UserId>();
filled.reserve(data.v.size());
for (const auto &item : data.v) {
item.match([&](const MTPDbotInfo &data) {
if (!data.vuser_id()) {
LOG(("API Error: BotInfo without UserId for commands map."));
return;
}
const auto id = UserId(*data.vuser_id());
if (!filled.emplace(id).second) {
LOG(("API Error: Two BotInfo for a single bot."));
return;
} else if (UpdateBotCommands(commands, id, data.vcommands())) {
result = true;
}
});
}
for (auto i = begin(commands); i != end(commands);) {
if (filled.contains(i->first)) {
++i;
} else {
i = commands.erase(i);
result = true;
}
}
return result;
BotCommand BotCommandFromTL(const MTPBotCommand &result) {
return result.match([](const MTPDbotCommand &data) {
return BotCommand {
.command = qs(data.vcommand().v),
.description = qs(data.vdescription().v),
};
});
}
} // namespace Data

View File

@ -22,15 +22,6 @@ struct BotCommand final {
}
};
bool UpdateBotCommands(
std::vector<BotCommand> &commands,
const MTPVector<MTPBotCommand> *data);
bool UpdateBotCommands(
base::flat_map<UserId, std::vector<BotCommand>> &commands,
UserId botId,
const MTPVector<MTPBotCommand> *data);
bool UpdateBotCommands(
base::flat_map<UserId, std::vector<BotCommand>> &commands,
const MTPVector<MTPBotInfo> &data);
[[nodiscard]] BotCommand BotCommandFromTL(const MTPBotCommand &result);
} // namespace Data

View File

@ -0,0 +1,42 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "data/data_peer_bot_commands.h"
namespace Data {
ChatBotCommands::Changed ChatBotCommands::update(
const std::vector<BotCommands> &list) {
auto changed = false;
if (list.empty()) {
changed = (list.empty() != empty());
clear();
} else {
for (const auto &commands : list) {
auto &value = operator[](commands.userId);
changed |= commands.commands.empty()
? remove(commands.userId)
: !ranges::equal(value, commands.commands);
value = commands.commands;
}
}
return changed;
}
BotCommands BotCommandsFromTL(const MTPBotInfo &result) {
return result.match([](const MTPDbotInfo &data) {
auto commands = ranges::views::all(
data.vcommands().v
) | ranges::views::transform(BotCommandFromTL) | ranges::to_vector;
return BotCommands{
.userId = UserId(data.vuser_id().v),
.commands = std::move(commands),
};
});
}
} // namespace Data

View File

@ -0,0 +1,32 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "data/data_peer_bot_command.h"
namespace Data {
struct BotCommands final {
UserId userId;
std::vector<BotCommand> commands;
};
struct ChatBotCommands final : public base::flat_map<
UserId,
std::vector<BotCommand>> {
public:
using Changed = bool;
using base::flat_map<UserId, std::vector<BotCommand>>::flat_map;
Changed update(const std::vector<BotCommands> &list);
};
[[nodiscard]] BotCommands BotCommandsFromTL(const MTPBotInfo &result);
} // namespace Data

View File

@ -47,7 +47,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_channel.h"
#include "data/data_chat.h"
#include "data/data_user.h"
#include "data/data_peer_bot_command.h"
#include "data/data_file_origin.h"
#include "data/data_download_manager.h"
#include "data/data_photo.h"

View File

@ -136,9 +136,17 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
botInfo->description = desc;
botInfo->text = Ui::Text::String(st::msgMinWidth);
}
const auto changedCommands = Data::UpdateBotCommands(
auto commands = ranges::views::all(
d.vcommands().v
) | ranges::views::transform(
Data::BotCommandFromTL
) | ranges::to_vector;
const auto changedCommands = !ranges::equal(
botInfo->commands,
d.vcommands());
commands);
botInfo->commands = std::move(commands);
const auto changedButton = Data::ApplyBotMenuButton(
botInfo.get(),
d.vmenu_button());

View File

@ -14,7 +14,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_changes.h"
#include "data/data_user.h"
#include "data/notify/data_notify_settings.h"
#include "data/data_peer_bot_command.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h"