Notification deep link test

This commit is contained in:
Dusko Angirevic 2017-10-25 16:30:23 +02:00
parent a7670ecee2
commit 78ebabf471
20 changed files with 487 additions and 69 deletions

View file

@ -14,7 +14,7 @@ TARGET = harbour-tooter
QT += network dbus sql
CONFIG += sailfishapp link_pkgconfig
PKGCONFIG += sailfishapp nemonotifications-qt5 Qt5SystemInfo
PKGCONFIG += sailfishapp nemonotifications-qt5
DEFINES += "APPVERSION=\\\"$${SPECVERSION}\\\""
DEFINES += "APPNAME=\\\"$${TARGET}\\\""
@ -24,10 +24,10 @@ DEFINES += "APPNAME=\\\"$${TARGET}\\\""
}
config.path = /usr/share/$${TARGET}/config/
config.files = config/icon-lock-harbour-maira.png
config.files = config/icon-lock-harbour-tooter.png
notification_categories.path = /usr/share/lipstick/notificationcategories
notification_categories.files = config/x-harbour.maira.activity.*
notification_categories.files = config/x-harbour.tooter.activity.*
dbus_services.path = /usr/share/dbus-1/services/
dbus_services.files = config/ba.dysko.harbour.tooter.service
@ -37,7 +37,9 @@ interfaces.files = config/ba.dysko.harbour.tooter.xml
SOURCES += src/harbour-tooter.cpp \
src/filedownloader.cpp \
src/imageuploader.cpp \
src/notifications.cpp \
src/dbusAdaptor.cpp \
src/dbus.cpp
@ -102,5 +104,7 @@ DISTFILES += \
HEADERS += \
src/imageuploader.h \
src/filedownloader.h \
src/notifications.h \
src/dbusAdaptor.h \
src/dbus.h

View file

@ -30,6 +30,7 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import org.nemomobile.notifications 1.0;
import "../lib/API.js" as Logic
@ -125,11 +126,64 @@ CoverBackground {
if (Logic.conf.notificationLastID < Logic.modelTLnotifications.get(i).id) {
notificationsNum++
Logic.notifier(Logic.modelTLnotifications.get(i))
var item = Logic.modelTLnotifications.get(i);
item.content = item.content.replace(/(<([^>]+)>)/ig,"").replaceAll("&quot;", "\"").replaceAll("&amp;", "&")
//Logic.notifier())
switch (item.type){
case "favourite":
//Notifications.notify("Tooter", "serverinfo.serverTitle", (item.reblog_account_display_name !== "" ? item.reblog_account_display_name : '@'+item.reblog_account_username) + ' ' + qsTrId("favourited"), false, item.created_at.getTime()/1000|0, "")
ntf.urgency = Notification.Normal
ntf.timestamp = item.created_at
ntf.summary = (item.reblog_account_display_name !== "" ? item.reblog_account_display_name : '@'+item.reblog_account_username) + ' ' + qsTr("favourited")
ntf.body = item.content
break;
case "follow":
ntf.urgency = Notification.Critical
ntf.timestamp = item.created_at
ntf.summary = (item.account_display_name !== "" ? item.account_display_name : '@'+item.account_username)
ntf.body = qsTr("followed you")
ntf.remoteActions[0].method = "showtoot"
ntf.remoteActions[0].arguments = ["user", ntf.summary]
break;
case "reblog":
ntf.urgency = Notification.Low
ntf.timestamp = item.created_at
ntf.summary = (item.reblog_account_display_name !== "" ? item.reblog_account_display_name : '@'+item.reblog_account_username) + ' ' + qsTr("boosted")
ntf.body = item.content
ntf.remoteActions[0].method = "showtoot"
ntf.remoteActions[0].arguments = ["toot", item.id]
break;
}
ntf.replacesId = 0;
ntf.publish();
}
}
notificationsLbl.text = notificationsNum;
Logic.conf.notificationLastID = notificationLastID;
}
Notification {
id: ntf
category: "x-harbour.tooter.activity"
appName: "Tooter"
appIcon: "/usr/share/harbour-tooter/config/icon-lock-harbour-tooter.png"
summary: "Notification summary"
body: "Notification body"
previewSummary: summary
previewBody: body
itemCount: 1
timestamp: "2013-02-20 18:21:00"
remoteActions: [ {
"name": "default",
"displayName": "Do something",
"icon": "icon-s-certificates",
"service": "ba.dysko.harbour.tooter",
"path": "/",
"iface": "ba.dysko.harbour.tooter",
"method": "openapp",
"arguments": [ ]
}]
onClicked: console.log("Clicked")
onClosed: console.log("Closed, reason: " + reason)
}
}

View file

@ -116,7 +116,7 @@ var notificationGenerator = function(item){
var notification;
switch (item.urgency){
case "normal":
notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { appName: "Tooter"; itemCount: 1; category: "x-harbour.tooter.activity"; urgency: Notification.Normal; }', Qt.application, 'InternalQmlObject');
notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { category: "x-harbour.tooter.activity"; appName: "Tooter"; appIcon: "/usr/share/harbour-tooter/config/icon-lock-harbour-tooter.png"; summary: "Notification summary"; body: "Notification body"; previewSummary: "Notification preview summary"; previewBody: "Notification preview body"; itemCount: 1; remoteActions: [ { "name": "default", "displayName": "Do something", "icon": "icon-s-certificates", "service": "ba.dysko.harbour.tooter", "path": "/", "iface": "ba.dysko.harbour.tooter", "method": "openapp", "arguments": [ ] }]; urgency: Notification.Normal; }', Qt.application, 'InternalQmlObject');
break;
case "critical":
notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { appName: "Tooter"; itemCount: 1; category: "x-harbour.tooter.activity"; urgency: Notification.Critical; remoteActions: [ { "name": "default", "displayName": "Do something", "icon": "icon-s-do-it", "service": "org.nemomobile.example", "path": "/example", "iface": "org.nemomobile.example", "method": "doSomething", "arguments": [ "argument", 1 ] },{ "name": "ignore", "displayName": "Ignore the problem", "icon": "icon-s-ignore", "service": "org.nemomobile.example", "path": "/example", "iface": "org.nemomobile.example", "method": "ignore", "arguments": [ "argument", 1 ] } ]; onClicked: console.log("Clicked"); onClosed: console.log("Closed, reason: " + reason); }', Qt.application, 'InternalQmlObject');
@ -124,7 +124,8 @@ var notificationGenerator = function(item){
default:
notification = Qt.createQmlObject('import org.nemomobile.notifications 1.0; Notification { appName: "Tooter"; itemCount: 1; category: "x-harbour.tooter.activity"; urgency: Notification.Low; }', Qt.application, 'InternalQmlObject');
}
notification.remoteActions = [ { "name": "app", "displayName": "Do something", "icon": "icon-s-do-it", "service": "ba.dysko.harbour.tooter", "path": "/", "iface": "ba.dysko.harbour.tooter", "method": "openapp", "arguments": [ ]}]
//notification.remoteActions = [ { "name": "app", "displayName": "Do something", "icon": "icon-s-do-it", "service": "ba.dysko.harbour.tooter", "path": "/", "iface": "ba.dysko.harbour.tooter", "method": "openapp", "arguments": [ ]}]
//Notifications.notify("Tooter", "serverinfo.serverTitle", " new activity", false, "2015-10-15 00:00:00", "aaa")
notification.timestamp = item.timestamp
notification.summary = item.summary

View file

@ -10,7 +10,7 @@ WorkerScript.onMessage = function(msg) {
// order notifications in ASC order
function orderNotifications(items){
for (var i = items.length-1; i > 0; i--){
if (items[i].id > msg.conf.notificationLastID)
if (items[i].id > 0 ) //msg.conf.notificationLastID)
WorkerScript.sendMessage({ 'fireNotification': true, "data": items[i]})
}
}
@ -251,7 +251,7 @@ function parseToot (data){
item['content'] = item['content'].replaceAll('#'+tag, '<a href="#'+tag+'">'+tag+'</a>')
}*/
item['attachments'] = [];
console.log("Image "+loadImages)
//console.log("Image "+loadImages)
for(var i = 0; i < data['media_attachments'].length ; i++){
var attachments = data['media_attachments'][i];

View file

@ -68,19 +68,6 @@ Page {
}
}
Text {
id: videoError
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: Theme.paddingMedium
visible: false;
font.pixelSize: Theme.fontSizeSmall;
text: video.errorString
color: Theme.highlightColor
}
onPositionChanged: function(){
//console.log(duration)
@ -122,6 +109,27 @@ Page {
anchors.leftMargin: 0
anchors.bottomMargin: Theme.paddingMedium
}
Rectangle {
visible: videoError.text != ""
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
color: Theme.highlightDimmerColor
height: videoError.height + 2*Theme.paddingMedium
width: parent.width
Label {
anchors.centerIn: parent
id: videoError
width: parent.width - 2*Theme.paddingMedium
wrapMode: Text.WordWrap
height: contentHeight
visible: false;
font.pixelSize: Theme.fontSizeSmall;
text: video.errorString
color: Theme.highlightColor
}
}
MouseArea {
anchors.fill: parent

View file

@ -61,30 +61,13 @@ SilicaListView {
MenuItem {
text: "NOTIFIKACIJA"
onClicked: {
Logic.notifier({
type: "follow",
urgency: "critical",
created_at: new Date(),
account_display_name: '@muo',
reblog_account_display_name: "@akakakak",
content: "blaaaaaa blaaaaaablaaaaaablaaaaaa"
})
Notifications.notify("Tooter", "serverinfo.serverTitle", " new activity", true, "", "aaa")
}
}
MenuItem {
text: "NOTIFIKACIJA2"
onClicked: {
Logic.notifier({
type: "reblog",
urgency: "critical",
created_at: new Date(),
account_display_name: '@muowww',
reblog_account_display_name: "@akakwwakak",
content: "blaaaaaa blaaaaawwwablaaaaaablaaaaaa"
})
Notifications.notify("Tooter", "serverinfo.serverTitle", " new activity", false, "2015-10-15 00:00:00", "aaa")
}
}
MenuItem {
@ -137,31 +120,6 @@ SilicaListView {
}
Button {
Notification {
id: notification
category: "x-harbour.tooter.activity"
appName: "Tooter"
appIcon: "/usr/share/harbour-tooter/config/icon-lock-harbour-tooter.png"
summary: "Notification summary"
body: "Notification body"
previewSummary: "Notification preview summary"
previewBody: "Notification preview body"
itemCount: 5
timestamp: "2013-02-20 18:21:00"
remoteActions: [ {
"name": "default",
"displayName": "Do something",
"icon": "icon-s-certificates",
"service": "ba.dysko.harbour.tooter",
"path": "/",
"iface": "ba.dysko.harbour.tooter",
"method": "openapp",
"arguments": [ ]
}]
onClicked: console.log("Clicked")
onClosed: console.log("Closed, reason: " + reason)
}
text: "Application notification" + (notification.replacesId ? " ID:" + notification.replacesId : "")
onClicked: notification.publish()
}
footer: Item{
@ -205,7 +163,10 @@ SilicaListView {
console.log(JSON.stringify(messageObject))
}
if (messageObject.fireNotification && notifier){
Logic.notifier(messageObject.data)
//Logic.notifier(messageObject.data)
console.log(JSON.stringify(messageObject.data))
notification.body = "a"
notification.publish()
}
}
@ -241,4 +202,29 @@ SilicaListView {
if (type !== "")
worker.sendMessage(msg);
}
Notification {
id: notification
category: "x-harbour.tooter.activity"
appName: "Tooter"
appIcon: "/usr/share/harbour-tooter/config/icon-lock-harbour-tooter.png"
summary: "Notification summary"
body: "Notification body"
previewSummary: "Notification preview summary"
previewBody: "Notification preview body"
itemCount: 5
timestamp: "2013-02-20 18:21:00"
remoteActions: [ {
"name": "default",
"displayName": "Do something",
"icon": "icon-s-certificates",
"service": "ba.dysko.harbour.tooter",
"path": "/",
"iface": "ba.dysko.harbour.tooter",
"method": "openapp",
"arguments": [ ]
}]
onClicked: console.log("Clicked")
onClosed: console.log("Closed, reason: " + reason)
}
}

68
src/filedownloader.cpp Normal file
View file

@ -0,0 +1,68 @@
/*
* Copyright (C) 2015-2017 kimmoli <kimmo.lindholm@eke.fi>
* All rights reserved.
*
* This file is part of Maira
*
* You may use this file under the terms of BSD license
*/
#include "filedownloader.h"
#include <QDebug>
FileDownloader::FileDownloader(QQmlEngine *engine, QObject *parent) :
QObject(parent)
{
m_engine = engine;
}
void FileDownloader::downloadFile(QUrl url, QString filename)
{
emit downloadStarted();
m_filename = filename;
qDebug() << "downloading" << url << "to" << filename;
QNetworkAccessManager *nam = m_engine->networkAccessManager();
QNetworkRequest request(url);
QNetworkReply *r = nam->get(request);
connect(r, SIGNAL(finished()), this, SLOT(fileDownloaded()));
}
void FileDownloader::open(QString filename)
{
QProcess proc;
QString path = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + filename;
proc.startDetached("/usr/bin/xdg-open" , QStringList() << path);
}
void FileDownloader::fileDownloaded()
{
QNetworkReply *pReply = qobject_cast<QNetworkReply *>(sender());
m_DownloadedData = pReply->readAll();
int httpstatus = pReply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug() << "HttpStatusCode" << httpstatus;
pReply->deleteLater();
if (httpstatus == 200)
{
QFile file(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + "/" + m_filename);
if (!file.open(QIODevice::WriteOnly))
{
emit downloadFailed("Download failed, can't create file");
return;
}
file.write(m_DownloadedData);
file.close();
emit downloadSuccess();
open(m_filename);
}
else
{
emit downloadFailed(QString("Download failed, error %1").arg(httpstatus));
}
}

45
src/filedownloader.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (C) 2015-2017 kimmoli <kimmo.lindholm@eke.fi>
* All rights reserved.
*
* This file is part of Maira
*
* You may use this file under the terms of BSD license
*/
#ifndef FILEDOWNLOADER_H
#define FILEDOWNLOADER_H
#include <QObject>
#include <QByteArray>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QFile>
#include <QStandardPaths>
#include <QQmlEngine>
#include <QProcess>
class FileDownloader : public QObject
{
Q_OBJECT
public:
explicit FileDownloader(QQmlEngine *engine, QObject *parent = 0);
Q_INVOKABLE void downloadFile(QUrl url, QString filename);
Q_INVOKABLE void open(QString filename);
signals:
void downloadStarted();
void downloadSuccess();
void downloadFailed(QString errorMsg);
private slots:
void fileDownloaded();
private:
QQmlEngine *m_engine;
QByteArray m_DownloadedData;
QString m_filename;
};
#endif // FILEDOWNLOADER_H

View file

@ -6,8 +6,16 @@
#include <sailfishapp.h>
#include <QQuickView>
#include <QtQml>
#include <QtGui/QGuiApplication>
#include <QScopedPointer>
#include <QQmlEngine>
#include <QGuiApplication>
#include <QQmlContext>
#include <QCoreApplication>
#include <QtNetwork>
#include <QtSystemInfo/QDeviceInfo>
#include "filedownloader.h"
#include "imageuploader.h"
#include "notifications.h"
#include "dbus.h"
int main(int argc, char *argv[])
@ -15,14 +23,21 @@ int main(int argc, char *argv[])
QScopedPointer<QGuiApplication> app(SailfishApp::application(argc, argv));
QScopedPointer<QQuickView> view(SailfishApp::createView());
//QQmlContext *context = view.data()->rootContext();
QQmlEngine* engine = view->engine();
FileDownloader *fd = new FileDownloader(engine);
view->rootContext()->setContextProperty("FileDownloader", fd);
qmlRegisterType<ImageUploader>("harbour.tooter.Uploader", 1, 0, "ImageUploader");
QQmlEngine* engine = view->engine();
Notifications *no = new Notifications();
view->rootContext()->setContextProperty("Notifications", no);
QObject::connect(engine, SIGNAL(quit()), app.data(), SLOT(quit()));
Dbus *dbus = new Dbus();
view->rootContext()->setContextProperty("Dbus", dbus);
view->rootContext()->setContextProperty("Dbus", dbus);
view->setSource(SailfishApp::pathTo("qml/harbour-tooter.qml"));
view->show();

78
src/notifications.cpp Normal file
View file

@ -0,0 +1,78 @@
/*
* Copyright (C) 2015-2017 kimmoli <kimmo.lindholm@eke.fi>
* All rights reserved.
*
* This file is part of Maira
*
* You may use this file under the terms of BSD license
*/
#include "notifications.h"
Notifications::Notifications(QObject *parent) :
QObject(parent)
{
}
void Notifications::notify(QString appName, QString summary, QString body, bool preview, QString ts, QString issuekey)
{
Notification notif;
QVariantList remoteactions;
if (preview)
{
notif.setPreviewSummary(summary);
notif.setPreviewBody(body);
notif.setCategory("x-harbour.tooter.activity");
if (issuekey.isEmpty())
{
remoteactions << Notification::remoteAction("default",
QString(),
"ba.dysko.habour.tooter",
"/",
"ba.dysko.habour.tooter",
"openapp",
QVariantList());
}
}
else
{
notif.setAppName(appName);
notif.setSummary(summary);
notif.setBody(body);
notif.setItemCount(1);
notif.setCategory("x-harbour.tooter.activity");
remoteactions << Notification::remoteAction("app",
QString(),
"ba.dysko.habour.tooter",
"/",
"ba.dysko.habour.tooter",
"openapp",
QVariantList());
}
notif.setReplacesId(0);
if (!ts.isEmpty())
notif.setHintValue("x-nemo-timestamp", QVariant(ts));
if (!issuekey.isEmpty())
{
QList<QVariant> args;
args.append(QStringList() << issuekey);
remoteactions << Notification::remoteAction("default",
QString(),
"ba.dysko.habour.tooter",
"/",
"ba.dysko.habour.tooter",
"showtoot",
args);
}
if (remoteactions.count() > 0)
notif.setRemoteActions(remoteactions);
notif.publish();
}

24
src/notifications.h Normal file
View file

@ -0,0 +1,24 @@
/*
* Copyright (C) 2015-2017 kimmoli <kimmo.lindholm@eke.fi>
* All rights reserved.
*
* This file is part of Maira
*
* You may use this file under the terms of BSD license
*/
#ifndef NOTIFICATIONS_H
#define NOTIFICATIONS_H
#include <QObject>
#include <nemonotifications-qt5/notification.h>
class Notifications : public QObject
{
Q_OBJECT
public:
explicit Notifications(QObject *parent = 0);
Q_INVOKABLE void notify(QString appName, QString summary, QString body, bool preview, QString ts, QString issuekey);
};
#endif // NOTIFICATIONS_H

View file

@ -78,6 +78,21 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Κτυπήστε για εισαγωγή</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished">στους σελιδοδείκτες</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">σας ακολουθούν</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished">προωθημένο</translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Tap to insert</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished">favourited</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">followed you</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished">boosted</translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Toca para insertar</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished">marcó como favorito</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">te empezó a seguir</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished">retooteó</translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Appuyez pour insérer</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished">a ajouté à ses favoris</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">volgde jou</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Tustejar per inserir</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished">a mes en favorit</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">vos sèc</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Тапни за убацивање</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">вас прати</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished">разглашено</translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>

View file

@ -78,6 +78,21 @@
<translation>Tap to insert</translation>
</message>
</context>
<context>
<name>CoverPage</name>
<message>
<source>favourited</source>
<translation type="unfinished">favourited</translation>
</message>
<message>
<source>followed you</source>
<translation type="unfinished">followed you</translation>
</message>
<message>
<source>boosted</source>
<translation type="unfinished">boosted</translation>
</message>
</context>
<context>
<name>ImageFullScreen</name>
<message>