Merge lp:~phablet-team/messaging-app/rtm-fit-finish into lp:messaging-app

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 218
Merged at revision: 176
Proposed branch: lp:~phablet-team/messaging-app/rtm-fit-finish
Merge into: lp:messaging-app
Diff against target: 3252 lines (+1303/-1212)
26 files modified
debian/control (+1/-0)
debian/rules (+1/-1)
src/qml/CMakeLists.txt (+2/-1)
src/qml/KeyboardRectangle.qml (+0/-4)
src/qml/LocalPageWithBottomEdge.qml (+406/-0)
src/qml/MMS/CMakeLists.txt (+4/-0)
src/qml/MMS/MMSBase.qml (+97/-0)
src/qml/MMS/MMSContact.qml (+25/-28)
src/qml/MMS/MMSDefault.qml (+8/-9)
src/qml/MMS/MMSImage.qml (+34/-53)
src/qml/MMS/MMSVideo.qml (+8/-9)
src/qml/MMS/PreviewerContact.qml (+27/-0)
src/qml/MainPage.qml (+74/-90)
src/qml/MessageBubble.qml (+94/-3)
src/qml/MessageDelegate.qml (+157/-291)
src/qml/Messages.qml (+217/-241)
src/qml/MultiRecipientInput.qml (+2/-2)
src/qml/NewRecipientPage.qml (+44/-20)
src/qml/PageWithBottomEdge.qml (+0/-367)
src/qml/ThreadDelegate.qml (+43/-65)
src/qml/assets/conversation_error@27.sci (+5/-0)
src/qml/assets/conversation_pending@27.sci (+5/-0)
src/qml/messaging-app.qml (+6/-3)
tests/autopilot/messaging_app/emulators.py (+38/-21)
tests/autopilot/messaging_app/tests/test_messaging.py (+5/-1)
tests/qml/tst_MessageBubble.qml (+0/-3)
To merge this branch: bzr merge lp:~phablet-team/messaging-app/rtm-fit-finish
Reviewer Review Type Date Requested Status
Gustavo Pichorim Boiko (community) Approve
PS Jenkins bot continuous-integration Needs Fixing
Review via email: mp+228532@code.launchpad.net

Commit message

- Visual update
- Added qtdeclarative5-ubuntu-history0.1 as a build dependency (necessary for unit tests)
- Created a new MMS source dir with files necessary for MMS visual.

To post a comment you must log in.
172. By Tiago Salem Herrmann

multiple fixes

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

use ListItemWithActions also for mms's

174. By Tiago Salem Herrmann

add transitions back and set image loading to be synchronous, as it breaks the transitions

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:173
http://jenkins.qa.ubuntu.com/job/messaging-app-ci/319/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2615/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2098
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-amd64-ci/113
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-armhf-ci/113
        deb: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-armhf-ci/113/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-i386-ci/113
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2747/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3858
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3858/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10568
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1752
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2351
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2351/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/messaging-app-ci/319/rebuild

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

FAILED: Continuous integration, rev:174
http://jenkins.qa.ubuntu.com/job/messaging-app-ci/320/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2616/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2099
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-amd64-ci/114
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-armhf-ci/114
        deb: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-armhf-ci/114/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-i386-ci/114
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2748/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3859
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/3859/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10569
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1753
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2352
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2352/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/messaging-app-ci/320/rebuild

review: Needs Fixing (continuous-integration)
175. By Renato Araujo Oliveira Filho

Implemente MessageBubble new visuals.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
176. By Renato Araujo Oliveira Filho

Fixed MessageBubble visuals.

177. By Renato Araujo Oliveira Filho

Fixed visuals for MMS pictures.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
178. By Renato Araujo Oliveira Filho

Margin fix.

179. By Renato Araujo Oliveira Filho

Fixed MessageBubble minimum size.

180. By Renato Araujo Oliveira Filho

Fixed item selection.

181. By Tiago Salem Herrmann

add unread count indicator

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

use a different delegate for mms text attachments

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
183. By Renato Araujo Oliveira Filho

Revert last commit.

184. By Renato Araujo Oliveira Filho

Morre fixes.

185. By Renato Araujo Oliveira Filho

Parent branch merged.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
186. By Renato Araujo Oliveira Filho

Initial message section implementation.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
187. By Renato Araujo Oliveira Filho

Remove dual sim section.

188. By Renato Araujo Oliveira Filho

Removed references to old section.

189. By Renato Araujo Oliveira Filho

Implemented dual sim switch.

190. By Renato Araujo Oliveira Filho

Parent merged.

191. By Renato Araujo Oliveira Filho

Allows only one item to be swipped.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
192. By Renato Araujo Oliveira Filho

Fixed typo.

193. By Renato Araujo Oliveira Filho

Added retry button for failed messages.

194. By Renato Araujo Oliveira Filho

Fixed application installation.

195. By Renato Araujo Oliveira Filho

Trunk merged.

196. By Tiago Salem Herrmann

fix contact delegate and add simple previewer

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

add PageWithBottomEdge again

Revision history for this message
Francis Ginther (fginther) wrote :

Build 333 failed due to a job update that didn't go as planned. A rebuild has been triggered.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:197
http://jenkins.qa.ubuntu.com/job/messaging-app-ci/333/
Executed test runs:
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-utopic-touch/2764
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-utopic/2205/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-amd64-ci/127
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-armhf-ci/127
        deb: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-armhf-ci/127/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/messaging-app-utopic-i386-ci/127
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-deb-autopilot-runner-mako/2857
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4007
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-armhf/4007/artifact/work/output/*zip*/output.zip
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/10721
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-utopic/1828/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2464
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-utopic-amd64/2464/artifact/work/output/*zip*/output.zip

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/messaging-app-ci/333/rebuild

review: Needs Fixing (continuous-integration)
198. By Renato Araujo Oliveira Filho

Fixed Header sections for single simcard.

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

fix message status indicator and attachment removal

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
200. By Renato Araujo Oliveira Filho

Trunk merged.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
201. By Renato Araujo Oliveira Filho

Fix account switch.

202. By Renato Araujo Oliveira Filho

Does not hid keyborad if list is flickering.

203. By Renato Araujo Oliveira Filho

Parent merged.

204. By Renato Araujo Oliveira Filho

Make unit test quicker.

205. By Renato Araujo Oliveira Filho

Run verbose tests.

206. By Renato Araujo Oliveira Filho

Added qtdeclarative5-ubuntu-history0.1 as a build dependency.

207. By Renato Araujo Oliveira Filho

Parent merged.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
208. By Renato Araujo Oliveira Filho

Revert removal of KeryboardRectangle.

209. By Renato Araujo Oliveira Filho

Parent merged.

210. By Renato Araujo Oliveira Filho

Fixed Messaging margins.

211. By Renato Araujo Oliveira Filho

Parent merged.

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

fix send button color
clip contact list loader
increase text filed size to avoid text being cut off

213. By Tiago Salem Herrmann

dont dismiss keyboard when selecting recipients

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

fix autopilot tests

215. By Tiago Salem Herrmann

more autopilot fixes

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

implement onAddDetailClicked signal

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

Wait until the OSD is gone before clicking the notification.

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

Fix autopilot tests.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

Are there any related MPs required for this MP to build/function as expected? YES
  - https://code.launchpad.net/~phablet-team/address-book-app/rtm-fit-finish/+merge/228529

Is your branch in sync with latest trunk? 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 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? NO PACKAGE CHANGE

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.
No, but it is because it needs the dependent MR to work.

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

review: Approve
219. By Renato Araujo Oliveira Filho

