summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2021-04-29 21:46:49 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2021-04-29 21:46:49 +0200
commitf626de04470de57d5443737804739cff27416d04 (patch)
tree0b5184b02d14663e436f46f2b98a27f11aed6522
parentActually use qt5.12 in CI (diff)
downloadnheko-f626de04470de57d5443737804739cff27416d04.tar.xz
Copy link to message
fixes #499
-rw-r--r--CMakeLists.txt2
-rw-r--r--resources/qml/TimelineView.qml7
-rw-r--r--src/Clipboard.cpp23
-rw-r--r--src/Clipboard.h18
-rw-r--r--src/timeline/TimelineModel.cpp44
-rw-r--r--src/timeline/TimelineModel.h1
-rw-r--r--src/timeline/TimelineViewManager.cpp5
7 files changed, 100 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 468480d8..70b74602 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -306,6 +306,7 @@ set(SRC_FILES
 	src/CallDevices.cpp
 	src/CallManager.cpp
 	src/ChatPage.cpp
+	src/Clipboard.cpp
 	src/ColorImageProvider.cpp
 	src/CommunitiesList.cpp
 	src/CommunitiesListItem.cpp
@@ -526,6 +527,7 @@ qt5_wrap_cpp(MOC_HEADERS
 	src/CallDevices.h
 	src/CallManager.h
 	src/ChatPage.h
+	src/Clipboard.h
 	src/CommunitiesList.h
 	src/CommunitiesListItem.h
 	src/CompletionProxyModel.h
diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml
index 81ca7705..59a98bdb 100644
--- a/resources/qml/TimelineView.qml
+++ b/resources/qml/TimelineView.qml
@@ -177,6 +177,13 @@ Page {
             enabled: visible
             text: qsTr("Open in external program")
             onTriggered: TimelineManager.timeline.openMedia(messageContextMenu.eventId)
+    }
+
+        Platform.MenuItem {
+            visible: messageContextMenu.eventId
+            enabled: visible
+            text: qsTr("Copy link to event")
+            onTriggered: TimelineManager.timeline.copyLinkToEvent(messageContextMenu.eventId)
         }
 
     }
diff --git a/src/Clipboard.cpp b/src/Clipboard.cpp
new file mode 100644
index 00000000..720f30fd
--- /dev/null
+++ b/src/Clipboard.cpp
@@ -0,0 +1,23 @@
+#include "Clipboard.h"
+
+#include <QClipboard>
+#include <QGuiApplication>
+
+Clipboard::Clipboard(QObject *parent)
+  : QObject(parent)
+{
+        connect(
+          QGuiApplication::clipboard(), &QClipboard::dataChanged, this, &Clipboard::textChanged);
+}
+
+void
+Clipboard::setText(QString text)
+{
+        QGuiApplication::clipboard()->setText(text);
+}
+
+QString
+Clipboard::text() const
+{
+        return QGuiApplication::clipboard()->text();
+}
diff --git a/src/Clipboard.h b/src/Clipboard.h
new file mode 100644
index 00000000..6d0dc2f0
--- /dev/null
+++ b/src/Clipboard.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <QObject>
+#include <QString>
+
+class Clipboard : public QObject
+{
+        Q_OBJECT
+        Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+
+public:
+        Clipboard(QObject *parent = nullptr);
+
+        QString text() const;
+        void setText(QString text_);
+signals:
+        void textChanged();
+};
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 5a0f9bad..2f7bfdd2 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -9,13 +9,16 @@
 #include <type_traits>
 
 #include <QCache>
+#include <QClipboard>
 #include <QDesktopServices>
 #include <QFileDialog>
+#include <QGuiApplication>
 #include <QMimeDatabase>
 #include <QRegularExpression>
 #include <QSettings>
 #include <QStandardPaths>
 
+#include "Cache_p.h"
 #include "ChatPage.h"
 #include "Config.h"
 #include "EventAccessors.h"
@@ -1336,6 +1339,47 @@ TimelineModel::scrollTimerEvent()
         }
 }
 
+void
+TimelineModel::copyLinkToEvent(QString eventId) const
+{
+        QStringList vias;
+
+        auto alias = cache::client()->getRoomAliases(room_id_.toStdString());
+        QString room;
+        if (alias) {
+                room = QString::fromStdString(alias->alias);
+                if (room.isEmpty() && !alias->alt_aliases.empty()) {
+                        room = QString::fromStdString(alias->alt_aliases.front());
+                }
+        }
+
+        if (room.isEmpty())
+                room = room_id_;
+
+        vias.push_back(QString("via=%1").arg(QString(
+          QUrl::toPercentEncoding(QString::fromStdString(http::client()->user_id().hostname())))));
+        auto members = cache::getMembers(room_id_.toStdString(), 0, 100);
+        for (const auto &m : members) {
+                if (vias.size() >= 4)
+                        break;
+
+                auto user_id =
+                  mtx::identifiers::parse<mtx::identifiers::User>(m.user_id.toStdString());
+                QString server = QString("via=%1").arg(
+                  QString(QUrl::toPercentEncoding(QString::fromStdString(user_id.hostname()))));
+
+                if (!vias.contains(server))
+                        vias.push_back(server);
+        }
+
+        auto link = QString("https://matrix.to/#/%1/%2?%3")
+                      .arg(QString(QUrl::toPercentEncoding(room)),
+                           QString(QUrl::toPercentEncoding(eventId)),
+                           vias.join('&'));
+
+        QGuiApplication::clipboard()->setText(link);
+}
+
 QString
 TimelineModel::formatTypingUsers(const std::vector<QString> &users, QColor bg)
 {
diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h
index f46409b3..4dbb1c08 100644
--- a/src/timeline/TimelineModel.h
+++ b/src/timeline/TimelineModel.h
@@ -235,6 +235,7 @@ public:
         Q_INVOKABLE void cacheMedia(QString eventId);
         Q_INVOKABLE bool saveMedia(QString eventId) const;
         Q_INVOKABLE void showEvent(QString eventId);
+        Q_INVOKABLE void copyLinkToEvent(QString eventId) const;
         void cacheMedia(QString eventId, std::function<void(const QString filename)> callback);
 
         std::vector<::Reaction> reactions(const std::string &event_id)
diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp
index 99f0b86e..decd245c 100644
--- a/src/timeline/TimelineViewManager.cpp
+++ b/src/timeline/TimelineViewManager.cpp
@@ -14,6 +14,7 @@
 
 #include "BlurhashProvider.h"
 #include "ChatPage.h"
+#include "Clipboard.h"
 #include "ColorImageProvider.h"
 #include "CompletionProxyModel.h"
 #include "DelegateChooser.h"
@@ -214,6 +215,10 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par
                   QQmlEngine::setObjectOwnership(ptr, QQmlEngine::CppOwnership);
                   return ptr;
           });
+        qmlRegisterSingletonType<Clipboard>(
+          "im.nheko", 1, 0, "Clipboard", [](QQmlEngine *, QJSEngine *) -> QObject * {
+                  return new Clipboard();
+          });
 
         qRegisterMetaType<mtx::events::collections::TimelineEvents>();
         qRegisterMetaType<std::vector<DeviceInfo>>();