Merge lp:~pkunal-parmar/ubuntu-calendar-app/LiveEventModification into lp:ubuntu-calendar-app

Proposed by Kunal Parmar
Status: Merged
Approved by: Alan Pope 🍺🐧🐱 πŸ¦„
Approved revision: 580
Merged at revision: 600
Proposed branch: lp:~pkunal-parmar/ubuntu-calendar-app/LiveEventModification
Merge into: lp:ubuntu-calendar-app
Diff against target: 326 lines (+138/-36)
5 files modified
EventBubble.qml (+22/-2)
NewEvent.qml (+2/-2)
TimeLineBase.qml (+28/-10)
TimeLineBaseComponent.qml (+74/-12)
TimeLineHeader.qml (+12/-10)
To merge this branch: bzr merge lp:~pkunal-parmar/ubuntu-calendar-app/LiveEventModification
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Alan Pope 🍺🐧🐱 πŸ¦„ (community) Approve
Review via email: mp+247711@code.launchpad.net

Commit message

User can create event by long press on TimeLine view,
Also event can be reschedules by darging it around.

Description of the change

As per new design[1] on page 4

User can create event by long press on TimeLine view,
Also event can be reschedules by darging it around.

Works like showen in below link,
http://youtu.be/qr32ch65DSQ

[1] https://docs.google.com/presentation/d/14NIPecPFKb_8Ad3O4suEGJqVOw9bC4n0s63uWalbZ98/edit#slide=id.g4160a5a3b_09

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: Approve (continuous-integration)
Revision history for this message
Mihir Soni (mihirsoni) wrote :

Wow !!!
This is great !! code wise it looks good I'll do more testing.

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Tested out on krillin and it works rather well.

The only issue I have is that it can be hard to get it to perfectly line up with hours. On a small screen it's easy to have meetings which look like they're lined up to an hour or half hour interval, but once you tap again on the meeting you find it's actually at 55, 05, 25 or 35 minutes past the hour. It's pretty easy to correct, so not a massive problem.

review: Approve
Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> Tested out on krillin and it works rather well.
>
> The only issue I have is that it can be hard to get it to perfectly line up
> with hours. On a small screen it's easy to have meetings which look like
> they're lined up to an hour or half hour interval, but once you tap again on
> the meeting you find it's actually at 55, 05, 25 or 35 minutes past the hour.
> It's pretty easy to correct, so not a massive problem.

Hi Alan, Thanks for testing it out,

I also thought the same, so as of when user create event by press and hold, event snaps to Hour.

But when use drag event to reschedule it, snap time interval is 5 minutes, I can easily make to 10 or 15 or whatever its good for user experience.

Thanks,

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

I think we should snap to 15.

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> I think we should snap to 15.

Done. Changed snap to 15 min.

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
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

seems like some issue with jenkins, re-approving

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 :

I tried re-running and it failed again. Asking ci people for help.

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

13:28 < vila> ha, the failing test seems to be:
13:28 < vila> 12:16:42.866 INFO _logging:41 - Starting test
              calendar_app.tests.test_weekview.TestWeekView.test_show_next_weeks
13:28 < vila> and it loops until 12:30:02.820 DEBUG _X11:309 - Releasing mouse button 1

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

I've opened https://bugs.launchpad.net/ubuntu-calendar-app/+bug/1423582 for the infinite loop issue.

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
Nicholas Skaggs (nskaggs) wrote :

Kunal, I have a working version in my branch; lp:~nskaggs/ubuntu-calendar-app/fix-infloop-ap

It needs flake8 fixes however.

Revision history for this message
Kunal Parmar (pkunal-parmar) wrote :

> Kunal, I have a working version in my branch; lp:~nskaggs/ubuntu-calendar-app
> /fix-infloop-ap
>
>
> It needs flake8 fixes however.

ok, I will merge and see how it goes

Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Has any progress made on this? We really need this merge landing before we can update calendar in the store.

Revision history for this message
Nicholas Skaggs (nskaggs) wrote :
580. By Kunal Parmar

