Move command calculation logic into InputBar

This commit is contained in:
Loren Burkholder 2023-02-27 18:06:24 -05:00
parent b6ef00b5ee
commit 22ac5d861e
5 changed files with 91 additions and 95 deletions

View file

@ -159,17 +159,8 @@ Item {
}
MessageInputWarning {
text: qsTr("The command /%1 is not recognized and will be sent as part of your message").arg(Nheko.getCommandFromText(input.text))
isVisible: {
if (!input.text)
return false;
let command = Nheko.getCommandFromText(input.text);
if (Nheko.isInvalidCommand(command) && ("/" + command !== input.text))
return true;
else
return false;
}
text: qsTr("The command /%1 is not recognized and will be sent as part of your message").arg(room ? room.input.currentCommand : "")
isVisible: room ? room.input.containsInvalidCommand : false
}
ReplyPopup {

View file

@ -224,8 +224,9 @@ InputBar::insertMimeData(const QMimeData *md)
}
void
InputBar::updateAtRoom(const QString &t)
InputBar::updateTextContentProperties(const QString &t)
{
// check for @room
bool roomMention = false;
if (t.size() > 4) {
@ -249,6 +250,54 @@ InputBar::updateAtRoom(const QString &t)
this->containsAtRoom_ = roomMention;
emit containsAtRoomChanged();
}
// check for invalid commands
auto commandName = getCommandAndArgs().first;
bool hasInvalidCommand{};
if (!commandName.isNull() && '/' + commandName != text()) {
static const QStringList validCommands{QStringLiteral("me"),
QStringLiteral("react"),
QStringLiteral("join"),
QStringLiteral("knock"),
QStringLiteral("part"),
QStringLiteral("leave"),
QStringLiteral("invite"),
QStringLiteral("kick"),
QStringLiteral("ban"),
QStringLiteral("unban"),
QStringLiteral("redact"),
QStringLiteral("roomnick"),
QStringLiteral("shrug"),
QStringLiteral("fliptable"),
QStringLiteral("unfliptable"),
QStringLiteral("sovietflip"),
QStringLiteral("clear-timeline"),
QStringLiteral("reset-state"),
QStringLiteral("rotate-megolm-session"),
QStringLiteral("md"),
QStringLiteral("cmark"),
QStringLiteral("plain"),
QStringLiteral("rainbow"),
QStringLiteral("rainbowme"),
QStringLiteral("notice"),
QStringLiteral("rainbownotice"),
QStringLiteral("confetti"),
QStringLiteral("rainbowconfetti"),
QStringLiteral("goto"),
QStringLiteral("converttodm"),
QStringLiteral("converttoroom")};
hasInvalidCommand = !validCommands.contains(commandName);
} else
hasInvalidCommand = false;
if (containsInvalidCommand_ != hasInvalidCommand) {
containsInvalidCommand_ = hasInvalidCommand;
emit containsInvalidCommandChanged();
}
if (currentCommand_ != commandName) {
currentCommand_ = commandName;
emit currentCommandChanged();
}
}
void
@ -263,7 +312,7 @@ InputBar::setText(const QString &newText)
if (history_.size() == INPUT_HISTORY_SIZE)
history_.pop_back();
updateAtRoom(QLatin1String(""));
updateTextContentProperties(QLatin1String(""));
emit textChanged(newText);
}
void
@ -284,7 +333,7 @@ InputBar::updateState(int selectionStart_,
history_.front() = text_;
history_index_ = 0;
updateAtRoom(text_);
updateTextContentProperties(text_);
// disabled, as it moves the cursor to the end
// emit textChanged(text_);
}
@ -312,7 +361,7 @@ InputBar::previousText()
else if (text().isEmpty())
history_index_--;
updateAtRoom(text());
updateTextContentProperties(text());
return text();
}
@ -323,7 +372,7 @@ InputBar::nextText()
if (history_index_ >= INPUT_HISTORY_SIZE)
history_index_ = 0;
updateAtRoom(text());
updateTextContentProperties(text());
return text();
}
@ -341,20 +390,11 @@ InputBar::send()
auto wasEdit = !room->edit().isEmpty();
if (text().startsWith('/')) {
int command_end = text().indexOf(QRegularExpression(QStringLiteral("\\s")));
if (command_end == -1)
command_end = text().size();
auto name = text().mid(1, command_end - 1);
auto args = text().mid(command_end + 1);
if (name.isEmpty() || name == QLatin1String("/")) {
message(args);
} else {
command(name, args);
}
} else {
auto [commandName, args] = getCommandAndArgs();
if (commandName.isNull())
message(text());
}
else
command(commandName, args);
if (!wasEdit) {
history_.push_front(QLatin1String(""));
@ -716,6 +756,24 @@ InputBar::video(const QString &filename,
room->sendMessageEvent(video, mtx::events::EventType::RoomMessage);
}
QPair<QString, QString>
InputBar::getCommandAndArgs() const
{
if (!text().startsWith('/'))
return {{}, text()};
int command_end = text().indexOf(QRegularExpression(QStringLiteral("\\s")));
if (command_end == -1)
command_end = text().size();
auto name = text().mid(1, command_end - 1);
auto args = text().mid(command_end + 1);
if (name.isEmpty() || name == QLatin1String("/")) {
return {{}, text()};
} else {
return {name, args};
}
}
void
InputBar::sticker(CombinedImagePackModel *model, int row)
{

View file

@ -173,6 +173,9 @@ class InputBar final : public QObject
Q_OBJECT
Q_PROPERTY(bool uploading READ uploading NOTIFY uploadingChanged)
Q_PROPERTY(bool containsAtRoom READ containsAtRoom NOTIFY containsAtRoomChanged)
Q_PROPERTY(
bool containsInvalidCommand READ containsInvalidCommand NOTIFY containsInvalidCommandChanged)
Q_PROPERTY(QString currentCommand READ currentCommand NOTIFY currentCommandChanged)
Q_PROPERTY(QString text READ text NOTIFY textChanged)
Q_PROPERTY(QVariantList uploads READ uploads NOTIFY uploadsChanged)
@ -198,6 +201,8 @@ public slots:
void setText(const QString &newText);
[[nodiscard]] bool containsAtRoom() const { return containsAtRoom_; }
bool containsInvalidCommand() const { return containsInvalidCommand_; }
QString currentCommand() const { return currentCommand_; }
void send();
bool tryPasteAttachment(bool fromMouse);
@ -225,6 +230,8 @@ signals:
void textChanged(QString newText);
void uploadingChanged(bool value);
void containsAtRoomChanged();
void containsInvalidCommandChanged();
void currentCommandChanged();
void uploadsChanged();
private:
@ -267,6 +274,7 @@ private:
const QSize &thumbnailDimensions,
const QString &blurhash);
QPair<QString, QString> getCommandAndArgs() const;
mtx::common::Relations generateRelations() const;
void startUploadFromPath(const QString &path);
@ -280,7 +288,7 @@ private:
}
}
void updateAtRoom(const QString &t);
void updateTextContentProperties(const QString &t);
QTimer typingRefresh_;
QTimer typingTimeout_;
@ -288,8 +296,10 @@ private:
std::deque<QString> history_;
std::size_t history_index_ = 0;
int selectionStart = 0, selectionEnd = 0, cursorPosition = 0;
bool uploading_ = false;
bool containsAtRoom_ = false;
bool uploading_ = false;
bool containsAtRoom_ = false;
bool containsInvalidCommand_ = false;
QString currentCommand_;
using UploadHandle = std::unique_ptr<MediaUpload, DeleteLaterDeleter>;
std::vector<UploadHandle> unconfirmedUploads;

