Merge lp:~libqtelegram-team/telegram-app/lib-fix-delays into lp:telegram-app/trunk

Proposed by Michał Karnicki
Status: Merged
Approved by: Roberto Mier Escandon
Approved revision: 95
Merged at revision: 94
Proposed branch: lp:~libqtelegram-team/telegram-app/lib-fix-delays
Merge into: lp:telegram-app/trunk
Diff against target: 506 lines (+135/-57)
8 files modified
qmlplugin/data.cpp (+41/-15)
qmlplugin/data.h (+7/-2)
qmlplugin/models/dialogsmodel.cpp (+59/-28)
qmlplugin/models/dialogsmodel.h (+8/-0)
qmlplugin/telegramclient.cpp (+1/-1)
qmlplugin/telegramclient.h (+1/-1)
qmlplugin/telegramservice.cpp (+17/-9)
qmlplugin/telegramservice.h (+1/-1)
To merge this branch: bzr merge lp:~libqtelegram-team/telegram-app/lib-fix-delays
Reviewer Review Type Date Requested Status
Roberto Mier Escandon (community) Approve
Review via email: mp+260708@code.launchpad.net

Description of the change

Requires: lp:~libqtelegram-team/libqtelegram/app-fix-delays

  Collapse in time updates to unread badge.
  Collapse in time updates to user metrics.
  Be smarter about updating dialog top messages.

Intentionally proposed to trunk.

To post a comment you must log in.
95. By Michał Karnicki

Rename method.

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

