From 89e0576adcbef9314ccb093a9fd7c9e0dbc132c2 Mon Sep 17 00:00:00 2001 From: Sebastian Wolf Date: Sun, 8 Nov 2020 21:13:04 +0100 Subject: [PATCH] Support open-with from external sources (e.g. web links) --- qml/harbour-fernschreiber.qml | 3 + qml/js/functions.js | 13 +++- qml/pages/OverviewPage.qml | 4 ++ qml/pages/SettingsPage.qml | 10 +++ src/appsettings.cpp | 15 +++++ src/appsettings.h | 5 ++ src/dbusadaptor.cpp | 8 +++ src/dbusadaptor.h | 2 + src/harbour-fernschreiber.cpp | 2 +- src/tdlibwrapper.cpp | 69 ++++++++++++++++++++- src/tdlibwrapper.h | 9 ++- translations/harbour-fernschreiber-de.ts | 8 +++ translations/harbour-fernschreiber-es.ts | 8 +++ translations/harbour-fernschreiber-fi.ts | 8 +++ translations/harbour-fernschreiber-hu.ts | 8 +++ translations/harbour-fernschreiber-it.ts | 8 +++ translations/harbour-fernschreiber-pl.ts | 8 +++ translations/harbour-fernschreiber-ru.ts | 8 +++ translations/harbour-fernschreiber-sv.ts | 8 +++ translations/harbour-fernschreiber-zh_CN.ts | 8 +++ translations/harbour-fernschreiber.ts | 8 +++ 21 files changed, 212 insertions(+), 8 deletions(-) diff --git a/qml/harbour-fernschreiber.qml b/qml/harbour-fernschreiber.qml index 575250a..761ba3b 100644 --- a/qml/harbour-fernschreiber.qml +++ b/qml/harbour-fernschreiber.qml @@ -33,5 +33,8 @@ ApplicationWindow onPleaseOpenMessage: { appWindow.activate(); } + onPleaseOpenUrl: { + appWindow.activate(); + } } } diff --git a/qml/js/functions.js b/qml/js/functions.js index 30a5b59..77bebd6 100644 --- a/qml/js/functions.js +++ b/qml/js/functions.js @@ -310,21 +310,28 @@ function enhanceMessageText(formattedText) { } function handleLink(link) { + var tMePrefix = tdLibWrapper.getOptionString("t_me_url"); if (link.indexOf("user://") === 0) { var userInformation = tdLibWrapper.getUserInformationByName(link.substring(8)); tdLibWrapper.createPrivateChat(userInformation.id); } else if (link.indexOf("userId://") === 0) { tdLibWrapper.createPrivateChat(link.substring(9)); + } else if (link.indexOf("tg://") === 0) { + console.log("Special TG link: " + link); + if (link.indexOf("tg://join?invite=") === 0) { + tdLibWrapper.joinChatByInviteLink(tMePrefix + "joinchat/" + link.substring(17)); + } else if (link.indexOf("tg://resolve?domain=") === 0) { + tdLibWrapper.searchPublicChat(link.substring(20)); + } } else { - var tMePrefix = tdLibWrapper.getOptionString("t_me_url"); if (link.indexOf(tMePrefix) === 0) { if (link.indexOf("joinchat") !== -1) { - console.log("Joining Chatto: " + link); + console.log("Joining Chat: " + link); tdLibWrapper.joinChatByInviteLink(link); // Do the necessary stuff to open the chat if successful // Fail with nice error message if it doesn't work } else { - console.log("SUCH! " + link.substring(tMePrefix.length)); + console.log("Search public chat: " + link.substring(tMePrefix.length)); tdLibWrapper.searchPublicChat(link.substring(tMePrefix.length)); // Check responses for updateBasicGroup or updateSupergroup // Fire createBasicGroupChat or createSupergroupChat diff --git a/qml/pages/OverviewPage.qml b/qml/pages/OverviewPage.qml index c749c7a..4bfeab8 100644 --- a/qml/pages/OverviewPage.qml +++ b/qml/pages/OverviewPage.qml @@ -50,6 +50,10 @@ Page { pageStack.push(Qt.resolvedUrl("../pages/ChatPage.qml"), { "chatInformation" : tdLibWrapper.getChat(chatId) }, PageStackAction.Immediate) } } + onPleaseOpenUrl: { + console.log("[OverviewPage] Opening URL requested: " + url); + Functions.handleLink(url); + } } Timer { diff --git a/qml/pages/SettingsPage.qml b/qml/pages/SettingsPage.qml index 09ea799..af4b6b1 100644 --- a/qml/pages/SettingsPage.qml +++ b/qml/pages/SettingsPage.qml @@ -52,6 +52,16 @@ Page { } } + TextSwitch { + checked: appSettings.useOpenWith + text: qsTr("Open-with menu integration") + description: qsTr("Integrate Fernschreiber into open-with menu of Sailfish OS") + automaticCheck: false + onClicked: { + appSettings.useOpenWith = !checked + } + } + ComboBox { id: feedbackComboBox label: qsTr("Notification feedback") diff --git a/src/appsettings.cpp b/src/appsettings.cpp index b5c0561..b1ccc7b 100644 --- a/src/appsettings.cpp +++ b/src/appsettings.cpp @@ -22,6 +22,7 @@ namespace { const QString KEY_SEND_BY_ENTER("sendByEnter"); + const QString KEY_USE_OPEN_WITH("useOpenWith"); const QString KEY_SHOW_STICKERS_AS_IMAGES("showStickersAsImages"); const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback"); } @@ -44,6 +45,20 @@ void AppSettings::setSendByEnter(bool sendByEnter) } } +bool AppSettings::getUseOpenWith() const +{ + return settings.value(KEY_USE_OPEN_WITH, true).toBool(); +} + +void AppSettings::setUseOpenWith(bool useOpenWith) +{ + if (getUseOpenWith() != useOpenWith) { + LOG(KEY_USE_OPEN_WITH << useOpenWith); + settings.setValue(KEY_USE_OPEN_WITH, useOpenWith); + emit useOpenWithChanged(); + } +} + bool AppSettings::showStickersAsImages() const { return settings.value(KEY_SHOW_STICKERS_AS_IMAGES, true).toBool(); diff --git a/src/appsettings.h b/src/appsettings.h index 723c914..58b1b81 100644 --- a/src/appsettings.h +++ b/src/appsettings.h @@ -24,6 +24,7 @@ class AppSettings : public QObject { Q_OBJECT Q_PROPERTY(bool sendByEnter READ getSendByEnter WRITE setSendByEnter NOTIFY sendByEnterChanged) + Q_PROPERTY(bool useOpenWith READ getUseOpenWith WRITE setUseOpenWith NOTIFY useOpenWithChanged) Q_PROPERTY(bool showStickersAsImages READ showStickersAsImages WRITE setShowStickersAsImages NOTIFY showStickersAsImagesChanged) Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged) @@ -41,6 +42,9 @@ public: bool getSendByEnter() const; void setSendByEnter(bool sendByEnter); + bool getUseOpenWith() const; + void setUseOpenWith(bool useOpenWith); + bool showStickersAsImages() const; void setShowStickersAsImages(bool showAsImages); @@ -49,6 +53,7 @@ public: signals: void sendByEnterChanged(); + void useOpenWithChanged(); void showStickersAsImagesChanged(); void notificationFeedbackChanged(); diff --git a/src/dbusadaptor.cpp b/src/dbusadaptor.cpp index 5d46b54..f2b91a1 100644 --- a/src/dbusadaptor.cpp +++ b/src/dbusadaptor.cpp @@ -31,3 +31,11 @@ void DBusAdaptor::openMessage(const QString &chatId, const QString &messageId) qDebug() << "[DBusAdaptor] Open Message " << chatId << messageId; emit pleaseOpenMessage(chatId, messageId); } + +void DBusAdaptor::openUrl(const QStringList &arguments) +{ + qDebug() << "[DBusAdaptor] Open Url" << arguments; + if (arguments.length() >= 1) { + emit pleaseOpenUrl(arguments.first()); + } +} diff --git a/src/dbusadaptor.h b/src/dbusadaptor.h index 7e5f9db..750775f 100644 --- a/src/dbusadaptor.h +++ b/src/dbusadaptor.h @@ -33,9 +33,11 @@ public: signals: void pleaseOpenMessage(const QString &chatId, const QString &messageId); + void pleaseOpenUrl(const QString &url); public slots: void openMessage(const QString &chatId, const QString &messageId); + void openUrl(const QStringList &arguments); }; diff --git a/src/harbour-fernschreiber.cpp b/src/harbour-fernschreiber.cpp index 09bdbee..614ec47 100644 --- a/src/harbour-fernschreiber.cpp +++ b/src/harbour-fernschreiber.cpp @@ -53,7 +53,7 @@ int main(int argc, char *argv[]) context->setContextProperty("appSettings", appSettings); qmlRegisterUncreatableType(uri, 1, 0, "AppSettings", QString()); - TDLibWrapper *tdLibWrapper = new TDLibWrapper(view.data()); + TDLibWrapper *tdLibWrapper = new TDLibWrapper(appSettings, view.data()); context->setContextProperty("tdLibWrapper", tdLibWrapper); qmlRegisterUncreatableType(uri, 1, 0, "TelegramAPI", QString()); diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp index 0c99272..f1445ef 100644 --- a/src/tdlibwrapper.cpp +++ b/src/tdlibwrapper.cpp @@ -47,9 +47,10 @@ namespace { const QString _EXTRA("@extra"); } -TDLibWrapper::TDLibWrapper(QObject *parent) : QObject(parent) +TDLibWrapper::TDLibWrapper(AppSettings *appSettings, QObject *parent) : QObject(parent) { LOG("Initializing TD Lib..."); + this->appSettings = appSettings; this->tdLibClient = td_json_client_create(); this->tdLibReceiver = new TDLibReceiver(this->tdLibClient, this); @@ -60,7 +61,11 @@ TDLibWrapper::TDLibWrapper(QObject *parent) : QObject(parent) } this->dbusInterface = new DBusInterface(this); - this->initializeOpenWith(); + if (this->appSettings->getUseOpenWith()) { + this->initializeOpenWith(); + } else { + this->removeOpenWith(); + } connect(this->tdLibReceiver, SIGNAL(versionDetected(QString)), this, SLOT(handleVersionDetected(QString))); connect(this->tdLibReceiver, SIGNAL(authorizationStateChanged(QString, QVariantMap)), this, SLOT(handleAuthorizationStateChanged(QString, QVariantMap))); @@ -110,6 +115,8 @@ TDLibWrapper::TDLibWrapper(QObject *parent) : QObject(parent) connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList))); + connect(this->appSettings, SIGNAL(useOpenWithChanged()), this, SLOT(handleOpenWithChanged())); + this->tdLibReceiver->start(); this->setLogVerbosityLevel(); @@ -737,6 +744,15 @@ void TDLibWrapper::joinChatByInviteLink(const QString &inviteLink) this->sendRequest(requestObject); } +void TDLibWrapper::getDeepLinkInfo(const QString &link) +{ + LOG("Resolving TG deep link" << link); + QVariantMap requestObject; + requestObject.insert(_TYPE, "getDeepLinkInfo"); + requestObject.insert("link", link); + this->sendRequest(requestObject); +} + void TDLibWrapper::searchEmoji(const QString &queryString) { LOG("Searching emoji" << queryString); @@ -1059,6 +1075,15 @@ void TDLibWrapper::handleEmojiSearchCompleted(const QString &queryString, const emit emojiSearchSuccessful(resultList); } +void TDLibWrapper::handleOpenWithChanged() +{ + if (this->appSettings->getUseOpenWith()) { + this->initializeOpenWith(); + } else { + this->removeOpenWith(); + } +} + void TDLibWrapper::setInitialParameters() { LOG("Sending initial parameters to TD Lib"); @@ -1105,6 +1130,39 @@ void TDLibWrapper::initializeOpenWith() { LOG("Initialize open-with"); + qDebug() << "Checking standard open URL file..."; + QString openUrlFilePath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/open-url.desktop"; + if (QFile::exists(openUrlFilePath)) { + qDebug() << "Standard open URL file exists, good!"; + } else { + qDebug() << "Copying standard open URL file to " << openUrlFilePath; + QFile::copy("/usr/share/applications/open-url.desktop", openUrlFilePath); + QProcess::startDetached("update-desktop-database " + QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); + } + + QString desktopFilePath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/harbour-fernschreiber-open-url.desktop"; + QFile desktopFile(desktopFilePath); + if (!desktopFile.exists()) { + qDebug() << "Creating Open-With file at " << desktopFile.fileName(); + if (desktopFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + QTextStream fileOut(&desktopFile); + fileOut.setCodec("UTF-8"); + fileOut << QString("[Desktop Entry]").toUtf8() << "\n"; + fileOut << QString("Type=Application").toUtf8() << "\n"; + fileOut << QString("Name=Fernschreiber").toUtf8() << "\n"; + fileOut << QString("Icon=harbour-fernschreiber").toUtf8() << "\n"; + fileOut << QString("NotShowIn=X-MeeGo;").toUtf8() << "\n"; + fileOut << QString("MimeType=text/html;x-scheme-handler/http;x-scheme-handler/https;x-scheme-handler/tg;").toUtf8() << "\n"; + fileOut << QString("X-Maemo-Service=de.ygriega.fernschreiber").toUtf8() << "\n"; + fileOut << QString("X-Maemo-Object-Path=/de/ygriega/fernschreiber").toUtf8() << "\n"; + fileOut << QString("X-Maemo-Method=de.ygriega.fernschreiber.openUrl").toUtf8() << "\n"; + fileOut << QString("Hidden=true;").toUtf8() << "\n"; + fileOut.flush(); + desktopFile.close(); + QProcess::startDetached("update-desktop-database " + QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); + } + } + QString dbusPathName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/dbus-1/services"; QDir dbusPath(dbusPathName); if (!dbusPath.exists()) { @@ -1127,6 +1185,13 @@ void TDLibWrapper::initializeOpenWith() } } +void TDLibWrapper::removeOpenWith() +{ + LOG("Remove open-with"); + QFile::remove(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/harbour-fernschreiber-open-url.desktop"); + QProcess::startDetached("update-desktop-database " + QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)); +} + const TDLibWrapper::Group *TDLibWrapper::updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash *groups) { Group* group = groups->value(groupId); diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h index 93d1702..20f34d1 100644 --- a/src/tdlibwrapper.h +++ b/src/tdlibwrapper.h @@ -25,12 +25,13 @@ #include "dbusadaptor.h" #include "dbusinterface.h" #include "emojisearchworker.h" +#include "appsettings.h" class TDLibWrapper : public QObject { Q_OBJECT public: - explicit TDLibWrapper(QObject *parent = nullptr); + explicit TDLibWrapper(AppSettings *appSettings, QObject *parent = nullptr); ~TDLibWrapper(); enum AuthorizationState { @@ -153,9 +154,12 @@ public: Q_INVOKABLE void getPollVoters(const QString &chatId, const qlonglong &messageId, const int &optionId, const int &limit, const int &offset, const QString &extra); Q_INVOKABLE void searchPublicChat(const QString &userName); Q_INVOKABLE void joinChatByInviteLink(const QString &inviteLink); + Q_INVOKABLE void getDeepLinkInfo(const QString &link); // Others (candidates for extraction ;)) Q_INVOKABLE void searchEmoji(const QString &queryString); + Q_INVOKABLE void initializeOpenWith(); + Q_INVOKABLE void removeOpenWith(); public: const Group* getGroup(qlonglong groupId) const; @@ -228,16 +232,17 @@ public slots: void handleSuperGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation); void handleStickerSets(const QVariantList &stickerSets); void handleEmojiSearchCompleted(const QString &queryString, const QVariantList &resultList); + void handleOpenWithChanged(); private: void setInitialParameters(); void setEncryptionKey(); void setLogVerbosityLevel(); - void initializeOpenWith(); const Group *updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash *groups); private: void *tdLibClient; + AppSettings *appSettings; TDLibReceiver *tdLibReceiver; DBusInterface *dbusInterface; QString version; diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts index b881cb4..0afb9f2 100644 --- a/translations/harbour-fernschreiber-de.ts +++ b/translations/harbour-fernschreiber-de.ts @@ -1062,6 +1062,14 @@ Use non-graphical feedback (sound, vibration) for notifications Nicht-grafische Rückmeldungen (Klänge, Vibration) bei Hinweisen nutzen + + Open-with menu integration + Integration im Öffnen-Mit-Menü + + + Integrate Fernschreiber into open-with menu of Sailfish OS + Fernschreiber ins Öffnen-Mit-Menü von Sailfish OS integrieren + StickerPicker diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts index 0483429..e824740 100644 --- a/translations/harbour-fernschreiber-es.ts +++ b/translations/harbour-fernschreiber-es.ts @@ -1056,6 +1056,14 @@ Use non-graphical feedback (sound, vibration) for notifications Usa comentarios no gráficos (sonido, vibración) para las notificaciones + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts index cba3ea4..e04bb8e 100644 --- a/translations/harbour-fernschreiber-fi.ts +++ b/translations/harbour-fernschreiber-fi.ts @@ -1063,6 +1063,14 @@ Use non-graphical feedback (sound, vibration) for notifications Käytä ei-graafista palautetta (ääni, värinä) ilmoituksille + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts index 8d835c9..d0dc370 100644 --- a/translations/harbour-fernschreiber-hu.ts +++ b/translations/harbour-fernschreiber-hu.ts @@ -1056,6 +1056,14 @@ Use non-graphical feedback (sound, vibration) for notifications + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts index b47bc33..3c922cb 100644 --- a/translations/harbour-fernschreiber-it.ts +++ b/translations/harbour-fernschreiber-it.ts @@ -1062,6 +1062,14 @@ Use non-graphical feedback (sound, vibration) for notifications Usa feedback non visuale come suoni e/o vibrazione per le notifiche + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts index 0f1e063..b4dba21 100644 --- a/translations/harbour-fernschreiber-pl.ts +++ b/translations/harbour-fernschreiber-pl.ts @@ -1068,6 +1068,14 @@ Use non-graphical feedback (sound, vibration) for notifications + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts index 7f977fb..f3a170b 100644 --- a/translations/harbour-fernschreiber-ru.ts +++ b/translations/harbour-fernschreiber-ru.ts @@ -1068,6 +1068,14 @@ Use non-graphical feedback (sound, vibration) for notifications Сопровождать уведомления звуками и вибрацией. + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts index c238cf9..f6cce56 100644 --- a/translations/harbour-fernschreiber-sv.ts +++ b/translations/harbour-fernschreiber-sv.ts @@ -1062,6 +1062,14 @@ Use non-graphical feedback (sound, vibration) for notifications Använd icke-grafisk återkoppling (ljud, vibration) för avisering + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts index c5fac06..5e61dd4 100644 --- a/translations/harbour-fernschreiber-zh_CN.ts +++ b/translations/harbour-fernschreiber-zh_CN.ts @@ -1056,6 +1056,14 @@ Use non-graphical feedback (sound, vibration) for notifications 使用非图像反馈进行通知(例如声音及振动) + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts index 8357958..7abeed8 100644 --- a/translations/harbour-fernschreiber.ts +++ b/translations/harbour-fernschreiber.ts @@ -1056,6 +1056,14 @@ Use non-graphical feedback (sound, vibration) for notifications + + Open-with menu integration + + + + Integrate Fernschreiber into open-with menu of Sailfish OS + + StickerPicker