Add purpose plugin

Implements #182
This commit is contained in:
Tobias Fella
2024-02-10 00:14:56 +01:00
parent 550dc43dc0
commit 6947fbc12a
11 changed files with 257 additions and 19 deletions

View File

@@ -49,3 +49,7 @@ License: CC0-1.0
Files: appiumtests/data/*
Copyright: 2023 Tobias Fella <tobias.fella@kde.org>
License: CC0-1.0
Files: src/purpose/purposeplugin.json
Copyright: 2023 Tobias Fella <tobias.fella@kde.org>
License: BSD-2-Clause

View File

@@ -72,6 +72,10 @@ set_package_properties(KF6Kirigami PROPERTIES
)
find_package(KF6KirigamiAddons 0.7.2 REQUIRED)
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Purpose)
endif ()
if(ANDROID)
find_package(OpenSSL)
set_package_properties(OpenSSL PROPERTIES

View File

@@ -3,6 +3,10 @@
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
add_subdirectory(purpose)
endif()
add_library(neochat STATIC
controller.cpp
controller.h
@@ -165,6 +169,8 @@ add_library(neochat STATIC
mediamanager.h
models/statekeysmodel.cpp
models/statekeysmodel.h
sharehandler.cpp
sharehandler.h
)
qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN

View File

@@ -44,6 +44,7 @@
#include "neochatconfig.h"
#include "roommanager.h"
#include "windowcontroller.h"
#include "sharehandler.h"
#ifdef HAVE_RUNNER
#include "runner.h"
@@ -186,6 +187,9 @@ int main(int argc, char *argv[])
parser.addOption(dbusActivatedOption);
#endif
QCommandLineOption shareOption(QStringLiteral("share"), i18n("Share a URL to Matrix"), QStringLiteral("text"));
parser.addOption(shareOption);
about.setupCommandLine(&parser);
parser.process(app);
about.processCommandLine(&parser);
@@ -215,26 +219,32 @@ int main(int argc, char *argv[])
#ifdef HAVE_KDBUSADDONS
service.connect(&service,
&KDBusService::activateRequested,
&RoomManager::instance(),
[&engine](const QStringList &arguments, const QString &workingDirectory) {
Q_UNUSED(workingDirectory);
&KDBusService::activateRequested,
&RoomManager::instance(),
[&engine](const QStringList &arguments, const QString &workingDirectory) {
Q_UNUSED(workingDirectory);
QWindow *window = windowFromEngine(&engine);
KWindowSystem::updateStartupId(window);
QWindow *window = windowFromEngine(&engine);
KWindowSystem::updateStartupId(window);
WindowController::instance().showAndRaiseWindow(QString());
WindowController::instance().showAndRaiseWindow(QString());
// Open matrix uri
if (arguments.isEmpty()) {
return;
}
auto args = arguments;
args.removeFirst();
for (const auto &arg : args) {
RoomManager::instance().resolveResource(arg);
}
});
// Open matrix uri
if (arguments.isEmpty()) {
return;
}
auto args = arguments;
args.removeFirst();
if (args.length() == 2 && args[0] == "--share"_ls) {
ShareHandler::instance().setText(args[1]);
return;
}
for (const auto &arg : args) {
RoomManager::instance().resolveResource(arg);
}
});
#endif
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
@@ -247,6 +257,10 @@ int main(int argc, char *argv[])
});
}
if (parser.isSet("share"_ls)) {
ShareHandler::instance().setText(parser.value(shareOption));
}
engine.addImageProvider(QLatin1String("mxc"), MatrixImageProvider::create(&engine, &engine));
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
@@ -255,7 +269,7 @@ int main(int argc, char *argv[])
return -1;
}
if (!parser.positionalArguments().isEmpty()) {
if (!parser.positionalArguments().isEmpty() && !parser.isSet("share"_ls)) {
RoomManager::instance().setUrlArgument(parser.positionalArguments()[0]);
}

View File

@@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
kcoreaddons_add_plugin(neochatplugin SOURCES purposeplugin.cpp INSTALL_NAMESPACE "kf6/purpose")
target_link_libraries(neochatplugin
Qt::DBus
KF6::Purpose
KF6::KIOGui
)

View File

@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: LGPL-2.1-or-later
#include <KIO/CommandLauncherJob>
#include <KPluginFactory>
#include <Purpose/PluginBase>
class NeoChatJob : public Purpose::Job
{
Q_OBJECT
public:
explicit NeoChatJob(QObject *parent)
: Purpose::Job(parent)
{
}
QStringList arrayToList(const QJsonArray &array)
{
QStringList ret;
for (const auto &val : array) {
ret += val.toString();
}
return ret;
}
void start() override
{
const QJsonArray urlsJson = data().value(QStringLiteral("urls")).toArray();
const QString title = data().value(QStringLiteral("title")).toString();
const QString message = QStringLiteral("%1 - %2").arg(title, arrayToList(urlsJson).join(QLatin1Char(' ')));
auto *job = new KIO::CommandLauncherJob(QStringLiteral("neochat"), {QStringLiteral("--share"), message});
connect(job, &KJob::finished, this, &NeoChatJob::emitResult);
job->start();
}
};
class Q_DECL_EXPORT PurposePlugin : public Purpose::PluginBase
{
Q_OBJECT
public:
PurposePlugin(QObject *p, const QVariantList &)
: Purpose::PluginBase(p)
{
}
Purpose::Job *createJob() const override
{
return new NeoChatJob(nullptr);
}
};
K_PLUGIN_CLASS_WITH_JSON(PurposePlugin, "purposeplugin.json")
#include "purposeplugin.moc"

View File

@@ -0,0 +1,18 @@
{
"KPlugin": {
"Authors": [
{
"Name": "Tobias Fella"
}
],
"Category": "Utilities",
"Description": "Share via NeoChat",
"Icon": "org.kde.neochat",
"License": "GPL",
"Name": "NeoChat",
"X-Purpose-ActionDisplay": "NeoChat"
},
"X-Purpose-PluginTypes": [
"ShareUrl"
]
}

View File

@@ -34,7 +34,25 @@ QQC2.Control {
onActiveFocusChanged: textField.forceActiveFocus()
onCurrentRoomChanged: _private.chatBarCache = currentRoom.mainCache
onCurrentRoomChanged: {
_private.chatBarCache = currentRoom.mainCache
if (ShareHandler.text.length > 0 && ShareHandler.room === root.currentRoom.id) {
textField.text = ShareHandler.text;
ShareHandler.text = "";
ShareHandler.room = "";
}
}
Connections {
target: ShareHandler
function onRoomChanged(): void {
if (ShareHandler.text.length > 0 && ShareHandler.room === root.currentRoom.id) {
textField.text = ShareHandler.text;
ShareHandler.text = "";
ShareHandler.room = "";
}
}
}
/**
* @brief The ActionsHandler object to use.

View File

@@ -53,6 +53,9 @@ Kirigami.ApplicationWindow {
MatrixImageProvider.connection = root.connection;
RoomManager.connection = root.connection;
SpaceHierarchyCache.connection = root.connection;
if (ShareHandler.text && root.connection) {
root.handleShare();
}
}
Connections {
@@ -236,6 +239,9 @@ Kirigami.ApplicationWindow {
RoomManager.connection = root.connection;
SpaceHierarchyCache.connection = root.connection;
WindowController.setBlur(pageStack, Config.blur && !Config.compactLayout);
if (ShareHandler.text && root.connection) {
root.handleShare()
}
if (Config.minimizeToSystemTrayOnStartup && !Kirigami.Settings.isMobile && Controller.supportSystemTray && Config.systemTray) {
restoreWindowGeometryConnections.enabled = true; // To restore window size and position
} else {
@@ -450,4 +456,25 @@ Kirigami.ApplicationWindow {
});
}
}
Connections {
target: ShareHandler
function onTextChanged(): void {
if (root.connection && ShareHandler.text.length > 0) {
handleShare();
}
}
}
function handleShare(): void {
const dialog = applicationWindow().pageStack.pushDialogLayer("qrc:/org/kde/neochat/qml/ChooseRoomDialog.qml", {
connection: root.connection
}, {
title: i18nc("@title", "Share"),
width: Kirigami.Units.gridUnit * 25
})
dialog.chosen.connect(function(targetRoomId) {
RoomManager.resolveResource(targetRoomId)
ShareHandler.room = targetRoomId
dialog.closeDialog()
})
}
}

37
src/sharehandler.cpp Normal file
View File

@@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "sharehandler.h"
ShareHandler::ShareHandler(QObject *parent)
: QObject(parent)
{}
QString ShareHandler::text() const
{
return m_text;
}
void ShareHandler::setText(const QString &text)
{
if (text == m_text) {
return;
}
m_text = text;
Q_EMIT textChanged();
}
QString ShareHandler::room() const
{
return m_room;
}
void ShareHandler::setRoom(const QString &roomId)
{
if (roomId == m_room) {
return;
}
m_room = roomId;
Q_EMIT roomChanged();
}

46
src/sharehandler.h Normal file
View File

@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
#pragma once
#include <QObject>
#include <QQmlEngine>
class ShareHandler : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(QString room READ room WRITE setRoom NOTIFY roomChanged)
public:
static ShareHandler &instance()
{
static ShareHandler _instance;
return _instance;
}
static ShareHandler *create(QQmlEngine *, QJSEngine *)
{
QQmlEngine::setObjectOwnership(&instance(), QQmlEngine::CppOwnership);
return &instance();
}
QString text() const;
void setText(const QString &url);
QString room() const;
void setRoom(const QString &roomId);
Q_SIGNALS:
void textChanged();
void roomChanged();
private:
explicit ShareHandler(QObject *parent = nullptr);
QString m_text;
QString m_room;
};