Brilliant!!!
Tested and superquick

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qmlplugin/data.cpp'
2--- qmlplugin/data.cpp 2015-05-05 17:09:36 +0000
3+++ qmlplugin/data.cpp 2015-06-01 13:36:23 +0000
4@@ -33,7 +33,8 @@
5 mFilesAvgTime(0),
6 mFilesCount(0),
7 mFilesTotalTime(0),
8- mLastUnreadCount(-1) {
9+ mLastUnreadCount(-1),
10+ mBadgeUpdateTimer(0) {
11
12 // Priorities for thumbnail sizes are m, b, s, a, x, c, y, d, w
13 mPhotoSmallPriorities.insert("m", 1);
14@@ -149,6 +150,7 @@
15 }
16 }
17
18+ qint32 newMessagesReceivedCount = 0;
19 Q_FOREACH (const Message &message, messages) {
20
21 qint32 dialogId = Tools::getBelongingDialogId(message);
22@@ -179,7 +181,11 @@
23 TelegramService *service = static_cast<TelegramService *>(mServiceRef);
24 service->messagesGetDialogs(0, dialogId, 1);
25 }
26+
27+ newMessagesReceivedCount += (!message.out() && message.unread()) ? 1 : 0;
28 }
29+ Q_EMIT messagesReceived(newMessagesReceivedCount);
30+ updateBadge();
31
32 Q_FOREACH (const SecretChatMessage &secretChatMessage, secretChatMessages) {
33
34@@ -250,9 +256,10 @@
35 }
36
37 if (!isIntermediateState) {
38- surfaceUnreadCount();
39+ updateBadge();
40 }
41
42+ Q_EMIT selfDestructMessages();
43 qCDebug(TG_PLUGIN_PROFILING) << "onUpdatesGetDifferenceAnswer - end:" << time.elapsed() << "ms";
44 }
45
46@@ -1700,7 +1707,7 @@
47 }
48
49 Q_EMIT messagesAdded(messageItems, messageItems.count());
50-
51+ Q_EMIT selfDestructMessages();
52 qCDebug(TG_PLUGIN_PROFILING) << "onMessagesForwardMessagesAnswer - end";
53 }
54
55@@ -1803,6 +1810,8 @@
56 mDbManager.finishTransaction();
57
58 Q_EMIT messageAdded(messageItem);
59+ Q_EMIT messagesReceived(1);
60+ Q_EMIT selfDestructMessages();
61 }
62
63 void Data::onUpdateShort(const Update &update, qint32 date) {
64@@ -1899,6 +1908,7 @@
65
66 MessageItem messageItem = getMessage(message.randomId());
67 Q_EMIT outgoingMessageAdded(chatId, messageItem);
68+ Q_EMIT selfDestructMessages();
69
70 // 'local' is the size for sent photos until having a server location and different sizes
71 // if there is a mediaLocalPath and media type is photo ro video, emit photo updated signal. Same for video
72@@ -2518,7 +2528,8 @@
73 service->messagesReceivedQueue(qts);
74
75 Q_EMIT messageAdded(messageItem);
76- surfaceUnreadCount();
77+ updateBadge();
78+ Q_EMIT selfDestructMessages();
79
80 qCDebug(TG_PLUGIN_PROFILING) << "onUpdateSecretChatMessage - end:" << time.elapsed() << "ms";
81 }
82@@ -2655,6 +2666,7 @@
83 qCCritical(TG_PLUGIN_LOGIC) << "Impossible insert new received message";
84 return false;
85 }
86+ Q_EMIT messagesReceived(1);
87
88 if (!executeAction(message)) {
89 mDbManager.rollbackTransaction();
90@@ -2672,6 +2684,7 @@
91
92 MessageItem messageItem = getMessage(message.id());
93 Q_EMIT messageAdded(messageItem);
94+ Q_EMIT selfDestructMessages();
95
96 if (newDialog) {
97 // Ask telegram servers for info about this just created dialog where it will be included the phone number
98@@ -2687,6 +2700,7 @@
99 case Update::typeUpdateReadMessages: {
100 if (markMessagesAsRead(update.messages())) {
101 Q_EMIT messagesMarkedAsRead(update.messages());
102+ Q_EMIT selfDestructMessages();
103 }
104
105 UpdatesState clientState = getState();
106@@ -2893,7 +2907,7 @@
107 }
108
109 bool Data::getProfilePhotoFileFromServer(const FileLocation &serverLocation, qint32 id, bool isUser, bool isThumbnail) {
110-
111+
112 if (serverLocation.classType() != FileLocation::typeFileLocationUnavailable) {
113 // Search in database if same location parameter are stored for thumbnail that
114 // received ones. In that case don't download cos it's the same file
115@@ -2911,7 +2925,7 @@
116 }
117
118 bool Data::downloadPhotoFileFromServer(const FileLocation &serverLocation, qint32 id, bool isUser, bool isThumbnail) {
119-
120+ qCWarning(TG_PLUGIN_LOGIC) << "Data::downloadPhotoFileFromServer";
121 if (serverLocation.classType() != FileLocation::typeFileLocationUnavailable) {
122 // create object with the data of the file to be downloaded
123 TelegramService *service = static_cast<TelegramService *>(mServiceRef);
124@@ -3891,7 +3905,7 @@
125 }
126
127 if (!query.next()) {
128- qCCritical(TG_PLUGIN_LOGIC) << "Message to update not found.";
129+ qCDebug(TG_PLUGIN_LOGIC) << "Message to update not found.";
130 return false;
131 }
132
133@@ -4925,11 +4939,7 @@
134
135 mDbManager.finishTransaction();
136
137- if (!message.out() && message.unread()) {
138- Q_EMIT messageReceived();
139- }
140-
141- surfaceUnreadCount();
142+ updateBadge();
143
144 return true;
145 }
146@@ -5128,7 +5138,7 @@
147 query.prepare(("UPDATE messages SET unread = 0 WHERE dialogId=:dialogId AND out = 0 AND unread = 1"));
148 query.bindValue(":dialogId", chatId);
149 if (query.exec()) {
150- surfaceUnreadCount();
151+ updateBadge();
152 }
153
154 Q_EMIT chatMarkedAsRead(chatId);
155@@ -5178,7 +5188,7 @@
156
157 mDbManager.finishTransaction();
158
159- surfaceUnreadCount();
160+ updateBadge();
161
162 return true;
163 }
164@@ -6647,7 +6657,23 @@
165 return dialog;
166 }
167
168-void Data::surfaceUnreadCount() {
169+void Data::updateBadge() {
170+ if (mBadgeUpdateTimer != 0) {
171+ killTimer(mBadgeUpdateTimer);
172+ }
173+ mBadgeUpdateTimer = startTimer(200);
174+}
175+
176+void Data::timerEvent(QTimerEvent *e) {
177+ if(e->timerId() == mBadgeUpdateTimer) {
178+ killTimer(mBadgeUpdateTimer);
179+ mBadgeUpdateTimer = 0;
180+ onUpdateBadge();
181+ }
182+ QObject::timerEvent(e);
183+}
184+
185+void Data::onUpdateBadge() {
186 QSqlQuery query;
187 query.prepare(QString("SELECT SUM(unreadCount) AS unreadCount FROM dialogsView"));
188
189
190=== modified file 'qmlplugin/data.h'
191--- qmlplugin/data.h 2015-05-05 17:09:36 +0000
192+++ qmlplugin/data.h 2015-06-01 13:36:23 +0000
193@@ -212,6 +212,8 @@
194 void updateChatPhoto(qint32 chatId, const Photo &photo);
195 void updateChatFull(const ChatFull &chatFull);
196
197+ void timerEvent(QTimerEvent *e);
198+
199 Q_SIGNALS:
200 void userInfo(const ContactItem &user);
201
202@@ -234,6 +236,7 @@
203 void messagesAdded(const QList<MessageItem> &messages, qint32 totalCount);
204 void messageAdded(const MessageItem &message);
205 void outgoingMessageAdded(qint32 recipientId, const MessageItem &message);
206+ void selfDestructMessages();
207 void messageUpdated(qint32 msgId, const MessageItem &message);
208
209 void chatMarkedAsRead(qint32 chatId);
210@@ -247,7 +250,7 @@
211 void messageDocumentUpdated(qint32 msgId, const QString &documentLocalPath, const QString &fileName = "", qint32 size = 0);
212
213 void messageSent();
214- void messageReceived();
215+ void messagesReceived(qint32 count);
216
217 void downloadingUpdated(qint32 id, bool downloading);
218 void downloadedPercentageUpdated(qint32 id, qint8 downloadedPercentage);
219@@ -271,6 +274,7 @@
220 DbManager mDbManager;
221
222 qint32 mLastUnreadCount;
223+ qint32 mBadgeUpdateTimer;
224
225 // time mesurement map for file downloading. Correlates fileId with a QTime object for calculate total download time
226 QMap<qint64, QTime *> mFileTimes;
227@@ -346,7 +350,8 @@
228 bool muteDialog(qint32 dialogId, bool muted);
229 bool muteDialogs(NotifyPeer::NotifyPeerType peerType, bool muted);
230
231- void surfaceUnreadCount();
232+ void updateBadge();
233+ void onUpdateBadge();
234
235 bool exists(qint32 id, bool isUser);
236
237
238=== modified file 'qmlplugin/models/dialogsmodel.cpp'
239--- qmlplugin/models/dialogsmodel.cpp 2015-02-16 13:51:55 +0000
240+++ qmlplugin/models/dialogsmodel.cpp 2015-06-01 13:36:23 +0000
241@@ -28,6 +28,7 @@
242 mCanFetchMore(true),
243 mState(Created),
244 mSecretDialogsCount(0),
245+ mTopMessagesTimer(0),
246 mTelegramClient(0) {
247 }
248
249@@ -420,41 +421,71 @@
250 }
251
252 void DialogsModel::onMessageAdded(const MessageItem &message) {
253+ mTopMessages.insert(message.dialogId(), message);
254
255 qint32 dialogId = message.dialogId();
256 qint32 pos = mDlgIdsMap.value(dialogId, -1);
257-
258 if (0 <= pos && pos < mDialogs.size()) {
259- DialogItem &dlg = mDialogs[pos];
260-
261- if (!message.out()) {
262- dlg.setTyping(false);
263- }
264-
265- //Remove previous top message id from mapping
266- MessageItem oldTopMessage = dlg.topMessage();
267- if (!oldTopMessage.isEmpty()) {
268- mTopMessageIdsMap.remove(oldTopMessage.id());
269- }
270-
271- dlg.setTopMessage(message);
272- dlg.setDate(message.date());
273- mTopMessageIdsMap.insert(message.id(), dlg.id());
274-
275 if (!message.out() && message.unread()) {
276+ DialogItem &dlg = mDialogs[pos];
277 dlg.setUnreadCount(dlg.unreadCount() + 1);
278 }
279-
280- const QVector<qint32> changedRoles(QVector<qint32>() << UnreadCountRole << DateRole << TopMessageIdRole << TopMessageFromIdRole <<
281- TopMessageFromFirstNameRole << TopMessageFromLastNameRole << TopMessageFromPhoneRole <<
282- TopMessageToIdRole << TopMessageOutRole << TopMessageUnreadRole << TopMessageSentRole <<
283- TopMessageDateRole << TopMessageTextRole << TopMessageMediaTypeRole <<
284- TopMessageActionTitleRole << TopMessageActionTypeRole << TopMessageActionUserRole <<
285- TypingRole << WhoIsTypingRole);
286- Q_EMIT dataChanged(index(pos), index(pos), changedRoles);
287- } else {
288- qCWarning(TG_PLUGIN_LOGIC) << "onMessageAdded: dialog not found for new top message";
289- }
290+ }
291+
292+ // Delay refreshing top messages while messages incoming.
293+ if (mTopMessagesTimer != 0) {
294+ killTimer(mTopMessagesTimer);
295+ }
296+ mTopMessagesTimer = startTimer(200);
297+}
298+
299+void DialogsModel::timerEvent(QTimerEvent *e) {
300+ if(e->timerId() == mTopMessagesTimer) {
301+ killTimer(mTopMessagesTimer);
302+ mTopMessagesTimer = 0;
303+ onTopMessagesChanged();
304+ }
305+ QAbstractListModel::timerEvent(e);
306+}
307+
308+void DialogsModel::onTopMessagesChanged() {
309+ qCDebug(TG_PLUGIN_LOGIC) << "onTopMessagesChanged";
310+
311+ Q_FOREACH(const MessageItem &message, mTopMessages.values()) {
312+
313+ qint32 dialogId = message.dialogId();
314+ qint32 pos = mDlgIdsMap.value(dialogId, -1);
315+
316+ if (0 <= pos && pos < mDialogs.size()) {
317+ DialogItem &dlg = mDialogs[pos];
318+
319+ if (!message.out()) {
320+ dlg.setTyping(false);
321+ }
322+
323+ //Remove previous top message id from mapping
324+ MessageItem oldTopMessage = dlg.topMessage();
325+ if (!oldTopMessage.isEmpty()) {
326+ mTopMessageIdsMap.remove(oldTopMessage.id());
327+ }
328+
329+ dlg.setTopMessage(message);
330+ dlg.setDate(message.date());
331+ mTopMessageIdsMap.insert(message.id(), dlg.id());
332+
333+ const QVector<qint32> changedRoles(QVector<qint32>() << UnreadCountRole << DateRole << TopMessageIdRole << TopMessageFromIdRole <<
334+ TopMessageFromFirstNameRole << TopMessageFromLastNameRole << TopMessageFromPhoneRole <<
335+ TopMessageToIdRole << TopMessageOutRole << TopMessageUnreadRole << TopMessageSentRole <<
336+ TopMessageDateRole << TopMessageTextRole << TopMessageMediaTypeRole <<
337+ TopMessageActionTitleRole << TopMessageActionTypeRole << TopMessageActionUserRole <<
338+ TypingRole << WhoIsTypingRole);
339+ Q_EMIT dataChanged(index(pos), index(pos), changedRoles);
340+ } else {
341+ qCWarning(TG_PLUGIN_LOGIC) << "onMessageAdded: dialog not found for new top message";
342+ }
343+ }
344+
345+ mTopMessages.clear();
346 }
347
348 void DialogsModel::onMessagesAdded(const QList<MessageItem> &messages, qint32 totalCount) {
349
350=== modified file 'qmlplugin/models/dialogsmodel.h'
351--- qmlplugin/models/dialogsmodel.h 2015-02-16 13:51:55 +0000
352+++ qmlplugin/models/dialogsmodel.h 2015-06-01 13:36:23 +0000
353@@ -95,6 +95,9 @@
354
355 Q_INVOKABLE void setTelegramClient(TelegramClient *telegramClient);
356
357+protected:
358+ void timerEvent(QTimerEvent *e);
359+
360 private:
361 QList<DialogItem> mDialogs;
362 // correlates dialog->id() --> index in m_dialogs
363@@ -106,6 +109,9 @@
364 ModelState mState;
365 qint32 mSecretDialogsCount;
366
367+ qint32 mTopMessagesTimer;
368+ QMap<qint32, MessageItem> mTopMessages;
369+
370 // reference to telegram client
371 TelegramClient *mTelegramClient;
372
373@@ -129,9 +135,11 @@
374 void onMessageAdded(const MessageItem &message);
375 void onMessagesAdded(const QList<MessageItem> &messages, qint32 totalCount);
376 void onOutgoingMessageAdded(qint32 recipientId, const MessageItem &message);
377+ void onTopMessagesChanged();
378 void onMessageUpdated(qint32 msgId, const MessageItem &message);
379 void onMessagesDeleted(const QList<qint32> msgIds);
380 void onMessagesMarkedAsRead(const QList<qint32> &msgIds);
381+
382 void onChatMarkedAsRead(qint32 dialogId);
383 void onChatHistoryDeleted(qint32 dialogId);
384 void onChatDeleted(qint32 dialogId);
385
386=== modified file 'qmlplugin/telegramclient.cpp'
387--- qmlplugin/telegramclient.cpp 2015-04-02 13:13:41 +0000
388+++ qmlplugin/telegramclient.cpp 2015-06-01 13:36:23 +0000
389@@ -95,7 +95,7 @@
390
391 connect(mTelegramService, SIGNAL(unreadCountChanged(qint32)), SIGNAL(unreadCountChanged(qint32)));
392 connect(mTelegramService, SIGNAL(messageSent()), SIGNAL(messageSent()));
393- connect(mTelegramService, SIGNAL(messageReceived()), SIGNAL(messageReceived()));
394+ connect(mTelegramService, SIGNAL(messagesReceived(qint32)), SIGNAL(messagesReceived(qint32)));
395
396 // connect database signals
397 DbManager &dbManager = mTelegramService->data().dbManager();
398
399=== modified file 'qmlplugin/telegramclient.h'
400--- qmlplugin/telegramclient.h 2015-04-02 13:13:41 +0000
401+++ qmlplugin/telegramclient.h 2015-06-01 13:36:23 +0000
402@@ -161,7 +161,7 @@
403
404 void unreadCountChanged(qint32 unreadCount);
405 void messageSent();
406- void messageReceived();
407+ void messagesReceived(qint32 count);
408
409 void userTyping(qint32 dialogId, const QString &whoIsTyping = QString());
410
411
412=== modified file 'qmlplugin/telegramservice.cpp'
413--- qmlplugin/telegramservice.cpp 2015-05-05 17:09:36 +0000
414+++ qmlplugin/telegramservice.cpp 2015-06-01 13:36:23 +0000
415@@ -68,7 +68,7 @@
416 connect(&mData, SIGNAL(dialogsAdded(QList<DialogItem>,qint32)), SIGNAL(dialogsAdded(QList<DialogItem>,qint32)));
417 connect(&mData, SIGNAL(unreadCountChanged(qint32)), SIGNAL(unreadCountChanged(qint32)));
418 connect(&mData, SIGNAL(messageSent()), SIGNAL(messageSent()));
419- connect(&mData, SIGNAL(messageReceived()), SIGNAL(messageReceived()));
420+ connect(&mData, SIGNAL(messagesReceived(qint32)), SIGNAL(messagesReceived(qint32)));
421 connect(&mData, SIGNAL(secretChatRequested(qint32,qint32,qint32,qint64)), SIGNAL(secretChatRequested(qint32,qint32,qint32,qint64)));
422 connect(&mData, SIGNAL(secretChatCreated(qint32)), SIGNAL(secretChatCreated(qint32)));
423 connect(&mData, SIGNAL(secretChatDiscarded(qint32)), SIGNAL(secretChatDiscarded(qint32)));
424@@ -78,9 +78,7 @@
425
426 mSelfDestructTimer.setSingleShot(true);
427 connect(&mSelfDestructTimer, SIGNAL(timeout()), this, SLOT(processSelfDestructMessages()));
428- connect(&mData, SIGNAL(messageAdded(MessageItem)), &mSelfDestructTimer, SIGNAL(timeout()));
429- connect(&mData, SIGNAL(messagesMarkedAsRead(QList<qint32>)),&mSelfDestructTimer, SIGNAL(timeout()));
430- connect(&mData, SIGNAL(outgoingMessageAdded(qint32,MessageItem)), &mSelfDestructTimer, SIGNAL(timeout()));
431+ connect(&mData, SIGNAL(selfDestructMessages()), &mSelfDestructTimer, SIGNAL(timeout()));
432 connect(this, SIGNAL(messagesReadEncryptedHistoryAnswer(qint64,bool)), &mSelfDestructTimer, SIGNAL(timeout()));
433 }
434
435@@ -128,7 +126,7 @@
436 }
437
438 mTelegramLib->init();
439- mSelfDestructTimer.start();
440+ QMetaObject::invokeMethod(&mSelfDestructTimer, "start", Qt::QueuedConnection);
441 }
442
443 void TelegramService::shutdown() {
444@@ -162,7 +160,7 @@
445
446 void TelegramService::onWoken() {
447 mTelegramLib->updatesGetState();
448- mSelfDestructTimer.start();
449+ QMetaObject::invokeMethod(&mSelfDestructTimer, "start", Qt::QueuedConnection);
450 updateUserProfiles();
451 Q_EMIT woken();
452 }
453@@ -944,6 +942,10 @@
454 }
455
456 void TelegramService::processSelfDestructMessages() {
457+ QTime time;
458+ time.start();
459+ qCDebug(TG_PLUGIN_LOGIC) << "processSelfDestructMessages";
460+
461 QSqlQuery query;
462
463 // Purge expired messages.
464@@ -965,6 +967,9 @@
465 if (query.exec() && query.next()) {
466 if (query.value("expires").isNull()) {
467 qCDebug(TG_PLUGIN_LOGIC) << "TTL: all expired messages deleted";
468+ if (mSelfDestructTimer.isActive()) {
469+ QMetaObject::invokeMethod(&mSelfDestructTimer, "stop", Qt::QueuedConnection);
470+ }
471 return;
472 }
473
474@@ -972,14 +977,17 @@
475 if (nextInSeconds > 0) {
476 qCDebug(TG_PLUGIN_LOGIC) << "TTL: next message in" << nextInSeconds << "s";
477 if (mSelfDestructTimer.isActive()) {
478- mSelfDestructTimer.stop();
479+ QMetaObject::invokeMethod(&mSelfDestructTimer, "stop", Qt::QueuedConnection);
480 }
481- mSelfDestructTimer.start(1000*nextInSeconds);
482+ QMetaObject::invokeMethod(&mSelfDestructTimer, "start", Qt::QueuedConnection,
483+ Q_ARG(qint32, 1000*nextInSeconds));
484 } else {
485 // We already have an expired message.
486- mSelfDestructTimer.start(500);
487+ QMetaObject::invokeMethod(&mSelfDestructTimer, "start", Qt::QueuedConnection,
488+ Q_ARG(qint32, 500));
489 }
490 }
491+ qCDebug(TG_PLUGIN_PROFILING) << "processSelfDestructMessages - end:" << time.elapsed() << "ms";
492 }
493
494 void TelegramService::createCrashFile() {
495
496=== modified file 'qmlplugin/telegramservice.h'
497--- qmlplugin/telegramservice.h 2015-03-26 17:16:20 +0000
498+++ qmlplugin/telegramservice.h 2015-06-01 13:36:23 +0000
499@@ -162,7 +162,7 @@
500
501 void unreadCountChanged(qint32 unreadCount);
502 void messageSent();
503- void messageReceived();
504+ void messagesReceived(qint32 count);
505
506 void userTyping(qint32 dialogId, const QString &whoIsTyping = QString());
507

Subscribers

People subscribed via source and target branches

to all changes: