Merge lp:~phablet-team/messaging-app/disconnect-on-exit-favorite-channels into lp:messaging-app/staging
- disconnect-on-exit-favorite-channels
- Merge into staging
Status: | Merged |
---|---|
Approved by: | Tiago Salem Herrmann |
Approved revision: | 681 |
Merged at revision: | 660 |
Proposed branch: | lp:~phablet-team/messaging-app/disconnect-on-exit-favorite-channels |
Merge into: | lp:messaging-app/staging |
Prerequisite: | lp:~phablet-team/messaging-app/improve-participants-screen |
Diff against target: |
802 lines (+314/-142) 12 files modified
debian/messaging-app-apparmor.additions (+4/-0) src/main.cpp (+3/-0) src/messagingapplication.cpp (+1/-2) src/qml/GroupChatInfoPage.qml (+6/-1) src/qml/MainPage.qml (+8/-2) src/qml/Messages.qml (+70/-24) src/qml/MessagingContactEditorPage.qml (+2/-2) src/qml/MessagingContactViewPage.qml (+34/-15) src/qml/NewRecipientPage.qml (+46/-9) src/qml/ParticipantInfoPage.qml (+80/-69) src/qml/messaging-app.qml (+54/-18) tests/qml/tst_MessagesView.qml (+6/-0) |
To merge this branch: | bzr merge lp:~phablet-team/messaging-app/disconnect-on-exit-favorite-channels |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Tiago Salem Herrmann (community) | Approve | ||
Review via email: mp+317267@code.launchpad.net |
Commit message
* Add a configuration option to disconnect from server on application exit.
* Allow to favorite a channels and store it on settings.
* Mark thread as not connected (opacity = 0.5)
Description of the change
- 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 Renato Araujo Oliveira Filho
-
Does not set appliaction name more than once.
Disable favorite auto-connection until fix the server. - 659. By Renato Araujo Oliveira Filho
-
reconnect with favorite channels on app startup.
- 660. By Renato Araujo Oliveira Filho
-
revert changes setting organization name (Fixed on SDK).
- 661. By Renato Araujo Oliveira Filho
-
Allow create contacts with IRC accounts from messaging app.
- 662. By Tiago Salem Herrmann
-
merge parent branch
- 663. By Tiago Salem Herrmann
-
fix first participant when contact matching is disabled
- 664. By Tiago Salem Herrmann
-
fix conflict
- 665. By Tiago Salem Herrmann
-
fix broken test
- 666. By Renato Araujo Oliveira Filho
-
Update contact view variable type.
This is necessary because the accountToAdd now is a dictonary with account protocol and uri.
- 667. By Renato Araujo Oliveira Filho
-
Does contact match on 1-1 conversation.
- 668. By Renato Araujo Oliveira Filho
-
Remove debug message.
- 669. By Renato Araujo Oliveira Filho
-
Enter in "newMessage" when no threadId is set.
Make sure that participants appear on multirecipient list.
- 670. By Renato Araujo Oliveira Filho
-
Re-designe contact info page.
- 671. By Renato Araujo Oliveira Filho
-
Do contact match using server address.
- 672. By Tiago Salem Herrmann
-
Register service to notify handler the app was launched
- 673. By Tiago Salem Herrmann
-
handler will disconnect the account. we don't need to request leave the channels
- 674. By Tiago Salem Herrmann
-
fix variable name
- 675. By Tiago Salem Herrmann
-
Allow dbus service registration on dbus
- 676. By Tiago Salem Herrmann
-
show connecting state when threads sorted by accounts
- 677. By Tiago Salem Herrmann
-
merge parent branch
- 678. By Tiago Salem Herrmann
-
merge parent
- 679. By Tiago Salem Herrmann
-
merge parent
- 680. By Tiago Salem Herrmann
-
only show call button for tel protocols
- 681. By Tiago Salem Herrmann
-
merge parent branch
Preview Diff
1 | === modified file 'debian/messaging-app-apparmor.additions' |
2 | --- debian/messaging-app-apparmor.additions 2016-01-11 12:10:08 +0000 |
3 | +++ debian/messaging-app-apparmor.additions 2017-03-08 22:08:54 +0000 |
4 | @@ -12,6 +12,10 @@ |
5 | bus=session |
6 | peer=(name=com.canonical.TelephonyServiceIndicator,label=unconfined), |
7 | |
8 | + dbus bind |
9 | + bus=session |
10 | + name=com.canonical.MessagingApp, |
11 | + |
12 | # make it possible for apps to register a telepathy observer |
13 | dbus bind |
14 | bus=session |
15 | |
16 | === modified file 'src/main.cpp' |
17 | --- src/main.cpp 2017-03-08 22:08:54 +0000 |
18 | +++ src/main.cpp 2017-03-08 22:08:54 +0000 |
19 | @@ -42,6 +42,9 @@ |
20 | // as it doesn’t play well with QtFolks. |
21 | int main(int argc, char** argv) |
22 | { |
23 | + QCoreApplication::setOrganizationName("com.ubuntu.messaging-app"); |
24 | + QCoreApplication::setApplicationName("MessagingApp"); |
25 | + |
26 | MessagingApplication application(argc, argv); |
27 | |
28 | if (!application.setup()) { |
29 | |
30 | === modified file 'src/messagingapplication.cpp' |
31 | --- src/messagingapplication.cpp 2017-03-08 22:08:54 +0000 |
32 | +++ src/messagingapplication.cpp 2017-03-08 22:08:54 +0000 |
33 | @@ -89,8 +89,6 @@ |
34 | MessagingApplication::MessagingApplication(int &argc, char **argv) |
35 | : QGuiApplication(argc, argv), m_view(0), m_applicationIsReady(false) |
36 | { |
37 | - setApplicationName("MessagingApp"); |
38 | - setOrganizationName("com.ubuntu.messaging-app"); |
39 | } |
40 | |
41 | bool MessagingApplication::fullscreen() const |
42 | @@ -101,6 +99,7 @@ |
43 | |
44 | bool MessagingApplication::setup() |
45 | { |
46 | + QDBusConnection::sessionBus().registerService("com.canonical.MessagingApp"); |
47 | installIconPath(); |
48 | static QList<QString> validSchemes; |
49 | bool fullScreen = false; |
50 | |
51 | === modified file 'src/qml/GroupChatInfoPage.qml' |
52 | --- src/qml/GroupChatInfoPage.qml 2017-03-08 22:08:54 +0000 |
53 | +++ src/qml/GroupChatInfoPage.qml 2017-03-08 22:08:54 +0000 |
54 | @@ -473,7 +473,12 @@ |
55 | leadingActions: canRemove() ? participantLeadingActions : null |
56 | onClicked: { |
57 | if (openProfileButton.visible) { |
58 | - mainStack.addPageToCurrentColumn(groupChatInfoPage, Qt.resolvedUrl("ParticipantInfoPage.qml"), {"delegate": participantDelegate, "chatEntry": chatEntry, "chatRoom": chatRoom}) |
59 | + mainStack.addPageToCurrentColumn(groupChatInfoPage, |
60 | + Qt.resolvedUrl("ParticipantInfoPage.qml"), |
61 | + {"delegate": participantDelegate, |
62 | + "chatEntry": chatEntry, |
63 | + "chatRoom": chatRoom, |
64 | + "protocolName": account.protocolInfo.name }) |
65 | } |
66 | } |
67 | Icon { |
68 | |
69 | === modified file 'src/qml/MainPage.qml' |
70 | --- src/qml/MainPage.qml 2017-03-08 22:08:54 +0000 |
71 | +++ src/qml/MainPage.qml 2017-03-08 22:08:54 +0000 |
72 | @@ -212,8 +212,14 @@ |
73 | function formatSectionTitle(title) { |
74 | if (mainView.sortThreadsBy === "timestamp") |
75 | return DateUtils.friendlyDay(Qt.formatDate(section, "yyyy/MM/dd"), i18n); |
76 | - else if (telepathyHelper.ready) |
77 | - return telepathyHelper.accountForId(title).displayName |
78 | + else if (telepathyHelper.ready) { |
79 | + var account = telepathyHelper.accountForId(title) |
80 | + if (account.connectionStatus == AccountEntry.ConnectionStatusConnecting) { |
81 | + return i18n.tr("%1 - Connecting...").arg(account.displayName) |
82 | + } else { |
83 | + return account.displayName |
84 | + } |
85 | + } |
86 | else |
87 | return title |
88 | } |
89 | |
90 | === modified file 'src/qml/Messages.qml' |
91 | --- src/qml/Messages.qml 2017-03-08 22:08:54 +0000 |
92 | +++ src/qml/Messages.qml 2017-03-08 22:08:54 +0000 |
93 | @@ -88,7 +88,18 @@ |
94 | property bool userTyping: false |
95 | property string userTypingId: "" |
96 | property string firstParticipantId: participantIds.length > 0 ? participantIds[0] : "" |
97 | - property variant firstParticipant: (participants && participants.length > 0) ? participants[0] : null |
98 | + property variant firstParticipant: { |
99 | + if (!participants || participants.length == 0) { |
100 | + return null |
101 | + } |
102 | + var participant = participants[0] |
103 | + if (typeof participant === "string") { |
104 | + return {identifier: participant, alias: participant} |
105 | + } else { |
106 | + return participant |
107 | + } |
108 | + } |
109 | + |
110 | property var threads: [] |
111 | property QtObject presenceRequest: presenceItem |
112 | property var accountsModel: getAccountsModel() |
113 | @@ -109,15 +120,16 @@ |
114 | return chatEntry.title |
115 | } |
116 | var roomInfo = threadInformation.chatRoomInfo |
117 | - if (roomInfo.Title != "") { |
118 | - return roomInfo.Title |
119 | - } else if (roomInfo.RoomName != "") { |
120 | - return roomInfo.RoomName |
121 | + if (roomInfo) { |
122 | + if (roomInfo.Title != "") { |
123 | + return roomInfo.Title |
124 | + } else if (roomInfo.RoomName != "") { |
125 | + return roomInfo.RoomName |
126 | + } |
127 | } |
128 | return "" |
129 | } |
130 | |
131 | - |
132 | signal ready |
133 | signal cancel |
134 | |
135 | @@ -531,7 +543,7 @@ |
136 | return |
137 | } |
138 | |
139 | - threadsModel.markThreadsAsRead(messages.threads); |
140 | + threadModel.markThreadsAsRead(messages.threads); |
141 | var properties = {'accountId': threads[0].accountId, 'threadId': threads[0].threadId, 'chatType': threads[0].chatType} |
142 | chatManager.acknowledgeAllMessages(properties) |
143 | } |
144 | @@ -546,6 +558,28 @@ |
145 | } |
146 | } |
147 | |
148 | + function participantIdentifierByProtocol(account, baseIdentifier) { |
149 | + if (account && account.protocolInfo) { |
150 | + switch(account.protocolInfo.name) { |
151 | + case "irc": |
152 | + if (account.parameters.server != "") |
153 | + return "%1@%2".arg(baseIdentifier).arg(account.parameters.server) |
154 | + return baseIdentifier |
155 | + default: |
156 | + return baseIdentifier |
157 | + } |
158 | + } |
159 | + } |
160 | + |
161 | + function contactMatchFieldFromProtocol(protocol, fallback) { |
162 | + switch(protocol) { |
163 | + case "irc": |
164 | + return ["X-IRC"]; |
165 | + default: |
166 | + return fallback |
167 | + } |
168 | + } |
169 | + |
170 | // Use a timer to make sure that 'threads' are correct set before try to select it |
171 | Timer { |
172 | id: selectThreadOnIdle |
173 | @@ -733,12 +767,12 @@ |
174 | State { |
175 | id: unknownContactState |
176 | name: "unknownContact" |
177 | - when: participants.length == 1 && contactWatcher.isUnknown |
178 | + when: !messages.newMessage && (participants.length === 1) && contactWatcher.isUnknown |
179 | |
180 | property list<QtObject> trailingActions: [ |
181 | Action { |
182 | objectName: "contactCallAction" |
183 | - visible: participants && participants.length === 1 && contactWatcher.interactive |
184 | + visible: participants && participants.length === 1 && contactWatcher.interactive && messages.account.addressableVCardFields.lastIndexOf("tel") != -1 |
185 | iconName: "call-start" |
186 | text: i18n.tr("Call") |
187 | onTriggered: { |
188 | @@ -750,12 +784,16 @@ |
189 | Action { |
190 | objectName: "addContactAction" |
191 | visible: contactWatcher.isUnknown && participants && participants.length === 1 && contactWatcher.interactive |
192 | + enabled: messages.account != null |
193 | iconName: "contact-new" |
194 | text: i18n.tr("Add") |
195 | onTriggered: { |
196 | Qt.inputMethod.hide() |
197 | - // FIXME: support other things than just phone numbers |
198 | - mainView.addPhoneToContact(messages, "", contactWatcher.identifier, null, null) |
199 | + mainView.addAccountToContact(messages, |
200 | + "", |
201 | + messages.account.protocolInfo.name, |
202 | + contactWatcher.identifier, |
203 | + null, null) |
204 | } |
205 | } |
206 | ] |
207 | @@ -836,7 +874,7 @@ |
208 | State { |
209 | id: knownContactState |
210 | name: "knownContact" |
211 | - when: participants.length == 1 && !contactWatcher.isUnknown |
212 | + when: !messages.newMessage && participants && participants.length === 1 && !contactWatcher.isUnknown |
213 | |
214 | property list<QtObject> trailingActions: [ |
215 | Action { |
216 | @@ -888,11 +926,17 @@ |
217 | } |
218 | } |
219 | } |
220 | - newMessage = (messages.threadId == "") || (messages.accountId == "" && messages.participants.length === 0) |
221 | restoreBindings() |
222 | if (threadId !== "" && accountId !== "" && threads.length == 0) { |
223 | addNewThreadToFilter(accountId, {"threadId": threadId, "chatType": chatType}) |
224 | } |
225 | + newMessage = (messages.threadId == "") || (messages.accountId == "" && messages.participants.length === 0) |
226 | + // if it is a new message we need to add participants into the multiRecipient list |
227 | + if (newMessage) { |
228 | + for (var i in participantIds) { |
229 | + multiRecipient.addRecipient(participantIds[i]) |
230 | + } |
231 | + } |
232 | // if we add multiple attachments at the same time, it break the Repeater + Loaders |
233 | fillAttachmentsTimer.start() |
234 | mainView.updateNewMessageStatus() |
235 | @@ -1102,7 +1146,7 @@ |
236 | } |
237 | |
238 | Repeater { |
239 | - model: account.protocolInfo.enableChatStates ? messages.chatEntry.chatStates : null |
240 | + model: account ? (account.protocolInfo.enableChatStates ? messages.chatEntry.chatStates : null) : null |
241 | delegate: Item { |
242 | function processChatState() { |
243 | if (modelData.state == ChatEntry.ChannelChatStateComposing) { |
244 | @@ -1123,8 +1167,9 @@ |
245 | |
246 | ContactWatcher { |
247 | id: typingContactWatcher |
248 | - identifier: messages.userTypingId |
249 | - addressableFields: messages.account ? messages.account.addressableVCardFields : [] |
250 | + identifier: messages.participantIdentifierByProtocol(messages.account, userTypingId) |
251 | + addressableFields: messages.account ? |
252 | + messages.contactMatchFieldFromProtocol(messages.account.protocolInfo.name, messages.account.addressableVCardFields) : [] |
253 | } |
254 | |
255 | MessagesHeader { |
256 | @@ -1272,12 +1317,13 @@ |
257 | |
258 | ContactWatcher { |
259 | id: contactWatcherInternal |
260 | - identifier: firstParticipant ? firstParticipant.identifier : "" |
261 | - contactId: firstParticipant ? firstParticipant.contactId : "" |
262 | - alias: firstParticipant ? firstParticipant.alias : "" |
263 | - avatar: firstParticipant ? firstParticipant.avatar : "" |
264 | - detailProperties: firstParticipant ? firstParticipant.detailProperties : {} |
265 | - addressableFields: messages.account ? messages.account.addressableVCardFields : [] |
266 | + identifier: firstParticipant && firstParticipant.identifier ? messages.participantIdentifierByProtocol(messages.account, firstParticipant.identifier) : "" |
267 | + contactId: firstParticipant && firstParticipant.contactId ? firstParticipant.contactId : "" |
268 | + alias: firstParticipant && firstParticipant.alias ? firstParticipant.alias : "" |
269 | + avatar: firstParticipant && firstParticipant.avatar ? firstParticipant.avatar : "" |
270 | + detailProperties: firstParticipant && firstParticipant.detailProperties ? firstParticipant.detailProperties : {} |
271 | + addressableFields: messages.account && messages.account.protocolInfo ? |
272 | + messages.contactMatchFieldFromProtocol(messages.account.protocolInfo.name, messages.account.addressableVCardFields) : [] |
273 | } |
274 | |
275 | HistoryUnionFilter { |
276 | @@ -1294,7 +1340,7 @@ |
277 | sort: HistorySort {} |
278 | groupingProperty: "participants" |
279 | filter: messages.accountId != "" && messages.threadId != "" ? filters : null |
280 | - matchContacts: messages.account.addressableVCardFields.length > 0 |
281 | + matchContacts: messages.account ? messages.account.addressableVCardFields.length > 0 : false |
282 | } |
283 | |
284 | ListView { |
285 | @@ -1322,7 +1368,7 @@ |
286 | id: eventModel |
287 | type: HistoryThreadModel.EventTypeText |
288 | filter: updateFilters(telepathyHelper.textAccounts.all, messages.chatType, messages.participantIds, messages.reloadFilters, messages.threads) |
289 | - matchContacts: messages.account.addressableVCardFields.length > 0 |
290 | + matchContacts: messages.account ? messages.account.addressableVCardFields.length > 0 : false |
291 | sort: HistorySort { |
292 | sortField: "timestamp" |
293 | sortOrder: HistorySort.DescendingOrder |
294 | |
295 | === modified file 'src/qml/MessagingContactEditorPage.qml' |
296 | --- src/qml/MessagingContactEditorPage.qml 2017-03-08 22:08:54 +0000 |
297 | +++ src/qml/MessagingContactEditorPage.qml 2017-03-08 22:08:54 +0000 |
298 | @@ -61,11 +61,11 @@ |
299 | |
300 | onContactSaved: { |
301 | if (root.contactListPage) { |
302 | - if (root.contactListPage.phoneToAdd !== "") { |
303 | + if (root.contactListPage.accountToAdd !== "") { |
304 | mainStack.removePages(root.contactListPage) |
305 | } else { |
306 | root.contactListPage.moveListToContact(contact) |
307 | - root.contactListPage.phoneToAdd = "" |
308 | + root.contactListPage.accountToAdd = null |
309 | } |
310 | } |
311 | } |
312 | |
313 | === modified file 'src/qml/MessagingContactViewPage.qml' |
314 | --- src/qml/MessagingContactViewPage.qml 2017-03-08 22:08:54 +0000 |
315 | +++ src/qml/MessagingContactViewPage.qml 2017-03-08 22:08:54 +0000 |
316 | @@ -33,26 +33,49 @@ |
317 | objectName: "contactViewPage" |
318 | |
319 | readonly property string contactEditorPageURL: Qt.resolvedUrl("MessagingContactEditorPage.qml") |
320 | - property string addPhoneToContact: "" |
321 | + property var accountToAdd: null |
322 | property var contactListPage: null |
323 | model: null |
324 | |
325 | - function addPhoneToContactImpl(contact, phoneNumber) |
326 | + function createContact(contact, detailName, newDetailSrc) |
327 | { |
328 | - var detailSourceTemplate = "import QtContacts 5.0; PhoneNumber{ number: \"" + phoneNumber.trim() + "\" }" |
329 | - var newDetail = Qt.createQmlObject(detailSourceTemplate, contact) |
330 | + var newDetail = Qt.createQmlObject(newDetailSrc, contact) |
331 | if (newDetail) { |
332 | contact.addDetail(newDetail) |
333 | mainStack.addPageToCurrentColumn(root, |
334 | root.contactEditorPageURL, |
335 | { model: root.model, |
336 | contact: contact, |
337 | - initialFocusSection: "phones", |
338 | + initialFocusSection: detailName, |
339 | newDetails: [newDetail], |
340 | contactListPage: root.contactListPage }) |
341 | - root.addPhoneToContact = "" |
342 | } else { |
343 | - console.warn("Fail to create phone number detail") |
344 | + console.warn("Fail to create contact with new detail") |
345 | + } |
346 | + |
347 | + } |
348 | + |
349 | + function addPhoneToContactImpl(contact, phoneNumber) |
350 | + { |
351 | + var detailSourceTemplate = "import QtContacts 5.0; PhoneNumber{ number: \"" + phoneNumber.trim() + "\" }" |
352 | + createContact(contact, "phones", detailSourceTemplate) |
353 | + } |
354 | + |
355 | + function addAccountToContactImpl(contact, account) |
356 | + { |
357 | + var detailSourceTemplate = "import QtContacts 5.0; OnlineAccount { protocol: " + account.protocol.trim() + "; accountUri: \"" + account.uri + "\" }" |
358 | + createContact(contact, "ims", detailSourceTemplate) |
359 | + } |
360 | + |
361 | + function commit() |
362 | + { |
363 | + if (root.accountToAdd) { |
364 | + if (root.accountToAdd.protocol === "OnlineAccount.Unknown") { |
365 | + root.addPhoneToContactImpl(contact, root.accountToAdd.uri) |
366 | + } else { |
367 | + root.addAccountToContactImpl(contact, root.accountToAdd) |
368 | + root.accountToAdd = null |
369 | + } |
370 | } |
371 | } |
372 | |
373 | @@ -144,17 +167,13 @@ |
374 | onContactRemoved: pageStack.removePages(root) |
375 | onContactFetched: { |
376 | root.contact = contact |
377 | - if (root.active && root.addPhoneToContact != "") { |
378 | - root.addPhoneToContactImpl(contact, root.addPhoneToContact) |
379 | - root.addPhoneToContact = "" |
380 | - } |
381 | + if (root.active) |
382 | + root.commit() |
383 | } |
384 | |
385 | onActiveChanged: { |
386 | - if (active && root.contact && root.addPhoneToContact != "") { |
387 | - root.addPhoneToContactImpl(contact, root.addPhoneToContact) |
388 | - root.addPhoneToContact = "" |
389 | - } |
390 | + if (active) |
391 | + root.commit() |
392 | } |
393 | |
394 | Component.onCompleted: { |
395 | |
396 | === modified file 'src/qml/NewRecipientPage.qml' |
397 | --- src/qml/NewRecipientPage.qml 2017-03-08 22:08:54 +0000 |
398 | +++ src/qml/NewRecipientPage.qml 2017-03-08 22:08:54 +0000 |
399 | @@ -26,7 +26,7 @@ |
400 | objectName: "newRecipientPage" |
401 | |
402 | property var itemCallback: null |
403 | - property string phoneToAdd: "" |
404 | + property var accountToAdd: null |
405 | property QtObject contactIndex: null |
406 | |
407 | function moveListToContact(contact) |
408 | @@ -50,6 +50,30 @@ |
409 | mainStack.removePages(newRecipientPage) |
410 | } |
411 | |
412 | + function createEmptyContactWithAccount(account, parent) |
413 | + { |
414 | + var details = [ {detail: "EmailAddress", field: "emailAddress", value: ""}, |
415 | + {detail: "Name", field: "firstName", value: ""} |
416 | + ] |
417 | + |
418 | + var newContact = Qt.createQmlObject("import QtContacts 5.0; Contact{ }", parent) |
419 | + var detailSourceTemplate = "import QtContacts 5.0; %1{ %2: \"%3\" }" |
420 | + for (var i=0; i < details.length; i++) { |
421 | + var detailMetaData = details[i] |
422 | + var newDetail = Qt.createQmlObject(detailSourceTemplate.arg(detailMetaData.detail) |
423 | + .arg(detailMetaData.field) |
424 | + .arg(detailMetaData.value), parent) |
425 | + newContact.addDetail(newDetail) |
426 | + } |
427 | + |
428 | + var accountSourceTemplate = "import QtContacts 5.0; OnlineAccount{ accountUri: \"%1\"; protocol: %2 }" |
429 | + var newDetail = Qt.createQmlObject(accountSourceTemplate |
430 | + .arg(account.uri) |
431 | + .arg(account.protocol), parent) |
432 | + newContact.addDetail(newDetail) |
433 | + return newContact |
434 | + } |
435 | + |
436 | header: PageHeader { |
437 | id: pageHeader |
438 | |
439 | @@ -186,12 +210,13 @@ |
440 | |
441 | filterTerm: searchField.text |
442 | onContactClicked: { |
443 | - if (newRecipientPage.phoneToAdd != "") { |
444 | - mainView.addPhoneToContact(newRecipientPage, |
445 | - contact, |
446 | - newRecipientPage.phoneToAdd, |
447 | - newRecipientPage, |
448 | - contactList.listModel) |
449 | + if (newRecipientPage.accountToAdd) { |
450 | + mainView.addAccountToContact(newRecipientPage, |
451 | + contact, |
452 | + accountToAdd.protocol, |
453 | + accountToAdd.uri, |
454 | + newRecipientPage, |
455 | + contactList.listModel) |
456 | } else { |
457 | mainView.showContactDetails(newRecipientPage, |
458 | contact, |
459 | @@ -201,12 +226,24 @@ |
460 | } |
461 | |
462 | onAddNewContactClicked: { |
463 | - var newContact = ContactsJS.createEmptyContact(newRecipientPage.phoneToAdd, newRecipientPage) |
464 | + var newContact = newRecipientPage.createEmptyContactWithAccount(newRecipientPage.accountToAdd, newRecipientPage) |
465 | + var focusField = "name" |
466 | + if (newRecipientPage.accountToAdd) { |
467 | + switch (newRecipientPage.accountToAdd.protocol) { |
468 | + case "ofono": |
469 | + focusField = "phones" |
470 | + break |
471 | + default: |
472 | + focusField = "ims" |
473 | + break |
474 | + } |
475 | + } |
476 | + |
477 | mainStack.addPageToCurrentColumn(newRecipientPage, |
478 | Qt.resolvedUrl("MessagingContactEditorPage.qml"), |
479 | { model: contactList.listModel, |
480 | contact: newContact, |
481 | - initialFocusSection: (newRecipientPage.phoneToAdd != "" ? "phones" : "name"), |
482 | + initialFocusSection: focusField, |
483 | contactListPage: newRecipientPage }) |
484 | } |
485 | } |
486 | |
487 | === modified file 'src/qml/ParticipantInfoPage.qml' |
488 | --- src/qml/ParticipantInfoPage.qml 2017-03-08 22:08:54 +0000 |
489 | +++ src/qml/ParticipantInfoPage.qml 2017-03-08 22:08:54 +0000 |
490 | @@ -26,8 +26,9 @@ |
491 | property var delegate |
492 | property var participant: delegate.participant |
493 | property var chatEntry |
494 | + property string protocolName: "ofono" |
495 | property bool chatRoom: false |
496 | - property bool knownContact: participant.contactId !== "" |
497 | + property bool knownContact: participant.contactId && (participant.contactId !== "") |
498 | |
499 | header: PageHeader { |
500 | id: pageHeader |
501 | @@ -37,7 +38,13 @@ |
502 | |
503 | Flickable { |
504 | id: contentsFlickable |
505 | - anchors.fill: parent |
506 | + anchors { |
507 | + top: parent.top |
508 | + bottom: buttons.top |
509 | + left: parent.left |
510 | + right: parent.right |
511 | + } |
512 | + |
513 | contentHeight: contentsColumn.height |
514 | clip: true |
515 | |
516 | @@ -105,73 +112,77 @@ |
517 | } |
518 | } |
519 | } |
520 | - |
521 | - Item { |
522 | - id: padding |
523 | - height: units.gu(1) |
524 | - anchors.left: parent.left |
525 | - anchors.right: parent.right |
526 | - } |
527 | - |
528 | - ListItems.ThinDivider { |
529 | - anchors { |
530 | - left: parent.left |
531 | - right: parent.right |
532 | - } |
533 | - } |
534 | - |
535 | - Item { |
536 | - id: padding3 |
537 | - height: units.gu(2) |
538 | - anchors.left: parent.left |
539 | - anchors.right: parent.right |
540 | - } |
541 | - |
542 | - Column { |
543 | - anchors { |
544 | - left: parent.left |
545 | - leftMargin: units.gu(2) |
546 | - } |
547 | - spacing: units.gu(2) |
548 | - Button { |
549 | - id: showInContactsButton |
550 | - text: knownContact ? i18n.tr("See in contacts") : i18n.tr("Add to contacts") |
551 | - onClicked: { |
552 | - if (knownContact) { |
553 | - mainView.showContactDetails(participantInfoPage, participant.contactId, null, null) |
554 | - } else { |
555 | - mainView.addPhoneToContact(participantInfoPage, "", participant.identifier, null, null) |
556 | - } |
557 | - } |
558 | - } |
559 | - |
560 | - Button { |
561 | - id: setAsAdminButton |
562 | - text: i18n.tr("Set as admin") |
563 | - visible: false |
564 | - // disabled until backends support this feature |
565 | - //visible: chatRoom && chatEntry.active && chatEntry.selfContactRoles == 3 |
566 | - } |
567 | - |
568 | - Button { |
569 | - id: sendMessageButton |
570 | - text: i18n.tr("Send private message") |
571 | - onClicked: { |
572 | - mainView.startChat({accountId: chatEntry.accountId, participantIds: [participant.identifier]}) |
573 | - pageStack.removePages(participantInfoPage) |
574 | - } |
575 | - } |
576 | - |
577 | - Button { |
578 | - id: leaveButton |
579 | - visible: delegate.canRemove() |
580 | - text: i18n.tr("Remove from group") |
581 | - color: Theme.palette.normal.negative |
582 | - onClicked: { |
583 | - delegate.removeFromGroup() |
584 | - pageStack.removePages(participantInfoPage) |
585 | - } |
586 | - } |
587 | + } |
588 | + } |
589 | + |
590 | + Column { |
591 | + id: buttons |
592 | + anchors { |
593 | + left: parent.left |
594 | + right: parent.right |
595 | + bottom: parent.bottom |
596 | + margins: units.gu(2) |
597 | + } |
598 | + spacing: units.gu(0.5) |
599 | + |
600 | + Button { |
601 | + id: showInContactsButton |
602 | + |
603 | + anchors { |
604 | + left: parent.left |
605 | + right: parent.right |
606 | + } |
607 | + text: knownContact ? i18n.tr("See in contacts") : i18n.tr("Add to contacts") |
608 | + onClicked: { |
609 | + console.debug("Know contact:" + participant.contactId) |
610 | + if (knownContact) { |
611 | + mainView.showContactDetails(participantInfoPage, participant.contactId, null, null) |
612 | + } else { |
613 | + mainView.addAccountToContact(participantInfoPage, "", protocolName, participant.identifier, null, null) |
614 | + } |
615 | + } |
616 | + } |
617 | + |
618 | + Button { |
619 | + id: setAsAdminButton |
620 | + |
621 | + anchors { |
622 | + left: parent.left |
623 | + right: parent.right |
624 | + } |
625 | + text: i18n.tr("Set as admin") |
626 | + visible: false |
627 | + // disabled until backends support this feature |
628 | + //visible: chatRoom && chatEntry.active && chatEntry.selfContactRoles == 3 |
629 | + } |
630 | + |
631 | + Button { |
632 | + id: sendMessageButton |
633 | + |
634 | + anchors { |
635 | + left: parent.left |
636 | + right: parent.right |
637 | + } |
638 | + text: i18n.tr("Send private message") |
639 | + onClicked: { |
640 | + mainView.startChat({accountId: chatEntry.accountId, participantIds: [participant.identifier]}) |
641 | + pageStack.removePages(participantInfoPage) |
642 | + } |
643 | + } |
644 | + |
645 | + Button { |
646 | + id: leaveButton |
647 | + |
648 | + anchors { |
649 | + left: parent.left |
650 | + right: parent.right |
651 | + } |
652 | + visible: delegate.canRemove() |
653 | + text: i18n.tr("Remove from group") |
654 | + color: Theme.palette.normal.negative |
655 | + onClicked: { |
656 | + delegate.removeFromGroup() |
657 | + pageStack.removePages(participantInfoPage) |
658 | } |
659 | } |
660 | } |
661 | |
662 | === modified file 'src/qml/messaging-app.qml' |
663 | --- src/qml/messaging-app.qml 2017-03-08 22:08:54 +0000 |
664 | +++ src/qml/messaging-app.qml 2017-03-08 22:08:54 +0000 |
665 | @@ -19,6 +19,7 @@ |
666 | import QtQuick 2.2 |
667 | import QtQuick.Window 2.2 |
668 | import Qt.labs.settings 1.0 |
669 | +import QtContacts 5.0 |
670 | import Ubuntu.Components 1.3 |
671 | import Ubuntu.Components.Popups 1.3 |
672 | import Ubuntu.Telephony 0.1 |
673 | @@ -81,13 +82,32 @@ |
674 | initialProperties) |
675 | } |
676 | |
677 | - function addPhoneToContact(currentPage, contact, phoneNumber, contactListPage, contactsModel) { |
678 | + function protocolFromString(protocolName) |
679 | + { |
680 | + if (protocolName.indexOf("OnlineAccount.") === 0) { |
681 | + // protocol already converted |
682 | + return protocolName |
683 | + } |
684 | + |
685 | + switch(protocolName) { |
686 | + case "irc": |
687 | + return "OnlineAccount.Irc" |
688 | + case "ofono": |
689 | + default: |
690 | + return "OnlineAccount.Unknown" |
691 | + } |
692 | + } |
693 | + |
694 | + function addAccountToContact(currentPage, contact, accountProtocol, accountUri, contactListPage, contactsModel) |
695 | + { |
696 | + var accountDetails = {"protocol": protocolFromString(accountProtocol), |
697 | + "uri": accountUri} |
698 | if (contact === "") { |
699 | mainStack.addPageToCurrentColumn(currentPage, |
700 | Qt.resolvedUrl("NewRecipientPage.qml"), |
701 | - { "phoneToAdd": phoneNumber }) |
702 | + { "accountToAdd": accountDetails }) |
703 | } else { |
704 | - var initialProperties = { "addPhoneToContact": phoneNumber } |
705 | + var initialProperties = { "accountToAdd": accountDetails } |
706 | if (contactListPage) { |
707 | initialProperties["contactListPage"] = contactListPage |
708 | } |
709 | @@ -110,13 +130,6 @@ |
710 | //TODO: disconnect from server |
711 | } |
712 | |
713 | - onApplicationActiveChanged: { |
714 | - if (applicationActive) { |
715 | - telepathyHelper.registerChannelObserver() |
716 | - } else { |
717 | - telepathyHelper.unregisterChannelObserver() |
718 | - } |
719 | - } |
720 | |
721 | function removeThreads(threads) { |
722 | for (var i in threads) { |
723 | @@ -141,8 +154,36 @@ |
724 | mainView.showMessagesView(properties) |
725 | } |
726 | |
727 | + function connectToFavoriteChannels(account) { |
728 | + var favs = favoriteChannels.getFavoriteChannels(account.accountId) |
729 | + for (var c in favs) { |
730 | + var favChannel = favs[c] |
731 | + if (favChannel) { |
732 | + console.debug("Start channel:" + account.accountId + "/" + favChannel) |
733 | + var properties = {'chatType': HistoryThreadModel.ChatTypeRoom, |
734 | + 'accountId': account.accountId, |
735 | + 'threadId': favChannel} |
736 | + chatManager.startChat(account.accountId, properties) |
737 | + } |
738 | + } |
739 | + } |
740 | + |
741 | + onApplicationActiveChanged: { |
742 | + if (applicationActive) { |
743 | + telepathyHelper.registerChannelObserver() |
744 | + } else { |
745 | + telepathyHelper.unregisterChannelObserver() |
746 | + } |
747 | + } |
748 | + |
749 | Connections { |
750 | target: telepathyHelper.textAccounts |
751 | + onAccountChanged: { |
752 | + if (active) { |
753 | + connectToFavoriteChannels(entry) |
754 | + } |
755 | + } |
756 | + |
757 | onActiveChanged: { |
758 | for (var i in telepathyHelper.textAccounts.active) { |
759 | if (telepathyHelper.textAccounts.active[i] == account) { |
760 | @@ -151,15 +192,7 @@ |
761 | } |
762 | account = Qt.binding(defaultPhoneAccount) |
763 | } |
764 | - } |
765 | |
766 | - Component.onDestruction: { |
767 | - for (var i in telepathyHelper.textAccounts.active) { |
768 | - var account = telepathyHelper.textAccounts.active[i] |
769 | - if (account.protocolInfo.leaveRoomsOnClose) { |
770 | - chatManager.leaveRooms(account.accountId, "") |
771 | - } |
772 | - } |
773 | } |
774 | |
775 | Connections { |
776 | @@ -174,6 +207,9 @@ |
777 | !settings.mainViewIgnoreFirstTimeDialog && mainPage.displayedThreadIndex < 0) { |
778 | PopupUtils.open(Qt.createComponent("Dialogs/NoDefaultSIMCardDialog.qml").createObject(mainView)) |
779 | } |
780 | + for (var i in telepathyHelper.textAccounts.active) { |
781 | + connectToFavoriteChannels(telepathyHelper.textAccounts.active[i]) |
782 | + } |
783 | } |
784 | } |
785 | |
786 | |
787 | === modified file 'tests/qml/tst_MessagesView.qml' |
788 | --- tests/qml/tst_MessagesView.qml 2017-03-08 22:08:54 +0000 |
789 | +++ tests/qml/tst_MessagesView.qml 2017-03-08 22:08:54 +0000 |
790 | @@ -161,6 +161,12 @@ |
791 | function updateNewMessageStatus() { } |
792 | } |
793 | |
794 | + Item { |
795 | + id: threadModel |
796 | + function markThreadsAsRead(threads) { |
797 | + } |
798 | + } |
799 | + |
800 | Messages { |
801 | id: messagesView |
802 | active: true |
Looks good. thanks.