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
1=== modified file 'EventBubble.qml'
2--- EventBubble.qml 2014-12-18 14:27:22 +0000
3+++ EventBubble.qml 2015-03-05 12:28:58 +0000
4@@ -33,6 +33,8 @@
5 property int depthInRow: 0;
6 property int sizeOfRow:0
7
8+ property bool isLiveEditing: false
9+
10 property Flickable flickable;
11
12 readonly property int minimumHeight: type == wideType
13@@ -46,7 +48,7 @@
14 Rectangle{
15 id: bg
16 anchors.fill: parent
17- border.color: "white"
18+ border.color: isLiveEditing ? "red" : "white"
19 }
20
21 function resize() {
22@@ -212,10 +214,28 @@
23 }
24 }
25
26+ Drag.active: dragArea.drag.active
27+
28 MouseArea {
29+ id: dragArea
30 anchors.fill: parent
31+ drag.target: isLiveEditing ? infoBubble : null
32+ drag.axis: Drag.YAxis
33+ drag.minimumY: flickable.y
34+ drag.maximumY: flickable.contentHeight - infoBubble.height
35+ onReleased: parent.Drag.drop()
36 onClicked: {
37- infoBubble.clicked(event);
38+ if( isLiveEditing ) {
39+ isLiveEditing = false;
40+ infoBubble.z -= 1;
41+ } else {
42+ infoBubble.clicked(event);
43+ }
44+ }
45+
46+ onPressAndHold: {
47+ isLiveEditing = true;
48+ infoBubble.z += 1;
49 }
50 }
51 }
52
53=== modified file 'NewEvent.qml'
54--- NewEvent.qml 2014-11-27 17:46:47 +0000
55+++ NewEvent.qml 2015-03-05 12:28:58 +0000
56@@ -109,7 +109,7 @@
57 event = Qt.createQmlObject("import QtOrganizer 5.0; Event { }", Qt.application,"NewEvent.qml");
58 //Create fresh Recurrence Object.
59 rule = Qt.createQmlObject("import QtOrganizer 5.0; RecurrenceRule {}", event.recurrence,"EventRepetition.qml");
60- selectCalendar(model.defaultCollection().collectionId);
61+ selectCalendar(model.defaultCollection().collectionId);
62 }
63
64 //Editing Event
65@@ -212,7 +212,7 @@
66 event.setDetail(audibleReminder);
67 }
68 event.collectionId = calendarsOption.model[calendarsOption.selectedIndex].collectionId;
69- model.saveItem(event);
70+ model.saveItem(event);
71 pageStack.pop();
72 root.eventAdded(event);
73 }
74
75=== modified file 'TimeLineBase.qml'
76--- TimeLineBase.qml 2014-11-04 17:30:15 +0000
77+++ TimeLineBase.qml 2015-03-05 12:28:58 +0000
78@@ -17,6 +17,8 @@
79 */
80 import QtQuick 2.3
81 import Ubuntu.Components 1.1
82+import QtOrganizer 5.0
83+
84 import "dateExt.js" as DateExt
85
86 Item {
87@@ -29,13 +31,6 @@
88
89 Component.onCompleted: {
90 bubbleOverLay.createEvents();
91- model.addModelChangeListener(destroyAllChildren);
92- model.addModelChangeListener(createEvents);
93- }
94-
95- Component.onDestruction: {
96- model.removeModelChangeListener(destroyAllChildren);
97- model.removeModelChangeListener(createEvents);
98 }
99
100 MouseArea {
101@@ -45,7 +40,8 @@
102 var selectedDate = new Date(day);
103 var hour = parseInt(mouseY / hourHeight);
104 selectedDate.setHours(hour)
105- pageStack.push(Qt.resolvedUrl("NewEvent.qml"), {"date":selectedDate, "model":eventModel});
106+ //pageStack.push(Qt.resolvedUrl("NewEvent.qml"), {"date":selectedDate, "model":eventModel});
107+ createOrganizerEvent(selectedDate);
108 }
109
110 onPressed: {
111@@ -56,6 +52,28 @@
112 }
113 }
114
115+ function getTimeFromYPos(y, day) {
116+ var date = new Date(day);
117+ var time = y / hourHeight;
118+ var minutes = time % 1 ;
119+ var hour = time - minutes;
120+ minutes = parseInt(60 * minutes);
121+ minutes = Math.floor(minutes/15) * 15;
122+ date.setHours(hour);
123+ date.setMinutes(minutes);
124+ return date;
125+ }
126+
127+ function createOrganizerEvent( startDate ) {
128+ var event = Qt.createQmlObject("import QtOrganizer 5.0; Event {}", Qt.application,"TimeLineBase.qml");
129+ event.collectionId = (model.defaultCollection().collectionId);
130+ var endDate = new Date( startDate.getTime() + 3600000 );
131+ event.startDateTime = startDate;
132+ event.endDateTime = endDate;
133+ event.displayLabel = i18n.tr("Untitled");
134+ model.saveItem(event);
135+ }
136+
137 TimeSeparator {
138 id: separator
139 objectName: "separator"
140@@ -84,7 +102,7 @@
141 }
142 }
143
144- function layoutEvents(array, depth) {
145+ function layoutEvents(array, depth) {
146 for(var i=0; i < array.length ; ++i) {
147 var schedule = array[i];
148 var event = intern.eventMap[schedule.id];
149@@ -93,7 +111,7 @@
150 }
151
152 function createEvents() {
153- if(!bubbleOverLay || bubbleOverLay == undefined || model === undefined) {
154+ if(!bubbleOverLay || bubbleOverLay == undefined || model === undefined || model === null) {
155 return;
156 }
157
158
159=== modified file 'TimeLineBaseComponent.qml'
160--- TimeLineBaseComponent.qml 2015-02-26 16:44:43 +0000
161+++ TimeLineBaseComponent.qml 2015-03-05 12:28:58 +0000
162@@ -41,6 +41,8 @@
163 //visible hour
164 property int scrollHour;
165
166+ property EventListModel mainModel;
167+
168 signal dateSelected(var date);
169
170 function scrollToCurrentTime() {
171@@ -98,17 +100,28 @@
172 }
173 }
174
175- EventListModel {
176- id: mainModel
177- startPeriod: startDay.midnight();
178- endPeriod: type == ViewType.ViewTypeWeek ? startPeriod.addDays(7).endOfDay(): startPeriod.endOfDay()
179- filter: eventModel.filter
180+ Timer{
181+ interval: 200; running: true; repeat: false
182+ onTriggered: {
183+ mainModel = modelComponent.createObject();
184+ activityLoader.running = Qt.binding( function (){ return mainModel.isLoading;});
185+ }
186+ }
187+
188+ Component {
189+ id: modelComponent
190+ EventListModel {
191+ id: mainModel
192+ startPeriod: startDay.midnight();
193+ endPeriod: type == ViewType.ViewTypeWeek ? startPeriod.addDays(7).endOfDay(): startPeriod.endOfDay()
194+ filter: eventModel.filter
195+ }
196 }
197
198 ActivityIndicator {
199+ id: activityLoader
200 visible: running
201 objectName : "activityIndicator"
202- running: mainModel.isLoading
203 anchors.centerIn: parent
204 z:2
205 }
206@@ -194,13 +207,62 @@
207 day: startDay.addDays(index)
208 model: mainModel
209
210- Component.onCompleted: {
211- model.addModelChangeListener(destroyAllChildren);
212- model.addModelChangeListener(createEvents);
213+ Connections{
214+ target: mainModel
215+
216+ onModelChanged: {
217+ createEvents();
218+ }
219 }
220- Component.onDestruction: {
221- model.removeModelChangeListener(destroyAllChildren);
222- model.removeModelChangeListener(createEvents);
223+
224+ DropArea {
225+ id: dropArea
226+ objectName: "mouseArea"
227+ anchors.fill: parent
228+
229+ function modifyEventForDrag(drag) {
230+ var event = drag.source.event;
231+ var diff = event.endDateTime.getTime() - event.startDateTime.getTime();
232+
233+ var startDate = getTimeFromYPos(drag.y, day);
234+ var endDate = new Date( startDate.getTime() + diff );
235+
236+ event.startDateTime = startDate;
237+ event.endDateTime = endDate;
238+
239+ return event;
240+ }
241+
242+ onDropped: {
243+ var event = dropArea.modifyEventForDrag(drop);
244+ model.saveItem(event);
245+ }
246+
247+ onPositionChanged: {
248+ dropArea.modifyEventForDrag(drag)
249+ var eventBubble = drag.source;
250+ eventBubble.assingnBgColor();
251+ eventBubble.setDetails();
252+
253+ if( eventBubble.y + eventBubble.height + units.gu(8) > timeLineView.contentY + timeLineView.height ) {
254+ var diff = Math.abs((eventBubble.y + eventBubble.height + units.gu(8)) -
255+ (timeLineView.height + timeLineView.contentY));
256+ timeLineView.contentY += diff
257+
258+ if(timeLineView.contentY >= timeLineView.contentHeight - timeLineView.height) {
259+ timeLineView.contentY = timeLineView.contentHeight - timeLineView.height
260+ }
261+ }
262+
263+ if(eventBubble.y - units.gu(8) < timeLineView.contentY ) {
264+ var diff = Math.abs((eventBubble.y - units.gu(8)) - timeLineView.contentY);
265+ timeLineView.contentY -= diff
266+
267+ if(timeLineView.contentY <= 0) {
268+ timeLineView.contentY = 0;
269+ }
270+ }
271+ }
272 }
273
274 Loader{
275
276=== modified file 'TimeLineHeader.qml'
277--- TimeLineHeader.qml 2015-02-26 16:44:43 +0000
278+++ TimeLineHeader.qml 2015-03-05 12:28:58 +0000
279@@ -106,17 +106,18 @@
280 SimpleDivider{}
281
282 AllDayEventComponent {
283+ id: dayAllDayComp
284 type: ViewType.ViewTypeDay
285 startDay: headerRoot.startDay
286 model: mainModel
287 width: parent.width
288 height: units.gu(5)
289
290- Component.onCompleted: {
291- mainModel.addModelChangeListener(createAllDayEvents);
292- }
293- Component.onDestruction: {
294- mainModel.removeModelChangeListener(createAllDayEvents);
295+ Connections{
296+ target: mainModel
297+ onModelChanged : {
298+ dayAllDayComp.createAllDayEvents();
299+ }
300 }
301 }
302 }
303@@ -158,17 +159,18 @@
304 SimpleDivider{}
305
306 AllDayEventComponent {
307+ id: weekAllDayComp
308 type: ViewType.ViewTypeWeek
309 startDay: headerRoot.startDay
310 width: parent.width
311 height: units.gu(5)
312 model: mainModel
313
314- Component.onCompleted: {
315- mainModel.addModelChangeListener(createAllDayEvents);
316- }
317- Component.onDestruction: {
318- mainModel.removeModelChangeListener(createAllDayEvents);
319+ Connections{
320+ target: mainModel
321+ onModelChanged : {
322+ weekAllDayComp.createAllDayEvents();
323+ }
324 }
325 }
326 }

Subscribers

People subscribed via source and target branches

to status/vote changes: