summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorLoren Burkholder <computersemiexpert@outlook.com>2023-02-27 18:06:24 -0500
committerLoren Burkholder <computersemiexpert@outlook.com>2023-02-28 20:10:25 -0500
commit22ac5d861e487ff39749f5d2bdda9113689e4b63 (patch)
tree8031235b2d798b37d0d9add9e6f8ddfb7e4531a6 /src/timeline
parentShow warning when invalid command is entered (diff)
downloadnheko-22ac5d861e487ff39749f5d2bdda9113689e4b63.tar.xz
Move command calculation logic into InputBar
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/InputBar.cpp94
-rw-r--r--src/timeline/InputBar.h16
2 files changed, 89 insertions, 21 deletions
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index 5184ba94..6c882cd4 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -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)
 {
diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h
index 80ad7f47..7385d272 100644
--- a/src/timeline/InputBar.h
+++ b/src/timeline/InputBar.h
@@ -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;