Support open-with from external sources (e.g. web links)

This commit is contained in:
Sebastian Wolf 2020-11-08 21:13:04 +01:00
parent 5127b8ae02
commit 89e0576adc
21 changed files with 212 additions and 8 deletions

View file

@ -33,5 +33,8 @@ ApplicationWindow
onPleaseOpenMessage: {
appWindow.activate();
}
onPleaseOpenUrl: {
appWindow.activate();
}
}
}

View file

@ -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

View file

@ -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 {

View file

@ -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")

View file

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

View file

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

View file

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

View file

@ -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);
};

View file

@ -53,7 +53,7 @@ int main(int argc, char *argv[])
context->setContextProperty("appSettings", appSettings);
qmlRegisterUncreatableType<AppSettings>(uri, 1, 0, "AppSettings", QString());
TDLibWrapper *tdLibWrapper = new TDLibWrapper(view.data());
TDLibWrapper *tdLibWrapper = new TDLibWrapper(appSettings, view.data());
context->setContextProperty("tdLibWrapper", tdLibWrapper);
qmlRegisterUncreatableType<TDLibWrapper>(uri, 1, 0, "TelegramAPI", QString());

View file

@ -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<qlonglong,Group*> *groups)
{
Group* group = groups->value(groupId);

View file

@ -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<qlonglong,Group*> *groups);
private:
void *tdLibClient;
AppSettings *appSettings;
TDLibReceiver *tdLibReceiver;
DBusInterface *dbusInterface;
QString version;

View file

@ -1062,6 +1062,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>Nicht-grafische Rückmeldungen (Klänge, Vibration) bei Hinweisen nutzen</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation>Integration im Öffnen-Mit-Menü</translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation>Fernschreiber ins Öffnen-Mit-Menü von Sailfish OS integrieren</translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1056,6 +1056,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>Usa comentarios no gráficos (sonido, vibración) para las notificaciones</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1063,6 +1063,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>Käytä ei-graafista palautetta (ääni, värinä) ilmoituksille</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1056,6 +1056,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1062,6 +1062,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>Usa feedback non visuale come suoni e/o vibrazione per le notifiche</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1068,6 +1068,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1068,6 +1068,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>Сопровождать уведомления звуками и вибрацией.</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1062,6 +1062,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>Använd icke-grafisk återkoppling (ljud, vibration) för avisering</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1056,6 +1056,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation>使</translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>

View file

@ -1056,6 +1056,14 @@
<source>Use non-graphical feedback (sound, vibration) for notifications</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Open-with menu integration</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Integrate Fernschreiber into open-with menu of Sailfish OS</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>StickerPicker</name>