Merge lp:~phablet-team/messaging-app/keyboard-navigation into lp:messaging-app

Proposed by Tiago Salem Herrmann
Status: Needs review
Proposed branch: lp:~phablet-team/messaging-app/keyboard-navigation
Merge into: lp:messaging-app
Diff against target: 296 lines (+95/-79)
4 files modified
src/qml/ContactSearchList.qml (+72/-70)
src/qml/MainPage.qml (+15/-3)
src/qml/Messages.qml (+4/-2)
src/qml/MultiRecipientInput.qml (+4/-4)
To merge this branch: bzr merge lp:~phablet-team/messaging-app/keyboard-navigation
Reviewer Review Type Date Requested Status
system-apps-ci-bot continuous-integration Needs Fixing
PS Jenkins bot continuous-integration Needs Fixing
Ubuntu Phablet Team Pending
Review via email: mp+286659@code.launchpad.net

Commit message

Add initial support for keyboard navigation.

Description of the change

Add initial support for keyboard navigation.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
493. By Tiago Salem Herrmann

Create temporary model with one phone number per row to fix keyboar navigation

494. By Tiago Salem Herrmann

handle return key to open a conversation

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
495. By Tiago Salem Herrmann

merge trunk

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

Revert the changes related to history-service.

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

Merge trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
system-apps-ci-bot (system-apps-ci-bot) wrote :

FAILED: Continuous integration, rev:497
https://jenkins.canonical.com/system-apps/job/lp-messaging-app-ci/9/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/system-apps/job/build/663/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-0-fetch/663
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=vivid+overlay/625
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=xenial+overlay/625
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-1-sourcepkg/release=yakkety/625
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=vivid+overlay/617/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/617
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=xenial+overlay/617/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/617
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=amd64,release=yakkety/617/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=vivid+overlay/617/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/617
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=xenial+overlay/617/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/617
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=armhf,release=yakkety/617/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=vivid+overlay/617/console
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/617
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=xenial+overlay/617/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/617
        deb: https://jenkins.canonical.com/system-apps/job/build-2-binpkg/arch=i386,release=yakkety/617/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/system-apps/job/lp-messaging-app-ci/9/rebuild

review: Needs Fixing (continuous-integration)

Unmerged revisions

497. By Gustavo Pichorim Boiko

Merge trunk.

496. By Gustavo Pichorim Boiko

Revert the changes related to history-service.

495. By Tiago Salem Herrmann

merge trunk

494. By Tiago Salem Herrmann

handle return key to open a conversation

493. By Tiago Salem Herrmann

Create temporary model with one phone number per row to fix keyboar navigation

492. By Tiago Salem Herrmann

Fix header in dual panel mode.

491. By Gustavo Pichorim Boiko

Use the search from history model itself.

490. By Tiago Salem Herrmann

remove wrong code added during merge

489. By Tiago Salem Herrmann

merge trunk

488. By Tiago Salem Herrmann

Add initial support for keyboard navigation

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/qml/ContactSearchList.qml'
2--- src/qml/ContactSearchList.qml 2015-11-03 13:16:43 +0000
3+++ src/qml/ContactSearchList.qml 2016-03-21 21:20:24 +0000
4@@ -31,8 +31,7 @@
5 onFilterTermChanged: console.debug("FILTER :" + filterTerm)
6
7 signal phonePicked(string phoneNumber)
8-
9- model: ContactListModel {
10+ ContactListModel {
11 id: contactModel
12
13 manager: "galera"
14@@ -63,84 +62,87 @@
15 }
16 }
17
18+ ListModel {
19+ id: contactListModel
20+ }
21+ Connections {
22+ target: contactModel
23+ onContactsChanged: {
24+ contactListModel.clear()
25+ for (var i in contactModel.contacts) {
26+ var contact = contactModel.contacts[i]
27+ for (var j in contact.phoneNumbers) {
28+ console.log(contact.phoneNumbers[j].number)
29+ contactListModel.append({"phoneNumber": contact.phoneNumbers[j],
30+ "displayLabel": contact.displayLabel})
31+ }
32+ }
33+ }
34+ }
35+
36+ model: contactListModel
37 ContactDetailPhoneNumberTypeModel {
38 id: phoneTypeModel
39 }
40
41- delegate: Item {
42+ delegate: ListItem.Empty {
43 anchors {
44 left: parent.left
45 right: parent.right
46- margins: units.gu(2)
47 }
48- height: phoneRepeater.count * units.gu(6)
49+ //margins: units.gu(2)
50+ height: units.gu(6)
51+ showDivider: false
52+ selected: focus
53+
54+ onClicked: root.phonePicked(phoneNumber.number)
55+
56 Column {
57 anchors.fill: parent
58- spacing: units.gu(1)
59-
60- Repeater {
61- id: phoneRepeater
62-
63- model: contact.phoneNumbers.length
64-
65- delegate: MouseArea {
66- anchors {
67- left: parent.left
68- right: parent.right
69- }
70- height: units.gu(5)
71-
72- onClicked: root.phonePicked(contact.phoneNumbers[index].number)
73-
74- Column {
75- anchors.fill: parent
76-
77- Label {
78- anchors {
79- left: parent.left
80- right: parent.right
81- }
82- height: units.gu(2)
83- text: {
84- // this is necessary to keep the string in the original format
85- var originalText = contact.displayLabel.label
86- var lowerSearchText = filterTerm.toLowerCase()
87- var lowerText = originalText.toLowerCase()
88- var searchIndex = lowerText.indexOf(lowerSearchText)
89- if (searchIndex !== -1) {
90- var piece = originalText.substr(searchIndex, lowerSearchText.length)
91- return originalText.replace(piece, "<b>" + piece + "</b>")
92- } else {
93- return originalText
94- }
95- }
96- fontSize: "medium"
97- color: UbuntuColors.lightAubergine
98- }
99- Label {
100- anchors {
101- left: parent.left
102- right: parent.right
103- }
104- height: units.gu(2)
105- text: {
106- var phoneDetail = contact.phoneNumbers[index]
107- return ("%1 %2").arg(phoneTypeModel.get(phoneTypeModel.getTypeIndex(phoneDetail)).label)
108- .arg(phoneDetail.number)
109- }
110- }
111- Item {
112- anchors {
113- left: parent.left
114- right: parent.right
115- }
116- height: units.gu(1)
117- }
118-
119- ListItem.ThinDivider {}
120- }
121- }
122- }
123+
124+ Label {
125+ anchors {
126+ left: parent.left
127+ right: parent.right
128+ }
129+ height: units.gu(2)
130+ text: {
131+ // this is necessary to keep the string in the original format
132+ var originalText = displayLabel.label
133+ var lowerSearchText = filterTerm.toLowerCase()
134+ var lowerText = originalText.toLowerCase()
135+ var searchIndex = lowerText.indexOf(lowerSearchText)
136+ if (searchIndex !== -1) {
137+ var piece = originalText.substr(searchIndex, lowerSearchText.length)
138+ return originalText.replace(piece, "<b>" + piece + "</b>")
139+ } else {
140+ return originalText
141+ }
142+ }
143+ fontSize: "medium"
144+ color: UbuntuColors.lightAubergine
145+ }
146+ Label {
147+ anchors {
148+ left: parent.left
149+ right: parent.right
150+ }
151+ height: units.gu(2)
152+ text: {
153+ var phoneDetail = phoneNumber
154+ return ("%1 %2").arg(phoneTypeModel.get(phoneTypeModel.getTypeIndex(phoneDetail)).label)
155+ .arg(phoneDetail.number)
156+ }
157+ }
158+ Item {
159+ anchors {
160+ left: parent.left
161+ right: parent.right
162+ }
163+ height: units.gu(1)
164+ }
165+
166+ ListItem.ThinDivider {}
167 }
168 }
169 }
170
171=== modified file 'src/qml/MainPage.qml'
172--- src/qml/MainPage.qml 2016-03-17 21:10:00 +0000
173+++ src/qml/MainPage.qml 2016-03-21 21:20:24 +0000
174@@ -50,15 +50,15 @@
175 }
176 inputMethodHints: Qt.ImhNoPredictiveText
177 placeholderText: i18n.tr("Search...")
178- onActiveFocusChanged: {
179+ /*onActiveFocusChanged: {
180 if (!activeFocus) {
181 searchField.text = ""
182 mainPage.searching = false
183 }
184- }
185+ }*/
186+ KeyNavigation.down: threadList
187 }
188
189- flickable: pageHeader.flickable
190 header: PageHeader {
191 id: pageHeader
192
193@@ -76,6 +76,8 @@
194 }
195 }
196
197+ flickable: pageHeader.flickable
198+
199 states: [
200 State {
201 id: defaultState
202@@ -86,6 +88,7 @@
203 Action {
204 objectName: "searchAction"
205 iconName: "search"
206+ shortcut: "Ctrl+f"
207 onTriggered: {
208 mainPage.searching = true
209 searchField.forceActiveFocus()
210@@ -104,6 +107,7 @@
211 objectName: "newMessageAction"
212 text: i18n.tr("New message")
213 iconName: "add"
214+ shortcut: "Ctrl+n"
215 onTriggered: mainView.bottomEdge.commit()
216 }
217
218@@ -126,6 +130,7 @@
219 visible: mainPage.searching
220 iconName: "back"
221 text: i18n.tr("Cancel")
222+ shortcut: searching ? "Esc" : undefined
223 onTriggered: {
224 searchField.text = ""
225 mainPage.searching = false
226@@ -242,6 +247,13 @@
227 // FIXME: find a better unique name
228 objectName: "thread%1".arg(participants[0].identifier)
229
230+ Keys.onPressed: {
231+ if (event.key == Qt.Key_Space || event.key == Qt.Key_Return) {
232+ threadDelegate.itemClicked(null)
233+ event.accepted = true;
234+ }
235+ }
236+
237 anchors {
238 left: parent.left
239 right: parent.right
240
241=== modified file 'src/qml/Messages.qml'
242--- src/qml/Messages.qml 2016-03-17 21:10:15 +0000
243+++ src/qml/Messages.qml 2016-03-21 21:20:24 +0000
244@@ -440,7 +440,7 @@
245 name: "cancel"
246 text: i18n.tr("Cancel")
247 iconName: "down"
248- shortcut: "Esc"
249+ shortcut: startedFromBottomEdge && !mainPage.searching ? "Esc" : undefined
250 onTriggered: {
251 messages.cancel()
252 }
253@@ -542,6 +542,7 @@
254 Action {
255 objectName: "selectionModeCancelAction"
256 iconName: "back"
257+ shortcut: selectionMode ? "Esc" : undefined
258 onTriggered: messageList.cancelSelection()
259 }
260 ]
261@@ -653,6 +654,7 @@
262 id: multiRecipient
263 objectName: "multiRecipient"
264 enabled: visible
265+ KeyNavigation.down: searchListLoader.item
266 anchors {
267 left: parent ? parent.left : undefined
268 right: parent ? parent.right : undefined
269@@ -963,7 +965,7 @@
270
271 property int resultCount: (status === Loader.Ready) ? item.count : 0
272
273- source: (multiRecipient.searchString !== "") && multiRecipient.focus ?
274+ source: (multiRecipient.searchString !== "") /*&& multiRecipient.focus*/ ?
275 Qt.resolvedUrl("ContactSearchList.qml") : ""
276 clip: true
277 visible: source != ""
278
279=== modified file 'src/qml/MultiRecipientInput.qml'
280--- src/qml/MultiRecipientInput.qml 2015-11-03 13:16:43 +0000
281+++ src/qml/MultiRecipientInput.qml 2016-03-21 21:20:24 +0000
282@@ -167,10 +167,10 @@
283 font.pixelSize: FontUtils.sizeToPixels("medium")
284 inputMethodHints: Qt.ImhNoPredictiveText
285 onActiveFocusChanged: {
286- if (!activeFocus && text !== "") {
287- addRecipient(text)
288- text = ""
289- }
290+ //if (!activeFocus && text !== "") {
291+ // addRecipient(text)
292+ // text = ""
293+ //}
294 }
295 onTextChanged: {
296 if (text.substring(text.length -1, text.length) == ",") {

Subscribers

People subscribed via source and target branches

to all changes: