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>>();
|