Fixed indentation

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-07-25 02:48:01 +0000
3+++ debian/control 2014-08-05 11:46:55 +0000
4@@ -14,6 +14,7 @@
5 qtdeclarative5-dev (>= 5.0),
6 qtdeclarative5-dev-tools,
7 qtdeclarative5-ubuntu-ui-toolkit-plugin,
8+ qtdeclarative5-ubuntu-history0.1,
9 qtpim5-dev,
10 xvfb,
11 Standards-Version: 3.9.4
12
13=== modified file 'debian/rules'
14--- debian/rules 2014-03-25 01:56:39 +0000
15+++ debian/rules 2014-08-05 11:46:55 +0000
16@@ -14,7 +14,7 @@
17
18 override_dh_auto_test:
19 flake8 tests/autopilot/messaging_app/
20- make -C obj-$(DEB_HOST_GNU_TYPE) test
21+ cd obj-$(DEB_HOST_GNU_TYPE); ctest -V
22
23 override_dh_translations:
24 # Override dh_translations to work around http://pad.lv/1183262.
25
26=== modified file 'src/qml/CMakeLists.txt'
27--- src/qml/CMakeLists.txt 2014-07-22 18:42:03 +0000
28+++ src/qml/CMakeLists.txt 2014-08-05 11:46:55 +0000
29@@ -12,6 +12,7 @@
30 set(3RD_PARTY_DIR 3rd_party)
31
32 install(FILES ${QML_JS_FILES} DESTINATION ${MESSAGING_APP_DIR})
33-install(DIRECTORY ${QML_DIRS} DESTINATION ${MESSAGING_APP_DIR})
34 install(DIRECTORY ${ASSETS_DIR} DESTINATION ${MESSAGING_APP_DIR})
35 install(DIRECTORY ${3RD_PARTY_DIR} DESTINATION ${MESSAGING_APP_DIR})
36+
37+add_subdirectory(MMS)
38
39=== modified file 'src/qml/KeyboardRectangle.qml'
40--- src/qml/KeyboardRectangle.qml 2013-07-17 21:47:45 +0000
41+++ src/qml/KeyboardRectangle.qml 2014-08-05 11:46:55 +0000
42@@ -25,10 +25,6 @@
43 anchors.bottom: parent.bottom
44 height: Qt.inputMethod.visible ? Qt.inputMethod.keyboardRectangle.height : 0
45
46- Behavior on height {
47- StandardAnimation { }
48- }
49-
50 function recursiveFindFocusedItem(parent) {
51 if (parent.activeFocus) {
52 return parent;
53
54=== added file 'src/qml/LocalPageWithBottomEdge.qml'
55--- src/qml/LocalPageWithBottomEdge.qml 1970-01-01 00:00:00 +0000
56+++ src/qml/LocalPageWithBottomEdge.qml 2014-08-05 11:46:55 +0000
57@@ -0,0 +1,406 @@
58+/*
59+ * Copyright (C) 2014 Canonical, Ltd.
60+ *
61+ * This program is free software; you can redistribute it and/or modify
62+ * it under the terms of the GNU General Public License as published by
63+ * the Free Software Foundation; version 3.
64+ *
65+ * This program is distributed in the hope that it will be useful,
66+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
67+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
68+ * GNU General Public License for more details.
69+ *
70+ * You should have received a copy of the GNU General Public License
71+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
72+ */
73+
74+/*
75+ Example:
76+
77+ MainView {
78+ objectName: "mainView"
79+
80+ applicationName: "com.ubuntu.developer.boiko.bottomedge"
81+
82+ width: units.gu(100)
83+ height: units.gu(75)
84+
85+ Component {
86+ id: pageComponent
87+
88+ PageWithBottomEdge {
89+ id: mainPage
90+ title: i18n.tr("Main Page")
91+
92+ Rectangle {
93+ anchors.fill: parent
94+ color: "white"
95+ }
96+
97+ bottomEdgePageComponent: Page {
98+ title: "Contents"
99+ anchors.fill: parent
100+ //anchors.topMargin: contentsPage.flickable.contentY
101+
102+ ListView {
103+ anchors.fill: parent
104+ model: 50
105+ delegate: ListItems.Standard {
106+ text: "One Content Item: " + index
107+ }
108+ }
109+ }
110+ bottomEdgeTitle: i18n.tr("Bottom edge action")
111+ }
112+ }
113+
114+ PageStack {
115+ id: stack
116+ Component.onCompleted: stack.push(pageComponent)
117+ }
118+ }
119+
120+*/
121+
122+import QtQuick 2.2
123+import Ubuntu.Components 1.1
124+
125+Page {
126+ id: page
127+
128+ property alias bottomEdgePageComponent: edgeLoader.sourceComponent
129+ property alias bottomEdgePageSource: edgeLoader.source
130+ property alias bottomEdgeTitle: tipLabel.text
131+ property alias bottomEdgeEnabled: bottomEdge.visible
132+ property int bottomEdgeExpandThreshold: page.height * 0.2
133+ property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded
134+ property bool reloadBottomEdgePage: true
135+
136+ readonly property alias bottomEdgePage: edgeLoader.item
137+ readonly property bool isReady: (bottomEdge.y === 0)
138+ readonly property bool isCollapsed: (bottomEdge.y === page.height)
139+ readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready)
140+ property var temporaryProperties: null
141+
142+ property bool _showEdgePageWhenReady: false
143+ property int _areaWhenExpanded: 0
144+
145+ signal bottomEdgeReleased()
146+ signal bottomEdgeDismissed()
147+
148+
149+ function showBottomEdgePage(source, properties)
150+ {
151+ edgeLoader.setSource(source, properties)
152+ temporaryProperties = properties
153+ _showEdgePageWhenReady = true
154+ }
155+
156+ function setBottomEdgePage(source, properties)
157+ {
158+ edgeLoader.setSource(source, properties)
159+ }
160+
161+ function _pushPage()
162+ {
163+ if (edgeLoader.status === Loader.Ready) {
164+ edgeLoader.item.active = true
165+ page.pageStack.push(edgeLoader.item)
166+ if (edgeLoader.item.flickable) {
167+ edgeLoader.item.flickable.contentY = -page.header.height
168+ edgeLoader.item.flickable.returnToBounds()
169+ }
170+ if (edgeLoader.item.ready)
171+ edgeLoader.item.ready()
172+ }
173+ }
174+
175+
176+ Component.onCompleted: {
177+ // avoid a binding on the expanded height value
178+ var expandedHeight = height;
179+ _areaWhenExpanded = expandedHeight;
180+ }
181+
182+ onActiveChanged: {
183+ if (active) {
184+ bottomEdge.state = "collapsed"
185+ }
186+ }
187+
188+ onBottomEdgePageLoadedChanged: {
189+ if (_showEdgePageWhenReady && bottomEdgePageLoaded) {
190+ bottomEdge.state = "expanded"
191+ _showEdgePageWhenReady = false
192+ }
193+ }
194+
195+ Rectangle {
196+ id: bgVisual
197+
198+ color: "black"
199+ anchors.fill: page
200+ opacity: 0.7 * ((page.height - bottomEdge.y) / page.height)
201+ z: 1
202+ }
203+
204+ Timer {
205+ id: hideIndicator
206+
207+ interval: 3000
208+ running: true
209+ repeat: false
210+ onTriggered: tip.hiden = true
211+ }
212+
213+ Rectangle {
214+ id: bottomEdge
215+ objectName: "bottomEdge"
216+
217+ readonly property int tipHeight: units.gu(3)
218+ readonly property int pageStartY: 0
219+
220+ z: 1
221+ color: Theme.palette.normal.background
222+ parent: page
223+ anchors {
224+ left: parent.left
225+ right: parent.right
226+ }
227+ height: page.height
228+ y: height
229+
230+ UbuntuShape {
231+ id: tip
232+ objectName: "bottomEdgeTip"
233+
234+ property bool hiden: false
235+
236+ readonly property double visiblePosition: (page.height - bottomEdge.y) < units.gu(1) ? -bottomEdge.tipHeight + (page.height - bottomEdge.y) : 0
237+ readonly property double invisiblePosition: (page.height - bottomEdge.y) < units.gu(1) ? -units.gu(1) : 0
238+
239+ z: -1
240+ anchors.horizontalCenter: parent.horizontalCenter
241+ y: hiden ? invisiblePosition : visiblePosition
242+
243+ width: tipLabel.paintedWidth + units.gu(6)
244+ height: bottomEdge.tipHeight + units.gu(1)
245+ color: Theme.palette.normal.overlay
246+ Label {
247+ id: tipLabel
248+
249+ anchors {
250+ top: parent.top
251+ left: parent.left
252+ right: parent.right
253+ }
254+ height: bottomEdge.tipHeight
255+ verticalAlignment: Text.AlignVCenter
256+ horizontalAlignment: Text.AlignHCenter
257+ opacity: tip.hiden ? 0.0 : 1.0
258+ Behavior on opacity {
259+ UbuntuNumberAnimation {
260+ duration: UbuntuAnimation.SnapDuration
261+ }
262+ }
263+ }
264+ Behavior on y {
265+ UbuntuNumberAnimation {
266+ duration: UbuntuAnimation.SnapDuration
267+ }
268+ }
269+ }
270+
271+ Rectangle {
272+ id: shadow
273+
274+ anchors {
275+ left: parent.left
276+ right: parent.right
277+ }
278+ height: units.gu(1)
279+ y: -height
280+ z: -2
281+ opacity: 0.0
282+ gradient: Gradient {
283+ GradientStop { position: 0.0; color: "transparent" }
284+ GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) }
285+ }
286+ }
287+
288+ MouseArea {
289+ id: mouseArea
290+
291+ preventStealing: true
292+ drag {
293+ axis: Drag.YAxis
294+ target: bottomEdge
295+ minimumY: bottomEdge.pageStartY
296+ maximumY: page.height
297+ threshold: 100
298+ }
299+
300+ anchors {
301+ left: parent.left
302+ right: parent.right
303+ }
304+ height: bottomEdge.tipHeight
305+ y: -height
306+
307+ onReleased: {
308+ page.bottomEdgeReleased()
309+ if (bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) {
310+ bottomEdge.state = "expanded"
311+ } else {
312+ bottomEdge.state = "collapsed"
313+ bottomEdge.y = bottomEdge.height
314+ }
315+ }
316+
317+ onClicked: {
318+ tip.hiden = false
319+ hideIndicator.restart()
320+ }
321+ }
322+
323+ state: "collapsed"
324+ onStateChanged: console.debug("State Changed:" + state)
325+ states: [
326+ State {
327+ name: "collapsed"
328+ PropertyChanges {
329+ target: bottomEdge
330+ y: bottomEdge.height
331+ }
332+ PropertyChanges {
333+ target: tip
334+ opacity: 1.0
335+ }
336+ PropertyChanges {
337+ target: hideIndicator
338+ running: true
339+ }
340+ },
341+ State {
342+ name: "expanded"
343+ PropertyChanges {
344+ target: bottomEdge
345+ y: bottomEdge.pageStartY
346+ }
347+ PropertyChanges {
348+ target: hideIndicator
349+ running: false
350+ }
351+ },
352+ State {
353+ name: "floating"
354+ when: mouseArea.drag.active
355+ PropertyChanges {
356+ target: shadow
357+ opacity: 1.0
358+ }
359+ PropertyChanges {
360+ target: hideIndicator
361+ running: false
362+ }
363+ PropertyChanges {
364+ target: tip
365+ hiden: false
366+ }
367+ }
368+ ]
369+
370+ transitions: [
371+ Transition {
372+ to: "expanded"
373+ SequentialAnimation {
374+ UbuntuNumberAnimation {
375+ target: bottomEdge
376+ property: "y"
377+ duration: UbuntuAnimation.SlowDuration
378+ }
379+ ScriptAction {
380+ script: page._pushPage()
381+ }
382+ }
383+ },
384+ Transition {
385+ from: "expanded"
386+ to: "collapsed"
387+ SequentialAnimation {
388+ ScriptAction {
389+ script: {
390+ Qt.inputMethod.hide()
391+ edgeLoader.item.parent = edgeLoader
392+ edgeLoader.item.anchors.fill = edgeLoader
393+ edgeLoader.item.active = false
394+ }
395+ }
396+ UbuntuNumberAnimation {
397+ target: bottomEdge
398+ property: "y"
399+ duration: UbuntuAnimation.SlowDuration
400+ }
401+ ScriptAction {
402+ script: {
403+ // destroy current bottom page
404+ if (page.reloadBottomEdgePage) {
405+ edgeLoader.active = false
406+ // remove properties from old instance
407+ if (edgeLoader.source !== "") {
408+ var properties = {}
409+ if (temporaryProperties !== null) {
410+ properties = temporaryProperties
411+ temporaryProperties = null
412+ }
413+
414+ edgeLoader.setSource(edgeLoader.source, properties)
415+ }
416+ }
417+
418+ // notify
419+ page.bottomEdgeDismissed()
420+
421+ // load a new bottom page in memory
422+ edgeLoader.active = true
423+
424+ tip.hiden = false
425+ hideIndicator.restart()
426+ }
427+ }
428+ }
429+ },
430+ Transition {
431+ from: "floating"
432+ to: "collapsed"
433+ UbuntuNumberAnimation {
434+ target: bottomEdge
435+ property: "opacity"
436+ }
437+ }
438+ ]
439+
440+ Loader {
441+ id: edgeLoader
442+
443+ z: 1
444+ active: true
445+ asynchronous: true
446+ anchors.fill: parent
447+
448+ //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging
449+ Binding {
450+ target: edgeLoader
451+ property: "anchors.topMargin"
452+ value: edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0
453+ when: (edgeLoader.status === Loader.Ready && !page.isReady)
454+ }
455+
456+ onLoaded: {
457+ if (page.isReady && edgeLoader.item.active != true) {
458+ page._pushPage()
459+ }
460+ }
461+ }
462+ }
463+}
464
465=== added file 'src/qml/MMS/CMakeLists.txt'
466--- src/qml/MMS/CMakeLists.txt 1970-01-01 00:00:00 +0000
467+++ src/qml/MMS/CMakeLists.txt 2014-08-05 11:46:55 +0000
468@@ -0,0 +1,4 @@
469+file(GLOB MMS_QML_JS_FILES *.qml *.js)
470+
471+add_custom_target(messaging_app_MMS_QMlFiles ALL SOURCES ${MMS_QML_JS_FILES})
472+install(FILES ${MMS_QML_JS_FILES} DESTINATION ${MESSAGING_APP_DIR}/MMS)
473
474=== added file 'src/qml/MMS/MMSBase.qml'
475--- src/qml/MMS/MMSBase.qml 1970-01-01 00:00:00 +0000
476+++ src/qml/MMS/MMSBase.qml 2014-08-05 11:46:55 +0000
477@@ -0,0 +1,97 @@
478+/*
479+ * Copyright 2012, 2013, 2014 Canonical Ltd.
480+ *
481+ * This file is part of messaging-app.
482+ *
483+ * messaging-app is free software; you can redistribute it and/or modify
484+ * it under the terms of the GNU General Public License as published by
485+ * the Free Software Foundation; version 3.
486+ *
487+ * messaging-app is distributed in the hope that it will be useful,
488+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
489+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
490+ * GNU General Public License for more details.
491+ *
492+ * You should have received a copy of the GNU General Public License
493+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
494+ */
495+import QtQuick 2.2
496+import Ubuntu.Components 1.1
497+import Ubuntu.Contacts 0.1
498+
499+ListItemWithActions {
500+ id: baseDelegate
501+
502+ property var attachment
503+ property bool parentSelected: false
504+ property bool incoming
505+ property bool showInfo: false
506+
507+ signal itemRemoved()
508+ signal attachmentClicked()
509+
510+ function checkClick(bubble, mouse) {
511+ var itemX1 = bubble.x
512+ var itemX2 = itemX1+bubble.width
513+ var itemY1 = bubble.y
514+ var itemY2 = itemY1+bubble.height
515+ if (mouse.x >= itemX1 && mouse.x <= itemX2 &&
516+ mouse.y >= itemY1 && mouse.y <= itemY2) {
517+ return true
518+ }
519+ return false
520+ }
521+
522+ Component.onCompleted: {
523+ visibleAttachments++
524+ }
525+ Component.onDestruction: {
526+ visibleAttachments--
527+ }
528+
529+ leftSideAction: Action {
530+ iconName: "delete"
531+ text: i18n.tr("Delete")
532+ onTriggered: baseDelegate.itemRemoved()
533+ }
534+
535+ internalAnchors {
536+ topMargin: 0
537+ bottomMargin: 0
538+ }
539+
540+ color: parentSelected ? selectedColor : Theme.palette.normal.background
541+ states: [
542+ State {
543+ when: incoming
544+ name: "incoming"
545+ AnchorChanges {
546+ target: bubble
547+ anchors.left: parent.left
548+ anchors.right: undefined
549+ }
550+ PropertyChanges {
551+ target: bubble
552+ anchors.leftMargin: units.gu(1)
553+ anchors.rightMargin: 0
554+ }
555+ },
556+ State {
557+ when: !incoming
558+ name: "outgoing"
559+ AnchorChanges {
560+ target: bubble
561+ anchors.left: undefined
562+ anchors.right: parent.right
563+ }
564+ PropertyChanges {
565+ target: bubble
566+ anchors.leftMargin: 0
567+ anchors.rightMargin: units.gu(1)
568+ }
569+ }
570+ ]
571+
572+ onSwippingChanged: messageList.updateSwippedItem(baseDelegate)
573+ onSwipeStateChanged: messageList.updateSwippedItem(baseDelegate)
574+}
575
576=== modified file 'src/qml/MMS/MMSContact.qml'
577--- src/qml/MMS/MMSContact.qml 2014-07-01 18:10:31 +0000
578+++ src/qml/MMS/MMSContact.qml 2014-08-05 11:46:55 +0000
579@@ -17,19 +17,18 @@
580 */
581
582 import QtQuick 2.0
583-import Ubuntu.Components.ListItems 0.1 as ListItem
584 import Ubuntu.Components 0.1
585+import Ubuntu.Contacts 0.1
586 import ".."
587
588-ListItem.Empty {
589+MMSBase {
590 id: vcardDelegate
591- property var attachment
592- property bool incoming
593- property string previewer: ""
594- property string textColor: incoming ? "#333333" : "#ffffff"
595- anchors.left: parent.left
596- anchors.right: parent.right
597- state: incoming ? "incoming" : "outgoing"
598+ property string previewer: "MMS/PreviewerContact.qml"
599+ onItemClicked: {
600+ if (checkClick(bubble, mouse)) {
601+ attachmentClicked()
602+ }
603+ }
604 states: [
605 State {
606 name: "incoming"
607@@ -50,8 +49,8 @@
608 }
609 PropertyChanges {
610 target: contactName
611- anchors.leftMargin: units.gu(1)
612- anchors.rightMargin: units.gu(1)
613+ anchors.leftMargin: units.gu(2)
614+ anchors.rightMargin: units.gu(2)
615 }
616 },
617 State {
618@@ -73,37 +72,35 @@
619 }
620 PropertyChanges {
621 target: contactName
622- anchors.leftMargin: units.gu(1)
623- anchors.rightMargin: units.gu(1)
624+ anchors.leftMargin: units.gu(2)
625+ anchors.rightMargin: units.gu(2)
626 }
627 }
628 ]
629- removable: true
630- confirmRemoval: true
631- height: bubble.height
632- clip: true
633- showDivider: false
634- highlightWhenPressed: false
635- MessageBubble {
636+ height: bubble.height + units.gu(2)
637+ Item {
638 id: bubble
639- incoming: vcardDelegate.incoming
640 anchors.top: parent.top
641- width: image.width + units.gu(4)
642- height: image.height + units.gu(2)
643+ width: avatar.width
644+ height: avatar.height
645+ ContactAvatar {
646+ id: avatar
647
648- Icon {
649- id: image
650+ fallbackAvatarUrl: "image://theme/contact"
651+ fallbackDisplayName: contactName.name
652+ anchors.centerIn: parent
653 height: units.gu(6)
654 width: units.gu(6)
655- name: "contact"
656- anchors.centerIn: parent
657- anchors.horizontalCenterOffset: incoming ? units.gu(0.5) : -units.gu(0.5)
658 }
659 }
660 Label {
661 id: contactName
662 property string name: application.contactNameFromVCard(attachment.filePath)
663 anchors.bottom: bubble.bottom
664+ anchors.left: incoming ? bubble.right : undefined
665+ anchors.right: !incoming ? bubble.left : undefined
666+ anchors.rightMargin: !incoming ? units.gu(1) : undefined
667+ anchors.leftMargin: incoming ? units.gu(1) : undefined
668 text: name !== "" ? name : i18n.tr("Unknown contact")
669 height: paintedHeight
670 width: paintedWidth
671
672=== modified file 'src/qml/MMS/MMSDefault.qml'
673--- src/qml/MMS/MMSDefault.qml 2014-05-05 16:56:56 +0000
674+++ src/qml/MMS/MMSDefault.qml 2014-08-05 11:46:55 +0000
675@@ -17,11 +17,10 @@
676 */
677
678 import QtQuick 2.0
679-import Ubuntu.Components.ListItems 0.1 as ListItem
680 import Ubuntu.Components 0.1
681 import ".."
682
683-ListItem.Empty {
684+MMSBase {
685 id: defaultDelegate
686 property var attachment
687 property bool incoming
688@@ -29,6 +28,11 @@
689 property string textColor: incoming ? "#333333" : "#ffffff"
690 anchors.left: parent.left
691 anchors.right: parent.right
692+ onItemClicked: {
693+ if (checkClick(bubble, mouse)) {
694+ attachmentClicked()
695+ }
696+ }
697 state: incoming ? "incoming" : "outgoing"
698 states: [
699 State {
700@@ -58,15 +62,10 @@
701 }
702 }
703 ]
704- removable: true
705- confirmRemoval: true
706- height: bubble.height
707+ height: bubble.height + units.gu(1)
708 clip: true
709- showDivider: false
710- highlightWhenPressed: false
711- MessageBubble {
712+ Item {
713 id: bubble
714- incoming: defaultDelegate.incoming
715 anchors.top: parent.top
716 width: label.width + units.gu(4)
717 height: label.height + units.gu(2)
718
719=== modified file 'src/qml/MMS/MMSImage.qml'
720--- src/qml/MMS/MMSImage.qml 2014-05-05 16:56:56 +0000
721+++ src/qml/MMS/MMSImage.qml 2014-08-05 11:46:55 +0000
722@@ -17,67 +17,48 @@
723 */
724
725 import QtQuick 2.0
726-import Ubuntu.Components.ListItems 0.1 as ListItem
727+import Ubuntu.Components 1.1
728+import Ubuntu.Contacts 0.1
729 import ".."
730
731-ListItem.Empty {
732+MMSBase {
733 id: imageDelegate
734- property var attachment
735- property bool incoming
736 property string previewer: "MMS/PreviewerImage.qml"
737- anchors.left: parent.left
738- anchors.right: parent.right
739- state: incoming ? "incoming" : "outgoing"
740- states: [
741- State {
742- name: "incoming"
743- AnchorChanges {
744- target: bubble
745- anchors.left: parent.left
746- anchors.right: undefined
747- }
748- PropertyChanges {
749- target: bubble
750- anchors.leftMargin: units.gu(1)
751- anchors.rightMargin: units.gu(1)
752- }
753- },
754- State {
755- name: "outgoing"
756- AnchorChanges {
757- target: bubble
758- anchors.left: undefined
759- anchors.right: parent.right
760- }
761- PropertyChanges {
762- target: bubble
763- anchors.leftMargin: units.gu(1)
764- anchors.rightMargin: units.gu(1)
765- }
766+ onItemClicked: {
767+ if (checkClick(bubble, mouse)) {
768+ attachmentClicked()
769 }
770- ]
771- removable: true
772- confirmRemoval: true
773- height: bubble.height
774- clip: true
775- showDivider: false
776- highlightWhenPressed: false
777- MessageBubble {
778+ }
779+
780+ height: imageAttachment.height
781+ UbuntuShape {
782 id: bubble
783- incoming: imageDelegate.incoming
784- anchors.top: parent.top
785- width: image.width + units.gu(3)
786- height: image.height + units.gu(2)
787-
788- Image {
789- id: image
790- anchors.centerIn: parent
791- anchors.horizontalCenterOffset: incoming ? units.gu(0.5) : -units.gu(0.5)
792- height: sourceSize.height < units.gu(20) ? sourceSize.height : units.gu(20)
793- fillMode: Image.PreserveAspectFit
794- asynchronous: true
795+ anchors {
796+ top: parent.top
797+ bottom: parent.bottom
798+ }
799+ width: image.width
800+ height: image.height
801+
802+ image: Image {
803+ id: imageAttachment
804+
805+ width: sourceSize.width > units.gu(30) ? units.gu(30) : sourceSize.width
806+ height: Math.min(sourceSize.height, units.gu(14))
807+ fillMode: Image.PreserveAspectCrop
808 smooth: true
809 source: attachment.filePath
810+ visible: false
811 }
812 }
813+
814+ Loader {
815+ active: (index == visibleAttachments-1) && !incoming && mmsText == "" && (inProgress || failed)
816+ visible: active
817+ height: active ? item.height : 0
818+ sourceComponent: statusIcon
819+ anchors.right: bubble.left
820+ anchors.rightMargin: units.gu(1)
821+ anchors.verticalCenter: bubble.verticalCenter
822+ }
823 }
824
825=== modified file 'src/qml/MMS/MMSVideo.qml'
826--- src/qml/MMS/MMSVideo.qml 2014-05-05 16:56:56 +0000
827+++ src/qml/MMS/MMSVideo.qml 2014-08-05 11:46:55 +0000
828@@ -17,18 +17,22 @@
829 */
830
831 import QtQuick 2.0
832-import Ubuntu.Components.ListItems 0.1 as ListItem
833 import Ubuntu.Components 0.1
834 import QtMultimedia 5.0
835 import ".."
836
837-ListItem.Empty {
838+MMSBase {
839 id: videoDelegate
840 property var attachment
841 property bool incoming
842 property string previewer: "MMS/PreviewerVideo.qml"
843 anchors.left: parent.left
844 anchors.right: parent.right
845+ onItemClicked: {
846+ if (checkClick(bubble, mouse)) {
847+ attachmentClicked()
848+ }
849+ }
850 state: incoming ? "incoming" : "outgoing"
851 states: [
852 State {
853@@ -58,15 +62,10 @@
854 }
855 }
856 ]
857- removable: true
858- confirmRemoval: true
859- height: bubble.height
860+ height: bubble.height + units.gu(1)
861 clip: true
862- showDivider: false
863- highlightWhenPressed: false
864- MessageBubble {
865+ Item {
866 id: bubble
867- incoming: videoDelegate.incoming
868 anchors.top: parent.top
869 width: videoOutput.width + units.gu(3)
870 height: videoOutput.height + units.gu(2)
871
872=== added file 'src/qml/MMS/PreviewerContact.qml'
873--- src/qml/MMS/PreviewerContact.qml 1970-01-01 00:00:00 +0000
874+++ src/qml/MMS/PreviewerContact.qml 2014-08-05 11:46:55 +0000
875@@ -0,0 +1,27 @@
876+/*
877+ * Copyright 2012, 2013, 2014 Canonical Ltd.
878+ *
879+ * This file is part of messaging-app.
880+ *
881+ * messaging-app is free software; you can redistribute it and/or modify
882+ * it under the terms of the GNU General Public License as published by
883+ * the Free Software Foundation; version 3.
884+ *
885+ * messaging-app is distributed in the hope that it will be useful,
886+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
887+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
888+ * GNU General Public License for more details.
889+ *
890+ * You should have received a copy of the GNU General Public License
891+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
892+ */
893+
894+import QtQuick 2.0
895+import Ubuntu.Components 0.1
896+import Ubuntu.Content 0.1
897+import ".."
898+
899+Previewer {
900+ title: application.contactNameFromVCard(attachment.filePath)
901+ clip: true
902+}
903
904=== modified file 'src/qml/MainPage.qml'
905--- src/qml/MainPage.qml 2014-07-25 16:20:57 +0000
906+++ src/qml/MainPage.qml 2014-08-05 11:46:55 +0000
907@@ -17,43 +17,41 @@
908 */
909
910 import QtQuick 2.0
911-import Ubuntu.Components 0.1
912+import Ubuntu.Components 1.1
913 import Ubuntu.Components.ListItems 0.1 as ListItem
914 import Ubuntu.History 0.1
915 import Ubuntu.Contacts 0.1
916 import "dateUtils.js" as DateUtils
917
918-PageWithBottomEdge {
919+LocalPageWithBottomEdge {
920 id: mainPage
921 property alias selectionMode: threadList.isInSelectionMode
922 property bool searching: false
923- tools: selectionMode ? selectionToolbar : searching ? searchToolbar : regularToolbar
924- title: selectionMode ? i18n.tr("Edit") : i18n.tr("Chats")
925- __customHeaderContents: mainPage.searching ? searchField : null
926-
927- bottomEdgeEnabled: !selectionMode
928+ property alias threadCount: threadList.count
929+
930+ function startSelection() {
931+ threadList.startSelection()
932+ }
933+
934+ state: selectionMode ? "select" : searching ? "search" : "default"
935+ title: selectionMode ? i18n.tr(" ") : i18n.tr("Chats")
936+
937+ bottomEdgeEnabled: !selectionMode && !searching
938 bottomEdgePageComponent: Messages {
939 active: false
940 }
941-
942 bottomEdgeTitle: i18n.tr("New Chat")
943- property alias threadCount: threadList.count
944-
945- function startSelection() {
946- threadList.startSelection()
947- }
948
949 TextField {
950 id: searchField
951 visible: mainPage.searching
952 anchors {
953 left: parent.left
954- topMargin: units.gu(1.5)
955- rightMargin: units.gu(1.5)
956- bottomMargin: units.gu(1.5)
957- verticalCenter: parent.verticalCenter
958+ right: parent.right
959+ rightMargin: units.gu(2)
960 }
961 inputMethodHints: Qt.ImhNoPredictiveText
962+ placeholderText: i18n.tr("Search...")
963 onActiveFocusChanged: {
964 if (!activeFocus) {
965 searchField.text = ""
966@@ -62,13 +60,25 @@
967 }
968 }
969
970- ToolbarItems {
971- id: searchToolbar
972-
973- visible: false
974- back: ToolbarButton {
975- visible: false
976- action: Action {
977+ states: [
978+ PageHeadState {
979+ name: "default"
980+ head: mainPage.head
981+ actions: [
982+ Action {
983+ objectName: "searchAction"
984+ iconName: "search"
985+ onTriggered: {
986+ mainPage.searching = true
987+ searchField.forceActiveFocus()
988+ }
989+ }
990+ ]
991+ },
992+ PageHeadState {
993+ name: "search"
994+ head: mainPage.head
995+ backAction: Action {
996 objectName: "cancelSearch"
997 visible: mainPage.searching
998 iconName: "close"
999@@ -78,58 +88,31 @@
1000 mainPage.searching = false
1001 }
1002 }
1003- }
1004- }
1005-
1006- ToolbarItems {
1007- id: regularToolbar
1008- visible: false
1009- ToolbarButton {
1010- id: searchButton
1011- objectName: "searchButton"
1012- action: Action {
1013- objectName: "searchAction"
1014- iconSource: "image://theme/search"
1015- onTriggered: {
1016- mainPage.searching = true
1017- searchField.forceActiveFocus()
1018- }
1019- }
1020- }
1021- }
1022-
1023- ToolbarItems {
1024- id: selectionToolbar
1025- visible: false
1026- back: ToolbarButton {
1027- id: selectionModeCancelButton
1028- objectName: "selectionModeCancelButton"
1029- action: Action {
1030+ contents: searchField
1031+ },
1032+ PageHeadState {
1033+ name: "select"
1034+ head: mainPage.head
1035+ backAction: Action {
1036 objectName: "selectionModeCancelAction"
1037- iconSource: "image://theme/close"
1038+ iconName: "close"
1039 onTriggered: threadList.cancelSelection()
1040 }
1041- }
1042- ToolbarButton {
1043- id: selectionModeSelectAllButton
1044- objectName: "selectionModeSelectAllButton"
1045- action: Action {
1046- objectName: "selectionModeSelectAllAction"
1047- iconSource: "image://theme/filter"
1048- onTriggered: threadList.selectAll()
1049- }
1050- }
1051- ToolbarButton {
1052- id: selectionModeDeleteButton
1053- objectName: "selectionModeDeleteButton"
1054- action: Action {
1055- objectName: "selectionModeDeleteAction"
1056- enabled: threadList.selectedItems.count > 0
1057- iconSource: "image://theme/delete"
1058- onTriggered: threadList.endSelection()
1059- }
1060- }
1061- }
1062+ actions: [
1063+ Action {
1064+ objectName: "selectionModeSelectAllAction"
1065+ iconName: "select"
1066+ onTriggered: threadList.selectAll()
1067+ },
1068+ Action {
1069+ objectName: "selectionModeDeleteAction"
1070+ enabled: threadList.selectedItems.count > 0
1071+ iconName: "delete"
1072+ onTriggered: threadList.endSelection()
1073+ }
1074+ ]
1075+ }
1076+ ]
1077
1078 HistoryThreadGroupingProxyModel {
1079 id: sortProxy
1080@@ -153,24 +136,21 @@
1081 Component {
1082 id: sectionDelegate
1083 Item {
1084- anchors.left: parent.left
1085- anchors.right: parent.right
1086- height: units.gu(5)
1087+ anchors {
1088+ left: parent.left
1089+ right: parent.right
1090+ margins: units.gu(2)
1091+ }
1092+ height: units.gu(3)
1093 Label {
1094- anchors.left: parent.left
1095- anchors.leftMargin: units.gu(2)
1096- anchors.verticalCenter: parent.verticalCenter
1097- fontSize: "medium"
1098+ anchors.fill: parent
1099 elide: Text.ElideRight
1100- color: "#5d5d5d"
1101 text: DateUtils.friendlyDay(Qt.formatDate(section, "yyyy/MM/dd"));
1102 verticalAlignment: Text.AlignVCenter
1103+ fontSize: "small"
1104 }
1105 ListItem.ThinDivider {
1106- anchors.leftMargin: units.gu(2)
1107- anchors.rightMargin: units.gu(2)
1108 anchors.bottom: parent.bottom
1109- opacity: 0.6
1110 }
1111 }
1112 }
1113@@ -178,26 +158,30 @@
1114 MultipleSelectionListView {
1115 id: threadList
1116 objectName: "threadList"
1117+
1118 anchors {
1119 top: parent.top
1120 left: parent.left
1121 right: parent.right
1122 bottom: keyboard.top
1123 }
1124-
1125 listModel: sortProxy
1126 section.property: "eventDate"
1127- spacing: searchField.text === "" ? units.gu(-2) : 0
1128+ //spacing: searchField.text === "" ? units.gu(-2) : 0
1129 section.delegate: searching && searchField.text !== "" ? null : sectionDelegate
1130 listDelegate: ThreadDelegate {
1131 id: threadDelegate
1132 objectName: "thread%1".arg(participants)
1133+
1134+ anchors {
1135+ left: parent.left
1136+ right: parent.right
1137+ }
1138+ height: units.gu(8)
1139 selectionMode: threadList.isInSelectionMode
1140 selected: threadList.isSelected(threadDelegate)
1141- removable: !selectionMode
1142- confirmRemoval: true
1143 searchTerm: mainPage.searching ? searchField.text : ""
1144- onClicked: {
1145+ onItemClicked: {
1146 if (threadList.isInSelectionMode) {
1147 if (!threadList.selectItem(threadDelegate)) {
1148 threadList.deselectItem(threadDelegate)
1149@@ -210,7 +194,7 @@
1150 mainStack.push(Qt.resolvedUrl("Messages.qml"), properties)
1151 }
1152 }
1153- onPressAndHold: {
1154+ onItemPressAndHold: {
1155 threadList.startSelection()
1156 threadList.selectItem(threadDelegate)
1157 }
1158
1159=== modified file 'src/qml/MessageBubble.qml'
1160--- src/qml/MessageBubble.qml 2014-05-05 16:56:56 +0000
1161+++ src/qml/MessageBubble.qml 2014-08-05 11:46:55 +0000
1162@@ -16,19 +16,110 @@
1163 * along with this program. If not, see <http://www.gnu.org/licenses/>.
1164 */
1165
1166-import QtQuick 2.0
1167+import QtQuick 2.2
1168+import Ubuntu.Components 1.1
1169+import Ubuntu.History 0.1
1170+
1171+import "dateUtils.js" as DateUtils
1172+import "3rd_party/ba-linkify.js" as BaLinkify
1173
1174 BorderImage {
1175- property bool incoming
1176+ id: root
1177+
1178+ property int messageStatus: -1
1179+ property bool incoming: false
1180+ property alias sender: senderName.text
1181+ property string messageText
1182+ property var messageTimeStamp
1183+ property int maxDelegateWidth: units.gu(30)
1184+
1185+ readonly property bool error: (messageStatus === HistoryThreadModel.MessageStatusPermanentlyFailed)
1186+ readonly property bool sending: (messageStatus === HistoryThreadModel.MessageStatusUnknown ||
1187+ messageStatus === HistoryThreadModel.MessageStatusTemporarilyFailed) && !incoming
1188+
1189 function selectBubble() {
1190 var fileName = "assets/conversation_";
1191- if (incoming) {
1192+ if (error) {
1193+ fileName += "error.sci"
1194+ } else if (sending) {
1195+ fileName += "pending.sci"
1196+ } else if (incoming) {
1197 fileName += "incoming.sci";
1198 } else {
1199 fileName += "outgoing.sci";
1200 }
1201 return fileName;
1202 }
1203+
1204+ function parseText(text) {
1205+ var phoneExp = /(\+?([0-9]+[ ]?)?\(?([0-9]+)\)?[-. ]?([0-9]+)[-. ]?([0-9]+)[-. ]?([0-9]+))/img;
1206+ // remove html tags
1207+ text = text.replace(/</g,'&lt;').replace(/>/g,'<tt>&gt;</tt>');
1208+ // replace line breaks
1209+ text = text.replace(/(\n)+/g, '<br />');
1210+ // check for links
1211+ text = BaLinkify.linkify(text);
1212+ // linkify phone numbers
1213+ return text.replace(phoneExp, '<a href="tel:///$1">$1</a>');
1214+ }
1215+
1216 onIncomingChanged: source = selectBubble()
1217 source: selectBubble()
1218+ height: childrenRect.height + units.gu(2)
1219+ width: Math.min(units.gu(27),
1220+ Math.max(textLabel.text.length, textTimestamp.text.length) * units.gu(1))
1221+ + border.left + border.right
1222+ Label {
1223+ id: senderName
1224+
1225+ anchors {
1226+ top: parent.top
1227+ topMargin: units.gu(1)
1228+ left: parent.left
1229+ leftMargin: incoming ? units.gu(2) : units.gu(1)
1230+ }
1231+ height: text === "" ? 0 : paintedHeight
1232+ fontSize: "large"
1233+ //color: Ubuntu.Colors.
1234+ }
1235+
1236+ Label {
1237+ id: textLabel
1238+ objectName: "messageText"
1239+
1240+ anchors {
1241+ top: sender == "" ? parent.top : senderName.bottom
1242+ topMargin: units.gu(1)
1243+ left: parent.left
1244+ leftMargin: incoming ? units.gu(2) : units.gu(1)
1245+ right: parent.right
1246+ rightMargin: incoming ? units.gu(1) : units.gu(1)
1247+ }
1248+ width: maxDelegateWidth
1249+ fontSize: "medium"
1250+ height: text === "" ? 0 : paintedHeight
1251+ onLinkActivated: Qt.openUrlExternally(link)
1252+ text: root.parseText(messageText)
1253+ wrapMode: Text.Wrap
1254+ color: root.incoming ? UbuntuColors.darkGrey : "white"
1255+ }
1256+
1257+ Label {
1258+ id: textTimestamp
1259+ objectName: "messageDate"
1260+
1261+ anchors{
1262+ top: textLabel.bottom
1263+ topMargin: units.gu(0.5)
1264+ left: parent.left
1265+ leftMargin: incoming ? units.gu(2) : units.gu(1)
1266+ }
1267+
1268+ visible: !root.sending
1269+ height: visible ? paintedHeight : 0
1270+ fontSize: "xx-small"
1271+ color: root.incoming ? UbuntuColors.lightGrey : "white"
1272+ opacity: root.incoming ? 1.0 : 0.8
1273+ text: Qt.formatDateTime(messageTimeStamp, "hh:mm AP")
1274+ }
1275 }
1276
1277=== modified file 'src/qml/MessageDelegate.qml'
1278--- src/qml/MessageDelegate.qml 2014-07-22 20:29:11 +0000
1279+++ src/qml/MessageDelegate.qml 2014-08-05 11:46:55 +0000
1280@@ -17,68 +17,91 @@
1281 */
1282
1283 import QtQuick 2.0
1284-import Ubuntu.Components 0.1
1285-import Ubuntu.Components.ListItems 0.1 as ListItem
1286+import Ubuntu.Components 1.1
1287 import Ubuntu.Components.Popups 0.1
1288 import Ubuntu.History 0.1
1289 import Ubuntu.Telephony 0.1
1290 import Ubuntu.Content 0.1
1291+import Ubuntu.Contacts 0.1
1292
1293 import "dateUtils.js" as DateUtils
1294-import "3rd_party/ba-linkify.js" as BaLinkify
1295
1296 Item {
1297 id: messageDelegate
1298- property bool incoming: false
1299+
1300+ property alias incoming: bubble.incoming
1301 property string textColor: incoming ? "#333333" : "white"
1302- property bool selectionMode: false
1303 property bool unread: false
1304- property alias confirmRemoval: internalDelegate.confirmRemoval
1305- property alias removable: internalDelegate.removable
1306- property alias selected: internalDelegate.selected
1307 property variant activeAttachment
1308 property string mmsText: ""
1309+ property string mmsTextId: ""
1310 property string accountLabel: ""
1311-
1312- anchors.left: parent ? parent.left : undefined
1313- anchors.right: parent ? parent.right: undefined
1314- height: attachments.height + internalDelegate.height
1315+ property bool selectionMode: false
1316+ property bool selected: false
1317+ property bool inProgress: (textMessageStatus === HistoryThreadModel.MessageStatusUnknown ||
1318+ textMessageStatus === HistoryThreadModel.MessageStatusTemporarilyFailed)
1319+ property bool failed: (textMessageStatus === HistoryThreadModel.MessageStatusPermanentlyFailed)
1320+ property int visibleAttachments: 0
1321
1322 signal resend()
1323- signal clicked()
1324- signal triggerSelectionMode()
1325+ signal itemPressAndHold(QtObject obj)
1326+ signal itemClicked(QtObject obj)
1327+
1328+ anchors {
1329+ left: parent ? parent.left : undefined
1330+ right: parent ? parent.right: undefined
1331+ }
1332+ height: attachments.height + bubbleItem.height
1333
1334 Component {
1335- id: popoverSaveAttachmentComponent
1336- Popover {
1337- id: popover
1338- Column {
1339- id: containerLayout
1340- anchors {
1341- left: parent.left
1342- top: parent.top
1343- right: parent.right
1344- }
1345- ListItem.Standard {
1346- text: i18n.tr("Save")
1347- onClicked: {
1348- mainStack.push(picker, {"url": activeAttachment.filePath, "handler": ContentHandler.Destination});
1349- PopupUtils.close(popover)
1350- }
1351- }
1352- ListItem.Standard {
1353- text: i18n.tr("Share")
1354- onClicked: {
1355- mainStack.push(picker, {"url": activeAttachment.filePath, "handler": ContentHandler.Share});
1356- PopupUtils.close(popover)
1357- }
1358- }
1359- ListItem.Standard {
1360- text: i18n.tr("Select")
1361- onClicked: {
1362- triggerSelectionMode()
1363- PopupUtils.close(popover)
1364- }
1365+ id: statusIcon
1366+ Item {
1367+ height: units.gu(4)
1368+ width: units.gu(4)
1369+ visible: !incoming && !messageDelegate.selectionMode
1370+ ActivityIndicator {
1371+ id: indicator
1372+
1373+ anchors.centerIn: parent
1374+ height: units.gu(2)
1375+ width: units.gu(2)
1376+ visible: running && !selectionMode
1377+ // if temporarily failed or unknown status, then show the spinner
1378+ running: inProgress
1379+ }
1380+
1381+ Item {
1382+ id: retrybutton
1383+
1384+ anchors.fill: parent
1385+ Icon {
1386+ id: icon
1387+
1388+ name: "reload"
1389+ color: "red"
1390+ height: units.gu(2)
1391+ width: units.gu(2)
1392+ anchors {
1393+ centerIn: parent
1394+ verticalCenterOffset: units.gu(-1)
1395+ }
1396+ }
1397+
1398+ Label {
1399+ text: i18n.tr("Failed!")
1400+ fontSize: "small"
1401+ color: "red"
1402+ anchors {
1403+ horizontalCenter: retrybutton.horizontalCenter
1404+ top: icon.bottom
1405+ }
1406+ }
1407+ visible: failed
1408+ MouseArea {
1409+ id: retrybuttonMouseArea
1410+
1411+ anchors.fill: parent
1412+ onClicked: messageDelegate.resend()
1413 }
1414 }
1415 }
1416@@ -86,18 +109,22 @@
1417
1418 Column {
1419 id: attachments
1420- anchors.top: parent.top
1421+ anchors {
1422+ top: parent.top
1423+ left: parent.left
1424+ right: parent.right
1425+ }
1426 height: childrenRect.height
1427- anchors.right: parent.right
1428- anchors.left: parent.left
1429- spacing: units.gu(2)
1430- // TODO: we currently support only images as attachments
1431 Repeater {
1432+ id: attachmentsRepeater
1433+
1434 model: textMessageAttachments
1435 Loader {
1436- anchors.left: parent.left
1437- anchors.right: parent.right
1438- height: item ? item.height : undefined
1439+ anchors {
1440+ left: parent ? parent.left : undefined
1441+ right: parent ? parent.right : undefined
1442+ }
1443+ height: item ? item.height : 0
1444 source: {
1445 if (startsWith(modelData.contentType, "image/")) {
1446 return "MMS/MMSImage.qml"
1447@@ -105,10 +132,10 @@
1448 return "MMS/MMSVideo.qml"
1449 } else if (startsWith(modelData.contentType, "application/smil") ||
1450 startsWith(modelData.contentType, "application/x-smil")) {
1451- console.log("Ignoring SMIL file")
1452 return ""
1453 } else if (startsWith(modelData.contentType, "text/plain") ) {
1454 mmsText = application.readTextFile(modelData.filePath)
1455+ mmsTextId = modelData.attachmentId
1456 return ""
1457 } else if (startsWith(modelData.contentType, "text/vcard") ||
1458 startsWith(modelData.contentType, "text/x-vcard")) {
1459@@ -127,20 +154,26 @@
1460 Connections {
1461 target: item
1462 onItemRemoved: {
1463- console.log("attachment removed: " + modelData.attachmentId)
1464 eventModel.removeEventAttachment(accountId, threadId, eventId, type, modelData.attachmentId)
1465- }
1466- }
1467- Connections {
1468- target: item
1469- onPressAndHold: {
1470- activeAttachment = modelData
1471- PopupUtils.open(popoverSaveAttachmentComponent, item)
1472- }
1473- }
1474- Connections {
1475- target: item
1476- onClicked: {
1477+ if (visibleAttachments == 1 && mmsText === "") {
1478+ // this is the last attachment. remove the whole event
1479+ eventModel.removeEvent(accountId, threadId, eventId, type)
1480+ return
1481+ }
1482+ }
1483+ }
1484+ Connections {
1485+ target: item
1486+ onItemPressAndHold: itemPressAndHold(bubbleItem)
1487+ }
1488+ Binding {
1489+ target: item
1490+ property: "parentSelected"
1491+ value: messageDelegate.selected
1492+ }
1493+ Connections {
1494+ target: item
1495+ onAttachmentClicked: {
1496 if (item.previewer === "") {
1497 activeAttachment = modelData
1498 PopupUtils.open(popoverSaveAttachmentComponent, item)
1499@@ -156,236 +189,69 @@
1500 }
1501 }
1502
1503- ListItem.Empty {
1504- id: internalDelegate
1505- anchors.top: attachments.bottom
1506- anchors.topMargin: textMessageAttachments.length > 0 ? units.gu(1) : undefined
1507- anchors.left: parent ? parent.left : undefined
1508- anchors.right: parent ? parent.right: undefined
1509- clip: true
1510- height: (textMessage === "" && mmsText === "" && textMessageAttachments.length > 0) ? 0 : bubble.height + date.height
1511- showDivider: false
1512- highlightWhenPressed: false
1513- onPressAndHold: PopupUtils.open(popoverMenuComponent, messageDelegate)
1514-
1515- onClicked: messageDelegate.clicked()
1516-
1517- Item {
1518- Component {
1519- id: popoverMenuComponent
1520- Popover {
1521- id: popover
1522- Column {
1523- id: containerLayout
1524- anchors {
1525- left: parent.left
1526- top: parent.top
1527- right: parent.right
1528- }
1529- ListItem.Standard {
1530- text: i18n.tr("Copy")
1531- onClicked: {
1532- Clipboard.push(textMessage);
1533- PopupUtils.close(popover)
1534- }
1535- }
1536- ListItem.Standard {
1537- objectName: "popoverSelectAction"
1538- text: i18n.tr("Select")
1539- onClicked: {
1540- triggerSelectionMode()
1541- PopupUtils.close(popover)
1542- }
1543- }
1544- }
1545- }
1546- }
1547- }
1548-
1549- Item {
1550- Component {
1551- id: popoverComponent
1552- Popover {
1553- id: popover
1554- Column {
1555- id: containerLayout
1556- anchors {
1557- left: parent.left
1558- top: parent.top
1559- right: parent.right
1560- }
1561- ListItem.Standard {
1562- text: i18n.tr("Try again")
1563- enabled: telepathyHelper.connected
1564- onClicked: {
1565- messageDelegate.resend()
1566- PopupUtils.close(popover)
1567- }
1568- }
1569- ListItem.Standard {
1570- text: i18n.tr("Cancel")
1571- onClicked: {
1572- eventModel.removeEvent(accountId, threadId, eventId, type)
1573- PopupUtils.close(popover)
1574- }
1575- }
1576- }
1577- }
1578- }
1579- }
1580-
1581- Icon {
1582- id: selectionIndicator
1583- visible: selectionMode
1584- name: "select"
1585- height: units.gu(3)
1586- width: units.gu(3)
1587- anchors.right: incoming ? undefined : bubble.left
1588- anchors.left: incoming ? bubble.right : undefined
1589- anchors.verticalCenter: bubble.verticalCenter
1590- anchors.leftMargin: incoming ? units.gu(2) : 0
1591- anchors.rightMargin: incoming ? 0 : units.gu(2)
1592- color: selected ? "white" : "grey"
1593- }
1594-
1595- ActivityIndicator {
1596- id: indicator
1597- height: units.gu(3)
1598- width: units.gu(3)
1599- anchors.right: bubble.left
1600- anchors.left: undefined
1601- anchors.verticalCenter: bubble.verticalCenter
1602- anchors.leftMargin: 0
1603- anchors.rightMargin: units.gu(1)
1604-
1605- visible: running && !selectionMode
1606- // if temporarily failed or unknown status, then show the spinner
1607- running: (textMessageStatus == HistoryThreadModel.MessageStatusUnknown ||
1608- textMessageStatus == HistoryThreadModel.MessageStatusTemporarilyFailed) && !incoming
1609- }
1610-
1611- Label {
1612- id: accountIndicator
1613- anchors {
1614- right: bubble.left
1615- rightMargin: units.gu(0.5)
1616- bottom: bubble.bottom
1617- }
1618- text: accountLabel
1619- visible: !incoming
1620- font.pixelSize: FontUtils.sizeToPixels("small")
1621- color: "green"
1622- }
1623-
1624- // FIXME: this is just a temporary workaround while we dont have the final design
1625- UbuntuShape {
1626- id: warningButton
1627- color: "yellow"
1628- height: units.gu(3)
1629- width: units.gu(3)
1630- anchors.right: accountIndicator.left
1631- anchors.left: undefined
1632- anchors.verticalCenter: bubble.verticalCenter
1633- anchors.leftMargin: 0
1634- anchors.rightMargin: units.gu(1)
1635- visible: (textMessageStatus == HistoryThreadModel.MessageStatusPermanentlyFailed) && !incoming && !selectionMode
1636- MouseArea {
1637- anchors.fill: parent
1638- onClicked: PopupUtils.open(popoverComponent, warningButton)
1639- }
1640- Label {
1641- text: "!"
1642- color: "black"
1643- anchors.centerIn: parent
1644- }
1645- }
1646-
1647- onItemRemoved: {
1648- eventModel.removeEvent(accountId, threadId, eventId, type)
1649- }
1650-
1651- Label {
1652- id: date
1653- objectName: 'messageDate'
1654- anchors.top: parent.top
1655- anchors{
1656- right: bubble.right
1657- rightMargin: units.gu(2)
1658- }
1659-
1660- height: paintedHeight + units.gu(0.5)
1661- fontSize: "x-small"
1662- color: "#333333"
1663- text: {
1664- if (indicator.visible)
1665- i18n.tr("Sending...")
1666- else if (warningButton.visible)
1667- i18n.tr("Failed")
1668- else
1669- DateUtils.friendlyDay(timestamp) + " " + Qt.formatDateTime(timestamp, "hh:mm AP")
1670- }
1671- }
1672+ ListItemWithActions {
1673+ id: bubbleItem
1674+
1675+ anchors {
1676+ top: attachments.bottom
1677+ left: parent.left
1678+ right: parent.right
1679+ }
1680+ internalAnchors {
1681+ topMargin: 0
1682+ bottomMargin: 0
1683+ }
1684+
1685+ height: bubble.visible ? bubble.height : 0
1686+ leftSideAction: Action {
1687+ iconName: "delete"
1688+ text: i18n.tr("Delete")
1689+ onTriggered: {
1690+ // if there are no attachments, remove the whole message
1691+ if (visibleAttachments == 0) {
1692+ eventModel.removeEvent(accountId, threadId, eventId, type)
1693+ return
1694+ }
1695+ // check if this is an mms text and we have more attachments
1696+ if (mmsText !== "" && visibleAttachments > 1) {
1697+ // remove only the text attachment if we have more attachments
1698+ eventModel.removeEventAttachment(accountId, threadId, eventId, type, mmsTextId)
1699+ mmsText = ""
1700+ mmsTextId = ""
1701+ return
1702+ }
1703+ }
1704+ }
1705+
1706+ selected: messageDelegate.selected
1707+ selectionMode: messageDelegate.selectionMode
1708+ onItemPressAndHold: messageDelegate.itemPressAndHold(bubbleItem)
1709+ onItemClicked: messageDelegate.itemClicked(bubbleItem)
1710+ onSwippingChanged: messageList.updateSwippedItem(bubbleItem)
1711+ onSwipeStateChanged: messageList.updateSwippedItem(bubbleItem)
1712
1713 MessageBubble {
1714 id: bubble
1715
1716- incoming: messageDelegate.incoming
1717- anchors.left: incoming ? parent.left : undefined
1718- anchors.leftMargin: units.gu(1)
1719- anchors.right: incoming ? undefined : parent.right
1720+ anchors {
1721+ top: parent.top
1722+ left: incoming ? parent.left : undefined
1723+ right: incoming ? undefined : parent.right
1724+ }
1725+ visible: (messageText !== "")
1726+ messageText: textMessage !== "" ? textMessage : mmsText
1727+ messageTimeStamp: timestamp
1728+ messageStatus: textMessageStatus
1729+ }
1730+
1731+ Loader {
1732+ id: statusIconLoader
1733+ active: !incoming && !messageDelegate.selectionMode && bubble.visible && (inProgress || failed)
1734+ sourceComponent: statusIcon
1735+ anchors.right: bubble.left
1736 anchors.rightMargin: units.gu(1)
1737- anchors.top: date.bottom
1738-
1739- height: messageContents.height + units.gu(4)
1740-
1741- Item {
1742- id: messageContents
1743- anchors {
1744- top: parent.top
1745- topMargin: units.gu(2)
1746- left: parent.left
1747- leftMargin: incoming ? units.gu(3) : units.gu(2)
1748- right: parent.right
1749- rightMargin: units.gu(3)
1750- }
1751- height: childrenRect.height
1752-
1753- // TODO: to be used only on multiparty chat
1754- Label {
1755- id: senderName
1756- anchors.top: parent.top
1757- height: text == "" ? 0 : paintedHeight
1758- fontSize: "large"
1759- color: textColor
1760- text: ""
1761- }
1762-
1763- Label {
1764- id: messageText
1765- objectName: 'messageText'
1766- anchors.top: parent.top
1767- anchors.left: parent.left
1768- anchors.right: parent.right
1769- height: paintedHeight
1770- wrapMode: Text.WrapAtWordBoundaryOrAnywhere
1771- fontSize: "medium"
1772- color: textColor
1773- //opacity: incoming ? 1 : 0.9
1774- text: textMessage !== "" ? parseText(textMessage) : parseText(mmsText)
1775- onLinkActivated: Qt.openUrlExternally(link)
1776- function parseText(text) {
1777- var phoneExp = /(\+?([0-9]+[ ]?)?\(?([0-9]+)\)?[-. ]?([0-9]+)[-. ]?([0-9]+)[-. ]?([0-9]+))/img;
1778- // remove html tags
1779- text = text.replace(/</g,'&lt;').replace(/>/g,'<tt>&gt;</tt>');
1780- // replace line breaks
1781- text = text.replace(/(\n)+/g, '<br />');
1782- // check for links
1783- text = BaLinkify.linkify(text);
1784- // linkify phone numbers
1785- return text.replace(phoneExp, '<a href="tel:///$1">$1</a>');
1786- }
1787- }
1788- }
1789+ anchors.verticalCenter: bubble.verticalCenter
1790 }
1791 }
1792+
1793 }
1794
1795=== modified file 'src/qml/Messages.qml'
1796--- src/qml/Messages.qml 2014-07-28 19:45:24 +0000
1797+++ src/qml/Messages.qml 2014-08-05 11:46:55 +0000
1798@@ -19,7 +19,7 @@
1799 import QtQuick 2.0
1800 import QtQuick.Window 2.0
1801 import QtContacts 5.0
1802-import Ubuntu.Components 0.1
1803+import Ubuntu.Components 1.1
1804 import Ubuntu.Components.ListItems 0.1 as ListItem
1805 import Ubuntu.Components.Popups 0.1
1806 import Ubuntu.Content 0.1
1807@@ -92,8 +92,7 @@
1808 }
1809
1810 flickable: null
1811- // we need to use isReady here to know if this is a bottom edge page or not.
1812- __customHeaderContents: participants.length === 0 && isReady ? newMessageHeader : null
1813+
1814 property bool isReady: false
1815 signal ready
1816 onReady: {
1817@@ -125,23 +124,6 @@
1818 }
1819 return i18n.tr("New Message")
1820 }
1821- tools: {
1822- if (selectionMode) {
1823- return messagesToolbarSelectionMode
1824- }
1825-
1826- if (participants.length == 0) {
1827- return messagesToolbarNewMessage
1828- } else if (participants.length == 1) {
1829- if (contactWatcher.isUnknown) {
1830- return messagesToolbarUnknownContact
1831- } else {
1832- return messagesToolbarKnownContact
1833- }
1834- } else if (groupChat){
1835- return messagesToolbarGroupChat
1836- }
1837- }
1838
1839 Component.onCompleted: {
1840 updateFilters()
1841@@ -156,7 +138,7 @@
1842 var componentUnion = "import Ubuntu.History 0.1; HistoryUnionFilter { %1 }"
1843 var componentFilters = ""
1844 for (var i in telepathyHelper.accountIds) {
1845- var filterValue = eventModel.threadIdForParticipants(telepathyHelper.accountIds[i],
1846+ var filterValue = eventModel.threadIdForParticipants(telepathyHelper.accountIds[i],
1847 HistoryThreadModel.EventTypeText,
1848 participants,
1849 HistoryThreadModel.MatchPhoneNumber)
1850@@ -262,89 +244,23 @@
1851 }
1852 }
1853
1854- Rectangle {
1855- id: accountList
1856- z: 1
1857- clip: !multipleAccounts
1858- anchors {
1859- left: parent.left
1860- right: parent.right
1861- top: parent.top
1862- }
1863- height: multipleAccounts ? childrenRect.height : 0
1864- color: "white"
1865- Row {
1866- anchors {
1867- top: parent.top
1868- horizontalCenter: parent.horizontalCenter
1869- }
1870- height: childrenRect.height
1871- width: childrenRect.width
1872- spacing: units.gu(2)
1873- Repeater {
1874- model: telepathyHelper.accounts
1875- delegate: Label {
1876- width: paintedWidth
1877- height: paintedHeight
1878- text: modelData.displayName
1879- font.pixelSize: FontUtils.sizeToPixels("small")
1880- color: messages.account == modelData ? "red" : "#5d5d5d"
1881- MouseArea {
1882- anchors {
1883- fill: parent
1884- // increase touch area
1885- leftMargin: units.gu(-1)
1886- rightMargin: units.gu(-1)
1887- bottomMargin: units.gu(-1)
1888- }
1889- onClicked: messages.account = modelData
1890- }
1891- }
1892- }
1893- }
1894+ head.sections.model: {
1895+ // does not show dual sim switch if there is only one sim
1896+ if (!multipleAccounts) {
1897+ return undefined
1898+ }
1899+
1900+ var accountNames = []
1901+ for(var i=0; i < telepathyHelper.accounts.length; i++) {
1902+ accountNames.push(telepathyHelper.accounts[i].displayName)
1903+ }
1904+ return accountNames
1905 }
1906-
1907- Item {
1908- id: newMessageHeader
1909- anchors {
1910- left: parent.left
1911- rightMargin: units.gu(1)
1912- right: parent.right
1913- bottom: parent.bottom
1914- }
1915- visible: participants.length == 0 && isReady && messages.active
1916- MultiRecipientInput {
1917- id: multiRecipient
1918- objectName: "multiRecipient"
1919- enabled: visible
1920- width: childrenRect.width
1921- anchors {
1922- left: parent.left
1923- right: addIcon.left
1924- rightMargin: units.gu(1)
1925- verticalCenter: parent.verticalCenter
1926- }
1927- }
1928- Icon {
1929- id: addIcon
1930- objectName: "addNewRecipientIcon"
1931- visible: multiRecipient.visible
1932- height: units.gu(3)
1933- width: units.gu(3)
1934- anchors {
1935- right: parent.right
1936- verticalCenter: parent.verticalCenter
1937- }
1938-
1939- name: "contact"
1940- color: "gray"
1941- MouseArea {
1942- anchors.fill: parent
1943- onClicked: {
1944- Qt.inputMethod.hide()
1945- mainStack.push(Qt.resolvedUrl("NewRecipientPage.qml"), {"multiRecipient": multiRecipient, "parentPage": messages})
1946- }
1947- }
1948+ head.sections.selectedIndex: Math.max(0, telepathyHelper.accounts.indexOf(messages.account))
1949+ Connections {
1950+ target: messages.head.sections
1951+ onSelectedIndexChanged: {
1952+ messages.account = telepathyHelper.accounts[head.sections.selectedIndex]
1953 }
1954 }
1955
1956@@ -360,6 +276,7 @@
1957 autoUpdate: false
1958 filterTerm: multiRecipient.searchString
1959 showSections: false
1960+ autoHideKeyboard: false
1961
1962 states: [
1963 State {
1964@@ -373,7 +290,7 @@
1965 ]
1966
1967 anchors {
1968- top: accountList.bottom
1969+ top: parent.top
1970 topMargin: units.gu(1)
1971 left: parent.left
1972 right: parent.right
1973@@ -489,9 +406,9 @@
1974 Loader {
1975 active: multiRecipient.searchString !== "" && multiRecipient.focus
1976 sourceComponent: contactSearchComponent
1977+ clip: true
1978 anchors {
1979- top: accountList.bottom
1980- topMargin: units.gu(1)
1981+ top: parent.top
1982 left: parent.left
1983 right: parent.right
1984 bottom: bottomPanel.top
1985@@ -508,129 +425,156 @@
1986 updateFilters()
1987 }
1988
1989- ToolbarItems {
1990- id: messagesToolbarSelectionMode
1991- visible: false
1992- back: ToolbarButton {
1993- id: selectionModeCancelButton
1994- objectName: "selectionModeCancelButton"
1995- action: Action {
1996+ state: {
1997+ if (participants.length === 0 && isReady) {
1998+ return "newMessage"
1999+ } else if (selectionMode) {
2000+ return "selection"
2001+ } else if (participants.length == 1) {
2002+ if (contactWatcher.isUnknown) {
2003+ return "unknownContact"
2004+ } else {
2005+ return "knownContact"
2006+ }
2007+ } else if (groupChat){
2008+ return "groupChat"
2009+ } else {
2010+ return ""
2011+ }
2012+ }
2013+
2014+ Action {
2015+ id: backButton
2016+ objectName: "backButton"
2017+ iconName: "back"
2018+ onTriggered: {
2019+ if (typeof mainPage !== 'undefined') {
2020+ mainPage.temporaryProperties = null
2021+ }
2022+ mainStack.pop()
2023+ }
2024+ }
2025+
2026+ states: [
2027+ PageHeadState {
2028+ name: "selection"
2029+ head: messages.head
2030+
2031+ backAction: Action {
2032 objectName: "selectionModeCancelAction"
2033- iconSource: "image://theme/close"
2034+ iconName: "close"
2035 onTriggered: messageList.cancelSelection()
2036 }
2037- }
2038- ToolbarButton {
2039- id: selectionModeSelectAllButton
2040- objectName: "selectionModeSelectAllButton"
2041- action: Action {
2042- objectName: "selectionModeSelectAllAction"
2043- iconSource: "image://theme/filter"
2044- onTriggered: messageList.selectAll()
2045- }
2046- }
2047- ToolbarButton {
2048- id: selectionModeDeleteButton
2049- objectName: "selectionModeDeleteButton"
2050- action: Action {
2051- objectName: "selectionModeDeleteAction"
2052- enabled: messageList.selectedItems.count > 0
2053- iconSource: "image://theme/delete"
2054- onTriggered: messageList.endSelection()
2055- }
2056- }
2057- }
2058-
2059- ToolbarItems {
2060- id: messagesToolbarGroupChat
2061- visible: false
2062- ToolbarButton {
2063- id: groupChatButton
2064- objectName: "groupChatButton"
2065- action: Action {
2066- objectName: "groupChatAction"
2067- iconSource: "image://theme/contact-group"
2068- onTriggered: {
2069- PopupUtils.open(participantsPopover, messages.header)
2070- }
2071- }
2072- }
2073- }
2074-
2075- ToolbarItems {
2076- id: messagesToolbarNewMessage
2077- visible: false
2078- back: ToolbarButton {
2079- action: Action {
2080- onTriggered: {
2081- mainPage.temporaryProperties = null
2082- mainStack.pop()
2083- }
2084- iconSource: "image://theme/back"
2085- }
2086- }
2087- }
2088-
2089- ToolbarItems {
2090- id: messagesToolbarUnknownContact
2091- visible: false
2092- ToolbarButton {
2093- objectName: "contactCallButton"
2094- action: Action {
2095- objectName: "contactCallAction"
2096- visible: participants.length == 1
2097- iconSource: "image://theme/call-start"
2098- text: i18n.tr("Call")
2099- onTriggered: {
2100- Qt.inputMethod.hide()
2101- Qt.openUrlExternally("tel:///" + encodeURIComponent(contactWatcher.phoneNumber))
2102- }
2103- }
2104- }
2105- ToolbarButton {
2106- objectName: "addContactButton"
2107- action: Action {
2108- objectName: "addContactAction"
2109- visible: contactWatcher.isUnknown && participants.length == 1
2110- iconSource: "image://theme/new-contact"
2111- text: i18n.tr("Add")
2112- onTriggered: {
2113- Qt.inputMethod.hide()
2114- Qt.openUrlExternally("addressbook:///addnewphone?callback=messaging-app.desktop&phone=" + encodeURIComponent(contactWatcher.phoneNumber));
2115- }
2116- }
2117- }
2118- }
2119-
2120- ToolbarItems {
2121- id: messagesToolbarKnownContact
2122- visible: false
2123- ToolbarButton {
2124- objectName: "contactCallButton"
2125- action: Action {
2126- objectName: "contactCallKnownAction"
2127- visible: participants.length == 1
2128- iconSource: "image://theme/call-start"
2129- text: i18n.tr("Call")
2130- onTriggered: {
2131- Qt.inputMethod.hide()
2132- Qt.openUrlExternally("tel:///" + encodeURIComponent(contactWatcher.phoneNumber))
2133- }
2134- }
2135- }
2136- ToolbarButton {
2137- objectName: "contactProfileButton"
2138- action: Action {
2139- objectName: "contactProfileAction"
2140- visible: !contactWatcher.isUnknown && participants.length == 1
2141- iconSource: "image://theme/contact"
2142- text: i18n.tr("Contact")
2143- onTriggered: {
2144- Qt.openUrlExternally("addressbook:///contact?callback=messaging-app.desktop&id=" + encodeURIComponent(contactWatcher.contactId))
2145- }
2146- }
2147- }
2148- }
2149+
2150+ actions: [
2151+ Action {
2152+ objectName: "selectionModeSelectAllAction"
2153+ iconName: "select"
2154+ onTriggered: messageList.selectAll()
2155+ },
2156+ Action {
2157+ objectName: "selectionModeDeleteAction"
2158+ enabled: messageList.selectedItems.count > 0
2159+ iconName: "delete"
2160+ onTriggered: messageList.endSelection()
2161+ }
2162+ ]
2163+ },
2164+ PageHeadState {
2165+ name: "groupChat"
2166+ head: messages.head
2167+ backAction: backButton
2168+
2169+ actions: [
2170+ Action {
2171+ objectName: "groupChatAction"
2172+ iconName: "contact-group"
2173+ onTriggered: PopupUtils.open(participantsPopover, messages.header)
2174+ }
2175+ ]
2176+ },
2177+ PageHeadState {
2178+ name: "unknownContact"
2179+ head: messages.head
2180+ backAction: backButton
2181+
2182+ actions: [
2183+ Action {
2184+ objectName: "contactCallAction"
2185+ visible: participants.length == 1
2186+ iconName: "call-start"
2187+ text: i18n.tr("Call")
2188+ onTriggered: {
2189+ Qt.inputMethod.hide()
2190+ Qt.openUrlExternally("tel:///" + encodeURIComponent(contactWatcher.phoneNumber))
2191+ }
2192+ },
2193+ Action {
2194+ objectName: "addContactAction"
2195+ visible: contactWatcher.isUnknown && participants.length == 1
2196+ iconName: "new-contact"
2197+ text: i18n.tr("Add")
2198+ onTriggered: {
2199+ Qt.inputMethod.hide()
2200+ Qt.openUrlExternally("addressbook:///addnewphone?callback=messaging-app.desktop&phone=" + encodeURIComponent(contactWatcher.phoneNumber));
2201+ }
2202+ }
2203+ ]
2204+ },
2205+ PageHeadState {
2206+ name: "newMessage"
2207+ head: messages.head
2208+ backAction: backButton
2209+ actions: [
2210+ Action {
2211+ objectName: "contactList"
2212+ iconName: "contact"
2213+ onTriggered: {
2214+ Qt.inputMethod.hide()
2215+ mainStack.push(Qt.resolvedUrl("NewRecipientPage.qml"), {"multiRecipient": multiRecipient, "parentPage": messages})
2216+ }
2217+ }
2218+
2219+ ]
2220+
2221+ contents: MultiRecipientInput {
2222+ id: multiRecipient
2223+ objectName: "multiRecipient"
2224+ enabled: visible
2225+ anchors {
2226+ left: parent ? parent.left : undefined
2227+ right: parent ? parent.right : undefined
2228+ rightMargin: units.gu(2)
2229+ }
2230+ }
2231+ },
2232+ PageHeadState {
2233+ name: "knownContact"
2234+ head: messages.head
2235+ backAction: backButton
2236+ actions: [
2237+ Action {
2238+ objectName: "contactCallKnownAction"
2239+ visible: participants.length == 1
2240+ iconName: "call-start"
2241+ text: i18n.tr("Call")
2242+ onTriggered: {
2243+ Qt.inputMethod.hide()
2244+ Qt.openUrlExternally("tel:///" + encodeURIComponent(contactWatcher.phoneNumber))
2245+ }
2246+ },
2247+ Action {
2248+ objectName: "contactProfileAction"
2249+ visible: !contactWatcher.isUnknown && participants.length == 1
2250+ iconSource: "image://theme/contact"
2251+ text: i18n.tr("Contact")
2252+ onTriggered: {
2253+ Qt.openUrlExternally("addressbook:///contact?callback=messaging-app.desktop&id=" + encodeURIComponent(contactWatcher.contactId))
2254+ }
2255+ }
2256+ ]
2257+ }
2258+ ]
2259
2260 HistoryEventModel {
2261 id: eventModel
2262@@ -652,44 +596,75 @@
2263 MultipleSelectionListView {
2264 id: messageList
2265 objectName: "messageList"
2266+
2267+ property var _currentSwipedItem: null
2268+
2269+ function updateSwippedItem(item)
2270+ {
2271+ if (item.swipping) {
2272+ return
2273+ }
2274+
2275+ if (item.swipeState !== "Normal") {
2276+ if (_currentSwipedItem !== item) {
2277+ if (_currentSwipedItem) {
2278+ _currentSwipedItem.resetSwipe()
2279+ }
2280+ _currentSwipedItem = item
2281+ }
2282+ } else if (item.swipeState !== "Normal" && _currentSwipedItem === item) {
2283+ _currentSwipedItem = null
2284+ }
2285+ }
2286 clip: true
2287 anchors {
2288- top: accountList.bottom
2289+ top: parent.top
2290 left: parent.left
2291 right: parent.right
2292 bottom: bottomPanel.top
2293 }
2294- // TODO: workaround to add some extra space at the bottom and top
2295+ // fake bottomMargin
2296 header: Item {
2297- height: units.gu(2)
2298- }
2299- footer: Item {
2300- height: units.gu(2)
2301- }
2302+ height: units.gu(1)
2303+ }
2304+
2305+ spacing: units.gu(1)
2306 listModel: participants.length > 0 ? sortProxy : null
2307 verticalLayoutDirection: ListView.BottomToTop
2308- spacing: units.gu(2)
2309 highlightFollowsCurrentItem: false
2310+ /*add: Transition {
2311+ UbuntuNumberAnimation {
2312+ properties: "anchors.leftMargin"
2313+ from: -width
2314+ to: 0
2315+ }
2316+ UbuntuNumberAnimation {
2317+ properties: "anchors.rightMargin"
2318+ from: -width
2319+ to: 0
2320+ }
2321+ }*/
2322+
2323 listDelegate: MessageDelegate {
2324 id: messageDelegate
2325 objectName: "message%1".arg(index)
2326 incoming: senderId != "self"
2327+ // TODO: we have several items inside
2328 selected: messageList.isSelected(messageDelegate)
2329 unread: newEvent
2330- removable: !messages.selectionMode
2331 selectionMode: messages.selectionMode
2332- confirmRemoval: true
2333 accountLabel: multipleAccounts ? telepathyHelper.accountForId(accountId).displayName : ""
2334- onClicked: {
2335+ // TODO: need select only the item
2336+ onItemClicked: {
2337 if (messageList.isInSelectionMode) {
2338 if (!messageList.selectItem(messageDelegate)) {
2339 messageList.deselectItem(messageDelegate)
2340 }
2341 }
2342 }
2343- onTriggerSelectionMode: {
2344+ onItemPressAndHold: {
2345 messageList.startSelection()
2346- clicked()
2347+ messageList.selectItem(messageDelegate)
2348 }
2349
2350 Component.onCompleted: {
2351@@ -912,7 +887,8 @@
2352 anchors.top: attachments.count == 0 ? textEntry.top : attachmentThumbnails.bottom
2353 anchors.left: parent.left
2354 anchors.right: parent.right
2355- height: units.gu(4)
2356+ // this value is to avoid letter being cut off
2357+ height: units.gu(4.3)
2358 style: MultiRecipientFieldStyle {}
2359 autoSize: true
2360 maximumLineCount: 0
2361@@ -946,7 +922,7 @@
2362 anchors.right: parent.right
2363 anchors.rightMargin: units.gu(2)
2364 text: "Send"
2365- color: "green"
2366+ color: enabled ? "#38b44a" : "#b2b2b2"
2367 width: units.gu(7)
2368 height: units.gu(4)
2369 font.pixelSize: FontUtils.sizeToPixels("small")
2370
2371=== modified file 'src/qml/MultiRecipientInput.qml'
2372--- src/qml/MultiRecipientInput.qml 2014-06-11 20:13:37 +0000
2373+++ src/qml/MultiRecipientInput.qml 2014-08-05 11:46:55 +0000
2374@@ -17,7 +17,7 @@
2375 */
2376
2377 import QtQuick 2.0
2378-import Ubuntu.Components 0.1
2379+import Ubuntu.Components 1.1
2380 import Ubuntu.Contacts 0.1
2381 import Ubuntu.Telephony 0.1
2382 import QtContacts 5.0
2383@@ -142,7 +142,7 @@
2384 width: units.gu(20)
2385 hasClearButton: false
2386 clip: false
2387- placeholderText: i18n.tr("Add contacts..")
2388+ placeholderText: multiRecipientWidget.recipientCount <= 0 ? i18n.tr("Add contacts...") :""
2389 font.family: "Ubuntu"
2390 font.weight: Font.Light
2391 color: "#752571"
2392
2393=== modified file 'src/qml/NewRecipientPage.qml'
2394--- src/qml/NewRecipientPage.qml 2014-07-17 16:09:02 +0000
2395+++ src/qml/NewRecipientPage.qml 2014-08-05 11:46:55 +0000
2396@@ -17,7 +17,7 @@
2397 */
2398
2399 import QtQuick 2.0
2400-import Ubuntu.Components 0.1
2401+import Ubuntu.Components 1.1
2402 import Ubuntu.Contacts 0.1
2403 import QtContacts 5.0
2404
2405@@ -28,21 +28,40 @@
2406
2407 title: i18n.tr("Add recipient")
2408
2409- __customHeaderContents: TextField {
2410- id: searchField
2411-
2412- anchors {
2413- left: parent.left
2414- leftMargin: units.gu(2)
2415- right: parent.right
2416- rightMargin: units.gu(2)
2417- topMargin: units.gu(1.5)
2418- bottomMargin: units.gu(1.5)
2419- verticalCenter: parent.verticalCenter
2420- }
2421- onTextChanged: contactList.currentIndex = -1
2422- inputMethodHints: Qt.ImhNoPredictiveText
2423- placeholderText: i18n.tr("Type to search by name or number")
2424+ head {
2425+ contents: TextField {
2426+ id: searchField
2427+
2428+ anchors {
2429+ left: parent.left
2430+ leftMargin: units.gu(2)
2431+ right: parent.right
2432+ rightMargin: units.gu(2)
2433+ topMargin: units.gu(1.5)
2434+ bottomMargin: units.gu(1.5)
2435+ verticalCenter: parent.verticalCenter
2436+ }
2437+ onTextChanged: contactList.currentIndex = -1
2438+ inputMethodHints: Qt.ImhNoPredictiveText
2439+ placeholderText: i18n.tr("Search...")
2440+ }
2441+ sections.model: ["All", "Favorites"]
2442+ }
2443+
2444+ Connections {
2445+ target: newRecipientPage.head.sections
2446+ onSelectedIndexChanged: {
2447+ switch (newRecipientPage.head.sections.selectedIndex) {
2448+ case 0:
2449+ contactList.showAllContacts()
2450+ break;
2451+ case 1:
2452+ contactList.showFavoritesContacts()
2453+ break;
2454+ default:
2455+ break;
2456+ }
2457+ }
2458 }
2459
2460 ContactListView {
2461@@ -69,13 +88,18 @@
2462 Qt.openUrlExternally("addressbook:///contact?callback=messaging-app.desktop&id=" + encodeURIComponent(contact.contactId))
2463 mainStack.pop()
2464 }
2465- }
2466-
2467- KeyboardRectangle {
2468- id: keyboard
2469+ onAddDetailClicked: {
2470+ // FIXME: the extra space at the end is needed so contacts-app opens the right view
2471+ Qt.openUrlExternally("addressbook:///addphone?callback=messaging-app.desktop&id=" + encodeURIComponent(contact.contactId) + "&phone= ")
2472+ mainStack.pop()
2473+ }
2474 }
2475
2476 // WORKAROUND: This is necessary to make the header visible from a bottom edge page
2477 Component.onCompleted: parentPage.active = false
2478 Component.onDestruction: parentPage.active = true
2479+
2480+ KeyboardRectangle {
2481+ id: keyboard
2482+ }
2483 }
2484
2485=== removed file 'src/qml/PageWithBottomEdge.qml'
2486--- src/qml/PageWithBottomEdge.qml 2014-06-25 21:14:26 +0000
2487+++ src/qml/PageWithBottomEdge.qml 1970-01-01 00:00:00 +0000
2488@@ -1,367 +0,0 @@
2489-/*
2490- * Copyright (C) 2014 Canonical, Ltd.
2491- *
2492- * This program is free software; you can redistribute it and/or modify
2493- * it under the terms of the GNU General Public License as published by
2494- * the Free Software Foundation; version 3.
2495- *
2496- * This program is distributed in the hope that it will be useful,
2497- * but WITHOUT ANY WARRANTY; without even the implied warranty of
2498- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2499- * GNU General Public License for more details.
2500- *
2501- * You should have received a copy of the GNU General Public License
2502- * along with this program. If not, see <http://www.gnu.org/licenses/>.
2503- */
2504-
2505-/*
2506- Example:
2507-
2508- MainView {
2509- objectName: "mainView"
2510-
2511- applicationName: "com.ubuntu.developer.boiko.bottomedge"
2512-
2513- width: units.gu(100)
2514- height: units.gu(75)
2515-
2516- Component {
2517- id: pageComponent
2518-
2519- PageWithBottomEdge {
2520- id: mainPage
2521- title: i18n.tr("Main Page")
2522-
2523- Rectangle {
2524- anchors.fill: parent
2525- color: "white"
2526- }
2527-
2528- bottomEdgePageComponent: Page {
2529- title: "Contents"
2530- anchors.fill: parent
2531- //anchors.topMargin: contentsPage.flickable.contentY
2532-
2533- ListView {
2534- anchors.fill: parent
2535- model: 50
2536- delegate: ListItems.Standard {
2537- text: "One Content Item: " + index
2538- }
2539- }
2540- }
2541- bottomEdgeTitle: i18n.tr("Bottom edge action")
2542- }
2543- }
2544-
2545- PageStack {
2546- id: stack
2547- Component.onCompleted: stack.push(pageComponent)
2548- }
2549- }
2550-
2551-*/
2552-
2553-import QtQuick 2.0
2554-import Ubuntu.Components 0.1
2555-
2556-Page {
2557- id: page
2558-
2559- property alias bottomEdgePageComponent: edgeLoader.sourceComponent
2560- property alias bottomEdgePageSource: edgeLoader.source
2561- property alias bottomEdgeTitle: tipLabel.text
2562- property alias bottomEdgeEnabled: bottomEdge.visible
2563- property int bottomEdgeExpandThreshold: page.height * 0.2
2564- property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded
2565- property bool reloadBottomEdgePage: true
2566-
2567- readonly property alias bottomEdgePage: edgeLoader.item
2568- readonly property bool isReady: (tip.opacity === 0.0)
2569- readonly property bool isCollapsed: (tip.opacity === 1.0)
2570- readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready)
2571- property var temporaryProperties: null
2572-
2573- property bool _showEdgePageWhenReady: false
2574- property int _areaWhenExpanded: 0
2575-
2576- signal bottomEdgeReleased()
2577- signal bottomEdgeDismissed()
2578-
2579-
2580- function showBottomEdgePage(source, properties)
2581- {
2582- edgeLoader.setSource(source, properties)
2583- temporaryProperties = properties
2584- _showEdgePageWhenReady = true
2585- }
2586-
2587- function setBottomEdgePage(source, properties)
2588- {
2589- edgeLoader.setSource(source, properties)
2590- }
2591-
2592- function _pushPage()
2593- {
2594- if (edgeLoader.status === Loader.Ready) {
2595- edgeLoader.item.active = true
2596- page.pageStack.push(edgeLoader.item)
2597- if (edgeLoader.item.flickable) {
2598- edgeLoader.item.flickable.contentY = -page.header.height
2599- edgeLoader.item.flickable.returnToBounds()
2600- }
2601- if (edgeLoader.item.ready)
2602- edgeLoader.item.ready()
2603- }
2604- }
2605-
2606-
2607- Component.onCompleted: {
2608- // avoid a binding on the expanded height value
2609- var expandedHeight = height;
2610- _areaWhenExpanded = expandedHeight;
2611- }
2612-
2613- onActiveChanged: {
2614- if (active) {
2615- bottomEdge.state = "collapsed"
2616- }
2617- }
2618-
2619- onBottomEdgePageLoadedChanged: {
2620- if (_showEdgePageWhenReady && bottomEdgePageLoaded) {
2621- bottomEdge.state = "expanded"
2622- _showEdgePageWhenReady = false
2623- }
2624- }
2625-
2626- Rectangle {
2627- id: bgVisual
2628-
2629- color: "black"
2630- anchors.fill: page
2631- opacity: 0.7 * ((page.height - bottomEdge.y) / page.height)
2632- z: 1
2633- }
2634-
2635- Rectangle {
2636- id: bottomEdge
2637- objectName: "bottomEdge"
2638-
2639- readonly property int tipHeight: units.gu(3)
2640- readonly property int pageStartY: 0
2641-
2642- z: 1
2643- color: Theme.palette.normal.background
2644- parent: page
2645- anchors {
2646- left: parent.left
2647- right: parent.right
2648- }
2649- height: page.height
2650- y: height
2651-
2652- Rectangle {
2653- id: shadow
2654-
2655- anchors {
2656- left: parent.left
2657- right: parent.right
2658- }
2659- height: units.gu(1)
2660- y: -height
2661- opacity: 0.0
2662- gradient: Gradient {
2663- GradientStop { position: 0.0; color: "transparent" }
2664- GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) }
2665- }
2666- }
2667-
2668- Item {
2669- id: tipContainer
2670- objectName: "bottomEdgeTip"
2671-
2672- width: childrenRect.width
2673- height: bottomEdge.tipHeight
2674- clip: true
2675- y: -bottomEdge.tipHeight
2676- anchors.horizontalCenter: parent.horizontalCenter
2677-
2678- UbuntuShape {
2679- id: tip
2680-
2681- width: tipLabel.paintedWidth + units.gu(6)
2682- height: bottomEdge.tipHeight + units.gu(1)
2683- color: Theme.palette.normal.overlay
2684- Label {
2685- id: tipLabel
2686-
2687- anchors {
2688- top: parent.top
2689- left: parent.left
2690- right: parent.right
2691- }
2692- height: bottomEdge.tipHeight
2693- verticalAlignment: Text.AlignVCenter
2694- horizontalAlignment: Text.AlignHCenter
2695- }
2696- }
2697- }
2698-
2699- MouseArea {
2700- preventStealing: true
2701- drag.axis: Drag.YAxis
2702- drag.target: bottomEdge
2703- drag.minimumY: bottomEdge.pageStartY
2704- drag.maximumY: page.height
2705-
2706- anchors {
2707- left: parent.left
2708- right: parent.right
2709- }
2710- height: bottomEdge.tipHeight
2711- y: -height
2712-
2713- onReleased: {
2714- page.bottomEdgeReleased()
2715- if (bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) {
2716- bottomEdge.state = "expanded"
2717- } else {
2718- bottomEdge.state = "collapsed"
2719- bottomEdge.y = bottomEdge.height
2720- }
2721- }
2722-
2723- onPressed: {
2724- bottomEdge.state = "floating"
2725- bottomEdge.y -= bottomEdge.tipHeight
2726- }
2727- }
2728-
2729- Behavior on y {
2730- UbuntuNumberAnimation {}
2731- }
2732-
2733- state: "collapsed"
2734- states: [
2735- State {
2736- name: "collapsed"
2737- PropertyChanges {
2738- target: bottomEdge
2739- y: bottomEdge.height
2740- }
2741- PropertyChanges {
2742- target: tip
2743- opacity: 1.0
2744- }
2745- },
2746- State {
2747- name: "expanded"
2748- PropertyChanges {
2749- target: bottomEdge
2750- y: bottomEdge.pageStartY
2751- }
2752- PropertyChanges {
2753- target: tip
2754- opacity: 0.0
2755- }
2756- },
2757- State {
2758- name: "floating"
2759- PropertyChanges {
2760- target: shadow
2761- opacity: 1.0
2762- }
2763- }
2764- ]
2765-
2766- transitions: [
2767- Transition {
2768- to: "expanded"
2769- SequentialAnimation {
2770- UbuntuNumberAnimation {
2771- targets: [bottomEdge,tip]
2772- properties: "y,opacity"
2773- duration: UbuntuAnimation.SlowDuration
2774- }
2775- ScriptAction {
2776- script: page._pushPage()
2777- }
2778- }
2779- },
2780- Transition {
2781- from: "expanded"
2782- to: "collapsed"
2783- SequentialAnimation {
2784- ScriptAction {
2785- script: {
2786- edgeLoader.item.parent = edgeLoader
2787- edgeLoader.item.anchors.fill = edgeLoader
2788- edgeLoader.item.active = false
2789- }
2790- }
2791- UbuntuNumberAnimation {
2792- targets: [bottomEdge,tip]
2793- properties: "y,opacity"
2794- duration: UbuntuAnimation.SlowDuration
2795- }
2796- ScriptAction {
2797- script: {
2798- // destroy current bottom page
2799- if (page.reloadBottomEdgePage) {
2800- edgeLoader.active = false
2801- // remove properties from old instance
2802- if (edgeLoader.source !== "") {
2803- var properties = {}
2804- if (temporaryProperties !== null) {
2805- properties = temporaryProperties
2806- temporaryProperties = null
2807- }
2808-
2809- edgeLoader.setSource(edgeLoader.source, properties)
2810- }
2811- }
2812-
2813- // notify
2814- page.bottomEdgeDismissed()
2815-
2816- // load a new bottom page in memory
2817- edgeLoader.active = true
2818- }
2819- }
2820- }
2821- },
2822- Transition {
2823- from: "floating"
2824- to: "collapsed"
2825- UbuntuNumberAnimation {
2826- targets: [bottomEdge,tip]
2827- properties: "y,opacity"
2828- }
2829- }
2830- ]
2831-
2832- Loader {
2833- id: edgeLoader
2834-
2835- z: 1
2836- active: true
2837- asynchronous: true
2838- anchors.fill: parent
2839-
2840- //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging
2841- Binding {
2842- target: edgeLoader
2843- property: "anchors.topMargin"
2844- value: edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0
2845- when: (edgeLoader.status === Loader.Ready && !page.isReady)
2846- }
2847-
2848- onLoaded: {
2849- if (page.isReady && edgeLoader.item.active != true) {
2850- page._pushPage()
2851- }
2852- }
2853- }
2854- }
2855-}
2856
2857=== modified file 'src/qml/ThreadDelegate.qml'
2858--- src/qml/ThreadDelegate.qml 2014-07-25 16:21:47 +0000
2859+++ src/qml/ThreadDelegate.qml 2014-08-05 11:46:55 +0000
2860@@ -17,17 +17,20 @@
2861 */
2862
2863 import QtQuick 2.0
2864-import Ubuntu.Components 0.1
2865-import Ubuntu.Components.ListItems 0.1 as ListItem
2866+import Ubuntu.Components 1.1
2867 import Ubuntu.Components.Popups 0.1
2868 import Ubuntu.Telephony 0.1
2869 import Ubuntu.Contacts 0.1
2870 import QtContacts 5.0
2871
2872-ListItem.Empty {
2873+ListItemWithActions {
2874 id: delegate
2875+
2876 property bool groupChat: participants.length > 1
2877 property string searchTerm
2878+ property string phoneNumber: delegateHelper.phoneNumber
2879+ property bool unknownContact: delegateHelper.isUnknown
2880+ property string threadId: model.threadId
2881 property string groupChatLabel: {
2882 var firstRecipient
2883 if (unknownContact) {
2884@@ -40,10 +43,8 @@
2885 return firstRecipient + " +" + String(participants.length-1)
2886 return firstRecipient
2887 }
2888- property string phoneNumber: delegateHelper.phoneNumber
2889- property bool unknownContact: delegateHelper.isUnknown
2890+
2891 property bool selectionMode: false
2892- property string threadId: model.threadId
2893 property string textMessage: {
2894 // check if this is an mms, if so, search for the actual text
2895 var imageCount = 0
2896@@ -81,7 +82,6 @@
2897 anchors.left: parent.left
2898 anchors.right: parent.right
2899 height: units.gu(10)
2900- showDivider: false
2901 // WORKAROUND: history-service can't filter by contact names
2902 onSearchTermChanged: {
2903 var found = false
2904@@ -95,48 +95,15 @@
2905 found = true
2906 }
2907
2908- height = found ? units.gu(10) : 0
2909+ height = found ? units.gu(8) : 0
2910 }
2911
2912- // FIXME: the selected state should be handled by the UITK
2913- Item {
2914- id: selection
2915-
2916- anchors {
2917- top: parent.top
2918- bottom: parent.bottom
2919- right: parent.right
2920- }
2921- width: visible ? units.gu(6) : 0
2922- opacity: selectionMode ? 1.0 : 0.0
2923- visible: opacity > 0.0
2924-
2925- Behavior on width {
2926- UbuntuNumberAnimation { }
2927- }
2928-
2929- Behavior on opacity {
2930- UbuntuNumberAnimation { }
2931- }
2932-
2933- Rectangle {
2934- id: selectionIndicator
2935- anchors.fill: parent
2936- color: "black"
2937- opacity: 0.2
2938- }
2939-
2940- Icon {
2941- anchors.centerIn: selectionIndicator
2942- name: "select"
2943- height: units.gu(3)
2944- width: units.gu(3)
2945- color: selected ? "white" : "grey"
2946-
2947- Behavior on color {
2948- ColorAnimation {
2949- duration: 100
2950- }
2951+ leftSideAction: Action {
2952+ iconName: "delete"
2953+ text: i18n.tr("Delete")
2954+ onTriggered: {
2955+ for (var i in threads) {
2956+ threadModel.removeThread(threads[i].accountId, threads[i].threadId, threads[i].type)
2957 }
2958 }
2959 }
2960@@ -147,27 +114,24 @@
2961 fallbackAvatarUrl: delegateHelper.avatar !== "" ? delegateHelper.avatar : "image://theme/contact"
2962 fallbackDisplayName: delegateHelper.alias
2963 showAvatarPicture: (delegateHelper.avatar !== "") || (initials.length === 0)
2964-
2965+ anchors {
2966+ left: parent.left
2967+ top: parent.top
2968+ bottom: parent.bottom
2969+ }
2970 height: units.gu(6)
2971 width: units.gu(6)
2972- anchors {
2973- left: parent.left
2974- leftMargin: units.gu(2)
2975- verticalCenter: parent.verticalCenter
2976- }
2977 }
2978
2979 Label {
2980 id: contactName
2981 anchors {
2982 top: avatar.top
2983- topMargin: units.gu(0.5)
2984 left: avatar.right
2985 leftMargin: units.gu(1)
2986 }
2987- font.weight: Font.Light
2988 fontSize: "medium"
2989- color: "#752571"
2990+ color: UbuntuColors.lightAubergine
2991 text: groupChat ? groupChatLabel : unknownContact ? delegateHelper.phoneNumber : delegateHelper.alias
2992 }
2993
2994@@ -175,12 +139,31 @@
2995 id: time
2996 anchors {
2997 verticalCenter: contactName.verticalCenter
2998- right: selection.left
2999+ right: parent.right
3000+ }
3001+ fontSize: "x-small"
3002+ text: Qt.formatDateTime(eventTimestamp,"h:mm ap")
3003+ }
3004+
3005+ UbuntuShape {
3006+ id: unreadCountIndicator
3007+ height: units.gu(2)
3008+ width: height
3009+ anchors {
3010+ top: time.bottom
3011+ topMargin: units.gu(1)
3012+ right: parent.right
3013 rightMargin: units.gu(2)
3014 }
3015- fontSize: "x-small"
3016- color: "#5d5d5d"
3017- text: Qt.formatDateTime(eventTimestamp,"h:mm ap")
3018+ visible: unreadCount > 0
3019+ color: "#38b44a"
3020+ Label {
3021+ anchors.centerIn: parent
3022+ text: unreadCount
3023+ color: "white"
3024+ fontSize: "x-small"
3025+ font.weight: Font.Light
3026+ }
3027 }
3028
3029 // This is currently not being used in the new designs, but let's keep it here for now
3030@@ -213,11 +196,6 @@
3031 text: textMessage
3032 font.weight: Font.Light
3033 }
3034- onItemRemoved: {
3035- for (var i in threads) {
3036- threadModel.removeThread(threads[i].accountId, threads[i].threadId, threads[i].type)
3037- }
3038- }
3039
3040 Item {
3041 id: delegateHelper
3042
3043=== added file 'src/qml/assets/conversation_error@27.png'
3044Binary files src/qml/assets/conversation_error@27.png 1970-01-01 00:00:00 +0000 and src/qml/assets/conversation_error@27.png 2014-08-05 11:46:55 +0000 differ
3045=== added file 'src/qml/assets/conversation_error@27.sci'
3046--- src/qml/assets/conversation_error@27.sci 1970-01-01 00:00:00 +0000
3047+++ src/qml/assets/conversation_error@27.sci 2014-08-05 11:46:55 +0000
3048@@ -0,0 +1,5 @@
3049+border.left: 63
3050+border.top: 46
3051+border.bottom: 88
3052+border.right: 44
3053+source: conversation_error@27.png
3054
3055=== modified file 'src/qml/assets/conversation_outgoing@27.png'
3056Binary files src/qml/assets/conversation_outgoing@27.png 2014-07-07 13:09:42 +0000 and src/qml/assets/conversation_outgoing@27.png 2014-08-05 11:46:55 +0000 differ
3057=== added file 'src/qml/assets/conversation_pending@27.png'
3058Binary files src/qml/assets/conversation_pending@27.png 1970-01-01 00:00:00 +0000 and src/qml/assets/conversation_pending@27.png 2014-08-05 11:46:55 +0000 differ
3059=== added file 'src/qml/assets/conversation_pending@27.sci'
3060--- src/qml/assets/conversation_pending@27.sci 1970-01-01 00:00:00 +0000
3061+++ src/qml/assets/conversation_pending@27.sci 2014-08-05 11:46:55 +0000
3062@@ -0,0 +1,5 @@
3063+border.left: 36
3064+border.top: 38
3065+border.bottom: 80
3066+border.right: 50
3067+source: conversation_pending@27.png
3068
3069=== modified file 'src/qml/messaging-app.qml'
3070--- src/qml/messaging-app.qml 2014-07-14 22:16:22 +0000
3071+++ src/qml/messaging-app.qml 2014-08-05 11:46:55 +0000
3072@@ -17,7 +17,7 @@
3073 */
3074
3075 import QtQuick 2.0
3076-import Ubuntu.Components 0.1
3077+import Ubuntu.Components 1.1
3078 import Ubuntu.Components.ListItems 0.1 as ListItem
3079 import Ubuntu.Components.Popups 0.1
3080 import Ubuntu.Telephony 0.1
3081@@ -26,11 +26,13 @@
3082 MainView {
3083 id: mainView
3084
3085+ property string newPhoneNumber
3086+
3087 automaticOrientation: true
3088 width: units.gu(40)
3089 height: units.gu(71)
3090 useDeprecatedToolbar: false
3091- property string newPhoneNumber
3092+ anchorToKeyboard: false
3093
3094 Component.onCompleted: {
3095 i18n.domain = "messaging-app"
3096@@ -144,9 +146,10 @@
3097 }
3098 }
3099
3100+
3101 PageStack {
3102 id: mainStack
3103+
3104 objectName: "mainStack"
3105- anchors.fill: parent
3106 }
3107 }
3108
3109=== modified file 'tests/autopilot/messaging_app/emulators.py'
3110--- tests/autopilot/messaging_app/emulators.py 2014-07-24 13:22:09 +0000
3111+++ tests/autopilot/messaging_app/emulators.py 2014-08-05 11:46:55 +0000
3112@@ -18,8 +18,8 @@
3113 from autopilot.input import Keyboard
3114 from autopilot.platform import model
3115 from autopilot.introspection.dbus import StateNotFoundError
3116-
3117 from ubuntuuitoolkit import emulators as toolkit_emulators
3118+from ubuntuuitoolkit._custom_proxy_objects import _common
3119
3120
3121 logger = logging.getLogger(__name__)
3122@@ -78,6 +78,10 @@
3123
3124 return self.wait_select_single("MainPage", objectName="")
3125
3126+ def go_back(self):
3127+ """Click back button from toolbar on messages page"""
3128+ self.get_header().click_custom_back_button()
3129+
3130 def click_header_action(self, action):
3131 """Click the action 'action' on the header"""
3132 self.get_header().click_action_button(action)
3133@@ -149,8 +153,8 @@
3134 """Return toolbar icon to add contact"""
3135
3136 return self.select_single(
3137- 'Icon',
3138- objectName='addNewRecipientIcon',
3139+ 'PageHeadButton',
3140+ objectName='contactList_header_button',
3141 )
3142
3143 def click_add_contact_icon(self):
3144@@ -280,11 +284,6 @@
3145 objectName="message0")
3146 self.long_press(message)
3147
3148- # now click the popover action
3149- select = self.wait_select_single("Standard",
3150- objectName="popoverSelectAction")
3151- self.pointing_device.click_object(select)
3152-
3153 # FIXME: there should be a better way to detect when the popover is
3154 # gone
3155 time.sleep(2)
3156@@ -420,7 +419,7 @@
3157 """Bring the bottom edge page to the screen"""
3158 self.bottomEdgePageLoaded.wait_for(True)
3159 try:
3160- action_item = self.wait_select_single('QQuickItem',
3161+ action_item = self.wait_select_single('UbuntuShape',
3162 objectName='bottomEdgeTip')
3163 start_x = (action_item.globalRect.x +
3164 (action_item.globalRect.width * 0.5))
3165@@ -457,7 +456,7 @@
3166
3167 def get_messages_count(self):
3168 """Return the number of meesages."""
3169- return self.select_single(
3170+ return self.wait_select_single(
3171 'MultipleSelectionListView', objectName='messageList').count
3172
3173 @autopilot_logging.log_action(logger.info)
3174@@ -508,18 +507,36 @@
3175 return messages
3176
3177
3178-class ThreadDelegate(toolkit_emulators.Empty):
3179+class ListItemWithActions(_common.UbuntuUIToolkitCustomProxyObjectBase):
3180+
3181+ def confirm_removal(self):
3182+ deleteButton = self.wait_select_single(name='delete')
3183+ self.pointing_device.click_object(deleteButton)
3184+
3185+ def swipe_to_delete(self):
3186+ x, y, width, height = self.globalRect
3187+ start_x = x + (width * 0.2)
3188+ stop_x = x + (width * 0.8)
3189+ start_y = stop_y = y + (height // 2)
3190+
3191+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
3192+
3193+ def active_action(self, action_index):
3194+ action_margin = ((self.actionWidth / 5) * 2)
3195+ x_offset = ((self.actionWidth + action_margin) * action_index)
3196+ x_offset += self.actionThreshold
3197+
3198+ x, y, width, height = self.globalRect
3199+ start_x = x + (width * 0.5)
3200+ stop_x = start_x - x_offset
3201+ start_y = stop_y = y + (height // 2)
3202+
3203+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
3204+
3205+
3206+class ThreadDelegate(ListItemWithActions):
3207 """Autopilot helper for ThreadDelegate."""
3208
3209
3210-class MessageDelegate(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
3211+class MessageDelegate(ListItemWithActions):
3212 """Autopilot helper for the MessageDelegate."""
3213-
3214- def swipe_to_delete(self):
3215- self._get_internal_list_item().swipe_to_delete()
3216-
3217- def _get_internal_list_item(self):
3218- return self.select_single(toolkit_emulators.Empty)
3219-
3220- def confirm_removal(self):
3221- self._get_internal_list_item().confirm_removal()
3222
3223=== modified file 'tests/autopilot/messaging_app/tests/test_messaging.py'
3224--- tests/autopilot/messaging_app/tests/test_messaging.py 2014-07-15 16:32:01 +0000
3225+++ tests/autopilot/messaging_app/tests/test_messaging.py 2014-08-05 11:46:55 +0000
3226@@ -333,7 +333,11 @@
3227
3228 self.main_view.enable_messages_selection_mode()
3229 messages_page.select_messages(1, 2)
3230- self.main_view.click_header_action('selectionModeDeleteAction')
3231+
3232+ # Wait a few seconds before clicking the header
3233+ # to make sure the OSD is already gone
3234+ time.sleep(5)
3235+ self.main_view.click_messages_header_delete()
3236
3237 remaining_messages = messages_page.get_messages()
3238 self.assertThat(remaining_messages, HasLength(1))
3239
3240=== modified file 'tests/qml/tst_MessageBubble.qml'
3241--- tests/qml/tst_MessageBubble.qml 2014-07-22 16:46:00 +0000
3242+++ tests/qml/tst_MessageBubble.qml 2014-08-05 11:46:55 +0000
3243@@ -64,9 +64,6 @@
3244 when: windowShown
3245
3246 function init() {
3247- waitForRendering(incomingMessageBubble);
3248- waitForRendering(outgoingMessageBubble);
3249- waitForRendering(changeIncomingMessageBubble);
3250 }
3251
3252 function cleanup() {

Subscribers

People subscribed via source and target branches

to all changes: