Merge lp:~libqtelegram-team/telegram-app/app-dev-cpp-push-helper into lp:telegram-app/app-dev

Proposed by Michał Karnicki
Status: Merged
Approved by: Giulio Collura
Approved revision: 278
Merged at revision: 269
Proposed branch: lp:~libqtelegram-team/telegram-app/app-dev-cpp-push-helper
Merge into: lp:telegram-app/app-dev
Diff against target: 700 lines (+594/-11)
12 files modified
.bzrignore (+1/-0)
CMakeLists.txt (+38/-1)
config.h.in (+0/-1)
push.cpp (+25/-0)
push.json (+1/-1)
pushclient.cpp (+113/-0)
pushclient.h (+76/-0)
pushhelper.cpp (+290/-0)
pushhelper.h (+41/-0)
scripts/pushlog.sh (+3/-0)
src.moved/_sctelegram.ini (+0/-8)
telegram.qml (+6/-0)
To merge this branch: bzr merge lp:~libqtelegram-team/telegram-app/app-dev-cpp-push-helper
Reviewer Review Type Date Requested Status
Giulio Collura Approve
Roberto Mier Escandon (community) Needs Fixing
Review via email: mp+250608@code.launchpad.net

Description of the change

Rewrote push helper in C++.

Add 'grouping' of notifications (no counter in notification of grouped messages yet).
Add clearing counter / notifications when logging out.

Requires lib: lp:~libqtelegram-team/libqtelegram/dev-cpp-push-helper
https://code.launchpad.net/~libqtelegram-team/libqtelegram/app-dev-cpp-push-helper/+merge/250608

Tested:
- reading msg on PC and opening Tg clears counter/notifications
- opening Tg and reading msg on PC clears counter/notifications
- opening chat clears counter
- most of incoming push notification types listed in pushhelper.cpp

To post a comment you must log in.
Revision history for this message
Michał Karnicki (karni) wrote :

Roberto, any idea why I need to use line 101 instead of 97 (which doesn't work)?

Revision history for this message
Roberto Mier Escandon (rmescandon) wrote :

helper should manage CHAT_MESSAGE_NOTEXT push received message from telegram servers (see https://core.telegram.org/api/push-updates)

review: Needs Fixing
Revision history for this message
Giulio Collura (gcollura) wrote :

As discussed extensively on IRC, this is working and looking fine. Thanks karni!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.bzrignore'
--- .bzrignore 2015-02-23 15:00:09 +0000
+++ .bzrignore 2015-02-24 16:42:37 +0000
@@ -2,6 +2,7 @@
2click2click
3*.click3*.click
4library4library
5push
5push.py6push.py
6config.h7config.h
7manifest.json8manifest.json
89
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2015-02-03 19:03:00 +0000
+++ CMakeLists.txt 2015-02-24 16:42:37 +0000
@@ -190,9 +190,35 @@
190 QML_JS_TARGET ALL SOURCES ${QML_JS_FILES}190 QML_JS_TARGET ALL SOURCES ${QML_JS_FILES}
191)191)
192192
193add_custom_target(
194 "_project_files" ALL SOURCES
195
196 "manifest.json.in"
197 "apparmor-telegram.json"
198 "push.json"
199 "apparmor-push.json"
200 "content-hub.json"
201 "telegram.desktop.in.in"
202
203 "config.h.in"
204 "push.cpp"
205 "pushhelper.h"
206 "pushhelper.cpp"
207 "pushclient.h"
208 "pushclient.cpp"
209
210 "push.py"
211 "countries.py"
212
213 "HACKING.md"
214 "README.md"
215 "README.translations"
216 "LICENSE"
217)
218
193configure_file(219configure_file(
194 config.h.in220 config.h.in
195 ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONL221 ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY
196)222)
197223
198set(telegram_app_SRCS224set(telegram_app_SRCS
@@ -218,3 +244,14 @@
218 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}244 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
219)245)
220246
247add_executable(push
248 push.cpp
249 pushhelper.cpp
250 pushclient.cpp
251)
252qt5_use_modules(push
253 Core
254 DBus
255)
256install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/push
257 DESTINATION ${CMAKE_INSTALL_BINDIR})
221258
=== modified file 'config.h.in'
--- config.h.in 2014-11-03 09:57:18 +0000
+++ config.h.in 2015-02-24 16:42:37 +0000
@@ -1,2 +1,1 @@
1
2#define TELEGRAM_VERSION "@APP_VERSION@"1#define TELEGRAM_VERSION "@APP_VERSION@"
32
=== added file 'push.cpp'
--- push.cpp 1970-01-01 00:00:00 +0000
+++ push.cpp 2015-02-24 16:42:37 +0000
@@ -0,0 +1,25 @@
1#include <QCoreApplication>
2#include <QStringList>
3#include <QTimer>
4
5#include "pushhelper.h"
6
7int main(int argc, char *argv[]) {
8 if (argc != 3) {
9 qFatal("Usage: %s infile outfile", argv[0]);
10 }
11
12 QCoreApplication app(argc, argv);
13 QStringList args = app.arguments();
14
15 PushHelper pushHelper("com.ubuntu.telegram_telegram",
16 QString(args.at(1)), QString(args.at(2)), &app);
17
18// QObject::connect(&pushHelper, SIGNAL(done()), &app, SLOT(quit()));
19 pushHelper.process();
20
21 // TODO check why I need this and the connect above doesn't work.
22 QTimer::singleShot(500, &app, SLOT(quit()));
23
24 return app.exec();
25}
026
=== modified file 'push.json'
--- push.json 2014-09-02 21:51:24 +0000
+++ push.json 2015-02-24 16:42:37 +0000
@@ -1,4 +1,4 @@
1{1{
2 "exec": "push.py",2 "exec": "push",
3 "app_id": "com.ubuntu.telegram_telegram"3 "app_id": "com.ubuntu.telegram_telegram"
4}4}
55
=== added file 'pushclient.cpp'
--- pushclient.cpp 1970-01-01 00:00:00 +0000
+++ pushclient.cpp 2015-02-24 16:42:37 +0000
@@ -0,0 +1,113 @@
1/*
2Copyright 2014 Canonical Ltd.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU Lesser General Public License, version 3
6as published by the Free Software Foundation.
7
8This program is distributed in the hope that it will be useful, but
9WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU Lesser General Public License for more details.
12
13You should have received a copy of the GNU Lesser General Public
14License along with this program. If not, see
15<http://www.gnu.org/licenses/>.
16*/
17
18#include "pushclient.h"
19#include <QtDBus/QDBusConnection>
20#include <QtDBus/QDBusMessage>
21#include <QtDBus/QDBusPendingCall>
22#include <QtDBus/QDBusPendingReply>
23#include <QTimer>
24
25#define PUSH_SERVICE "com.ubuntu.PushNotifications"
26#define POSTAL_SERVICE "com.ubuntu.Postal"
27#define PUSH_PATH "/com/ubuntu/PushNotifications"
28#define POSTAL_PATH "/com/ubuntu/Postal"
29#define PUSH_IFACE "com.ubuntu.PushNotifications"
30#define POSTAL_IFACE "com.ubuntu.Postal"
31
32PushClient::PushClient(QObject *parent) : QObject(parent) {
33}
34
35void PushClient::registerApp(const QString &appId) {
36 pkgname = appId.split("_").at(0);
37 pkgname = pkgname.replace(".","_2e").replace("-","_2d");
38 Q_EMIT appIdChanged(appId);
39}
40
41QString PushClient::getAppId() {
42 return appId;
43}
44
45QString PushClient::getToken() {
46 return token;
47}
48
49void PushClient::emitError() {
50 Q_EMIT error(status);
51}
52
53void PushClient::clearPersistent(const QStringList &tags) {
54 QDBusConnection bus = QDBusConnection::sessionBus();
55 QString path(POSTAL_PATH);
56 path += "/" + pkgname;
57 QDBusMessage message = QDBusMessage::createMethodCall(
58 POSTAL_SERVICE, path, POSTAL_IFACE, "ClearPersistent");
59 message << this->appId;
60 for (int i = 0; i < tags.size(); ++i) {
61 message << tags.at(i);
62 }
63 bus.send(message);
64
65 QDBusPendingCall pcall = bus.asyncCall(message);
66 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
67 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
68 this, SLOT(clearPersistentFinished(QDBusPendingCallWatcher*)));
69}
70
71void PushClient::clearPersistentFinished(QDBusPendingCallWatcher *watcher) {
72 QDBusPendingReply<void> reply = *watcher;
73
74 if (reply.isError()) {
75 Q_EMIT error(reply.error().message());
76 } else {
77 Q_EMIT persistentCleared();
78 }
79 watcher->deleteLater();
80}
81
82void PushClient::setCount(int count) {
83 QDBusConnection bus = QDBusConnection::sessionBus();
84 QString path(POSTAL_PATH);
85 bool visible = count != 0;
86 counter = count;
87 path += "/" + pkgname;
88 QDBusMessage message = QDBusMessage::createMethodCall(POSTAL_SERVICE, path, POSTAL_IFACE, "setCounter");
89 message << this->appId << count << visible;
90 QDBusPendingCall pcall = bus.asyncCall(message);
91 QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
92 connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)),
93 this, SLOT(setCounterFinished(QDBusPendingCallWatcher*)));
94}
95
96void PushClient::setCounterFinished(QDBusPendingCallWatcher *watcher) {
97 QDBusPendingReply<void> reply = *watcher;
98 if (reply.isError()) {
99 Q_EMIT error(reply.error().message());
100 }
101 else {
102 Q_EMIT countChanged(counter);
103 }
104 watcher->deleteLater();
105}
106
107int PushClient::getCount() {
108 return counter;
109}
110
111void PushClient::setAppId(const QString &appId) {
112 this->appId = appId;
113}
0114
=== added file 'pushclient.h'
--- pushclient.h 1970-01-01 00:00:00 +0000
+++ pushclient.h 2015-02-24 16:42:37 +0000
@@ -0,0 +1,76 @@
1/*
2Copyright 2014 Canonical Ltd.
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU Lesser General Public License, version 3
6as published by the Free Software Foundation.
7
8This program is distributed in the hope that it will be useful, but
9WITHOUT ANY WARRANTY; without even the implied warranty of
10MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11GNU Lesser General Public License for more details.
12
13You should have received a copy of the GNU Lesser General Public
14License along with this program. If not, see
15<http://www.gnu.org/licenses/>.
16*/
17
18#ifndef PUSHCLIENT_H
19#define PUSHCLIENT_H
20
21#include <QObject>
22#include <QString>
23#include <QStringList>
24
25class QDBusPendingCallWatcher;
26
27class PushClient : public QObject {
28 Q_OBJECT
29
30public:
31 explicit PushClient(QObject *parent = 0);
32
33 QString getAppId();
34 void setAppId(const QString &appId);
35 QString getToken();
36 QString getStatus() { return this->status; }
37 int getCount();
38 void setCount(int count);
39
40 void registerApp(const QString &appid);
41
42 Q_PROPERTY(QString appId WRITE setAppId READ getAppId NOTIFY appIdChanged);
43 Q_PROPERTY(QString token READ getToken NOTIFY tokenChanged);
44 Q_PROPERTY(QStringList notifications NOTIFY notificationsChanged);
45 Q_PROPERTY(QString status READ getStatus NOTIFY statusChanged);
46 Q_PROPERTY(int count READ getCount WRITE setCount NOTIFY countChanged)
47
48signals:
49 void appIdChanged(const QString &appId);
50 void tokenChanged(const QString &token);
51 void statusChanged(const QString &status);
52 void countChanged(int count);
53 void notificationsChanged(const QStringList &notifications);
54 void persistentChanged(const QStringList &tags);
55 void persistentCleared();
56
57 void error(const QString &error);
58
59public slots:
60 void emitError();
61 void clearPersistent(const QStringList &tags);
62
63private slots:
64 void setCounterFinished(QDBusPendingCallWatcher *watcher);
65 void clearPersistentFinished(QDBusPendingCallWatcher *watcher);
66
67private:
68 QString appId;
69 QString pkgname;
70 QString token;
71 QString status;
72 QStringList notifications;
73 int counter;
74};
75
76#endif // PUSHCLIENT_H
077
=== added file 'pushhelper.cpp'
--- pushhelper.cpp 1970-01-01 00:00:00 +0000
+++ pushhelper.cpp 2015-02-24 16:42:37 +0000
@@ -0,0 +1,290 @@
1#include <QDebug>
2#include <QFile>
3#include <QJsonDocument>
4#include <QJsonArray>
5#include <QStringList>
6#include <QTextStream>
7
8#include "pushhelper.h"
9
10PushHelper::PushHelper(QString appId, QString infile, QString outfile,
11 QObject *parent) : QObject(parent) {
12 connect(&mPushClient, SIGNAL(persistentCleared()),
13 this, SLOT(notificationDismissed()));
14
15 mPushClient.setAppId(appId);
16 mPushClient.registerApp(appId);
17 mInfile = infile;
18 mOutfile = outfile;
19}
20
21PushHelper::~PushHelper() {
22}
23
24void PushHelper::process() {
25 QString tag = "";
26
27 QJsonObject pushMessage = readPushMessage(mInfile);
28 mPostalMessage = pushToPostalMessage(pushMessage, tag);
29 if (!tag.isEmpty()) {
30 dismissNotification(tag);
31 }
32}
33
34void PushHelper::notificationDismissed() {
35 writePostalMessage(mPostalMessage, mOutfile);
36 Q_EMIT done();
37}
38
39QJsonObject PushHelper::readPushMessage(const QString &filename) {
40 QFile file(filename);
41 file.open(QIODevice::ReadOnly | QIODevice::Text);
42
43 QString val = file.readAll();
44 file.close();
45 return QJsonDocument::fromJson(val.toUtf8()).object();
46}
47
48void PushHelper::writePostalMessage(const QJsonObject &postalMessage, const QString &filename) {
49 QFile out;
50 out.setFileName(filename);
51 out.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
52
53 QTextStream(&out) << QJsonDocument(postalMessage).toJson();
54 out.close();
55}
56
57QJsonObject PushHelper::pushToPostalMessage(const QJsonObject &push, QString &tag) {
58 QString summary = "";
59 QString body = "";
60 qint32 count = 0;
61
62 QJsonObject message = push["message"].toObject();
63 QJsonObject custom = message["custom"].toObject();
64
65 QString key = "";
66 if (message.keys().contains("loc_key")) {
67 key = message["loc_key"].toString();
68 }
69 QJsonArray args;
70 if (message.keys().contains("loc_args")) {
71 args = message["loc_args"].toArray();
72 }
73
74 QString chatId = "0"; // More useful as string in this context.
75 if (custom.keys().contains("from_id")) {
76 chatId = custom["from_id"].toString();
77 }
78 if (custom.keys().contains("chat_id")) {
79 chatId = custom["chat_id"].toString();
80 }
81
82 QString tg = QString("Telegram");
83 summary = args[0].toString();
84
85 if (key == "MESSAGE_TEXT") {
86
87 body = args[1].toString();
88
89 } else if (key == "MESSAGE_NOTEXT") {
90
91 body = "sent you a message";
92
93 } else if (key == "MESSAGE_PHOTO") {
94
95 body = "sent you a photo";
96
97 } else if (key == "MESSAGE_VIDEO") {
98
99 body = "sent you a video";
100
101 } else if (key == "MESSAGE_DOC") {
102
103 body = "sent you a document";
104
105 } else if (key == "MESSAGE_AUDIO") {
106
107 body = "sent you a voice message";
108
109 } else if (key == "MESSAGE_CONTACT") {
110
111 body = "shared a contact with you";
112
113 } else if (key == "MESSAGE_GEO") {
114
115 body = "sent you a map";
116
117 } else if (key == "CHAT_MESSAGE_TEXT") {
118
119 summary = args[1].toString();
120 body = args[0].toString() + ": " + args[2].toString();
121
122 } else if (key == "CHAT_MESSAGE_NOTEXT") {
123
124 summary = args[1].toString();
125 body = args[0].toString() + " sent a message to the group";
126
127 } else if (key == "CHAT_MESSAGE_PHOTO") {
128
129 summary = args[1].toString();
130 body = args[0].toString() + " sent a photo to the group";
131
132 } else if (key == "CHAT_MESSAGE_VIDEO") {
133
134 summary = args[1].toString();
135 body = args[0].toString() + " sent a video to the group";
136
137 } else if (key == "CHAT_MESSAGE_DOC") {
138
139 summary = args[1].toString();
140 body = args[0].toString() + " sent a document to the group";
141
142 } else if (key == "CHAT_MESSAGE_AUDIO") {
143
144 summary = args[1].toString();
145 body = args[0].toString() + " sent a voice message to the group";
146
147 } else if (key == "CHAT_MESSAGE_CONTACT") {
148
149 summary = args[1].toString();
150 body = args[0].toString() + " sent a contact to the group";
151
152 } else if (key == "CHAT_MESSAGE_GEO") {
153
154 summary = args[1].toString();
155 body = args[0].toString() + " sent a map to the group";
156
157 } else if (key == "CHAT_CREATED") {
158
159 summary = args[1].toString();
160 body = args[0].toString() + " invited you to the group";
161
162 } else if (key == "CHAT_TITLE_EDITED") {
163
164 summary = args[1].toString();
165 body = args[0].toString() + " changed group name";
166
167 } else if (key == "CHAT_PHOTO_EDITED") {
168
169 summary = args[1].toString();
170 body = args[0].toString() + " changed group photo";
171
172 } else if (key == "CHAT_ADD_MEMBER") {
173
174 summary = args[1].toString();
175 body = args[0].toString() + " invited " + args[2].toString();
176
177 } else if (key == "CHAT_ADD_YOU") {
178
179 summary = args[1].toString();
180 body = args[0].toString() + " invited you to the group";
181
182 } else if (key == "CHAT_DELETE_MEMBER") {
183
184 summary = args[1].toString();
185 body = args[0].toString() + " kicked " + args[2].toString();
186
187 } else if (key == "CHAT_DELETE_YOU") {
188
189 summary = args[1].toString();
190 body = args[0].toString() + " kicked you from the group";
191
192 } else if (key == "CHAT_LEFT") {
193
194 summary = args[1].toString();
195 body = args[0].toString() + " has left the group";
196
197 } else if (key == "CHAT_RETURNED") {
198
199 summary = args[1].toString();
200 body = args[0].toString() + " has returned to the group";
201
202 } else if (key == "GEOCHAT_CHECKIN") {
203
204 summary = "@ " + args[1].toString();
205 body = args[0].toString() + " has checked-in";
206
207 } else if (key == "CONTACT_JOINED") {
208
209 summary = tg;
210 body = args[0].toString() + " joined Telegram!";
211
212 } else if (key == "AUTH_UNKNOWN") {
213
214 summary = args[0].toString();
215 body = "New login from unrecognized device";
216
217 } else if (key == "AUTH_REGION") {
218
219 summary = args[0].toString() + " @ " + args[1].toString();
220 body = "New login from unrecognized device";
221
222 } else if (key == "CONTACT_PHOTO") {
223
224 body = "updated profile photo";
225
226 } else if (key == "ENCRYPTION_REQUEST") {
227
228 summary = tg;
229 body = "You have a new message";
230
231 } else if (key == "ENCRYPTION_ACCEPT") {
232
233 summary = tg;
234 body = "You have a new message";
235
236 } else if (key == "ENCRYPTED_MESSAGE") {
237
238 summary = tg;
239 body = "You have a new message";
240
241 } else {
242 qDebug() << "Unhandled push type: " << key;
243 return QJsonObject();
244 }
245
246 QJsonArray actions = QJsonArray();
247 QString actionUri = QString("telegram://chat/%1").arg(chatId);
248 actions.append(actionUri);
249
250 if (message.keys().contains("badge")) {
251 count = message["badge"].toInt();
252 } else if (push.keys().contains("notification")) {
253 // Legacy. Notification section is only used to retrieve the unread count.
254 count = push["notification"]
255 .toObject()["emblem-counter"]
256 .toObject()["count"]
257 .toInt();
258 }
259
260 tag = chatId;
261
262 QJsonObject card;
263 card["summary"] = summary;
264 card["body"] = body;
265 card["actions"] = actions;
266 card["popup"] = true; // TODO make setting
267 card["persist"] = true; // TODO make setting
268
269 QJsonObject emblem;
270 emblem["count"] = count;
271 emblem["visible"] = count > 0;
272
273 QJsonObject notification;
274 notification["tag"] = tag;
275 notification["card"] = card;
276 notification["emblem-counter"] = emblem;
277 notification["sound"] = true; // TODO make setting
278 notification["vibrate"] = true; // TODO make setting
279
280 QJsonObject postalMessage = QJsonObject();
281 postalMessage["notification"] = notification;
282
283 return postalMessage;
284}
285
286void PushHelper::dismissNotification(const QString &tag) {
287 QStringList tags;
288 tags << tag;
289 mPushClient.clearPersistent(tags);
290}
0291
=== added file 'pushhelper.h'
--- pushhelper.h 1970-01-01 00:00:00 +0000
+++ pushhelper.h 2015-02-24 16:42:37 +0000
@@ -0,0 +1,41 @@
1#ifndef PUSH_HELPER_H
2#define PUSH_HELPER_H
3
4#include <QObject>
5#include <QString>
6#include <QJsonObject>
7
8#include "pushclient.h"
9
10/**
11 * See: https://core.telegram.org/api/push-updates
12 */
13class PushHelper : public QObject {
14 Q_OBJECT
15
16public:
17 PushHelper(QString appId, QString infile, QString outfile, QObject *parent = 0);
18 ~PushHelper();
19 void process();
20
21Q_SIGNALS:
22 void done();
23
24public Q_SLOTS:
25 void notificationDismissed();
26
27protected:
28 QJsonObject readPushMessage(const QString &filename);
29 void writePostalMessage(const QJsonObject &postalMessage, const QString &filename);
30 QJsonObject pushToPostalMessage(const QJsonObject &push, QString &tag);
31 void dismissNotification(const QString &tag);
32
33private:
34 PushClient mPushClient;
35 QString mInfile;
36 QString mOutfile;
37
38 QJsonObject mPostalMessage;
39};
40
41#endif
042
=== added file 'scripts/pushlog.sh'
--- scripts/pushlog.sh 1970-01-01 00:00:00 +0000
+++ scripts/pushlog.sh 2015-02-24 16:42:37 +0000
@@ -0,0 +1,3 @@
1#!/bin/bash
2
3adb shell "tail -f /home/phablet/.cache/upstart/ubuntu-push-client.log"
04
=== removed directory 'src.moved'
=== removed file 'src.moved/_sctelegram.ini'
--- src.moved/_sctelegram.ini 2014-11-21 19:07:32 +0000
+++ src.moved/_sctelegram.ini 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
1[ScopeConfig]
2DisplayName=Telegram
3Description=This is a Telegram scope
4Author=Victor Palau
5Art=contacts.Art
6Icon=./tasks.png
7SearchHint=search for a message
8HotKey=tasks.HotKey
90
=== modified file 'telegram.qml'
--- telegram.qml 2015-02-23 19:56:40 +0000
+++ telegram.qml 2015-02-24 16:42:37 +0000
@@ -573,6 +573,9 @@
573 showIntro = false;573 showIntro = false;
574 }574 }
575575
576 pushClient.count = 0;
577 pushClient.clearPersistent([]);
578
576 logoutResetSession(showIntro);579 logoutResetSession(showIntro);
577 logoutResetUI(showIntro);580 logoutResetUI(showIntro);
578 }581 }
@@ -695,6 +698,9 @@
695698
696 onUnreadCountChanged: {699 onUnreadCountChanged: {
697 pushClient.count = unreadCount;700 pushClient.count = unreadCount;
701 if (unreadCount === 0) {
702 pushClient.clearPersistent([]);
703 }
698 }704 }
699705
700 // We need to clean-up and streamline our APIs ;)706 // We need to clean-up and streamline our APIs ;)

Subscribers

People subscribed via source and target branches

to all changes: