Merge lp:~tiagosh/messaging-app/dual-sim2 into lp:messaging-app

Proposed by Tiago Salem Herrmann
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 147
Merged at revision: 150
Proposed branch: lp:~tiagosh/messaging-app/dual-sim2
Merge into: lp:messaging-app
Diff against target: 465 lines (+154/-54)
6 files modified
src/qml/MainPage.qml (+6/-4)
src/qml/MessageDelegate.qml (+15/-1)
src/qml/Messages.qml (+128/-46)
src/qml/NewRecipientPage.qml (+1/-1)
src/qml/ThreadDelegate.qml (+3/-1)
tests/autopilot/messaging_app/emulators.py (+1/-1)
To merge this branch: bzr merge lp:~tiagosh/messaging-app/dual-sim2
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+226906@code.launchpad.net

Commit message

- Implement sim card switcher when there is more than one account available (label is hardcoded for now)
- Update some visuals to match the new spec
- Merge messages from different accounts

Description of the change

- Implement sim card switcher when there is more than one account available (label is hardcoded for now)
- Update some visuals to match the new spec
- Merge messages from different accounts

--Checklist--
Are there any related MPs required for this MP to build/function as expected? Please list.
https://code.launchpad.net/~tiagosh/telephony-service/dual-sim2/+merge/226904
https://code.launchpad.net/~boiko/history-service/thread_proxy_model/+merge/226758

Is your branch in sync with latest trunk (e.g. bzr pull lp:trunk -> no changes)
Yes

Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator?
Yes

Did you successfully run all tests found in your component's Test Plan (https://wiki.ubuntu.com/Process/Merges/TestPlan/messaging-app) on device or emulator?
Yes

If you changed the UI, was the change specified/approved by design?
Yes

If you changed the packaging (debian), did you add a core-dev as a reviewer to this MP?
N/A

To post a comment you must log in.
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

The code is looking good, there are just a few minor things that need to be fixed. Please check the inline diff comments.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~tiagosh/messaging-app/dual-sim2 updated
147. By Tiago Salem Herrmann

fix translation
update method name to reflect its real job
remove unused code

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?
Yes

Did CI run pass? If not, please explain why.
Yes

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?
Yes

Code looks good and works as expected!

review: Approve
lp:~tiagosh/messaging-app/dual-sim2 updated
148. By Tiago Salem Herrmann

merge trunk

149. By Tiago Salem Herrmann

only show accountLabel if there is more than 1 account

150. By Tiago Salem Herrmann

increase touch area

151. By Tiago Salem Herrmann

increase font size
fix bottom edge swipe

Revision history for this message
Brendan Donegan (brendan-donegan) wrote :

The CI run did not pass here - I guess the failures have been ignored because of false positives? That should really be fixed, and until then the tests should be run manually on the device. If you had done this you would have noticed you broke a test by changing the 'name' property of the Add contact icon from 'new-contact' to 'contact'.

Revision history for this message
Brendan Donegan (brendan-donegan) wrote :

Also, are we planning to have any tests for the dual SIM feature?

Revision history for this message
Tiago Salem Herrmann (tiagosh) wrote :

The tests failed because this MR needs changes in the history-service and telephony-service, as explained in the MR description. If you check the logs you will see that the app is not even running correctly because the new proxy model is inexistent. Also, I probably forgot to run the tests manually (only tested the functionalities on the device) and ended up breaking the test. My bad! I will fix this still today. Thank for the report.

About tests for dual sim, I believe we need to add some, but the current infrastructure (with-ofono-phonesim script) does not support this setup yet.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/qml/MainPage.qml'
2--- src/qml/MainPage.qml 2014-06-17 13:18:57 +0000
3+++ src/qml/MainPage.qml 2014-07-17 21:29:41 +0000
4@@ -131,11 +131,12 @@
5 }
6 }
7
8- SortProxyModel {
9+ HistoryThreadGroupingProxyModel {
10 id: sortProxy
11 sortRole: HistoryThreadModel.LastEventTimestampRole
12 sourceModel: threadModel
13 ascending: false
14+ groupingProperty: "participants"
15 }
16
17 HistoryThreadModel {
18@@ -201,7 +202,6 @@
19 }
20 } else {
21 var properties = {}
22- properties["threadId"] = threadId
23 properties["accountId"] = accountId
24 properties["participants"] = participants
25 properties["keyboardFocus"] = false
26@@ -215,8 +215,10 @@
27 }
28 onSelectionDone: {
29 for (var i=0; i < items.count; i++) {
30- var thread = items.get(i).model
31- threadModel.removeThread(thread.accountId, thread.threadId, thread.type)
32+ var threads = items.get(i).model.threads
33+ for (var j in threads) {
34+ threadModel.removeThread(threads[j].accountId, threads[j].threadId, threads[j].type)
35+ }
36 }
37 }
38
39
40=== modified file 'src/qml/MessageDelegate.qml'
41--- src/qml/MessageDelegate.qml 2014-07-07 13:11:03 +0000
42+++ src/qml/MessageDelegate.qml 2014-07-17 21:29:41 +0000
43@@ -38,6 +38,7 @@
44 property alias selected: internalDelegate.selected
45 property variant activeAttachment
46 property string mmsText: ""
47+ property string accountLabel: ""
48
49 anchors.left: parent ? parent.left : undefined
50 anchors.right: parent ? parent.right: undefined
51@@ -262,13 +263,26 @@
52 textMessageStatus == HistoryThreadModel.MessageStatusTemporarilyFailed) && !incoming && mmsText === ""
53 }
54
55+ Label {
56+ id: accountIndicator
57+ anchors {
58+ right: bubble.left
59+ rightMargin: units.gu(0.5)
60+ bottom: bubble.bottom
61+ }
62+ text: accountLabel
63+ visible: !incoming
64+ font.pixelSize: FontUtils.sizeToPixels("small")
65+ color: "green"
66+ }
67+
68 // FIXME: this is just a temporary workaround while we dont have the final design
69 UbuntuShape {
70 id: warningButton
71 color: "yellow"
72 height: units.gu(3)
73 width: units.gu(3)
74- anchors.right: bubble.left
75+ anchors.right: accountIndicator.left
76 anchors.left: undefined
77 anchors.verticalCenter: bubble.verticalCenter
78 anchors.leftMargin: 0
79
80=== modified file 'src/qml/Messages.qml'
81--- src/qml/Messages.qml 2014-07-16 15:11:35 +0000
82+++ src/qml/Messages.qml 2014-07-17 21:29:41 +0000
83@@ -31,9 +31,8 @@
84 Page {
85 id: messages
86 objectName: "messagesPage"
87- property string threadId: ""
88- property bool newMessage: threadId === ""
89- // FIXME: we should get the account ID properly when dealing with multiple accounts
90+ // FIXME this info must come from system settings or telephony-service
91+ property var accounts: {"ofono/ofono/account0": "SIM 1", "ofono/ofono/account1": "SIM 2"}
92 property string accountId: telepathyHelper.accountIds[0]
93 property variant participants: []
94 property bool groupChat: participants.length > 1
95@@ -46,6 +45,7 @@
96 property var activeTransfer: null
97 property int activeAttachmentIndex: -1
98 property var sharedAttachmentsTransfer: []
99+ property string lastFilter: ""
100 property string text: ""
101
102 function addAttachmentsToModel(transfer) {
103@@ -64,6 +64,10 @@
104 }
105 }
106
107+ function checkNetwork() {
108+ return telepathyHelper.isAccountConnected(messages.accountId)
109+ }
110+
111 ListModel {
112 id: attachments
113 }
114@@ -85,7 +89,7 @@
115
116 flickable: null
117 // we need to use isReady here to know if this is a bottom edge page or not.
118- __customHeaderContents: newMessage && isReady ? newMessageHeader : null
119+ __customHeaderContents: participants.length === 0 && isReady ? newMessageHeader : null
120 property bool isReady: false
121 signal ready
122 onReady: {
123@@ -112,7 +116,7 @@
124 if (participants.length == 1) {
125 return firstRecipient
126 } else {
127- return i18n.tr("Group")
128+ return i18n.tr("Group (%1 members)").arg(participants.length)
129 }
130 }
131 return i18n.tr("New Message")
132@@ -136,17 +140,37 @@
133 }
134
135 Component.onCompleted: {
136- threadId = getCurrentThreadId()
137+ updateFilters()
138 addAttachmentsToModel(sharedAttachmentsTransfer)
139 }
140
141- function getCurrentThreadId() {
142- if (participants.length == 0)
143- return ""
144- return eventModel.threadIdForParticipants(accountId,
145- HistoryThreadModel.EventTypeText,
146- participants,
147- HistoryThreadModel.MatchPhoneNumber)
148+ function updateFilters() {
149+ if (participants.length == 0) {
150+ eventModel.filter = null
151+ return
152+ }
153+ var componentUnion = "import Ubuntu.History 0.1; HistoryUnionFilter { %1 }"
154+ var componentFilters = ""
155+ for (var i = 0; i < telepathyHelper.accountIds.length; i++) {
156+ var filterValue = eventModel.threadIdForParticipants(telepathyHelper.accountIds[i],
157+ HistoryThreadModel.EventTypeText,
158+ participants,
159+ HistoryThreadModel.MatchPhoneNumber)
160+ if (filterValue === "") {
161+ continue
162+ }
163+ componentFilters += 'HistoryFilter { filterProperty: "threadId"; filterValue: "%1" } '.arg(filterValue)
164+ }
165+ if (componentFilters === "") {
166+ eventModel.filter = null
167+ lastFilter = ""
168+ return
169+ }
170+ if (componentFilters != lastFilter) {
171+ var finalString = componentUnion.arg(componentFilters)
172+ eventModel.filter = Qt.createQmlObject(finalString, eventModel)
173+ lastFilter = componentFilters
174+ }
175 }
176
177 function markMessageAsRead(accountId, threadId, eventId, type) {
178@@ -216,6 +240,65 @@
179 }
180 }
181
182+ Component {
183+ id: noNetworkDialog
184+ Dialog {
185+ id: dialogue
186+ title: i18n.tr("No network")
187+ text: telepathyHelper.accountIds.length >= 2 ? i18n.tr("There is currently no network on %1").arg(messages.accounts[messages.accountId]) : i18n.tr("There is currently no network.")
188+ Button {
189+ objectName: "closeNoNetworkDialog"
190+ text: i18n.tr("Close")
191+ color: UbuntuColors.orange
192+ onClicked: {
193+ PopupUtils.close(dialogue)
194+ Qt.inputMethod.hide()
195+ }
196+ }
197+ }
198+ }
199+
200+ Rectangle {
201+ id: accountList
202+ z: 1
203+ anchors {
204+ left: parent.left
205+ right: parent.right
206+ top: parent.top
207+ }
208+ height: telepathyHelper.accountIds.length > 1 ? childrenRect.height : 0
209+ color: "white"
210+ Row {
211+ anchors {
212+ top: parent.top
213+ horizontalCenter: parent.horizontalCenter
214+ }
215+ height: childrenRect.height
216+ width: childrenRect.width
217+ spacing: units.gu(2)
218+ Repeater {
219+ model: telepathyHelper.accountIds
220+ delegate: Label {
221+ width: paintedWidth
222+ height: paintedHeight
223+ text: messages.accounts[modelData]
224+ font.pixelSize: FontUtils.sizeToPixels("small")
225+ color: messages.accountId == modelData ? "red" : "#5d5d5d"
226+ MouseArea {
227+ anchors {
228+ fill: parent
229+ // increase touch area
230+ leftMargin: units.gu(-1)
231+ rightMargin: units.gu(-1)
232+ bottomMargin: units.gu(-1)
233+ }
234+ onClicked: messages.accountId = modelData
235+ }
236+ }
237+ }
238+ }
239+ }
240+
241 Item {
242 id: newMessageHeader
243 anchors {
244@@ -223,7 +306,6 @@
245 rightMargin: units.gu(1)
246 right: parent.right
247 bottom: parent.bottom
248- top: parent.top
249 }
250 visible: participants.length == 0 && isReady && messages.active
251 MultiRecipientInput {
252@@ -248,7 +330,7 @@
253 verticalCenter: parent.verticalCenter
254 }
255
256- name: "new-contact"
257+ name: "contact"
258 color: "gray"
259 MouseArea {
260 anchors.fill: parent
261@@ -285,7 +367,7 @@
262 ]
263
264 anchors {
265- top: parent.top
266+ top: accountList.bottom
267 topMargin: units.gu(1)
268 left: parent.left
269 right: parent.right
270@@ -403,7 +485,7 @@
271 }
272
273 onParticipantsChanged: {
274- threadId = getCurrentThreadId()
275+ updateFilters()
276 }
277
278 ToolbarItems {
279@@ -447,7 +529,7 @@
280 objectName: "groupChatButton"
281 action: Action {
282 objectName: "groupChatAction"
283- iconSource: "image://theme/navigation-menu"
284+ iconSource: "image://theme/contact-group"
285 onTriggered: {
286 PopupUtils.open(participantsPopover, messages.header)
287 }
288@@ -533,16 +615,7 @@
289 HistoryEventModel {
290 id: eventModel
291 type: HistoryThreadModel.EventTypeText
292- filter: HistoryIntersectionFilter {
293- HistoryFilter {
294- filterProperty: "threadId"
295- filterValue: threadId
296- }
297- HistoryFilter {
298- filterProperty: "accountId"
299- filterValue: accountId
300- }
301- }
302+ filter: null
303 sort: HistorySort {
304 sortField: "timestamp"
305 sortOrder: HistorySort.DescendingOrder
306@@ -551,7 +624,7 @@
307
308 SortProxyModel {
309 id: sortProxy
310- sourceModel: eventModel
311+ sourceModel: eventModel.filter ? eventModel : null
312 sortRole: HistoryEventModel.TimestampRole
313 ascending: false
314 }
315@@ -561,7 +634,7 @@
316 objectName: "messageList"
317 clip: true
318 anchors {
319- top: parent.top
320+ top: accountList.bottom
321 left: parent.left
322 right: parent.right
323 bottom: bottomPanel.top
324@@ -573,7 +646,7 @@
325 footer: Item {
326 height: units.gu(2)
327 }
328- listModel: !newMessage ? sortProxy : null
329+ listModel: participants.length > 0 ? sortProxy : null
330 verticalLayoutDirection: ListView.BottomToTop
331 spacing: units.gu(2)
332 highlightFollowsCurrentItem: false
333@@ -586,6 +659,7 @@
334 removable: !messages.selectionMode
335 selectionMode: messages.selectionMode
336 confirmRemoval: true
337+ accountLabel: telepathyHelper.accountIds.length > 1 ? messages.accounts[accountId] : ""
338 onClicked: {
339 if (messageList.isInSelectionMode) {
340 if (!messageList.selectItem(messageDelegate)) {
341@@ -624,7 +698,7 @@
342 return
343 }
344 eventModel.removeEvent(accountId, threadId, eventId, type)
345- chatManager.sendMessage(messages.participants, textMessage, accountId)
346+ chatManager.sendMessage(messages.participants, textMessage, messages.accountId)
347 }
348 }
349 onSelectionDone: {
350@@ -666,7 +740,7 @@
351 height: units.gu(3)
352 width: units.gu(3)
353 color: "gray"
354- name: "camera"
355+ name: "camera-app-symbolic"
356 MouseArea {
357 anchors.fill: parent
358 onClicked: {
359@@ -825,6 +899,8 @@
360 placeholderText: i18n.tr("Write a message...")
361 focus: textEntry.focus
362 font.family: "Ubuntu"
363+ font.pixelSize: FontUtils.sizeToPixels("medium")
364+ color: "#5d5d5d"
365 text: messages.text
366 }
367
368@@ -852,10 +928,10 @@
369 text: "Send"
370 color: "green"
371 width: units.gu(7)
372+ height: units.gu(4)
373+ font.pixelSize: FontUtils.sizeToPixels("small")
374 enabled: {
375- if (!telepathyHelper.connected)
376- return false
377- if (participants.length > 0 || multiRecipient.recipientCount > 0) {
378+ if (participants.length > 0 || multiRecipient.recipientCount > 0) {
379 if (textEntry.text != "" || textEntry.inputMethodComposing || attachments.count > 0) {
380 return true
381 }
382@@ -863,26 +939,32 @@
383 return false
384 }
385 onClicked: {
386+ if (!checkNetwork()) {
387+ Qt.inputMethod.hide()
388+ PopupUtils.open(noNetworkDialog)
389+ return
390+ }
391 // make sure we flush everything we have prepared in the OSK preedit
392 Qt.inputMethod.commit();
393 if (textEntry.text == "" && attachments.count == 0) {
394 return
395 }
396- if (participants.length == 0 && multiRecipient.recipientCount > 0) {
397- participants = multiRecipient.recipients
398- }
399 if (messages.accountId == "") {
400 // FIXME: handle dual sim
401 messages.accountId = telepathyHelper.accountIds[0]
402 }
403- if (messages.newMessage) {
404- // create the new thread and get the threadId
405- messages.threadId = eventModel.threadIdForParticipants(messages.accountId,
406- HistoryThreadModel.EventTypeText,
407- participants,
408- HistoryThreadModel.MatchPhoneNumber,
409- true)
410+ // dont change the participants list
411+ if (participants.length == 0) {
412+ participants = multiRecipient.recipients
413 }
414+ // create the new thread and update the threadId list
415+ eventModel.threadIdForParticipants(messages.accountId,
416+ HistoryThreadModel.EventTypeText,
417+ participants,
418+ HistoryThreadModel.MatchPhoneNumber,
419+ true)
420+
421+ updateFilters()
422 messages.pendingMessage = true
423 if (attachments.count > 0) {
424 var newAttachments = []
425
426=== modified file 'src/qml/NewRecipientPage.qml'
427--- src/qml/NewRecipientPage.qml 2014-07-16 15:11:35 +0000
428+++ src/qml/NewRecipientPage.qml 2014-07-17 21:29:41 +0000
429@@ -42,7 +42,7 @@
430 }
431 onTextChanged: contactList.currentIndex = -1
432 inputMethodHints: Qt.ImhNoPredictiveText
433- placeholderText: i18n.tr("Type a name or phone to search")
434+ placeholderText: i18n.tr("Type to search by name or number")
435 }
436
437 ContactListView {
438
439=== modified file 'src/qml/ThreadDelegate.qml'
440--- src/qml/ThreadDelegate.qml 2014-07-06 22:06:24 +0000
441+++ src/qml/ThreadDelegate.qml 2014-07-17 21:29:41 +0000
442@@ -180,7 +180,9 @@
443 font.weight: Font.Light
444 }
445 onItemRemoved: {
446- threadModel.removeThread(accountId, threadId, type)
447+ for (var i in threads) {
448+ threadModel.removeThread(threads[i].accountId, threads[i].threadId, threads[i].type)
449+ }
450 }
451
452 Item {
453
454=== modified file 'tests/autopilot/messaging_app/emulators.py'
455--- tests/autopilot/messaging_app/emulators.py 2014-07-15 16:32:01 +0000
456+++ tests/autopilot/messaging_app/emulators.py 2014-07-17 21:29:41 +0000
457@@ -449,7 +449,7 @@
458 ThreadDelegate, objectName='thread{}'.format(participants))
459 self.pointing_device.click_object(thread)
460 root = self.get_root_instance()
461- return root.wait_select_single(Messages, threadId=thread.threadId)
462+ return root.wait_select_single(Messages, participants=participants)
463
464
465 class Messages(toolkit_emulators.UbuntuUIToolkitEmulatorBase):

Subscribers

People subscribed via source and target branches