Merge lp:~phablet-team/messaging-app/improve-participants-screen into lp:messaging-app/staging
- improve-participants-screen
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Tiago Salem Herrmann |
Approved revision: | 665 |
Merged at revision: | 659 |
Proposed branch: | lp:~phablet-team/messaging-app/improve-participants-screen |
Merge into: | lp:messaging-app/staging |
Prerequisite: | lp:~phablet-team/messaging-app/configure_sort |
Diff against target: |
832 lines (+325/-189) 11 files modified
debian/control (+1/-1) src/main.cpp (+0/-3) src/messagingapplication.cpp (+1/-0) src/qml/FavoriteChannels.qml (+93/-0) src/qml/GroupChatInfoPage.qml (+137/-149) src/qml/MainPage.qml (+15/-4) src/qml/Messages.qml (+59/-21) src/qml/ParticipantDelegate.qml (+3/-2) src/qml/SettingsPage.qml (+3/-3) src/qml/ThreadDelegate.qml (+6/-6) src/qml/messaging-app.qml (+7/-0) |
To merge this branch: | bzr merge lp:~phablet-team/messaging-app/improve-participants-screen |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tiago Salem Herrmann (community) | Approve | ||
Review via email: mp+316774@code.launchpad.net |
Commit message
Improve participants screen performance
Description of the change
Improve participants screen performance
- 642. By Tiago Salem Herrmann
-
merge parent
- 643. By Tiago Salem Herrmann
-
merge parent branch
- 644. By Tiago Salem Herrmann
-
merge parent branch
- 645. By Tiago Salem Herrmann
-
merge parent branch
- 646. By Tiago Salem Herrmann
-
Enable chat states dinamically
- 647. By Renato Araujo Oliveira Filho
-
Parent merged.
- 648. By Renato Araujo Oliveira Filho
-
Added 'qtdeclarative5
-ubuntu- keyboard- extensions0. 1' as app dep. - 649. By Renato Araujo Oliveira Filho
-
Add a configaration option to disconnect from server on application exit.
- 650. By Renato Araujo Oliveira Filho
-
Allow to favorite a channels and store it on settings.
- 651. By Renato Araujo Oliveira Filho
-
Save favorite channes by account.
- 652. By Renato Araujo Oliveira Filho
-
Revert changes related with disabling unactive channels.
- 653. By Renato Araujo Oliveira Filho
-
Use ChatEntry object on delegates to check if the channel is connected or not.
- 654. By Renato Araujo Oliveira Filho
-
Avoid auto-connect on channels.
- 655. By Renato Araujo Oliveira Filho
-
Removed deprecated code.
- 656. By Renato Araujo Oliveira Filho
-
Fixed favorites settings.
Remove '\' from account id before save on settings to avoid it to be saved as section.
- 657. By Renato Araujo Oliveira Filho
-
merged.
- 658. By Tiago Salem Herrmann
-
merge parent branch
- 659. By Tiago Salem Herrmann
-
merge parent
- 660. By Tiago Salem Herrmann
-
fix missing ,
- 661. By Tiago Salem Herrmann
-
fix other typos
- 662. By Tiago Salem Herrmann
-
merge parent branch
- 663. By Tiago Salem Herrmann
-
remove unused code
- 664. By Renato Araujo Oliveira Filho
-
Remove changes about 'disconnectOnQuit' this is not necessary this will be handled by server side.
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
> Just one request to remove some code, looks good otherwise.
Fixed.
- 665. By Renato Araujo Oliveira Filho
-
Removed empty function.
Tiago Salem Herrmann (tiagosh) wrote : | # |
looks good. thanks!
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2017-03-22 20:57:29 +0000 |
3 | +++ debian/control 2017-03-22 20:57:29 +0000 |
4 | @@ -26,7 +26,6 @@ |
5 | qtdeclarative5-ubuntu-content1, |
6 | qtdeclarative5-ubuntu-addressbook0.1, |
7 | qtdeclarative5-ubuntu-thumbnailer0.1, |
8 | - qtdeclarative5-ubuntu-keyboard-extensions0.1, |
9 | qtdeclarative5-qtcontacts-plugin, |
10 | qtdeclarative5-folderlistmodel-plugin, |
11 | qtmultimedia5-dev, |
12 | @@ -52,6 +51,7 @@ |
13 | qtdeclarative5-ubuntu-telephony-phonenumber0.1, |
14 | qtdeclarative5-ubuntu-history0.1 | qtdeclarative5-ubuntu-history-plugin, |
15 | qtdeclarative5-ubuntu-telephony0.1 | qtdeclarative5-ubuntu-telephony-plugin, |
16 | + qtdeclarative5-ubuntu-keyboard-extensions0.1, |
17 | qtdeclarative5-qtcontacts-plugin, |
18 | qtdeclarative5-gsettings1.0, |
19 | qml-module-qt-labs-settings, |
20 | |
21 | === modified file 'src/main.cpp' |
22 | --- src/main.cpp 2014-08-26 19:07:12 +0000 |
23 | +++ src/main.cpp 2017-03-22 20:57:29 +0000 |
24 | @@ -42,9 +42,6 @@ |
25 | // as it doesn’t play well with QtFolks. |
26 | int main(int argc, char** argv) |
27 | { |
28 | - QGuiApplication::setApplicationName("Messaging App"); |
29 | - QGuiApplication::setOrganizationName("com.ubuntu.messaging-app"); |
30 | - |
31 | MessagingApplication application(argc, argv); |
32 | |
33 | if (!application.setup()) { |
34 | |
35 | === modified file 'src/messagingapplication.cpp' |
36 | --- src/messagingapplication.cpp 2017-03-22 20:57:29 +0000 |
37 | +++ src/messagingapplication.cpp 2017-03-22 20:57:29 +0000 |
38 | @@ -90,6 +90,7 @@ |
39 | : QGuiApplication(argc, argv), m_view(0), m_applicationIsReady(false) |
40 | { |
41 | setApplicationName("MessagingApp"); |
42 | + setOrganizationName("com.ubuntu.messaging-app"); |
43 | } |
44 | |
45 | bool MessagingApplication::fullscreen() const |
46 | |
47 | === added file 'src/qml/FavoriteChannels.qml' |
48 | --- src/qml/FavoriteChannels.qml 1970-01-01 00:00:00 +0000 |
49 | +++ src/qml/FavoriteChannels.qml 2017-03-22 20:57:29 +0000 |
50 | @@ -0,0 +1,93 @@ |
51 | +/* |
52 | + * Copyright 2012-2016 Canonical Ltd. |
53 | + * |
54 | + * This file is part of messaging-app. |
55 | + * |
56 | + * messaging-app is free software; you can redistribute it and/or modify |
57 | + * it under the terms of the GNU General Public License as published by |
58 | + * the Free Software Foundation; version 3. |
59 | + * |
60 | + * messaging-app is distributed in the hope that it will be useful, |
61 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
62 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
63 | + * GNU General Public License for more details. |
64 | + * |
65 | + * You should have received a copy of the GNU General Public License |
66 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
67 | + */ |
68 | + |
69 | +import QtQuick 2.2 |
70 | +import Qt.labs.settings 1.0 |
71 | + |
72 | + |
73 | +Item { |
74 | + property var _favoritesByAccount: [] |
75 | + |
76 | + |
77 | + function getFavoriteChannels(account) |
78 | + { |
79 | + var settings = settingsFromAccount(account) |
80 | + return favoriteChannels(settings) |
81 | + } |
82 | + |
83 | + function favoriteIndex(account, fav) |
84 | + { |
85 | + return getFavoriteChannels(account).indexOf(fav) |
86 | + } |
87 | + |
88 | + function isFavorite(account, fav) |
89 | + { |
90 | + return (favoriteIndex(account, fav) !== -1) |
91 | + } |
92 | + |
93 | + function addFavorite(account, fav) { |
94 | + var settings = settingsFromAccount(account) |
95 | + if (favoriteIndexFromSettings(settings, fav) === -1) { |
96 | + settings.favoriteChannels += ";" + fav |
97 | + } |
98 | + } |
99 | + |
100 | + function removeFavorite(account, fav) { |
101 | + var settings = settingsFromAccount(account) |
102 | + var index = favoriteIndexFromSettings(settings, fav) |
103 | + if (index !== -1) { |
104 | + var list = settings.favoriteChannels.split(";") |
105 | + list.splice(index, 1) |
106 | + settings.favoriteChannels = list.join(";") |
107 | + } |
108 | + } |
109 | + |
110 | + // private |
111 | + function settingsFromAccount(account) { |
112 | + var account_ = account.replace(/\//g,"#") |
113 | + if (account_ in _favoritesByAccount) { |
114 | + return _favoritesByAccount[account_] |
115 | + } else { |
116 | + var settings = favoriteByAccountComponent.createObject(this, {'category': account_}) |
117 | + _favoritesByAccount[account_] = settings |
118 | + return settings |
119 | + } |
120 | + } |
121 | + |
122 | + function favoriteIndexFromSettings(settings, fav) |
123 | + { |
124 | + return settings.favoriteChannels.split(";").indexOf(fav) |
125 | + } |
126 | + |
127 | + function favoriteChannels(settings) |
128 | + { |
129 | + if (settings.favoriteChannels.length > 0) { |
130 | + return settings.favoriteChannels.split(";") |
131 | + } else { |
132 | + return [] |
133 | + } |
134 | + } |
135 | + |
136 | + Component { |
137 | + id: favoriteByAccountComponent |
138 | + Settings { |
139 | + objectName: "settings_" + category |
140 | + property string favoriteChannels: "" |
141 | + } |
142 | + } |
143 | +} |
144 | |
145 | === modified file 'src/qml/GroupChatInfoPage.qml' |
146 | --- src/qml/GroupChatInfoPage.qml 2017-03-22 20:57:29 +0000 |
147 | +++ src/qml/GroupChatInfoPage.qml 2017-03-22 20:57:29 +0000 |
148 | @@ -56,9 +56,19 @@ |
149 | } |
150 | return [] |
151 | } |
152 | + |
153 | + ParticipantsModel { |
154 | + id: participantsModel |
155 | + chatEntry: groupChatInfoPage.chatEntry.active ? groupChatInfoPage.chatEntry : null |
156 | + } |
157 | + |
158 | + property var participantsSize: participants.length + localPendingParticipants.length + remotePendingParticipants.length |
159 | + |
160 | property variant allParticipants: { |
161 | var participantList = [] |
162 | - |
163 | + if (chatEntry.active) { |
164 | + return participantList |
165 | + } |
166 | for (var i in participants) { |
167 | var participant = participants[i] |
168 | participant["state"] = 0 |
169 | @@ -84,6 +94,7 @@ |
170 | participantList.push(participant) |
171 | } |
172 | } |
173 | + participantList.sort(function(a,b) {return (a.identifier.toLowerCase() > b.identifier.toLowerCase()) ? 1 : ((b.identifier.toLowerCase() > a.identifier.toLowerCase()) ? -1 : 0);} ); |
174 | return participantList |
175 | } |
176 | |
177 | @@ -158,7 +169,34 @@ |
178 | title: groupChatInfoPage.headerString |
179 | // FIXME: uncomment once the header supports subtitle |
180 | //subtitle: i18n.tr("%1 member", "%1 members", allParticipants.length) |
181 | - flickable: contentsFlickable |
182 | + |
183 | + trailingActionBar { |
184 | + id: trailingBar |
185 | + actions: [ |
186 | + Action { |
187 | + iconName: "close" |
188 | + text: i18n.tr("End group") |
189 | + onTriggered: destroyGroup() |
190 | + enabled: chatRoom && !isPhoneAccount && chatEntry.active && chatEntry.selfContactRoles & 2 |
191 | + visible: enabled |
192 | + }, |
193 | + Action { |
194 | + iconName: "system-log-out" |
195 | + text: groupChatInfoPage.leaveString |
196 | + visible: enabled |
197 | + onTriggered: { |
198 | + if (chatEntry.leaveChat()) { |
199 | + application.showNotificationMessage(groupChatInfoPage.leaveSuccessString, "tick") |
200 | + mainView.emptyStack() |
201 | + } else { |
202 | + application.showNotificationMessage(groupChatInfoPage.leaveFailedString, "dialog-error-symbolic") |
203 | + } |
204 | + |
205 | + } |
206 | + enabled: chatRoom && !isPhoneAccount && chatEntry.active && !(chatEntry.selfContactRoles & 2) |
207 | + } |
208 | + ] |
209 | + } |
210 | } |
211 | |
212 | function addRecipientFromSearch(identifier, alias, avatar) { |
213 | @@ -166,12 +204,25 @@ |
214 | } |
215 | |
216 | function addRecipient(identifier, contact) { |
217 | - for (var i=0; i < allParticipants; i++) { |
218 | - if (identifier == allParticipants[i].identifier) { |
219 | - application.showNotificationMessage(i18n.tr("This recipient was already selected"), "dialog-error-symbolic") |
220 | - return |
221 | - } |
222 | - } |
223 | + for (var i=0; i < participants; i++) { |
224 | + if (identifier == participants[i].identifier) { |
225 | + application.showNotificationMessage(i18n.tr("This recipient was already selected"), "dialog-error-symbolic") |
226 | + return |
227 | + } |
228 | + } |
229 | + for (var i=0; i < localPendingParticipants; i++) { |
230 | + if (identifier == localPendingParticipants[i].identifier) { |
231 | + application.showNotificationMessage(i18n.tr("This recipient was already selected"), "dialog-error-symbolic") |
232 | + return |
233 | + } |
234 | + } |
235 | + for (var i=0; i < remotePendingParticipants; i++) { |
236 | + if (identifier == remotePendingParticipants[i].identifier) { |
237 | + application.showNotificationMessage(i18n.tr("This recipient was already selected"), "dialog-error-symbolic") |
238 | + return |
239 | + } |
240 | + } |
241 | + |
242 | searchItem.text = "" |
243 | |
244 | chatEntry.inviteParticipants([identifier], "") |
245 | @@ -195,30 +246,22 @@ |
246 | } |
247 | } |
248 | |
249 | - Flickable { |
250 | + ListView { |
251 | id: contentsFlickable |
252 | - property var emptySpaceHeight: height - contentsColumn.topItemsHeight+contentsFlickable.contentY |
253 | anchors { |
254 | - top: parent.top |
255 | + top: groupChatInfoPage.header.top |
256 | + topMargin: groupChatInfoPage.header.height |
257 | left: parent.left |
258 | right: parent.right |
259 | bottom: keyboard.top |
260 | } |
261 | - contentHeight: contentsColumn.height |
262 | - clip: true |
263 | - |
264 | - Column { |
265 | - id: contentsColumn |
266 | - property var topItemsHeight: groupInfo.height+participantsHeader.height+searchItem.height+units.gu(1) |
267 | - |
268 | + |
269 | + header: Item { |
270 | anchors { |
271 | - top: parent.top |
272 | left: parent.left |
273 | right: parent.right |
274 | } |
275 | - |
276 | height: childrenRect.height |
277 | - |
278 | Item { |
279 | id: groupInfo |
280 | height: visible ? groupAvatar.height + groupAvatar.anchors.topMargin + units.gu(1) : 0 |
281 | @@ -226,6 +269,7 @@ |
282 | enabled: chatEntry.active |
283 | |
284 | anchors { |
285 | + top: parent.top |
286 | left: parent.left |
287 | right: parent.right |
288 | } |
289 | @@ -306,18 +350,11 @@ |
290 | } |
291 | } |
292 | |
293 | - ListItems.ThinDivider { |
294 | - visible: groupInfo.visible |
295 | - anchors { |
296 | - left: parent.left |
297 | - right: parent.right |
298 | - } |
299 | - } |
300 | - |
301 | Item { |
302 | id: participantsHeader |
303 | enabled: chatEntry.active |
304 | anchors { |
305 | + top: groupInfo.bottom |
306 | left: parent.left |
307 | right: parent.right |
308 | } |
309 | @@ -330,7 +367,7 @@ |
310 | leftMargin: units.gu(2) |
311 | verticalCenter: addParticipantButton.verticalCenter |
312 | } |
313 | - text: !searchItem.enabled ? i18n.tr("Participants: %1").arg(allParticipants.length) : i18n.tr("Add participant:") |
314 | + text: !searchItem.enabled ? i18n.tr("Participants: %1").arg(participantsSize) : i18n.tr("Add participant:") |
315 | } |
316 | |
317 | Button { |
318 | @@ -360,22 +397,16 @@ |
319 | } |
320 | } |
321 | |
322 | - ListItems.ThinDivider { |
323 | - anchors { |
324 | - left: parent.left |
325 | - right: parent.right |
326 | - } |
327 | - } |
328 | - |
329 | ContactSearchWidget { |
330 | id: searchItem |
331 | enabled: false |
332 | height: enabled ? units.gu(6) : 0 |
333 | clip: true |
334 | parentPage: groupChatInfoPage |
335 | - searchResultsHeight: contentsFlickable.emptySpaceHeight |
336 | + searchResultsHeight: keyboard.y-y-height |
337 | onContactPicked: addRecipientFromSearch(identifier, alias, avatar) |
338 | anchors { |
339 | + top: participantsHeader.bottom |
340 | left: parent.left |
341 | right: parent.right |
342 | } |
343 | @@ -383,124 +414,81 @@ |
344 | UbuntuNumberAnimation {} |
345 | } |
346 | } |
347 | + } |
348 | |
349 | - ListItems.ThinDivider { |
350 | - visible: searchItem.enabled |
351 | - anchors { |
352 | - left: parent.left |
353 | - right: parent.right |
354 | - } |
355 | + ListItemActions { |
356 | + id: participantLeadingActions |
357 | + delegate: Label { |
358 | + anchors.verticalCenter: parent.verticalCenter |
359 | + anchors.horizontalCenter: parent.horizontalCenter |
360 | + height: contentHeight |
361 | + width: contentWidth+units.gu(2) |
362 | + verticalAlignment: Text.AlignVCenter |
363 | + horizontalAlignment: Text.AlignHCenter |
364 | + text: i18n.tr("Remove") |
365 | } |
366 | - |
367 | - |
368 | - ListItemActions { |
369 | - id: participantLeadingActions |
370 | - delegate: Label { |
371 | - anchors.verticalCenter: parent.verticalCenter |
372 | - anchors.horizontalCenter: parent.horizontalCenter |
373 | - height: contentHeight |
374 | - width: contentWidth+units.gu(2) |
375 | - verticalAlignment: Text.AlignVCenter |
376 | - horizontalAlignment: Text.AlignHCenter |
377 | + actions: [ |
378 | + Action { |
379 | text: i18n.tr("Remove") |
380 | - } |
381 | - actions: [ |
382 | - Action { |
383 | - text: i18n.tr("Remove") |
384 | - onTriggered: { |
385 | - // in case account is not a phone one, alert that if the group is going to have no active participants |
386 | - // it can be dissolved by the server |
387 | - if (chatEntry.chatType == ChatEntry.ChatTypeRoom && chatEntry.participants.length === 1 /*the active participant to remove now*/) { |
388 | - var properties = {} |
389 | - properties["groupName"] = groupName.text |
390 | - PopupUtils.open(Qt.createComponent("Dialogs/EmptyGroupWarningDialog.qml").createObject(groupChatInfoPage), groupChatInfoPage, properties) |
391 | - } else { |
392 | - var delegate = participantsRepeater.itemAt(value) |
393 | - delegate.removeFromGroup(); |
394 | - } |
395 | - } |
396 | - } |
397 | - ] |
398 | - } |
399 | - |
400 | - Repeater { |
401 | - id: participantsRepeater |
402 | - model: allParticipants |
403 | - |
404 | - ParticipantDelegate { |
405 | - id: participantDelegate |
406 | - function canRemove() { |
407 | - if (!groupChatInfoPage.chatRoom /*not a group*/ |
408 | - || !chatEntry.active /*not active*/ |
409 | - || modelData.roles & 2 /*not admin*/ |
410 | - || modelData.state === 2 /*remote pending*/) { |
411 | - return false |
412 | - } |
413 | - // temporary workaround |
414 | - if (account && account.protocolInfo.name == "irc") { |
415 | - return false |
416 | - } |
417 | - return (chatEntry.groupFlags & ChatEntry.ChannelGroupFlagCanRemove) |
418 | - } |
419 | - function removeFromGroup() { |
420 | - var participant = participantDelegate.participant |
421 | - chatEntry.removeParticipants([participant.identifier], "") |
422 | - participantDelegate.height = 0 |
423 | - } |
424 | - participant: modelData |
425 | - leadingActions: canRemove() ? participantLeadingActions : undefined |
426 | - onClicked: { |
427 | - if (openProfileButton.visible) { |
428 | - mainStack.addPageToCurrentColumn(groupChatInfoPage, Qt.resolvedUrl("ParticipantInfoPage.qml"), {"delegate": participantDelegate, "chatEntry": chatEntry, "chatRoom": chatRoom}) |
429 | - } |
430 | - } |
431 | - Icon { |
432 | - id: openProfileButton |
433 | - anchors.right: parent.right |
434 | - anchors.rightMargin: units.gu(1) |
435 | - anchors.verticalCenter: parent.verticalCenter |
436 | - height: units.gu(2) |
437 | - name: "go-next" |
438 | - } |
439 | - } |
440 | - } |
441 | - Item { |
442 | - id: padding |
443 | - height: units.gu(3) |
444 | - anchors.left: parent.left |
445 | + onTriggered: { |
446 | + // in case account is not a phone one, alert that if the group is going to have no active participants |
447 | + // it can be dissolved by the server |
448 | + if (chatEntry.chatType == ChatEntry.ChatTypeRoom && chatEntry.participants.length === 1 /*the active participant to remove now*/) { |
449 | + var properties = {} |
450 | + properties["groupName"] = groupName.text |
451 | + PopupUtils.open(Qt.createComponent("Dialogs/EmptyGroupWarningDialog.qml").createObject(groupChatInfoPage), groupChatInfoPage, properties) |
452 | + } else { |
453 | + var delegate = contentsFlickable.itemAt(value) |
454 | + delegate.removeFromGroup(); |
455 | + } |
456 | + } |
457 | + } |
458 | + ] |
459 | + } |
460 | + |
461 | + model: chatEntry.active ? participantsModel : allParticipants |
462 | + |
463 | + delegate: ParticipantDelegate { |
464 | + id: participantDelegate |
465 | + function canRemove() { |
466 | + if (!groupChatInfoPage.chatRoom /*not a group*/ |
467 | + || !chatEntry.active /*not active*/ |
468 | + || model.roles & 2 /*not admin*/ |
469 | + || model.state === 2 /*remote pending*/) { |
470 | + return false |
471 | + } |
472 | + // temporary workaround |
473 | + if (account && account.protocolInfo.name == "irc") { |
474 | + return false |
475 | + } |
476 | + return (chatEntry.groupFlags & ChatEntry.ChannelGroupFlagCanRemove) |
477 | + } |
478 | + function removeFromGroup() { |
479 | + var participant = participantDelegate.participant |
480 | + chatEntry.removeParticipants([participant.identifier], "") |
481 | + participantDelegate.height = 0 |
482 | + } |
483 | + participant: chatEntry.active ? model : modelData |
484 | + leadingActions: canRemove() ? participantLeadingActions : null |
485 | + onClicked: { |
486 | + if (openProfileButton.visible) { |
487 | + mainStack.addPageToCurrentColumn(groupChatInfoPage, Qt.resolvedUrl("ParticipantInfoPage.qml"), {"delegate": participantDelegate, "chatEntry": chatEntry, "chatRoom": chatRoom}) |
488 | + } |
489 | + } |
490 | + Icon { |
491 | + id: openProfileButton |
492 | anchors.right: parent.right |
493 | - } |
494 | - Row { |
495 | - enabled: chatEntry.active |
496 | - anchors { |
497 | - right: parent.right |
498 | - rightMargin: units.gu(2) |
499 | - } |
500 | - layoutDirection: Qt.RightToLeft |
501 | - spacing: units.gu(1) |
502 | - Button { |
503 | - id: destroyButton |
504 | - visible: chatRoom && !isPhoneAccount && chatEntry.active && chatEntry.selfContactRoles & 2 |
505 | - text: i18n.tr("End group") |
506 | - color: Theme.palette.normal.negative |
507 | - onClicked: destroyGroup() |
508 | - } |
509 | - Button { |
510 | - id: leaveButton |
511 | - visible: chatRoom && !isPhoneAccount && chatEntry.active && !(chatEntry.selfContactRoles & 2) |
512 | - text: groupChatInfoPage.leaveString |
513 | - onClicked: { |
514 | - if (chatEntry.leaveChat()) { |
515 | - application.showNotificationMessage(groupChatInfoPage.leaveSuccessString, "tick") |
516 | - mainView.emptyStack() |
517 | - } else { |
518 | - application.showNotificationMessage(groupChatInfoPage.leaveFailedString, "dialog-error-symbolic") |
519 | - } |
520 | - } |
521 | - } |
522 | + anchors.rightMargin: units.gu(1) |
523 | + anchors.verticalCenter: parent.verticalCenter |
524 | + height: units.gu(2) |
525 | + name: "go-next" |
526 | } |
527 | } |
528 | } |
529 | + Scrollbar { |
530 | + flickableItem: contentsFlickable |
531 | + align: Qt.AlignTrailing |
532 | + } |
533 | KeyboardRectangle { |
534 | id: keyboard |
535 | } |
536 | |
537 | === modified file 'src/qml/MainPage.qml' |
538 | --- src/qml/MainPage.qml 2017-03-22 20:57:29 +0000 |
539 | +++ src/qml/MainPage.qml 2017-03-22 20:57:29 +0000 |
540 | @@ -210,7 +210,7 @@ |
541 | id: sectionDelegate |
542 | ThreadsSectionDelegate { |
543 | function formatSectionTitle(title) { |
544 | - if (mainView.sortTrheadsBy === "timestamp") |
545 | + if (mainView.sortThreadsBy === "timestamp") |
546 | return DateUtils.friendlyDay(Qt.formatDate(section, "yyyy/MM/dd"), i18n); |
547 | else if (telepathyHelper.ready) |
548 | return telepathyHelper.accountForId(title).displayName |
549 | @@ -238,7 +238,7 @@ |
550 | clip: true |
551 | currentIndex: -1 |
552 | //spacing: searchField.text === "" ? units.gu(-2) : 0 |
553 | - section.property: mainView.sortTrheadsBy === "title" ? "accountId" : "eventDate" |
554 | + section.property: mainView.sortThreadsBy === "title" ? "accountId" : "eventDate" |
555 | section.delegate: searching && searchField.text !== "" ? null : sectionDelegate |
556 | header: ListItem.Standard { |
557 | // FIXME: update |
558 | @@ -279,15 +279,15 @@ |
559 | if (displayedEvent != null) { |
560 | properties["scrollToEventId"] = displayedEvent.eventId |
561 | } |
562 | + properties["chatEntry"] = chatEntry |
563 | delete properties["participants"] |
564 | delete properties["localPendingParticipants"] |
565 | delete properties["remotePendingParticipants"] |
566 | mainView.showMessagesView(properties) |
567 | } |
568 | |
569 | - |
570 | // FIXME: find a better unique name |
571 | - objectName: "thread%1".arg(participants[0].identifier) |
572 | + objectName: "thread%1".arg(participants.length > 0 ? participants[0].identifier : "") |
573 | Component.onCompleted: mainPage.newThreadCreated(model) |
574 | |
575 | anchors { |
576 | @@ -321,6 +321,17 @@ |
577 | threadList.startSelection() |
578 | threadList.selectItem(threadDelegate) |
579 | } |
580 | + |
581 | + ChatEntry { |
582 | + id: chatEntry |
583 | + chatType: model.properties.chatType |
584 | + participantIds: model.properties.participantIds |
585 | + chatId: model.properties.threadId |
586 | + accountId: model.properties.accountId |
587 | + autoRequest: false |
588 | + } |
589 | + |
590 | + opacity: !groupChat || chatEntry.active ? 1.0 : 0.5 |
591 | } |
592 | onSelectionDone: { |
593 | var threadsToRemove = [] |
594 | |
595 | === modified file 'src/qml/Messages.qml' |
596 | --- src/qml/Messages.qml 2017-03-22 20:57:29 +0000 |
597 | +++ src/qml/Messages.qml 2017-03-22 20:57:29 +0000 |
598 | @@ -94,7 +94,7 @@ |
599 | property var accountsModel: getAccountsModel() |
600 | property alias oskEnabled: keyboard.oskEnabled |
601 | property bool isReady: false |
602 | - property QtObject chatEntry: chatEntryObject |
603 | + property QtObject chatEntry |
604 | property string firstRecipientAlias: ((contactWatcher.isUnknown && |
605 | contactWatcher.isInteractive) || |
606 | contactWatcher.alias === "") ? contactWatcher.identifier : contactWatcher.alias |
607 | @@ -104,6 +104,19 @@ |
608 | property bool isBroadcast: chatType != ChatEntry.ChatTypeRoom && (participantIds.length > 1 || multiRecipient.recipientCount > 1) |
609 | |
610 | property alias validator: sendMessageValidator |
611 | + property string chatTitle: { |
612 | + if (chatEntry.title !== "") { |
613 | + return chatEntry.title |
614 | + } |
615 | + var roomInfo = threadInformation.chatRoomInfo |
616 | + if (roomInfo.Title != "") { |
617 | + return roomInfo.Title |
618 | + } else if (roomInfo.RoomName != "") { |
619 | + return roomInfo.RoomName |
620 | + } |
621 | + return "" |
622 | + } |
623 | + |
624 | |
625 | signal ready |
626 | signal cancel |
627 | @@ -679,6 +692,17 @@ |
628 | visible: enabled |
629 | iconName: "view-refresh" |
630 | onTriggered: messages.chatEntry.startChat() |
631 | + }, |
632 | + Action { |
633 | + id: favoriteAction |
634 | + visible: chatEntry.active && (messages.chatType == HistoryThreadModel.ChatTypeRoom) |
635 | + iconName: mainView.favoriteChannels.isFavorite(messages.accountId, messages.chatTitle) ? "starred" : "non-starred" |
636 | + onTriggered: { |
637 | + if (iconName == "starred") |
638 | + mainView.favoriteChannels.removeFavorite(messages.accountId, messages.chatTitle) |
639 | + else |
640 | + mainView.favoriteChannels.addFavorite(messages.accountId, messages.chatTitle) |
641 | + } |
642 | } |
643 | |
644 | ] |
645 | @@ -689,15 +713,10 @@ |
646 | title: { |
647 | var finalParticipants = (participants ? participants.length : 0) |
648 | if (messages.chatType == HistoryThreadModel.ChatTypeRoom) { |
649 | - if (chatEntry.title !== "") { |
650 | - return chatEntry.title |
651 | - } |
652 | - var roomInfo = threadInformation.chatRoomInfo |
653 | - if (roomInfo.Title != "") { |
654 | - return roomInfo.Title |
655 | - } else if (roomInfo.RoomName != "") { |
656 | - return roomInfo.RoomName |
657 | - } |
658 | + if (messages.chatTitle != "") { |
659 | + return messages.chatTitle |
660 | + } |
661 | + |
662 | // include the "Me" participant to be consistent with |
663 | // group info page |
664 | if (roomInfo.Joined) { |
665 | @@ -851,6 +870,10 @@ |
666 | ] |
667 | |
668 | Component.onCompleted: { |
669 | + if (!chatEntry) { |
670 | + chatEntry = chatEntryComponent.createObject(this) |
671 | + } |
672 | + |
673 | // we only revert back to phone account if this is a 1-1 chat, |
674 | // in which case the handler will fallback to multimedia if needed |
675 | if (messages.accountId !== "" && chatType !== HistoryThreadModel.ChatTypeRoom) { |
676 | @@ -1040,16 +1063,22 @@ |
677 | } |
678 | } |
679 | |
680 | - ChatEntry { |
681 | - id: chatEntryObject |
682 | - chatType: messages.chatType |
683 | - participantIds: messages.participantIds |
684 | - chatId: messages.threadId |
685 | - accountId: messages.accountId |
686 | - autoRequest: !newMessage && !messages.account.protocolInfo.enableRejoin |
687 | - |
688 | + Component { |
689 | + id: chatEntryComponent |
690 | + |
691 | + ChatEntry { |
692 | + id: chatEntryObject |
693 | + chatType: messages.chatType |
694 | + participantIds: messages.participantIds |
695 | + chatId: messages.threadId |
696 | + accountId: messages.accountId |
697 | + } |
698 | + } |
699 | + |
700 | + Connections { |
701 | + target: messages.chatEntry |
702 | onChatTypeChanged: { |
703 | - messages.chatType = chatEntryObject.chatType |
704 | + messages.chatType = chatEntry.chatType |
705 | } |
706 | |
707 | onMessageSent: { |
708 | @@ -1066,9 +1095,15 @@ |
709 | } |
710 | } |
711 | |
712 | + Binding { |
713 | + target: messages.chatEntry |
714 | + property: "autoRequest" |
715 | + value: !messages.newMessage && !messages.account.protocolInfo.enableRejoin |
716 | + } |
717 | + |
718 | Repeater { |
719 | - model: messages.chatEntry.chatStates |
720 | - Item { |
721 | + model: account.protocolInfo.enableChatStates ? messages.chatEntry.chatStates : null |
722 | + delegate: Item { |
723 | function processChatState() { |
724 | if (modelData.state == ChatEntry.ChannelChatStateComposing) { |
725 | messages.userTyping = true |
726 | @@ -1458,6 +1493,9 @@ |
727 | maxHeight: messages.height - keyboard.height - screenTop.y |
728 | text: messages.text |
729 | onTextChanged: { |
730 | + if (!account.protocolInfo.enableChatStates) { |
731 | + return |
732 | + } |
733 | if (text == "" && !composeBar.inputMethodComposing) { |
734 | messages.chatEntry.setChatState(ChatEntry.ChannelChatStateActive) |
735 | selfTypingTimer.stop() |
736 | |
737 | === modified file 'src/qml/ParticipantDelegate.qml' |
738 | --- src/qml/ParticipantDelegate.qml 2016-10-18 13:32:28 +0000 |
739 | +++ src/qml/ParticipantDelegate.qml 2017-03-22 20:57:29 +0000 |
740 | @@ -51,9 +51,10 @@ |
741 | id: avatar |
742 | enabled: true |
743 | fallbackAvatarUrl: { |
744 | - if (participant.avatar !== "") { |
745 | + if (participant && participant.avatar && participant.avatar !== "") { |
746 | + console.log(participant.avatar) |
747 | return participant.avatar |
748 | - } else if (participant.alias === "") { |
749 | + } else if (participant && participant.alias === "") { |
750 | return "image://theme/contact" |
751 | } |
752 | return "" |
753 | |
754 | === modified file 'src/qml/SettingsPage.qml' |
755 | --- src/qml/SettingsPage.qml 2017-03-22 20:57:29 +0000 |
756 | +++ src/qml/SettingsPage.qml 2017-03-22 20:57:29 +0000 |
757 | @@ -34,7 +34,7 @@ |
758 | readonly property var setMethods: { |
759 | "mmsEnabled": function(value) { telepathyHelper.mmsEnabled = value }, |
760 | "threadSort": function(value) { mainView.sortThreadsBy = value }, |
761 | - "compactView": function(value) { mainView.compactView = value } |
762 | + "compactView": function(value) { mainView.compactView = value }, |
763 | //"characterCountEnabled": function(value) { msgSettings.showCharacterCount = value } |
764 | } |
765 | |
766 | @@ -66,8 +66,8 @@ |
767 | { "type": "options", |
768 | "data": { "name": "threadSort", |
769 | "description": i18n.tr("Sort threads"), |
770 | - "currentValue": mainView.sortTrheadsBy, |
771 | - "subtitle": settingsPage.sortByModel[mainView.sortTrheadsBy], |
772 | + "currentValue": mainView.sortThreadsBy, |
773 | + "subtitle": settingsPage.sortByModel[mainView.sortThreadsBy], |
774 | "options": sortByModel, |
775 | "setMethod": "threadSort"} |
776 | } |
777 | |
778 | === modified file 'src/qml/ThreadDelegate.qml' |
779 | --- src/qml/ThreadDelegate.qml 2017-03-22 20:57:29 +0000 |
780 | +++ src/qml/ThreadDelegate.qml 2017-03-22 20:57:29 +0000 |
781 | @@ -373,10 +373,10 @@ |
782 | |
783 | Item { |
784 | id: delegateHelper |
785 | - property string phoneNumber: participant.identifier |
786 | - property string alias: participant.alias ? participant.alias : "" |
787 | - property string avatar: participant.avatar ? participant.avatar : "" |
788 | - property string contactId: participant.contactId ? participant.contactId : "" |
789 | + property string phoneNumber: participant ? participant.identifier : "" |
790 | + property string alias: participant && participant.alias ? participant.alias : "" |
791 | + property string avatar: participant && participant.avatar ? participant.avatar : "" |
792 | + property string contactId: participant && participant.contactId ? participant.contactId : "" |
793 | property alias subTypes: phoneDetail.subTypes |
794 | property alias contexts: phoneDetail.contexts |
795 | property bool isUnknown: contactId === "" |
796 | @@ -509,8 +509,8 @@ |
797 | |
798 | PhoneNumber { |
799 | id: phoneDetail |
800 | - contexts: participant.phoneContexts ? participant.phoneContexts : [] |
801 | - subTypes: participant.phoneSubTypes ? participant.phoneSubTypes : [] |
802 | + contexts: participant && participant.phoneContexts ? participant.phoneContexts : [] |
803 | + subTypes: participant && participant.phoneSubTypes ? participant.phoneSubTypes : [] |
804 | } |
805 | |
806 | ContactDetailPhoneNumberTypeModel { |
807 | |
808 | === modified file 'src/qml/messaging-app.qml' |
809 | --- src/qml/messaging-app.qml 2017-03-22 20:57:29 +0000 |
810 | +++ src/qml/messaging-app.qml 2017-03-22 20:57:29 +0000 |
811 | @@ -39,9 +39,12 @@ |
812 | // settings |
813 | property alias sortThreadsBy: globalSettings.sortThreadsBy |
814 | property alias compactView: globalSettings.compactView |
815 | + property alias favoriteChannels: favoriteChannelsItem |
816 | + |
817 | // private |
818 | property var _pendingProperties: null |
819 | |
820 | + |
821 | function updateNewMessageStatus() { |
822 | activeMessagesView = application.findMessagingChild("messagesPage", "active", true) |
823 | } |
824 | @@ -497,4 +500,8 @@ |
825 | layout.completed = true; |
826 | } |
827 | } |
828 | + |
829 | + FavoriteChannels { |
830 | + id: favoriteChannelsItem |
831 | + } |
832 | } |
Just one request to remove some code, looks good otherwise.