Merge lp:~rpadovani/reminders-app/bottomEdge into lp:reminders-app

Proposed by Riccardo Padovani
Status: Merged
Approved by: Nicholas Skaggs
Approved revision: 198
Merged at revision: 241
Proposed branch: lp:~rpadovani/reminders-app/bottomEdge
Merge into: lp:reminders-app
Diff against target: 525 lines (+404/-6)
6 files modified
src/app/qml/components/PageWithBottomEdge.qml (+376/-0)
src/app/qml/reminders.qml (+5/-1)
src/app/qml/ui/EditNotePage.qml (+1/-0)
src/app/qml/ui/EditNoteView.qml (+3/-0)
src/app/qml/ui/NotebooksPage.qml (+4/-2)
src/app/qml/ui/NotesPage.qml (+15/-3)
To merge this branch: bzr merge lp:~rpadovani/reminders-app/bottomEdge
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Michael Zanetti (community) Approve
Review via email: mp+231118@code.launchpad.net

Commit message

Implemented bottomEdge

Description of the change

Added bottomEdge in phone mode: to avoid an annoying flickering when users open a notebook, the bottomEdge is loaded only after notes are loaded (only for notebooks page).

The bottomEdge component has been modified for our purpose

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Zanetti (mzanetti) wrote :

small nitpick inline (2 comments). Works reasonably well.

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Thanks, improved

Revision history for this message
Michael Zanetti (mzanetti) wrote :

ack

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

E: Release 'utopic' for 'qtdeclarative5-nemo-qml-plugin-folderlistmodel' was not found
E: Release 'utopic' for 'qtdeclarative5-pamauthentication0.1' was not found
E: Release 'utopic' for 'qtdeclarative5-placesmodel0.1' was not found
E: Release 'utopic' for 'ubuntu-filemanager-app' was not found
E: Release 'utopic' for 'ubuntu-filemanager-app-autopilot' was not found

Looks oddly broken?

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Francis Ginther (fginther) wrote :

> E: Release 'utopic' for 'qtdeclarative5-nemo-qml-plugin-folderlistmodel' was
> not found
> E: Release 'utopic' for 'qtdeclarative5-pamauthentication0.1' was not found
> E: Release 'utopic' for 'qtdeclarative5-placesmodel0.1' was not found
> E: Release 'utopic' for 'ubuntu-filemanager-app' was not found
> E: Release 'utopic' for 'ubuntu-filemanager-app-autopilot' was not found
>
> Looks oddly broken?

This appears to be fallout from the recent testing issues.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/app/qml/components/PageWithBottomEdge.qml'
2--- src/app/qml/components/PageWithBottomEdge.qml 1970-01-01 00:00:00 +0000
3+++ src/app/qml/components/PageWithBottomEdge.qml 2014-09-03 16:57:24 +0000
4@@ -0,0 +1,376 @@
5+/*
6+ * Copyright (C) 2014 Canonical, Ltd.
7+ *
8+ * This program is free software; you can redistribute it and/or modify
9+ * it under the terms of the GNU General Public License as published by
10+ * the Free Software Foundation; version 3.
11+ *
12+ * This program is distributed in the hope that it will be useful,
13+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+ * GNU General Public License for more details.
16+ *
17+ * You should have received a copy of the GNU General Public License
18+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+ */
20+
21+/*
22+ Example:
23+
24+ MainView {
25+ objectName: "mainView"
26+
27+ applicationName: "com.ubuntu.developer.boiko.bottomedge"
28+
29+ width: units.gu(100)
30+ height: units.gu(75)
31+
32+ Component {
33+ id: pageComponent
34+
35+ PageWithBottomEdge {
36+ id: mainPage
37+ title: i18n.tr("Main Page")
38+
39+ Rectangle {
40+ anchors.fill: parent
41+ color: "white"
42+ }
43+
44+ bottomEdgePageComponent: Page {
45+ title: "Contents"
46+ anchors.fill: parent
47+ //anchors.topMargin: contentsPage.flickable.contentY
48+
49+ ListView {
50+ anchors.fill: parent
51+ model: 50
52+ delegate: ListItems.Standard {
53+ text: "One Content Item: " + index
54+ }
55+ }
56+ }
57+ bottomEdgeTitle: i18n.tr("Bottom edge action")
58+ }
59+ }
60+
61+ PageStack {
62+ id: stack
63+ Component.onCompleted: stack.push(pageComponent)
64+ }
65+ }
66+
67+*/
68+
69+import QtQuick 2.0
70+import Ubuntu.Components 0.1
71+import Evernote 0.1
72+
73+Page {
74+ id: page
75+
76+ property alias bottomEdgePageComponent: edgeLoader.sourceComponent
77+ property alias bottomEdgePageSource: edgeLoader.source
78+ property alias bottomEdgeTitle: tipLabel.text
79+ property alias bottomEdgeEnabled: bottomEdge.visible
80+ property int bottomEdgeExpandThreshold: page.height * 0.2
81+ property int bottomEdgeExposedArea: bottomEdge.state !== "expanded" ? (page.height - bottomEdge.y - bottomEdge.tipHeight) : _areaWhenExpanded
82+ property bool reloadBottomEdgePage: true
83+
84+ readonly property alias bottomEdgePage: edgeLoader.item
85+ readonly property bool isReady: (tip.opacity === 0.0)
86+ readonly property bool isCollapsed: (tip.opacity === 1.0)
87+ readonly property bool bottomEdgePageLoaded: (edgeLoader.status == Loader.Ready)
88+ property var temporaryProperties: null
89+
90+ property bool bottomEdgeLabelVisible: true
91+
92+ property bool _showEdgePageWhenReady: false
93+ property int _areaWhenExpanded: 0
94+
95+ signal bottomEdgeReleased()
96+ signal bottomEdgeDismissed()
97+
98+
99+ function showBottomEdgePage(source, properties)
100+ {
101+ edgeLoader.setSource(source, properties)
102+ temporaryProperties = properties
103+ _showEdgePageWhenReady = true
104+ }
105+
106+ function setBottomEdgePage(source, properties)
107+ {
108+ edgeLoader.setSource(source, properties)
109+ }
110+
111+ function _pushPage()
112+ {
113+ if (edgeLoader.status === Loader.Ready) {
114+ edgeLoader.item.active = true
115+
116+ NotesStore.createNote("Untitled", filter);
117+
118+ if (edgeLoader.item.flickable) {
119+ edgeLoader.item.flickable.contentY = -page.header.height
120+ edgeLoader.item.flickable.returnToBounds()
121+ }
122+ if (edgeLoader.item.ready)
123+ edgeLoader.item.ready()
124+ }
125+ }
126+
127+
128+ Component.onCompleted: {
129+ // avoid a binding on the expanded height value
130+ var expandedHeight = height;
131+ _areaWhenExpanded = expandedHeight;
132+ }
133+
134+ onActiveChanged: {
135+ if (active) {
136+ bottomEdge.state = "collapsed"
137+ }
138+ }
139+
140+ onBottomEdgePageLoadedChanged: {
141+ if (_showEdgePageWhenReady && bottomEdgePageLoaded) {
142+ bottomEdge.state = "expanded"
143+ _showEdgePageWhenReady = false
144+ }
145+ }
146+
147+ Rectangle {
148+ id: bgVisual
149+
150+ visible: bottomEdgeLabelVisible
151+
152+ color: "black"
153+ anchors.fill: page
154+ opacity: 0.7 * ((page.height - bottomEdge.y) / page.height)
155+ z: 1
156+ }
157+
158+ Rectangle {
159+ id: bottomEdge
160+ objectName: "bottomEdge"
161+
162+ readonly property int tipHeight: units.gu(3)
163+ readonly property int pageStartY: 0
164+
165+ visible: bottomEdgeLabelVisible
166+
167+ z: 1
168+ color: Theme.palette.normal.background
169+ parent: page
170+ anchors {
171+ left: parent.left
172+ right: parent.right
173+ }
174+ height: page.height
175+ y: height
176+
177+ Rectangle {
178+ id: shadow
179+
180+ anchors {
181+ left: parent.left
182+ right: parent.right
183+ }
184+ height: units.gu(1)
185+ y: -height
186+ opacity: 0.0
187+ gradient: Gradient {
188+ GradientStop { position: 0.0; color: "transparent" }
189+ GradientStop { position: 1.0; color: Qt.rgba(0, 0, 0, 0.2) }
190+ }
191+ }
192+
193+ Item {
194+ id: tipContainer
195+ objectName: "bottomEdgeTip"
196+
197+ width: childrenRect.width
198+ height: bottomEdge.tipHeight
199+ clip: true
200+ y: -bottomEdge.tipHeight
201+ anchors.horizontalCenter: parent.horizontalCenter
202+
203+ UbuntuShape {
204+ id: tip
205+
206+ width: tipLabel.paintedWidth + units.gu(6)
207+ height: bottomEdge.tipHeight + units.gu(1)
208+ color: Theme.palette.normal.overlay
209+ Label {
210+ id: tipLabel
211+
212+ anchors {
213+ top: parent.top
214+ left: parent.left
215+ right: parent.right
216+ }
217+ height: bottomEdge.tipHeight
218+ verticalAlignment: Text.AlignVCenter
219+ horizontalAlignment: Text.AlignHCenter
220+ }
221+ }
222+ }
223+
224+ MouseArea {
225+ preventStealing: true
226+ drag.axis: Drag.YAxis
227+ drag.target: bottomEdge
228+ drag.minimumY: bottomEdge.pageStartY
229+ drag.maximumY: page.height
230+
231+ anchors {
232+ left: parent.left
233+ right: parent.right
234+ }
235+ height: bottomEdge.tipHeight
236+ y: -height
237+
238+ onReleased: {
239+ page.bottomEdgeReleased()
240+ if (bottomEdge.y < (page.height - bottomEdgeExpandThreshold - bottomEdge.tipHeight)) {
241+ bottomEdge.state = "expanded"
242+ } else {
243+ bottomEdge.state = "collapsed"
244+ bottomEdge.y = bottomEdge.height
245+ }
246+ }
247+
248+ onPressed: {
249+ bottomEdge.state = "floating"
250+ bottomEdge.y -= bottomEdge.tipHeight
251+ }
252+ }
253+
254+ Behavior on y {
255+ UbuntuNumberAnimation {}
256+ }
257+
258+ state: "collapsed"
259+ states: [
260+ State {
261+ name: "collapsed"
262+ PropertyChanges {
263+ target: bottomEdge
264+ y: bottomEdge.height
265+ }
266+ PropertyChanges {
267+ target: tip
268+ opacity: 1.0
269+ }
270+ },
271+ State {
272+ name: "expanded"
273+ PropertyChanges {
274+ target: bottomEdge
275+ y: bottomEdge.pageStartY
276+ }
277+ PropertyChanges {
278+ target: tip
279+ opacity: 0.0
280+ }
281+ },
282+ State {
283+ name: "floating"
284+ PropertyChanges {
285+ target: shadow
286+ opacity: 1.0
287+ }
288+ }
289+ ]
290+
291+ transitions: [
292+ Transition {
293+ to: "expanded"
294+ SequentialAnimation {
295+ UbuntuNumberAnimation {
296+ targets: [bottomEdge,tip]
297+ properties: "y,opacity"
298+ duration: UbuntuAnimation.SlowDuration
299+ }
300+ ScriptAction {
301+ script: page._pushPage()
302+ }
303+ }
304+ },
305+ Transition {
306+ from: "expanded"
307+ to: "collapsed"
308+ SequentialAnimation {
309+ ScriptAction {
310+ script: {
311+ edgeLoader.item.parent = edgeLoader
312+ edgeLoader.item.anchors.fill = edgeLoader
313+ edgeLoader.item.active = false
314+ }
315+ }
316+ UbuntuNumberAnimation {
317+ targets: [bottomEdge,tip]
318+ properties: "y,opacity"
319+ duration: UbuntuAnimation.SlowDuration
320+ }
321+ ScriptAction {
322+ script: {
323+ // destroy current bottom page
324+ if (page.reloadBottomEdgePage) {
325+ edgeLoader.active = false
326+ // remove properties from old instance
327+ if (edgeLoader.source !== "") {
328+ var properties = {}
329+ if (temporaryProperties !== null) {
330+ properties = temporaryProperties
331+ temporaryProperties = null
332+ }
333+
334+ edgeLoader.setSource(edgeLoader.source, properties)
335+ }
336+ }
337+
338+ // notify
339+ page.bottomEdgeDismissed()
340+
341+ // load a new bottom page in memory
342+ edgeLoader.active = true
343+ }
344+ }
345+ }
346+ },
347+ Transition {
348+ from: "floating"
349+ to: "collapsed"
350+ UbuntuNumberAnimation {
351+ targets: [bottomEdge,tip]
352+ properties: "y,opacity"
353+ }
354+ }
355+ ]
356+
357+ Loader {
358+ id: edgeLoader
359+
360+ z: 1
361+ active: true
362+ asynchronous: true
363+ anchors.fill: parent
364+
365+ //WORKAROUND: The SDK move the page contents down to allocate space for the header we need to avoid that during the page dragging
366+ Binding {
367+ target: edgeLoader
368+ property: "anchors.topMargin"
369+ value: edgeLoader.item && edgeLoader.item.flickable ? edgeLoader.item.flickable.contentY : 0
370+ when: (edgeLoader.status === Loader.Ready && !page.isReady)
371+ }
372+
373+ onLoaded: {
374+ if (page.isReady && edgeLoader.item.active != true) {
375+ page._pushPage()
376+ }
377+ }
378+ }
379+ }
380+}
381
382=== modified file 'src/app/qml/reminders.qml'
383--- src/app/qml/reminders.qml 2014-08-06 09:44:18 +0000
384+++ src/app/qml/reminders.qml 2014-09-03 16:57:24 +0000
385@@ -207,6 +207,8 @@
386 page: NotesPage {
387 id: notesPage
388
389+ narrowMode: root.narrowMode
390+
391 onEditNote: {
392 root.switchToEditMode(note)
393 }
394@@ -236,11 +238,13 @@
395 page: NotebooksPage {
396 id: notebooksPage
397
398+ narrowMode: root.narrowMode
399+
400 onOpenNotebook: {
401 var component = Qt.createComponent(Qt.resolvedUrl("ui/NotesPage.qml"))
402 var page = component.createObject();
403 print("opening note page for notebook", notebookGuid)
404- pagestack.push(page, {title: title, filter: notebookGuid});
405+ pagestack.push(page, {title: title, filter: notebookGuid, narrowMode: narrowMode});
406 page.selectedNoteChanged.connect(function() {
407 print("foo", page.selectedNote);
408 if (page.selectedNote) {
409
410=== modified file 'src/app/qml/ui/EditNotePage.qml'
411--- src/app/qml/ui/EditNotePage.qml 2014-05-07 16:34:06 +0000
412+++ src/app/qml/ui/EditNotePage.qml 2014-09-03 16:57:24 +0000
413@@ -25,6 +25,7 @@
414 Page {
415 id: root
416 property alias note: editNoteView.note
417+ property alias isBottomEdge: editNoteView.isBottomEdge
418
419 signal exitEditMode(var note)
420
421
422=== modified file 'src/app/qml/ui/EditNoteView.qml'
423--- src/app/qml/ui/EditNoteView.qml 2014-07-14 13:40:24 +0000
424+++ src/app/qml/ui/EditNoteView.qml 2014-09-03 16:57:24 +0000
425@@ -26,6 +26,7 @@
426 Item {
427 id: root
428 property var note
429+ property bool isBottomEdge: false
430
431 onNoteChanged: {
432 for (var i = 0; i < notebookSelector.model.count; i++) {
433@@ -74,6 +75,7 @@
434 spacing: units.gu(1)
435
436 Row {
437+ visible: !root.isBottomEdge
438 anchors { left: parent.left; right: parent.right }
439 height: units.gu(5)
440 spacing: units.gu(2)
441@@ -126,6 +128,7 @@
442 }
443
444 Divider {
445+ visible: !root.isBottomEdge
446 anchors { leftMargin: -units.gu(2); rightMargin: -units.gu(2) }
447 height: units.gu(2)
448 }
449
450=== modified file 'src/app/qml/ui/NotebooksPage.qml'
451--- src/app/qml/ui/NotebooksPage.qml 2014-06-24 00:01:51 +0000
452+++ src/app/qml/ui/NotebooksPage.qml 2014-09-03 16:57:24 +0000
453@@ -26,7 +26,9 @@
454 id: root
455 objectName: 'notebooksPage'
456
457- signal openNotebook(string title, string notebookGuid)
458+ property bool narrowMode
459+
460+ signal openNotebook(string title, string notebookGuid, bool narrowMode)
461
462 onActiveChanged: {
463 if (active) {
464@@ -135,7 +137,7 @@
465 delegate: NotebooksDelegate {
466 onClicked: {
467 print("selected notebook:", model.guid)
468- root.openNotebook(name, model.guid)
469+ root.openNotebook(name, model.guid, narrowMode)
470 }
471 }
472
473
474=== modified file 'src/app/qml/ui/NotesPage.qml'
475--- src/app/qml/ui/NotesPage.qml 2014-08-14 17:17:05 +0000
476+++ src/app/qml/ui/NotesPage.qml 2014-09-03 16:57:24 +0000
477@@ -23,13 +23,24 @@
478 import Evernote 0.1
479 import "../components"
480
481-Page {
482+PageWithBottomEdge {
483 id: root
484
485 property var selectedNote: null
486+ property bool narrowMode
487
488 property alias filter: notes.filterNotebookGuid
489
490+ // We enable bottomEdge only in narrowMode.
491+ // To avoid flashing when a notebook is loaded, we wait to have all notes
492+ // loaded, but only in notebook view (when a filter is set), not in notes
493+ // page, because there isn't he flashing.
494+ bottomEdgeLabelVisible: narrowMode && (!notes.filterNotebookGuid || !notes.loading)
495+ bottomEdgeTitle: i18n.tr("Add note")
496+ bottomEdgePageComponent: EditNotePage {
497+ isBottomEdge: true;
498+ }
499+
500 signal openSearch()
501 signal editNote(var note)
502
503@@ -42,11 +53,12 @@
504 tools: ToolbarItems {
505 ToolbarButton {
506 action: Action {
507+ visible: !narrowMode
508 text: i18n.tr("Add note")
509 iconName: "add"
510 onTriggered: {
511 NotesStore.createNote(i18n.tr("Untitled"), filter);
512- }
513+ }
514 }
515 }
516
517@@ -118,7 +130,7 @@
518 }
519 }
520 }
521- }
522+ }
523
524 Notes {
525 id: notes

Subscribers

People subscribed via source and target branches