Merge lp:~martin-borho/ubuntu-weather-app/reboot-real-weather-data into lp:ubuntu-weather-app
- reboot-real-weather-data
- Merge into reboot
Status: | Superseded |
---|---|
Proposed branch: | lp:~martin-borho/ubuntu-weather-app/reboot-real-weather-data |
Merge into: | lp:ubuntu-weather-app |
Diff against target: |
323 lines (+169/-47) 4 files modified
app/components/HomeGraphic.qml (+3/-1) app/ubuntu-weather-app.qml (+84/-11) app/ui/HomePage.qml (+81/-30) po/com.ubuntu.weather.pot (+1/-5) |
To merge this branch: | bzr merge lp:~martin-borho/ubuntu-weather-app/reboot-real-weather-data |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Weather Developers | Pending | ||
Review via email: mp+249001@code.launchpad.net |
This proposal supersedes a proposal from 2015-02-07.
Commit message
Description of the change
Filled static prototype components with real weather data.
- 7. By Martin Borho
-
Filled static prototype components with real weather data.
Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.
- 8. By Andrew Hayzen
-
* Add bottom edge page listing the locations.
Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.
- 9. By Andrew Hayzen
-
* Use Settings API, with migration of data - deletion of old data not enabled yet.
Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.
- 10. By Andrew Hayzen
-
* Basic implementation of settings for Units, DataProvider and RefreshInterval. Fixes: https:/
/bugs.launchpad .net/bugs/ 1420609. Approved by Victor Thompson, Ubuntu Phone Apps Jenkins Bot.
- 11. By Martin Borho
-
Put locations in a Listview and all in a Flickable
- 12. By Martin Borho
-
removed snapMode for LocatioonPanes due to error
- 13. By Martin Borho
-
minor comments changes
- 14. By Martin Borho
-
added current property to settings
- 15. By Martin Borho
-
removed highlightMoveDu
ration - 16. By Martin Borho
-
currentIndex gets set from settings.current
- 17. By Martin Borho
-
formatting
- 18. By Martin Borho
-
pushing HomePage.qml directly to pagestack
Unmerged revisions
Preview Diff
1 | === modified file 'app/components/HomeGraphic.qml' | |||
2 | --- app/components/HomeGraphic.qml 2015-02-03 21:26:09 +0000 | |||
3 | +++ app/components/HomeGraphic.qml 2015-02-07 17:40:43 +0000 | |||
4 | @@ -23,6 +23,8 @@ | |||
5 | 23 | height: units.gu(32) | 23 | height: units.gu(32) |
6 | 24 | width: parent.width | 24 | width: parent.width |
7 | 25 | 25 | ||
8 | 26 | property alias icon: iconLabel.text | ||
9 | 27 | |||
10 | 26 | // TODO: will be on 'rails' (horizontal listview?) to reveal hourly forecast | 28 | // TODO: will be on 'rails' (horizontal listview?) to reveal hourly forecast |
11 | 27 | Image { | 29 | Image { |
12 | 28 | anchors { | 30 | anchors { |
13 | @@ -36,10 +38,10 @@ | |||
14 | 36 | color: "#F00" | 38 | color: "#F00" |
15 | 37 | 39 | ||
16 | 38 | Label { | 40 | Label { |
17 | 41 | id: iconLabel | ||
18 | 39 | anchors { | 42 | anchors { |
19 | 40 | centerIn: parent | 43 | centerIn: parent |
20 | 41 | } | 44 | } |
21 | 42 | text: "IMAGE HERE!" | ||
22 | 43 | } | 45 | } |
23 | 44 | } | 46 | } |
24 | 45 | } | 47 | } |
25 | 46 | 48 | ||
26 | === modified file 'app/ubuntu-weather-app.qml' | |||
27 | --- app/ubuntu-weather-app.qml 2015-02-06 15:35:49 +0000 | |||
28 | +++ app/ubuntu-weather-app.qml 2015-02-07 17:40:43 +0000 | |||
29 | @@ -41,20 +41,64 @@ | |||
30 | 41 | useDeprecatedToolbar: false | 41 | useDeprecatedToolbar: false |
31 | 42 | anchorToKeyboard: true | 42 | anchorToKeyboard: true |
32 | 43 | 43 | ||
33 | 44 | /* | ||
34 | 45 | List of locations and their data, accessible through index | ||
35 | 46 | */ | ||
36 | 47 | property var locationsList: [] | ||
37 | 48 | |||
38 | 49 | /* | ||
39 | 50 | Index of Location before a refresh, to go back after | ||
40 | 51 | */ | ||
41 | 52 | property int indexAtRefresh: -1 | ||
42 | 53 | |||
43 | 54 | /* | ||
44 | 55 | Set default values for settings here | ||
45 | 56 | */ | ||
46 | 57 | property var settings: { | ||
47 | 58 | "units": Qt.locale().measurementSystem === Locale.MetricSystem ? "metric" : "imperial", | ||
48 | 59 | "wind_units": Qt.locale().measurementSystem === Locale.MetricSystem ? "kmh" : "mph", | ||
49 | 60 | "precip_units": Qt.locale().measurementSystem === Locale.MetricSystem ? "mm" : "in", | ||
50 | 61 | "service": "weatherchannel" | ||
51 | 62 | } | ||
52 | 63 | |||
53 | 64 | /* | ||
54 | 65 | Scale symbols and labels. | ||
55 | 66 | */ | ||
56 | 67 | property string tempScale | ||
57 | 68 | property string speedScale | ||
58 | 69 | property string precipScale | ||
59 | 70 | property string tempUnits | ||
60 | 71 | property string windUnits | ||
61 | 72 | property string precipUnits | ||
62 | 73 | |||
63 | 74 | /* | ||
64 | 75 | After reading the settings from storage and updating the default | ||
65 | 76 | settings with the user selected ones, (re)load pages! | ||
66 | 77 | */ | ||
67 | 44 | Component.onCompleted: { | 78 | Component.onCompleted: { |
78 | 45 | storage.getLocations(function(locations) { | 79 | storage.getSettings(function(storedSettings) { |
79 | 46 | WeatherApi.sendRequest({ | 80 | for(var settingName in storedSettings) { |
80 | 47 | action: "updateData", | 81 | settings[settingName] = storedSettings[settingName]; |
81 | 48 | params: { | 82 | } |
82 | 49 | locations:locations, | 83 | setScalesAndLabels(); |
83 | 50 | force:false, | 84 | refreshData(); |
74 | 51 | service: "weatherchannel", | ||
75 | 52 | api_key: Key.twcKey | ||
76 | 53 | } | ||
77 | 54 | }, responseDataHandler) | ||
84 | 55 | }) | 85 | }) |
85 | 56 | } | 86 | } |
86 | 57 | 87 | ||
87 | 88 | function setScalesAndLabels() { | ||
88 | 89 | // set scales | ||
89 | 90 | tempScale = String("°") + ((settings["units"] === "imperial") ? "F" : "C") | ||
90 | 91 | speedScale = ((settings["wind_units"] === "mph") ? "mph" : "km/h") | ||
91 | 92 | precipScale = ((settings["precip_units"] === "in") ? "in" : "mm") | ||
92 | 93 | tempUnits = ((settings["units"] === 'imperial') ? 'imperial' : 'metric') | ||
93 | 94 | windUnits = ((settings["wind_units"] === 'mph') ? 'imperial' : 'metric') | ||
94 | 95 | precipUnits = ((settings["precip_units"] === 'in') ? 'imperial' : 'metric') | ||
95 | 96 | } | ||
96 | 97 | |||
97 | 98 | /* | ||
98 | 99 | Handle response data from data backend. Checks if a location | ||
99 | 100 | was updated and has to be stored again. | ||
100 | 101 | */ | ||
101 | 58 | function responseDataHandler(messageObject) { | 102 | function responseDataHandler(messageObject) { |
102 | 59 | if(!messageObject.error) { | 103 | if(!messageObject.error) { |
103 | 60 | if(messageObject.action === "updateData") { | 104 | if(messageObject.action === "updateData") { |
104 | @@ -65,7 +109,7 @@ | |||
105 | 65 | } | 109 | } |
106 | 66 | }); | 110 | }); |
107 | 67 | //print(JSON.stringify(messageObject.result)); | 111 | //print(JSON.stringify(messageObject.result)); |
109 | 68 | //buildTabs(messageObject.result); | 112 | fillPages(messageObject.result); |
110 | 69 | } | 113 | } |
111 | 70 | } else { | 114 | } else { |
112 | 71 | console.log(messageObject.error.msg+" / "+messageObject.error.request.url) | 115 | console.log(messageObject.error.msg+" / "+messageObject.error.request.url) |
113 | @@ -73,6 +117,35 @@ | |||
114 | 73 | } | 117 | } |
115 | 74 | } | 118 | } |
116 | 75 | 119 | ||
117 | 120 | /* Fill the location pages with their data. */ | ||
118 | 121 | function fillPages(locations) { | ||
119 | 122 | locationsList = locations; | ||
120 | 123 | // refactor this when Location are in a ListView! | ||
121 | 124 | homePage.renderData(); | ||
122 | 125 | } | ||
123 | 126 | |||
124 | 127 | /* | ||
125 | 128 | Refresh data, either directly from storage or by checking against | ||
126 | 129 | API instead. | ||
127 | 130 | */ | ||
128 | 131 | function refreshData(from_storage, force_refresh) { | ||
129 | 132 | if(from_storage === true && force_refresh !== true) { | ||
130 | 133 | storage.getLocations(fillPages); | ||
131 | 134 | } else { | ||
132 | 135 | storage.getLocations(function(locations) { | ||
133 | 136 | WeatherApi.sendRequest({ | ||
134 | 137 | action: "updateData", | ||
135 | 138 | params: { | ||
136 | 139 | locations:locations, | ||
137 | 140 | force:force_refresh, | ||
138 | 141 | service:settings["service"], | ||
139 | 142 | api_key: Key.twcKey | ||
140 | 143 | } | ||
141 | 144 | }, responseDataHandler) | ||
142 | 145 | }); | ||
143 | 146 | } | ||
144 | 147 | } | ||
145 | 148 | |||
146 | 76 | Data.Storage { | 149 | Data.Storage { |
147 | 77 | id: storage | 150 | id: storage |
148 | 78 | } | 151 | } |
149 | 79 | 152 | ||
150 | === modified file 'app/ui/HomePage.qml' | |||
151 | --- app/ui/HomePage.qml 2015-02-03 21:26:09 +0000 | |||
152 | +++ app/ui/HomePage.qml 2015-02-07 17:40:43 +0000 | |||
153 | @@ -24,14 +24,85 @@ | |||
154 | 24 | 24 | ||
155 | 25 | Page { | 25 | Page { |
156 | 26 | // Set to null otherwise the header is shown (but blank) over the top of the listview | 26 | // Set to null otherwise the header is shown (but blank) over the top of the listview |
157 | 27 | id: locationPage | ||
158 | 27 | flickable: null | 28 | flickable: null |
159 | 28 | 29 | ||
160 | 30 | /* | ||
161 | 31 | Data properties | ||
162 | 32 | */ | ||
163 | 33 | property string name; | ||
164 | 34 | property string conditionText | ||
165 | 35 | property int currentTemp | ||
166 | 36 | property string todayMaxTemp | ||
167 | 37 | property string todayMinTemp | ||
168 | 38 | property string iconName | ||
169 | 39 | |||
170 | 40 | // TODO map iconnames to source image names | ||
171 | 41 | property var iconMap: { | ||
172 | 42 | "moon": "moon.svg" | ||
173 | 43 | // etc pp | ||
174 | 44 | } | ||
175 | 45 | |||
176 | 46 | /* | ||
177 | 47 | Format date object by given format. | ||
178 | 48 | */ | ||
179 | 49 | function formatTimestamp(dateData, format) { | ||
180 | 50 | var date = new Date(dateData.year, dateData.month, dateData.date, dateData.hours, dateData.minutes) | ||
181 | 51 | return Qt.formatDate(date, i18n.tr(format)) | ||
182 | 52 | } | ||
183 | 53 | |||
184 | 54 | /* | ||
185 | 55 | Extracts values from the location weather data and puts them into the appropriate components | ||
186 | 56 | to display them. | ||
187 | 57 | |||
188 | 58 | Attention: Data access happens through "weatherApp.locationList[]" by index, since complex | ||
189 | 59 | data in models will lead to type problems. | ||
190 | 60 | */ | ||
191 | 61 | function renderData() { | ||
192 | 62 | var index = Math.floor(Math.random()*weatherApp.locationsList.length), // TODO get this value from ListView.currentIndex later! | ||
193 | 63 | data = weatherApp.locationsList[index], | ||
194 | 64 | current = data.data[0].current, | ||
195 | 65 | forecasts = data.data, | ||
196 | 66 | forecastsLength = forecasts.length, | ||
197 | 67 | today = forecasts[0], | ||
198 | 68 | tempUnits = weatherApp.tempUnits, | ||
199 | 69 | tempScale = weatherApp.tempScale; | ||
200 | 70 | |||
201 | 71 | // set general location data | ||
202 | 72 | name = data.location.adminName1; | ||
203 | 73 | |||
204 | 74 | // set current temps and condition | ||
205 | 75 | iconName = (current.icon) ? current.icon : "" | ||
206 | 76 | conditionText = (current.condition.main) ? current.condition.main : current.condition; // difference TWC/OWM | ||
207 | 77 | todayMaxTemp = (today[tempUnits].tempMax) ? Math.round(today[tempUnits].tempMax).toString() + tempScale: ""; | ||
208 | 78 | todayMinTemp = Math.round(today[tempUnits].tempMin.toString()) + tempScale; | ||
209 | 79 | currentTemp = Math.round(current[tempUnits].temp); | ||
210 | 80 | |||
211 | 81 | // reset days list | ||
212 | 82 | mainPageWeekdayListView.model.clear() | ||
213 | 83 | |||
214 | 84 | // set daily forecasts | ||
215 | 85 | if(forecastsLength > 0) { | ||
216 | 86 | for(var x=1;x<forecastsLength;x++) { | ||
217 | 87 | // print(JSON.stringify(forecasts[x][units])) | ||
218 | 88 | var dayData = { | ||
219 | 89 | day: formatTimestamp(forecasts[x].date, 'dddd'), | ||
220 | 90 | low: Math.round(forecasts[x][tempUnits].tempMin).toString() + tempScale, | ||
221 | 91 | high: (forecasts[x][tempUnits].tempMax !== undefined) ? Math.round(forecasts[x][tempUnits].tempMax).toString() + tempScale : "", | ||
222 | 92 | image: (forecasts[x].icon !== undefined && iconMap[forecasts[x].icon] !== undefined) ? iconMap[forecasts[x].icon] + tempScale : "" | ||
223 | 93 | } | ||
224 | 94 | mainPageWeekdayListView.model.append(dayData); | ||
225 | 95 | } | ||
226 | 96 | } | ||
227 | 97 | } | ||
228 | 98 | |||
229 | 29 | ListView { | 99 | ListView { |
230 | 30 | id: mainPageWeekdayListView | 100 | id: mainPageWeekdayListView |
231 | 31 | anchors { | 101 | anchors { |
232 | 32 | fill: parent | 102 | fill: parent |
233 | 33 | margins: units.gu(2) | 103 | margins: units.gu(2) |
234 | 34 | } | 104 | } |
235 | 105 | |||
236 | 35 | header: Column { | 106 | header: Column { |
237 | 36 | anchors { | 107 | anchors { |
238 | 37 | left: parent.left | 108 | left: parent.left |
239 | @@ -40,50 +111,30 @@ | |||
240 | 40 | spacing: units.gu(1) | 111 | spacing: units.gu(1) |
241 | 41 | 112 | ||
242 | 42 | HeaderRow { | 113 | HeaderRow { |
244 | 43 | locationName: "Hackney" // TODO: non static | 114 | locationName: locationPage.name |
245 | 44 | } | 115 | } |
246 | 45 | 116 | ||
247 | 46 | HomeGraphic { | 117 | HomeGraphic { |
249 | 47 | 118 | icon: locationPage.iconName | |
250 | 48 | } | 119 | } |
251 | 49 | 120 | ||
252 | 50 | HomeTempInfo { | 121 | HomeTempInfo { |
257 | 51 | description: i18n.tr("Rainy & windy") // TODO: non static | 122 | description: locationPage.conditionText |
258 | 52 | high: "13°C" | 123 | high: locationPage.todayMaxTemp |
259 | 53 | low: "10°C" | 124 | low: locationPage.todayMinTemp |
260 | 54 | now: "13°" // TODO: non static | 125 | now: locationPage.currentTemp |
261 | 55 | } | 126 | } |
262 | 56 | 127 | ||
263 | 57 | ListItem.ThinDivider { | 128 | ListItem.ThinDivider { |
264 | 58 | 129 | ||
265 | 59 | } | 130 | } |
266 | 60 | } | 131 | } |
289 | 61 | model: ListModel { // TODO: non static | 132 | model: ListModel {} |
290 | 62 | ListElement { | 133 | |
269 | 63 | day: "Saturday" | ||
270 | 64 | low: 12 | ||
271 | 65 | high: 15 | ||
272 | 66 | } | ||
273 | 67 | ListElement { | ||
274 | 68 | day: "Sunday" | ||
275 | 69 | low: 14 | ||
276 | 70 | high: 18 | ||
277 | 71 | } | ||
278 | 72 | ListElement { | ||
279 | 73 | day: "Monday" | ||
280 | 74 | low: 10 | ||
281 | 75 | high: 11 | ||
282 | 76 | } | ||
283 | 77 | ListElement { | ||
284 | 78 | day: "Tuesday" | ||
285 | 79 | low: -7 | ||
286 | 80 | high: 0 | ||
287 | 81 | } | ||
288 | 82 | } | ||
291 | 83 | delegate: DayDelegate { | 134 | delegate: DayDelegate { |
292 | 84 | day: model.day | 135 | day: model.day |
295 | 85 | high: model.high + "°C" // TODO: non static | 136 | high: model.high |
296 | 86 | low: model.low + "°C" | 137 | low: model.low |
297 | 87 | } | 138 | } |
298 | 88 | } | 139 | } |
299 | 89 | } | 140 | } |
300 | 90 | 141 | ||
301 | === modified file 'po/com.ubuntu.weather.pot' | |||
302 | --- po/com.ubuntu.weather.pot 2015-02-03 21:26:09 +0000 | |||
303 | +++ po/com.ubuntu.weather.pot 2015-02-07 17:40:43 +0000 | |||
304 | @@ -8,7 +8,7 @@ | |||
305 | 8 | msgstr "" | 8 | msgstr "" |
306 | 9 | "Project-Id-Version: ubuntu-weather-app\n" | 9 | "Project-Id-Version: ubuntu-weather-app\n" |
307 | 10 | "Report-Msgid-Bugs-To: \n" | 10 | "Report-Msgid-Bugs-To: \n" |
309 | 11 | "POT-Creation-Date: 2015-02-03 21:25+0000\n" | 11 | "POT-Creation-Date: 2015-02-07 18:30+0100\n" |
310 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
311 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
312 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
313 | @@ -21,10 +21,6 @@ | |||
314 | 21 | msgid "Today" | 21 | msgid "Today" |
315 | 22 | msgstr "" | 22 | msgstr "" |
316 | 23 | 23 | ||
317 | 24 | #: ../app/ui/HomePage.qml:51 | ||
318 | 25 | msgid "Rainy & windy" | ||
319 | 26 | msgstr "" | ||
320 | 27 | |||
321 | 28 | #: ubuntu-weather-app.desktop.in.in.h:1 | 24 | #: ubuntu-weather-app.desktop.in.in.h:1 |
322 | 29 | msgid "Weather" | 25 | msgid "Weather" |
323 | 30 | msgstr "" | 26 | msgstr "" |