Merge lp:~renatofilho/address-book-service/demo-app-with-fetch-hint into lp:~phablet-team/address-book-service/contact-demo-app

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Renato Araujo Oliveira Filho
Approved revision: 17
Merged at revision: 9
Proposed branch: lp:~renatofilho/address-book-service/demo-app-with-fetch-hint
Merge into: lp:~phablet-team/address-book-service/contact-demo-app
Prerequisite: lp:~renatofilho/address-book-service/fetch-hint
Diff against target: 347 lines (+200/-35)
4 files modified
ContactEditor.qml (+7/-8)
ContactList.js (+35/-0)
ContactList.qml (+157/-27)
debian/contacts-demo-app.install (+1/-0)
To merge this branch: bzr merge lp:~renatofilho/address-book-service/demo-app-with-fetch-hint
Reviewer Review Type Date Requested Status
Bill Filler (community) Approve
Review via email: mp+171630@code.launchpad.net

Commit message

Used fetcHint on contact model to fetch only contact name and phone.

To post a comment you must log in.
Revision history for this message
Bill Filler (bfiller) wrote :

not working right.
- I can't select an item from the list
- double clicking only sometimes works and only ever shows the first contact in the list as that's the one that is selected
- we shouldn't use double click to get into edit mode, single click should do that like in the past
- in fact, single click should just take you into view of contact detail mode. Editing is then done from there not from the main screen.

review: Needs Fixing
16. By Renato Araujo Oliveira Filho

Merged "lp:~renatofilho/address-book-service/demo-app-with-section"

17. By Renato Araujo Oliveira Filho

Fixed contact edit action

Revision history for this message
Bill Filler (bfiller) wrote :

approved

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ContactEditor.qml'
2--- ContactEditor.qml 2013-06-23 00:19:40 +0000
3+++ ContactEditor.qml 2013-06-27 17:17:26 +0000
4@@ -73,14 +73,13 @@
5 }
6 ListItem.ThinDivider {}
7 }
8-
9+
10 function setContactDetails(contact) {
11 contact.name.firstName = contactFirstName.text
12 contact.name.middleName = contactMiddleName.text
13 contact.name.lastName = contactLastName.text
14 contact.email.emailAddress = contactEmail.text
15 contact.phoneNumber.number = contactPhone.text
16- console.debug("Update contact number:" + contactPhone.text)
17 }
18
19 function updateContact() {
20@@ -90,14 +89,14 @@
21 newContact.save()
22 contactEditor.model.saveContact(newContact)
23
24- } else if ((contactFirstName.text != contactEditor.contact.name.firstName) ||
25- (contactMiddleName.text != contactEditor.contact.name.middleName) ||
26- (contactLastName.text != contactEditor.contact.name.lastName) ||
27- (contactEmail.text != contactEditor.contact.email.emailAddress) ||
28- (contactPhone.text != contactEditor.contact.phoneNumber.number)) {
29+ } else if ((contactFirstName.text !== contactEditor.contact.name.firstName) ||
30+ (contactMiddleName.text !== contactEditor.contact.name.middleName) ||
31+ (contactLastName.text !== contactEditor.contact.name.lastName) ||
32+ (contactEmail.text !== contactEditor.contact.email.emailAddress) ||
33+ (contactPhone.text !== contactEditor.contact.phoneNumber.number)) {
34 // update existing contact
35 setContactDetails(contactEditor.contact)
36- contactEditor.contact.save()
37+ contact.save()
38 }
39 }
40
41
42=== added file 'ContactList.js'
43--- ContactList.js 1970-01-01 00:00:00 +0000
44+++ ContactList.js 2013-06-27 17:17:26 +0000
45@@ -0,0 +1,35 @@
46+/****************************************************************************
47+**
48+** Copyright (C) 2013 Canonical Ltd
49+**
50+****************************************************************************/
51+
52+var sectionData = [];
53+var _sections = [];
54+
55+function initSectionData(list) {
56+ if (!list || !list.model) {
57+ return;
58+ }
59+
60+ sectionData = [];
61+ _sections = [];
62+
63+ var current = "",
64+ prop = list.section.property,
65+ item;
66+
67+ for (var i = 0, count = list.model.contacts.length; i < count; i++) {
68+ item = list.sectionValueForContact(list.model.contacts[i])
69+ if (item !== current) {
70+ current = item;
71+ _sections.push(current);
72+ sectionData.push({ index: i, header: current });
73+ }
74+ }
75+}
76+
77+function getIndexFor(sectionName) {
78+ var val = sectionData[_sections.indexOf(sectionName)].index;
79+ return val === 0 || val > 0 ? val : -1;
80+}
81
82=== modified file 'ContactList.qml'
83--- ContactList.qml 2013-06-23 00:19:40 +0000
84+++ ContactList.qml 2013-06-27 17:17:26 +0000
85@@ -8,6 +8,8 @@
86 import Ubuntu.Components 0.1
87 import Ubuntu.Components.ListItems 0.1 as ListItem
88
89+import "ContactList.js" as Sections
90+
91 Page {
92 id: mainPage
93
94@@ -32,6 +34,13 @@
95 direction: Qt.AscendingOrder
96 }
97 ]
98+
99+ fetchHint: FetchHint {
100+ detailTypesHint: [ContactDetail.Avatar,
101+ ContactDetail.Name,
102+ ContactDetail.PhoneNumber]
103+ }
104+
105 Component.onCompleted: {
106 if (manager == "memory")
107 contactsModel.importContacts(Qt.resolvedUrl("example.vcf"))
108@@ -41,9 +50,7 @@
109 var fullValue = ""
110
111 if (contact) {
112- console.debug("FieldNames:" + fieldNames)
113 var fieldNameList = fieldNames.split(",")
114- console.debug("FieldNameList:" + fieldNameList)
115 for (var fieldNameIndex in fieldNameList) {
116 var fieldName = fieldNameList[fieldNameIndex]
117 var value = "";
118@@ -73,52 +80,137 @@
119 }
120 }
121
122-
123-
124- ListView {
125- id: listView
126+ ListView {
127+ id: alphabetView
128+
129+ property string selectedLetter: contactListView.contentY > 0 ? contactListView.itemAt(0, contactListView.contentY).sectionName : "A"
130+
131+ anchors {
132+ top: parent.top
133+ left: parent.left
134+ right: parent.right
135+ }
136+ focus: true
137+ height: units.gu(4)
138+ orientation: ListView.Horizontal
139+
140+ model: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ]
141+ delegate: Label {
142+ text: modelData
143+ font.bold: alphabetView.selectedLetter == text
144+ horizontalAlignment: Text.AlignHCenter
145+ fontSize: "large"
146+ width: units.gu(3)
147+
148+ MouseArea {
149+ anchors.fill: parent
150+ onClicked: {
151+ contactListView.scroolToSection(modelData)
152+ }
153+ }
154+
155+ }
156+ }
157+
158+ ListView {
159+ id: contactListView
160
161 property string title
162
163- anchors.fill: parent
164+ clip: true
165+ snapMode: ListView.NoSnap
166+ section {
167+ property: "contact.name.firstName"
168+ criteria: ViewSection.FirstCharacter
169+ delegate: ListItem.Header {
170+ id: listHeader
171+ //text: section
172+ visible: false
173+ height: 0
174+ }
175+ }
176+
177+ anchors {
178+ top: alphabetView.bottom
179+ left: parent.left
180+ right: parent.right
181+ bottom: parent.bottom
182+ }
183 model: contactsModel
184 header: ListItem.Header {
185- id: listHeader
186-
187- text: listView.title
188+ text: contactListView.title
189 }
190
191 onCountChanged: {
192+ dirtyTimer.restart()
193 if (mainPage.startTime) {
194 var currentTime = new Date();
195 var elapsed = currentTime.getTime() - mainPage.startTime.getTime()
196- listView.title = "Elapsed time to load " + count + " contacts: " + (elapsed/1000) + " secs"
197+ contactListView.title = "Elapsed time to load " + count + " contacts: " + (elapsed/1000) + " secs"
198 }
199 }
200
201 delegate: ListItem.Subtitled {
202 property variant contactObject: contact
203 property string contactId: contact.contactId
204+ property string sectionName: ListView.section
205
206- icon: Qt.resolvedUrl("avatar.png")
207+ icon: contact && contact.avatar && (contact.avatar.imageUrl != "") ? Qt.resolvedUrl(contact.avatar.imageUrl) : Qt.resolvedUrl("avatar.png")
208 text: contactsModel.titleField ? contactsModel.getContactDetails(contact, contactsModel.titleField) : ""
209 subText: contactsModel.subTitleField ? contactsModel.getContactDetails(contact, contactsModel.subTitleField) : ""
210- selected: listView.currentIndex === index
211-
212- onClicked: {
213- listView.currentIndex = index
214- pageStack.push(Qt.resolvedUrl("ContactEditor.qml"), {model: contactsModel, contact: listView.currentItem.contactObject})
215- }
216+ selected: contactListView.currentIndex === index
217+
218+ MouseArea {
219+ anchors.fill: parent
220+ onClicked: {
221+ contactListView.currentIndex = index
222+ }
223+ onDoubleClicked: {
224+ editContactPriv.contactId = contactListView.currentItem.contactObject.contactId
225+ }
226+ }
227+ }
228+
229+ UbuntuNumberAnimation { id: scroolToSectionAnimation; target: contactListView; property: "contentY"; }
230+ function scroolToSection(targetSection) {
231+ scroolToSectionAnimation.from = contactListView.contentY
232+ contactListView.positionViewAtIndex(Sections.getIndexFor(targetSection), ListView.Beginning)
233+ scroolToSectionAnimation.to = contactListView.contentY
234+ scroolToSectionAnimation.running = true
235+ }
236+
237+ // function used to build the section cache by "ContactList.js"
238+ function sectionValueForContact(contact) {
239+ if (contact) {
240+ return contact.name && contact.name.firstName ? contact.name.firstName[0] : ""
241+ } else {
242+ return null
243+ }
244+ }
245+ }
246+
247+ Timer {
248+ id: dirtyTimer
249+
250+ interval: 2000
251+ running: false
252+ repeat: false
253+ onTriggered: {
254+ Sections.initSectionData(contactListView)
255 }
256 }
257
258 ActivityIndicator {
259- running: listView.count == 0
260+ id: busyIndicator
261+
262+ property bool pageIsBusy: false
263+
264+ running: contactListView.count == 0 || pageIsBusy
265 visible: running
266- anchors.centerIn: listView
267+ anchors.centerIn: contactListView
268 }
269
270- tools: ToolbarItems {
271+ tools: ToolbarActions {
272 Action {
273 text: i18n.tr("Settings")
274 iconSource: Qt.resolvedUrl("settings.png")
275@@ -128,7 +220,9 @@
276 Action {
277 text: i18n.tr("Edit")
278 iconSource: Qt.resolvedUrl("edit.png")
279- onTriggered: pageStack.push(Qt.resolvedUrl("ContactEditor.qml"), {model: contactsModel, contact: listView.currentItem.contactObject})
280+ onTriggered: {
281+ editContactPriv.contactId = contactListView.currentItem.contactObject.contactId
282+ }
283 }
284 Action {
285 text: i18n.tr("New")
286@@ -139,9 +233,45 @@
287 text: i18n.tr("Delete")
288 iconSource: Qt.resolvedUrl("delete.png")
289 onTriggered: {
290- console.debug("Delete: " + listView.currentItem.contactId)
291- contactsModel.removeContact(listView.currentItem.contactId);
292- }
293- }
294- }
295+ contactsModel.removeContact(contactListView.currentItem.contactId);
296+ }
297+ }
298+ }
299+
300+ Item {
301+ id: editContactPriv
302+
303+ property string contactId
304+ property int currentQueryId: -1
305+
306+ visible: false
307+ Connections {
308+ target: contactsModel
309+ onContactsFetched: {
310+ if (requestId == editContactPriv.currentQueryId) {
311+ editContactPriv.currentQueryId = -1
312+ busyIndicator.pageIsBusy = false
313+ pageStack.push(Qt.resolvedUrl("ContactEditor.qml"),
314+ {model: contactsModel, contact: fetchedContacts[0]})
315+ }
316+ }
317+ }
318+
319+ onContactIdChanged: {
320+ if (!contactId || (currentQueryId != -1)) {
321+ return
322+ }
323+
324+ busyIndicator.pageIsBusy = true
325+
326+ currentQueryId = contactsModel.fetchContacts([contactId])
327+ if (currentQueryId == -1) {
328+ busyIndicator.pageIsBusy = false
329+ }
330+ }
331+
332+
333+ }
334+
335+
336 }
337
338=== modified file 'debian/contacts-demo-app.install'
339--- debian/contacts-demo-app.install 2013-06-07 19:19:01 +0000
340+++ debian/contacts-demo-app.install 2013-06-27 17:17:26 +0000
341@@ -1,5 +1,6 @@
342 contacts-demo-app usr/bin/
343 contacts-demo-app.desktop usr/share/applications/
344 *.qml usr/share/contacts-demo-app/
345+*.js usr/share/contacts-demo-app/
346 *.png usr/share/contacts-demo-app/
347 *.vcf usr/share/contacts-demo-app/

Subscribers

People subscribed via source and target branches