merge from trunk

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'EventBubble.qml'
--- EventBubble.qml 2014-12-18 14:27:22 +0000
+++ EventBubble.qml 2015-03-05 12:28:58 +0000
@@ -33,6 +33,8 @@
33 property int depthInRow: 0;33 property int depthInRow: 0;
34 property int sizeOfRow:034 property int sizeOfRow:0
3535
36 property bool isLiveEditing: false
37
36 property Flickable flickable;38 property Flickable flickable;
3739
38 readonly property int minimumHeight: type == wideType40 readonly property int minimumHeight: type == wideType
@@ -46,7 +48,7 @@
46 Rectangle{48 Rectangle{
47 id: bg49 id: bg
48 anchors.fill: parent50 anchors.fill: parent
49 border.color: "white"51 border.color: isLiveEditing ? "red" : "white"
50 }52 }
5153
52 function resize() {54 function resize() {
@@ -212,10 +214,28 @@
212 }214 }
213 }215 }
214216
217 Drag.active: dragArea.drag.active
218
215 MouseArea {219 MouseArea {
220 id: dragArea
216 anchors.fill: parent221 anchors.fill: parent
222 drag.target: isLiveEditing ? infoBubble : null
223 drag.axis: Drag.YAxis
224 drag.minimumY: flickable.y
225 drag.maximumY: flickable.contentHeight - infoBubble.height
226 onReleased: parent.Drag.drop()
217 onClicked: {227 onClicked: {
218 infoBubble.clicked(event);228 if( isLiveEditing ) {
229 isLiveEditing = false;
230 infoBubble.z -= 1;
231 } else {
232 infoBubble.clicked(event);
233 }
234 }
235
236 onPressAndHold: {
237 isLiveEditing = true;
238 infoBubble.z += 1;
219 }239 }
220 }240 }
221}241}
222242
=== modified file 'NewEvent.qml'
--- NewEvent.qml 2014-11-27 17:46:47 +0000
+++ NewEvent.qml 2015-03-05 12:28:58 +0000
@@ -109,7 +109,7 @@
109 event = Qt.createQmlObject("import QtOrganizer 5.0; Event { }", Qt.application,"NewEvent.qml");109 event = Qt.createQmlObject("import QtOrganizer 5.0; Event { }", Qt.application,"NewEvent.qml");
110 //Create fresh Recurrence Object.110 //Create fresh Recurrence Object.
111 rule = Qt.createQmlObject("import QtOrganizer 5.0; RecurrenceRule {}", event.recurrence,"EventRepetition.qml");111 rule = Qt.createQmlObject("import QtOrganizer 5.0; RecurrenceRule {}", event.recurrence,"EventRepetition.qml");
112 selectCalendar(model.defaultCollection().collectionId); 112 selectCalendar(model.defaultCollection().collectionId);
113 }113 }
114114
115 //Editing Event115 //Editing Event
@@ -212,7 +212,7 @@
212 event.setDetail(audibleReminder);212 event.setDetail(audibleReminder);
213 }213 }
214 event.collectionId = calendarsOption.model[calendarsOption.selectedIndex].collectionId;214 event.collectionId = calendarsOption.model[calendarsOption.selectedIndex].collectionId;
215 model.saveItem(event); 215 model.saveItem(event);
216 pageStack.pop();216 pageStack.pop();
217 root.eventAdded(event);217 root.eventAdded(event);
218 }218 }
219219
=== modified file 'TimeLineBase.qml'
--- TimeLineBase.qml 2014-11-04 17:30:15 +0000
+++ TimeLineBase.qml 2015-03-05 12:28:58 +0000
@@ -17,6 +17,8 @@
17 */17 */
18import QtQuick 2.318import QtQuick 2.3
19import Ubuntu.Components 1.119import Ubuntu.Components 1.1
20import QtOrganizer 5.0
21
20import "dateExt.js" as DateExt22import "dateExt.js" as DateExt
2123
22Item {24Item {
@@ -29,13 +31,6 @@
2931
30 Component.onCompleted: {32 Component.onCompleted: {
31 bubbleOverLay.createEvents();33 bubbleOverLay.createEvents();
32 model.addModelChangeListener(destroyAllChildren);
33 model.addModelChangeListener(createEvents);
34 }
35
36 Component.onDestruction: {
37 model.removeModelChangeListener(destroyAllChildren);
38 model.removeModelChangeListener(createEvents);
39 }34 }
4035
41 MouseArea {36 MouseArea {
@@ -45,7 +40,8 @@
45 var selectedDate = new Date(day);40 var selectedDate = new Date(day);
46 var hour = parseInt(mouseY / hourHeight);41 var hour = parseInt(mouseY / hourHeight);
47 selectedDate.setHours(hour)42 selectedDate.setHours(hour)
48 pageStack.push(Qt.resolvedUrl("NewEvent.qml"), {"date":selectedDate, "model":eventModel});43 //pageStack.push(Qt.resolvedUrl("NewEvent.qml"), {"date":selectedDate, "model":eventModel});
44 createOrganizerEvent(selectedDate);
49 }45 }
5046
51 onPressed: {47 onPressed: {
@@ -56,6 +52,28 @@
56 }52 }
57 }53 }
5854
55 function getTimeFromYPos(y, day) {
56 var date = new Date(day);
57 var time = y / hourHeight;
58 var minutes = time % 1 ;
59 var hour = time - minutes;
60 minutes = parseInt(60 * minutes);
61 minutes = Math.floor(minutes/15) * 15;
62 date.setHours(hour);
63 date.setMinutes(minutes);
64 return date;
65 }
66
67 function createOrganizerEvent( startDate ) {
68 var event = Qt.createQmlObject("import QtOrganizer 5.0; Event {}", Qt.application,"TimeLineBase.qml");
69 event.collectionId = (model.defaultCollection().collectionId);
70 var endDate = new Date( startDate.getTime() + 3600000 );
71 event.startDateTime = startDate;
72 event.endDateTime = endDate;
73 event.displayLabel = i18n.tr("Untitled");
74 model.saveItem(event);
75 }
76
59 TimeSeparator {77 TimeSeparator {
60 id: separator78 id: separator
61 objectName: "separator"79 objectName: "separator"
@@ -84,7 +102,7 @@
84 }102 }
85 }103 }
86104
87 function layoutEvents(array, depth) { 105 function layoutEvents(array, depth) {
88 for(var i=0; i < array.length ; ++i) {106 for(var i=0; i < array.length ; ++i) {
89 var schedule = array[i];107 var schedule = array[i];
90 var event = intern.eventMap[schedule.id];108 var event = intern.eventMap[schedule.id];
@@ -93,7 +111,7 @@
93 }111 }
94112
95 function createEvents() {113 function createEvents() {
96 if(!bubbleOverLay || bubbleOverLay == undefined || model === undefined) {114 if(!bubbleOverLay || bubbleOverLay == undefined || model === undefined || model === null) {
97 return;115 return;
98 }116 }
99117
100118
=== modified file 'TimeLineBaseComponent.qml'
--- TimeLineBaseComponent.qml 2015-02-26 16:44:43 +0000
+++ TimeLineBaseComponent.qml 2015-03-05 12:28:58 +0000
@@ -41,6 +41,8 @@
41 //visible hour41 //visible hour
42 property int scrollHour;42 property int scrollHour;
4343
44 property EventListModel mainModel;
45
44 signal dateSelected(var date);46 signal dateSelected(var date);
4547
46 function scrollToCurrentTime() {48 function scrollToCurrentTime() {
@@ -98,17 +100,28 @@
98 }100 }
99 }101 }
100102
101 EventListModel {103 Timer{
102 id: mainModel104 interval: 200; running: true; repeat: false
103 startPeriod: startDay.midnight();105 onTriggered: {
104 endPeriod: type == ViewType.ViewTypeWeek ? startPeriod.addDays(7).endOfDay(): startPeriod.endOfDay()106 mainModel = modelComponent.createObject();
105 filter: eventModel.filter107 activityLoader.running = Qt.binding( function (){ return mainModel.isLoading;});
108 }
109 }
110
111 Component {
112 id: modelComponent
113 EventListModel {
114 id: mainModel
115 startPeriod: startDay.midnight();
116 endPeriod: type == ViewType.ViewTypeWeek ? startPeriod.addDays(7).endOfDay(): startPeriod.endOfDay()
117 filter: eventModel.filter
118 }
106 }119 }
107120
108 ActivityIndicator {121 ActivityIndicator {
122 id: activityLoader
109 visible: running123 visible: running
110 objectName : "activityIndicator"124 objectName : "activityIndicator"
111 running: mainModel.isLoading
112 anchors.centerIn: parent125 anchors.centerIn: parent
113 z:2126 z:2
114 }127 }
@@ -194,13 +207,62 @@
194 day: startDay.addDays(index)207 day: startDay.addDays(index)
195 model: mainModel208 model: mainModel
196209
197 Component.onCompleted: {210 Connections{
198 model.addModelChangeListener(destroyAllChildren);211 target: mainModel
199 model.addModelChangeListener(createEvents);212
213 onModelChanged: {
214 createEvents();
215 }
200 }216 }
201 Component.onDestruction: {217
202 model.removeModelChangeListener(destroyAllChildren);218 DropArea {
203 model.removeModelChangeListener(createEvents);219 id: dropArea
220 objectName: "mouseArea"
221 anchors.fill: parent
222
223 function modifyEventForDrag(drag) {
224 var event = drag.source.event;
225 var diff = event.endDateTime.getTime() - event.startDateTime.getTime();
226
227 var startDate = getTimeFromYPos(drag.y, day);
228 var endDate = new Date( startDate.getTime() + diff );
229
230 event.startDateTime = startDate;
231 event.endDateTime = endDate;
232
233 return event;
234 }
235
236 onDropped: {
237 var event = dropArea.modifyEventForDrag(drop);
238 model.saveItem(event);
239 }
240
241 onPositionChanged: {
242 dropArea.modifyEventForDrag(drag)
243 var eventBubble = drag.source;
244 eventBubble.assingnBgColor();
245 eventBubble.setDetails();
246
247 if( eventBubble.y + eventBubble.height + units.gu(8) > timeLineView.contentY + timeLineView.height ) {
248 var diff = Math.abs((eventBubble.y + eventBubble.height + units.gu(8)) -
249 (timeLineView.height + timeLineView.contentY));
250 timeLineView.contentY += diff
251
252 if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) {
253 timeLineView.contentY = timeLineView.contentHeight - timeLineView.height
254 }
255 }
256
257 if(eventBubble.y - units.gu(8) < timeLineView.contentY ) {
258 var diff = Math.abs((eventBubble.y - units.gu(8)) - timeLineView.contentY);
259 timeLineView.contentY -= diff
260
261 if(timeLineView.contentY <= 0) {
262 timeLineView.contentY = 0;
263 }
264 }
265 }
204 }266 }
205267
206 Loader{268 Loader{
207269
=== modified file 'TimeLineHeader.qml'
--- TimeLineHeader.qml 2015-02-26 16:44:43 +0000
+++ TimeLineHeader.qml 2015-03-05 12:28:58 +0000
@@ -106,17 +106,18 @@
106 SimpleDivider{}106 SimpleDivider{}
107107
108 AllDayEventComponent {108 AllDayEventComponent {
109 id: dayAllDayComp
109 type: ViewType.ViewTypeDay110 type: ViewType.ViewTypeDay
110 startDay: headerRoot.startDay111 startDay: headerRoot.startDay
111 model: mainModel112 model: mainModel
112 width: parent.width113 width: parent.width
113 height: units.gu(5)114 height: units.gu(5)
114115
115 Component.onCompleted: {116 Connections{
116 mainModel.addModelChangeListener(createAllDayEvents);117 target: mainModel
117 }118 onModelChanged : {
118 Component.onDestruction: {119 dayAllDayComp.createAllDayEvents();
119 mainModel.removeModelChangeListener(createAllDayEvents);120 }
120 }121 }
121 }122 }
122 }123 }
@@ -158,17 +159,18 @@
158 SimpleDivider{}159 SimpleDivider{}
159160
160 AllDayEventComponent {161 AllDayEventComponent {
162 id: weekAllDayComp
161 type: ViewType.ViewTypeWeek163 type: ViewType.ViewTypeWeek
162 startDay: headerRoot.startDay164 startDay: headerRoot.startDay
163 width: parent.width165 width: parent.width
164 height: units.gu(5)166 height: units.gu(5)
165 model: mainModel167 model: mainModel
166168
167 Component.onCompleted: {169 Connections{
168 mainModel.addModelChangeListener(createAllDayEvents);170 target: mainModel
169 }171 onModelChanged : {
170 Component.onDestruction: {172 weekAllDayComp.createAllDayEvents();
171 mainModel.removeModelChangeListener(createAllDayEvents);173 }
172 }174 }
173 }175 }
174 }176 }

Subscribers

People subscribed via source and target branches

to status/vote changes: