summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--resources/qml/MessageInput.qml13
-rw-r--r--resources/qml/NhekoBusyIndicator.qml4
-rw-r--r--src/ChatPage.cpp32
-rw-r--r--src/ChatPage.h1
-rw-r--r--src/TextInputWidget.cpp30
-rw-r--r--src/TextInputWidget.h5
-rw-r--r--src/timeline/InputBar.cpp45
-rw-r--r--src/timeline/InputBar.h1
-rw-r--r--src/timeline/TimelineViewManager.cpp136
-rw-r--r--src/timeline/TimelineViewManager.h31
10 files changed, 86 insertions, 212 deletions
diff --git a/resources/qml/MessageInput.qml b/resources/qml/MessageInput.qml
index a1220599..17e1198d 100644
--- a/resources/qml/MessageInput.qml
+++ b/resources/qml/MessageInput.qml
@@ -17,14 +17,18 @@ Rectangle {
         spacing: 16
 
         ImageButton {
+            visible: TimelineManager.callsSupported
             Layout.alignment: Qt.AlignBottom
             hoverEnabled: true
             width: 22
             height: 22
-            image: ":/icons/icons/ui/place-call.png"
+            image: TimelineManager.isOnCall ? ":/icons/icons/ui/end-call.png" : ":/icons/icons/ui/place-call.png"
+            ToolTip.visible: hovered
+            ToolTip.text: TimelineManager.isOnCall ? qsTr("Hang up") : qsTr("Place a call")
             Layout.topMargin: 8
             Layout.bottomMargin: 8
             Layout.leftMargin: 16
+            onClicked: TimelineManager.timeline.input.callButton()
         }
 
         ImageButton {
@@ -35,7 +39,10 @@ Rectangle {
             image: ":/icons/icons/ui/paper-clip-outline.png"
             Layout.topMargin: 8
             Layout.bottomMargin: 8
+            Layout.leftMargin: TimelineManager.callsSupported ? 0 : 16
             onClicked: TimelineManager.timeline.input.openFileSelection()
+            ToolTip.visible: hovered
+            ToolTip.text: qsTr("Send a file")
 
             Rectangle {
                 anchors.fill: parent
@@ -112,6 +119,8 @@ Rectangle {
             image: ":/icons/icons/ui/smile.png"
             Layout.topMargin: 8
             Layout.bottomMargin: 8
+            ToolTip.visible: hovered
+            ToolTip.text: qsTr("Emoji")
         }
 
         ImageButton {
@@ -123,6 +132,8 @@ Rectangle {
             Layout.topMargin: 8
             Layout.bottomMargin: 8
             Layout.rightMargin: 16
+            ToolTip.visible: hovered
+            ToolTip.text: qsTr("Send")
             onClicked: {
                 TimelineManager.timeline.input.send();
                 textArea.clear();
diff --git a/resources/qml/NhekoBusyIndicator.qml b/resources/qml/NhekoBusyIndicator.qml
index 8889989a..89a40dd5 100644
--- a/resources/qml/NhekoBusyIndicator.qml
+++ b/resources/qml/NhekoBusyIndicator.qml
@@ -6,8 +6,8 @@ BusyIndicator {
     id: control
 
     contentItem: Item {
-        implicitWidth: Math.min(parent.height, parent.width)
-        implicitHeight: implicitWidth
+        implicitWidth: 64
+        implicitHeight: 64
 
         Item {
             id: item
diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index e09041e7..c703d95f 100644
--- a/src/ChatPage.cpp
+++ b/src/ChatPage.cpp
@@ -268,38 +268,6 @@ ChatPage::ChatPage(QSharedPointer<UserSettings> userSettings, QWidget *parent)
                 this,
                 SIGNAL(unreadMessages(int)));
 
-        connect(text_input_, &TextInputWidget::callButtonPress, this, [this]() {
-                if (callManager_->onActiveCall()) {
-                        callManager_->hangUp();
-                } else {
-                        if (auto roomInfo = cache::singleRoomInfo(current_room_.toStdString());
-                            roomInfo.member_count != 2) {
-                                showNotification("Calls are limited to 1:1 rooms.");
-                        } else {
-                                std::vector<RoomMember> members(
-                                  cache::getMembers(current_room_.toStdString()));
-                                const RoomMember &callee =
-                                  members.front().user_id == utils::localUser() ? members.back()
-                                                                                : members.front();
-                                auto dialog = new dialogs::PlaceCall(
-                                  callee.user_id,
-                                  callee.display_name,
-                                  QString::fromStdString(roomInfo.name),
-                                  QString::fromStdString(roomInfo.avatar_url),
-                                  userSettings_,
-                                  MainWindow::instance());
-                                connect(dialog, &dialogs::PlaceCall::voice, this, [this]() {
-                                        callManager_->sendInvite(current_room_, false);
-                                });
-                                connect(dialog, &dialogs::PlaceCall::video, this, [this]() {
-                                        callManager_->sendInvite(current_room_, true);
-                                });
-                                utils::centerWidget(dialog, MainWindow::instance());
-                                dialog->show();
-                        }
-                }
-        });
-
         connect(
           this, &ChatPage::updateGroupsInfo, communitiesList_, &CommunitiesList::setCommunities);
 
diff --git a/src/ChatPage.h b/src/ChatPage.h
index 41c6f276..7eb37f04 100644
--- a/src/ChatPage.h
+++ b/src/ChatPage.h
@@ -88,6 +88,7 @@ public:
         static ChatPage *instance() { return instance_; }
 
         QSharedPointer<UserSettings> userSettings() { return userSettings_; }
+        CallManager *callManager() { return callManager_; }
         void deleteConfigs();
 
         CommunitiesList *communitiesList() { return communitiesList_; }
diff --git a/src/TextInputWidget.cpp b/src/TextInputWidget.cpp
index 232c0cad..1a856abb 100644
--- a/src/TextInputWidget.cpp
+++ b/src/TextInputWidget.cpp
@@ -431,15 +431,6 @@ TextInputWidget::TextInputWidget(QWidget *parent)
         topLayout_->setSpacing(0);
         topLayout_->setContentsMargins(13, 1, 13, 0);
 
-#ifdef GSTREAMER_AVAILABLE
-        callBtn_ = new FlatButton(this);
-        changeCallButtonState(webrtc::State::DISCONNECTED);
-        connect(&WebRTCSession::instance(),
-                &WebRTCSession::stateChanged,
-                this,
-                &TextInputWidget::changeCallButtonState);
-#endif
-
         QIcon send_file_icon;
         send_file_icon.addFile(":/icons/icons/ui/paper-clip-outline.png");
 
@@ -508,9 +499,6 @@ TextInputWidget::TextInputWidget(QWidget *parent)
         emojiBtn_->setIcon(emoji_icon);
         emojiBtn_->setIconSize(QSize(ButtonHeight, ButtonHeight));
 
-#ifdef GSTREAMER_AVAILABLE
-        topLayout_->addWidget(callBtn_);
-#endif
         topLayout_->addWidget(sendFileBtn_);
         topLayout_->addWidget(input_);
         topLayout_->addWidget(emojiBtn_);
@@ -518,9 +506,6 @@ TextInputWidget::TextInputWidget(QWidget *parent)
 
         setLayout(topLayout_);
 
-#ifdef GSTREAMER_AVAILABLE
-        connect(callBtn_, &FlatButton::clicked, this, &TextInputWidget::callButtonPress);
-#endif
         connect(sendMessageBtn_, &FlatButton::clicked, input_, &FilteredTextEdit::submit);
         connect(sendFileBtn_, SIGNAL(clicked()), this, SLOT(openFileSelection()));
         connect(emojiBtn_,
@@ -570,18 +555,3 @@ TextInputWidget::paintEvent(QPaintEvent *)
 
         style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
 }
-
-void
-TextInputWidget::changeCallButtonState(webrtc::State state)
-{
-        QIcon icon;
-        if (state == webrtc::State::ICEFAILED || state == webrtc::State::DISCONNECTED) {
-                callBtn_->setToolTip(tr("Place a call"));
-                icon.addFile(":/icons/icons/ui/place-call.png");
-        } else {
-                callBtn_->setToolTip(tr("Hang up"));
-                icon.addFile(":/icons/icons/ui/end-call.png");
-        }
-        callBtn_->setIcon(icon);
-        callBtn_->setIconSize(QSize(ButtonHeight * 1.1, ButtonHeight * 1.1));
-}
diff --git a/src/TextInputWidget.h b/src/TextInputWidget.h
index 44419547..9613f209 100644
--- a/src/TextInputWidget.h
+++ b/src/TextInputWidget.h
@@ -26,7 +26,6 @@
 #include <QTextEdit>
 #include <QWidget>
 
-#include "WebRTCSession.h"
 #include "dialogs/PreviewUploadOverlay.h"
 #include "emoji/PickButton.h"
 #include "popups/SuggestionsPopup.h"
@@ -155,7 +154,6 @@ public:
 
 public slots:
         void focusLineEdit() { input_->setFocus(); }
-        void changeCallButtonState(webrtc::State);
 
 private slots:
         void addSelectedEmoji(const QString &emoji);
@@ -163,8 +161,6 @@ private slots:
 signals:
         void heightChanged(int height);
 
-        void callButtonPress();
-
         void sendJoinRoomRequest(const QString &room);
         void sendInviteRoomRequest(const QString &userid, const QString &reason);
         void sendKickRoomRequest(const QString &userid, const QString &reason);
@@ -185,7 +181,6 @@ private:
 
         LoadingIndicator *spinner_;
 
-        FlatButton *callBtn_;
         FlatButton *sendFileBtn_;
         FlatButton *sendMessageBtn_;
         emoji::PickButton *emojiBtn_;
diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp
index bd8f6414..dc287f94 100644
--- a/src/timeline/InputBar.cpp
+++ b/src/timeline/InputBar.cpp
@@ -12,13 +12,16 @@
 #include <mtx/responses/media.hpp>
 
 #include "Cache.h"
+#include "CallManager.h"
 #include "ChatPage.h"
 #include "Logging.h"
+#include "MainWindow.h"
 #include "MatrixClient.h"
 #include "Olm.h"
 #include "TimelineModel.h"
 #include "UserSettingsPage.h"
 #include "Utils.h"
+#include "dialogs/PlaceCall.h"
 #include "dialogs/PreviewUploadOverlay.h"
 
 #include "blurhash.hpp"
@@ -511,3 +514,45 @@ InputBar::showPreview(const QMimeData &source, QString path, const QStringList &
                     });
           });
 }
+
+void
+InputBar::callButton()
+{
+        auto callManager_ = ChatPage::instance()->callManager();
+        if (callManager_->onActiveCall()) {
+                callManager_->hangUp();
+        } else {
+                auto current_room_ = room->roomId();
+                if (auto roomInfo = cache::singleRoomInfo(current_room_.toStdString());
+                    roomInfo.member_count != 2) {
+                        ChatPage::instance()->showNotification("Calls are limited to 1:1 rooms.");
+                } else {
+                        std::vector<RoomMember> members(
+                          cache::getMembers(current_room_.toStdString()));
+                        const RoomMember &callee = members.front().user_id == utils::localUser()
+                                                     ? members.back()
+                                                     : members.front();
+                        auto dialog =
+                          new dialogs::PlaceCall(callee.user_id,
+                                                 callee.display_name,
+                                                 QString::fromStdString(roomInfo.name),
+                                                 QString::fromStdString(roomInfo.avatar_url),
+                                                 ChatPage::instance()->userSettings(),
+                                                 MainWindow::instance());
+                        connect(dialog,
+                                &dialogs::PlaceCall::voice,
+                                callManager_,
+                                [callManager_, current_room_]() {
+                                        callManager_->sendInvite(current_room_, false);
+                                });
+                        connect(dialog,
+                                &dialogs::PlaceCall::video,
+                                callManager_,
+                                [callManager_, current_room_]() {
+                                        callManager_->sendInvite(current_room_, true);
+                                });
+                        utils::centerWidget(dialog, MainWindow::instance());
+                        dialog->show();
+                }
+        }
+}
diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h
index 35e3f8a4..a52a3904 100644
--- a/src/timeline/InputBar.h
+++ b/src/timeline/InputBar.h
@@ -27,6 +27,7 @@ public slots:
         void updateState(int selectionStart, int selectionEnd, int cursorPosition, QString text);
         void openFileSelection();
         bool uploading() const { return uploading_; }
+        void callButton();
 
 signals:
         void insertText(QString text);
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index f949498d..1392c505 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -244,6 +244,26 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
                 &CallManager::newVideoCallState,
                 this,
                 &TimelineViewManager::videoCallChanged);
+
+        connect(&WebRTCSession::instance(),
+                &WebRTCSession::stateChanged,
+                this,
+                &TimelineViewManager::onCallChanged);
+}
+
+bool
+TimelineViewManager::isOnCall() const
+{
+        return callManager_->onActiveCall();
+}
+bool
+TimelineViewManager::callsSupported() const
+{
+#ifdef GSTREAMER_AVAILABLE
+        return true;
+#else
+        return false;
+#endif
 }
 
 void
@@ -506,122 +526,6 @@ TimelineViewManager::queueReactionMessage(const QString &reactedEvent, const QSt
                 timeline_->redactEvent(selfReactedEvent);
         }
 }
-
-void
-TimelineViewManager::queueImageMessage(const QString &roomid,
-                                       const QString &filename,
-                                       const std::optional<mtx::crypto::EncryptedFile> &file,
-                                       const QString &url,
-                                       const QString &mime,
-                                       uint64_t dsize,
-                                       const QSize &dimensions,
-                                       const QString &blurhash)
-{
-        mtx::events::msg::Image image;
-        image.info.mimetype = mime.toStdString();
-        image.info.size     = dsize;
-        image.info.blurhash = blurhash.toStdString();
-        image.body          = filename.toStdString();
-        image.info.h        = dimensions.height();
-        image.info.w        = dimensions.width();
-
-        if (file)
-                image.file = file;
-        else
-                image.url = url.toStdString();
-
-        auto model = models.value(roomid);
-        if (!model->reply().isEmpty()) {
-                image.relates_to.in_reply_to.event_id = model->reply().toStdString();
-                model->resetReply();
-        }
-
-        model->sendMessageEvent(image, mtx::events::EventType::RoomMessage);
-}
-
-void
-TimelineViewManager::queueFileMessage(
-  const QString &roomid,
-  const QString &filename,
-  const std::optional<mtx::crypto::EncryptedFile> &encryptedFile,
-  const QString &url,
-  const QString &mime,
-  uint64_t dsize)
-{
-        mtx::events::msg::File file;
-        file.info.mimetype = mime.toStdString();
-        file.info.size     = dsize;
-        file.body          = filename.toStdString();
-
-        if (encryptedFile)
-                file.file = encryptedFile;
-        else
-                file.url = url.toStdString();
-
-        auto model = models.value(roomid);
-        if (!model->reply().isEmpty()) {
-                file.relates_to.in_reply_to.event_id = model->reply().toStdString();
-                model->resetReply();
-        }
-
-        model->sendMessageEvent(file, mtx::events::EventType::RoomMessage);
-}
-
-void
-TimelineViewManager::queueAudioMessage(const QString &roomid,
-                                       const QString &filename,
-                                       const std::optional<mtx::crypto::EncryptedFile> &file,
-                                       const QString &url,
-                                       const QString &mime,
-                                       uint64_t dsize)
-{
-        mtx::events::msg::Audio audio;
-        audio.info.mimetype = mime.toStdString();
-        audio.info.size     = dsize;
-        audio.body          = filename.toStdString();
-        audio.url           = url.toStdString();
-
-        if (file)
-                audio.file = file;
-        else
-                audio.url = url.toStdString();
-
-        auto model = models.value(roomid);
-        if (!model->reply().isEmpty()) {
-                audio.relates_to.in_reply_to.event_id = model->reply().toStdString();
-                model->resetReply();
-        }
-
-        model->sendMessageEvent(audio, mtx::events::EventType::RoomMessage);
-}
-
-void
-TimelineViewManager::queueVideoMessage(const QString &roomid,
-                                       const QString &filename,
-                                       const std::optional<mtx::crypto::EncryptedFile> &file,
-                                       const QString &url,
-                                       const QString &mime,
-                                       uint64_t dsize)
-{
-        mtx::events::msg::Video video;
-        video.info.mimetype = mime.toStdString();
-        video.info.size     = dsize;
-        video.body          = filename.toStdString();
-
-        if (file)
-                video.file = file;
-        else
-                video.url = url.toStdString();
-
-        auto model = models.value(roomid);
-        if (!model->reply().isEmpty()) {
-                video.relates_to.in_reply_to.event_id = model->reply().toStdString();
-                model->resetReply();
-        }
-
-        model->sendMessageEvent(video, mtx::events::EventType::RoomMessage);
-}
-
 void
 TimelineViewManager::queueCallMessage(const QString &roomid,
                                       const mtx::events::msg::CallInvite &callInvite)
diff --git a/src/timeline/TimelineViewManager.h b/src/timeline/TimelineViewManager.h
index 02e0e132..371e9af2 100644
--- a/src/timeline/TimelineViewManager.h
+++ b/src/timeline/TimelineViewManager.h
@@ -41,6 +41,8 @@ class TimelineViewManager : public QObject
         Q_PROPERTY(QString callPartyName READ callPartyName NOTIFY callPartyChanged)
         Q_PROPERTY(QString callPartyAvatarUrl READ callPartyAvatarUrl NOTIFY callPartyChanged)
         Q_PROPERTY(bool isMicMuted READ isMicMuted NOTIFY micMuteChanged)
+        Q_PROPERTY(bool isOnCall READ isOnCall NOTIFY onCallChanged)
+        Q_PROPERTY(bool callsSupported READ callsSupported CONSTANT)
 
 public:
         TimelineViewManager(CallManager *callManager, ChatPage *parent = nullptr);
@@ -95,6 +97,7 @@ signals:
         void videoCallChanged();
         void callPartyChanged();
         void micMuteChanged();
+        void onCallChanged();
 
 public slots:
         void updateReadReceipts(const QString &room_id, const std::vector<QString> &event_ids);
@@ -104,38 +107,14 @@ public slots:
         void setHistoryView(const QString &room_id);
         void updateColorPalette();
         void queueReactionMessage(const QString &reactedEvent, const QString &reactionKey);
-        void queueImageMessage(const QString &roomid,
-                               const QString &filename,
-                               const std::optional<mtx::crypto::EncryptedFile> &file,
-                               const QString &url,
-                               const QString &mime,
-                               uint64_t dsize,
-                               const QSize &dimensions,
-                               const QString &blurhash);
-        void queueFileMessage(const QString &roomid,
-                              const QString &filename,
-                              const std::optional<mtx::crypto::EncryptedFile> &file,
-                              const QString &url,
-                              const QString &mime,
-                              uint64_t dsize);
-        void queueAudioMessage(const QString &roomid,
-                               const QString &filename,
-                               const std::optional<mtx::crypto::EncryptedFile> &file,
-                               const QString &url,
-                               const QString &mime,
-                               uint64_t dsize);
-        void queueVideoMessage(const QString &roomid,
-                               const QString &filename,
-                               const std::optional<mtx::crypto::EncryptedFile> &file,
-                               const QString &url,
-                               const QString &mime,
-                               uint64_t dsize);
         void queueCallMessage(const QString &roomid, const mtx::events::msg::CallInvite &);
         void queueCallMessage(const QString &roomid, const mtx::events::msg::CallCandidates &);
         void queueCallMessage(const QString &roomid, const mtx::events::msg::CallAnswer &);
         void queueCallMessage(const QString &roomid, const mtx::events::msg::CallHangUp &);
 
         void updateEncryptedDescriptions();
+        bool isOnCall() const;
+        bool callsSupported() const;
 
         void enableBackButton()
         {