Track only strings in BotCommand struct.

This commit is contained in:
John Preston 2021-07-01 12:49:37 +03:00
parent a8df3dcf91
commit 93d99d6173
4 changed files with 55 additions and 68 deletions

View file

@ -29,6 +29,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/popup_menu.h"
#include "ui/widgets/scroll_area.h"
#include "ui/widgets/input_fields.h"
#include "ui/text/text_options.h"
#include "ui/image/image.h"
#include "ui/effects/path_shift_gradient.h"
#include "ui/ui_utility.h"
@ -441,7 +442,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
} else if (_type == Type::BotCommands) {
bool listAllSuggestions = _filter.isEmpty();
bool hasUsername = _filter.indexOf('@') > 0;
base::flat_map<UserData*, bool> bots;
base::flat_set<not_null<UserData*>> bots;
int32 cnt = 0;
if (_chat) {
if (_chat->noParticipantInfo()) {
@ -453,10 +454,10 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
} else if (!user->botInfo->inited) {
user->session().api().requestFullPeer(user);
}
if (user->botInfo->commands.isEmpty()) {
if (user->botInfo->commands.empty()) {
continue;
}
bots.emplace(user, true);
bots.emplace(user);
cnt += user->botInfo->commands.size();
}
}
@ -465,7 +466,7 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
_user->session().api().requestFullPeer(_user);
}
cnt = _user->botInfo->commands.size();
bots.emplace(_user, true);
bots.emplace(_user);
} else if (_channel && _channel->isMegagroup()) {
if (_channel->mgInfo->bots.empty()) {
if (!_channel->mgInfo->botStatus) {
@ -478,15 +479,25 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
} else if (!user->botInfo->inited) {
user->session().api().requestFullPeer(user);
}
if (user->botInfo->commands.isEmpty()) {
if (user->botInfo->commands.empty()) {
continue;
}
bots.emplace(user, true);
bots.emplace(user);
cnt += user->botInfo->commands.size();
}
}
}
if (cnt) {
const auto make = [&](
not_null<UserData*> user,
const BotCommand &command) {
return BotCommandRow{
user,
command.command,
command.description,
user->activeUserpicView()
};
};
brows.reserve(cnt);
int32 botStatus = _chat ? _chat->botStatus : ((_channel && _channel->isMegagroup()) ? _channel->mgInfo->botStatus : -1);
if (_chat) {
@ -498,32 +509,32 @@ void FieldAutocomplete::updateFiltered(bool resetScroll) {
} else if (!user->botInfo->inited) {
user->session().api().requestFullPeer(user);
}
if (user->botInfo->commands.isEmpty()) {
if (user->botInfo->commands.empty()) {
continue;
}
bots.remove(user);
for (auto j = 0, l = user->botInfo->commands.size(); j != l; ++j) {
for (const auto &command : user->botInfo->commands) {
if (!listAllSuggestions) {
auto toFilter = (hasUsername || botStatus == 0 || botStatus == 2)
? user->botInfo->commands.at(j).command + '@' + user->username
: user->botInfo->commands.at(j).command;
? command.command + '@' + user->username
: command.command;
if (!toFilter.startsWith(_filter, Qt::CaseInsensitive)/* || toFilter.size() == _filter.size()*/) {
continue;
}
}
brows.push_back({ user, &user->botInfo->commands.at(j) });
brows.push_back(make(user, command));
}
}
}
if (!bots.empty()) {
for (auto i = bots.cbegin(), e = bots.cend(); i != e; ++i) {
UserData *user = i->first;
for (int32 j = 0, l = user->botInfo->commands.size(); j < l; ++j) {
const auto user = *i;
for (const auto &command : user->botInfo->commands) {
if (!listAllSuggestions) {
QString toFilter = (hasUsername || botStatus == 0 || botStatus == 2) ? user->botInfo->commands.at(j).command + '@' + user->username : user->botInfo->commands.at(j).command;
QString toFilter = (hasUsername || botStatus == 0 || botStatus == 2) ? command.command + '@' + user->username : command.command;
if (!toFilter.startsWith(_filter, Qt::CaseInsensitive)/* || toFilter.size() == _filter.size()*/) continue;
}
brows.push_back({ user, &user->botInfo->commands.at(j) });
brows.push_back(make(user, command));
}
}
}
@ -940,8 +951,7 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
auto &row = _brows->at(i);
const auto user = row.user;
const auto command = row.command;
auto toHighlight = command->command;
auto toHighlight = row.command;
int32 botStatus = _parent->chat() ? _parent->chat()->botStatus : ((_parent->channel() && _parent->channel()->isMegagroup()) ? _parent->channel()->mgInfo->botStatus : -1);
if (hasUsername || botStatus == 0 || botStatus == 2) {
toHighlight += '@' + user->username;
@ -959,9 +969,16 @@ void FieldAutocomplete::Inner::paintEvent(QPaintEvent *e) {
auto addleft = commandTextWidth + st::mentionPadding.left();
auto widthleft = mentionwidth - addleft;
if (widthleft > st::mentionFont->elidew && !command->descriptionText().isEmpty()) {
if (!row.description.isEmpty()
&& row.descriptionText.isEmpty()) {
row.descriptionText.setText(
st::defaultTextStyle,
row.description,
Ui::NameTextOptions());
}
if (widthleft > st::mentionFont->elidew && !row.descriptionText.isEmpty()) {
p.setPen((selected ? st::mentionFgOver : st::mentionFg)->p);
command->descriptionText().drawElided(p, mentionleft + addleft, i * st::mentionHeight + st::mentionTop, widthleft);
row.descriptionText.drawElided(p, mentionleft + addleft, i * st::mentionHeight + st::mentionTop, widthleft);
}
}
}
@ -1063,7 +1080,7 @@ bool FieldAutocomplete::Inner::chooseAtIndex(
} else if (!_brows->empty()) {
if (index < _brows->size()) {
const auto user = _brows->at(index).user;
const auto command = _brows->at(index).command;
const auto &command = _brows->at(index).command;
const auto botStatus = _parent->chat()
? _parent->chat()->botStatus
: ((_parent->channel() && _parent->channel()->isMegagroup())
@ -1074,7 +1091,7 @@ bool FieldAutocomplete::Inner::chooseAtIndex(
|| botStatus == 2
|| _parent->filter().indexOf('@') > 0);
const auto commandString = QString("/%1%2").arg(
command->command,
command,
insertUsername ? ('@' + user->username) : QString());
_botCommandChosen.fire({ commandString, method });

View file

@ -136,8 +136,10 @@ private:
struct BotCommandRow {
not_null<UserData*> user;
not_null<const BotCommand*> command;
QString command;
QString description;
std::shared_ptr<Data::CloudImageView> userpic;
Ui::Text::String descriptionText;
};
using HashtagRows = std::vector<QString>;

View file

@ -24,32 +24,6 @@ using UpdateFlag = Data::PeerUpdate::Flag;
} // namespace
BotCommand::BotCommand(
const QString &command,
const QString &description)
: command(command)
, _description(description) {
}
bool BotCommand::setDescription(const QString &description) {
if (_description != description) {
_description = description;
_descriptionText = Ui::Text::String();
return true;
}
return false;
}
const Ui::Text::String &BotCommand::descriptionText() const {
if (_descriptionText.isEmpty() && !_description.isEmpty()) {
_descriptionText.setText(
st::defaultTextStyle,
_description,
Ui::NameTextOptions());
}
return _descriptionText;
}
UserData::UserData(not_null<Data::Session*> owner, PeerId id)
: PeerData(owner, id) {
}
@ -132,7 +106,7 @@ void UserData::setBotInfoVersion(int version) {
botInfo->version = version;
owner().userIsBotChanged(this);
} else if (botInfo->version < version) {
if (!botInfo->commands.isEmpty()) {
if (!botInfo->commands.empty()) {
botInfo->commands.clear();
owner().botCommandsChanged(this);
}
@ -162,17 +136,21 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
int32 j = 0;
for (const auto &command : v) {
command.match([&](const MTPDbotCommand &data) {
const auto cmd = qs(data.vcommand());
const auto desc = qs(data.vdescription());
const auto command = qs(data.vcommand());
const auto description = qs(data.vdescription());
if (botInfo->commands.size() <= j) {
botInfo->commands.push_back(BotCommand(cmd, desc));
botInfo->commands.push_back({
.command = command,
.description = description,
});
changedCommands = true;
} else {
if (botInfo->commands[j].command != cmd) {
botInfo->commands[j].command = cmd;
if (botInfo->commands[j].command != command) {
botInfo->commands[j].command = command;
changedCommands = true;
}
if (botInfo->commands[j].setDescription(desc)) {
if (botInfo->commands[j].description != description) {
botInfo->commands[j].description = description;
changedCommands = true;
}
}

View file

@ -10,19 +10,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_peer.h"
#include "dialogs/dialogs_key.h"
class BotCommand {
public:
BotCommand(const QString &command, const QString &description);
bool setDescription(const QString &description);
const Ui::Text::String &descriptionText() const;
struct BotCommand {
QString command;
private:
QString _description;
mutable Ui::Text::String _descriptionText;
QString description;
};
struct BotInfo {
@ -31,7 +21,7 @@ struct BotInfo {
bool cantJoinGroups = false;
int version = 0;
QString description, inlinePlaceholder;
QList<BotCommand> commands;
std::vector<BotCommand> commands;
Ui::Text::String text = { int(st::msgMinWidth) }; // description
QString startToken, startGroupToken, shareGameShortName;