View file

@ -190,63 +190,3 @@ Nheko::setWindowRole([[maybe_unused]] QWindow *win, [[maybe_unused]] QString new
QXcbWindowFunctions::setWmWindowRole(win, newRole.toUtf8());
#endif
}
QString
Nheko::getCommandFromText(const QString &text)
{
if (text.startsWith('/')) {
int command_end = text.indexOf(QRegularExpression(QStringLiteral("\\s")));
if (command_end == -1)
command_end = text.size();
auto command = text.mid(1, command_end - 1);
if (command.isEmpty() || command == QLatin1String("/"))
return {};
else {
return command;
}
} else
return {};
}
bool
Nheko::isInvalidCommand(QString command) const
{
if (command.size() <= 0)
return false;
static const QStringList validCommands{QStringLiteral("/me"),
QStringLiteral("/react"),
QStringLiteral("/join"),
QStringLiteral("/knock"),
QStringLiteral("/part"),
QStringLiteral("/leave"),
QStringLiteral("/invite"),
QStringLiteral("/kick"),
QStringLiteral("/ban"),
QStringLiteral("/unban"),
QStringLiteral("/redact"),
QStringLiteral("/roomnick"),
QStringLiteral("/shrug"),
QStringLiteral("/fliptable"),
QStringLiteral("/unfliptable"),
QStringLiteral("/sovietflip"),
QStringLiteral("/clear-timeline"),
QStringLiteral("/reset-state"),
QStringLiteral("/rotate-megolm-session"),
QStringLiteral("/md"),
QStringLiteral("/cmark"),
QStringLiteral("/plain"),
QStringLiteral("/rainbow"),
QStringLiteral("/rainbowme"),
QStringLiteral("/notice"),
QStringLiteral("/rainbownotice"),
QStringLiteral("/confetti"),
QStringLiteral("/rainbowconfetti"),
QStringLiteral("/goto"),
QStringLiteral("/converttodm"),
QStringLiteral("/converttoroom")};
if (!command.startsWith('/'))
command.prepend('/');
return !validCommands.contains(command);
}

View file

@ -72,9 +72,6 @@ public:
Q_INVOKABLE void setTransientParent(QWindow *window, QWindow *parentWindow) const;
Q_INVOKABLE void setWindowRole(QWindow *win, QString newRole) const;
Q_INVOKABLE QString getCommandFromText(const QString &text);
Q_INVOKABLE bool isInvalidCommand(QString command) const;
public slots:
void updateUserProfile();