170.2.7
by Roman Shchekin
List mode now correctly (almost) works on tablets! |
1 |
import QtQuick 2.0 |
2 |
import QtQuick.XmlListModel 2.0 |
|
3 |
||
4 |
import Ubuntu.Components 0.1 |
|
5 |
import Ubuntu.Components.ListItems 0.1 as ListItems |
|
6 |
import Ubuntu.Components.Popups 0.1 |
|
7 |
||
8 |
import "databasemodule_v2.js" as DB |
|
9 |
import "dateutils.js" as DateUtils |
|
10 |
||
11 |
Item { |
|
12 |
id: pageItself
|
|
13 |
||
14 |
property int topicId: 0 |
|
15 |
property var listViewModel: null |
|
16 |
property bool isShorts: topicId == 0 |
|
17 |
||
18 |
property var listTools: listModeTools |
|
19 |
||
20 |
function getListToots() { |
|
21 |
return listModeTools |
|
22 |
}
|
|
23 |
||
24 |
function reload() { |
|
25 |
listViewModel = getModel() |
|
26 |
}
|
|
27 |
||
28 |
function clear() { |
|
29 |
listViewModel = null |
|
30 |
}
|
|
31 |
||
32 |
function showArticle(modelIndex) { |
|
33 |
listArticleView.setFeed(listViewModel, modelIndex) |
|
34 |
}
|
|
35 |
||
36 |
Component { |
|
37 |
id: listModeDelegate
|
|
38 |
||
39 |
Item { |
|
40 |
id: readIndicator
|
|
41 |
||
42 |
width: parent.width |
|
43 |
height: units.gu(14) |
|
44 |
||
45 |
UbuntuShape { |
|
46 |
id: listItem
|
|
47 |
objectName: "feedlistitems" |
|
48 |
||
49 |
color: model.status == "1" ? Qt.rgba(0, 0, 0, 0.7) : Qt.rgba(0, 0, 0, 0.4) |
|
50 |
radius: "medium" |
|
51 |
width: parent.width - units.gu(4) |
|
52 |
height: parent.height - units.gu(2) |
|
53 |
anchors.centerIn: parent |
|
54 |
||
55 |
property bool useNoImageIcon: (pic.width == 0 || model.image == null || model.image == "") |
|
56 |
||
57 |
Item { |
|
58 |
id: shapeClipper
|
|
59 |
height: parent.height |
|
60 |
width: uPic.width > (listItem.width * 0.75) ? (listItem.width * 0.70) : (uPic.width == 0 ? units.gu(1) : (uPic.width - units.gu(1.5))) |
|
61 |
clip: true |
|
62 |
||
63 |
UbuntuShape { |
|
64 |
id: uPic
|
|
65 |
||
66 |
height: parent.height |
|
67 |
width: pic.width |
|
68 |
radius: "medium" |
|
69 |
||
70 |
image: Image { |
|
71 |
id: pic
|
|
72 |
height: { |
|
73 |
if (implicitHeight < 50 || implicitWidth < 50) |
|
74 |
return 0 |
|
75 |
else return uPic.height |
|
76 |
||
77 |
}
|
|
78 |
width: height |
|
79 |
source: selectIcon() |
|
80 |
sourceSize.width: uPic.height * 2 |
|
81 |
||
82 |
function selectIcon() { |
|
83 |
var img = model.image |
|
84 |
return (model.image == null || model.image == "" ) ? /*Qt.resolvedUrl("rssreader64.png")*/ "" : model.image |
|
85 |
}
|
|
86 |
}
|
|
87 |
}
|
|
88 |
} // Item shapeClipper |
|
89 |
||
90 |
ActivityIndicator { |
|
91 |
id: loadingIndicator
|
|
92 |
anchors.verticalCenter: parent.verticalCenter |
|
93 |
anchors.left: parent.left |
|
94 |
anchors.leftMargin: listItem.height / 3 |
|
95 |
running: pic.status == Image.Loading |
|
96 |
visible: running |
|
97 |
}
|
|
98 |
||
99 |
/* Ubuntu logo for articles without an image.
|
|
100 |
*/
|
|
101 |
Image { |
|
102 |
anchors.centerIn: loadingIndicator |
|
103 |
visible: listItem.useNoImageIcon && !loadingIndicator.running |
|
104 |
source: Qt.resolvedUrl("icons_tmp/dash-home.svg") |
|
105 |
width: units.gu(6) |
|
106 |
height: width |
|
107 |
}
|
|
108 |
||
109 |
Column { |
|
110 |
id: content
|
|
111 |
||
112 |
anchors { |
|
113 |
fill: parent; topMargin: units.gu(1.5); bottomMargin: units.gu(1.5); |
|
114 |
leftMargin: listItem.height + units.gu(0.5); rightMargin: units.gu(1.5) |
|
115 |
}
|
|
116 |
spacing: units.gu(1) |
|
117 |
||
118 |
Row { |
|
119 |
width: parent.width |
|
120 |
height: labelTime.paintedHeight |
|
121 |
spacing: units.gu(0.5) |
|
122 |
||
123 |
Image { |
|
124 |
id: imgFavourite
|
|
125 |
anchors.verticalCenter: labelTime.verticalCenter |
|
126 |
fillMode: Image.PreserveAspectCrop |
|
127 |
source: Qt.resolvedUrl("icons_tmp/favorite-selected.svg") |
|
128 |
sourceSize.height: model.favourite == "1" ? units.gu(1.5) : 0 |
|
129 |
visible: model.favourite == "1" |
|
130 |
}
|
|
131 |
||
132 |
Label { |
|
133 |
id: labelTime
|
|
134 |
text: DateUtils.formatRelativeTime(i18n, model.pubdate) |
|
135 |
fontSize: "x-small" |
|
136 |
width: parent.width - units.gu(2) |
|
137 |
wrapMode: Text.WrapAtWordBoundaryOrAnywhere |
|
138 |
opacity: 0.6 |
|
139 |
}
|
|
140 |
} // Row |
|
141 |
||
142 |
Label { |
|
143 |
id: labelTitle
|
|
144 |
||
145 |
text: model.title |
|
146 |
width: parent.width |
|
147 |
height: parent.height - parent.spacing * 2 - labelTime.paintedHeight - labelFeedname.paintedHeight |
|
148 |
wrapMode: Text.WrapAtWordBoundaryOrAnywhere |
|
149 |
fontSize: "small" |
|
150 |
textFormat: Text.PlainText |
|
151 |
font.weight: Font.DemiBold |
|
152 |
elide: Text.ElideRight |
|
153 |
opacity: model.status == "1" ? 0.4 : 0.8 |
|
154 |
}
|
|
155 |
||
156 |
Label { |
|
157 |
id: labelFeedname
|
|
158 |
objectName: "labelFeedname" |
|
159 |
||
160 |
text: model.feed_name |
|
161 |
fontSize: "x-small" |
|
162 |
width: parent.width |
|
163 |
wrapMode: Text.WrapAtWordBoundaryOrAnywhere |
|
164 |
opacity: 0.6 |
|
165 |
}
|
|
166 |
} // Column |
|
167 |
||
168 |
||
169 |
MouseArea { |
|
170 |
anchors.fill: parent |
|
171 |
onClicked: { |
|
172 |
if (mainView.isTabletMode) |
|
173 |
pageItself.showArticle(model.index) |
|
174 |
else mainView.toRssPage(listViewModel, model.index) |
|
175 |
}
|
|
176 |
}
|
|
177 |
}
|
|
178 |
} //Rectangle |
|
179 |
} // Component |
|
180 |
||
181 |
||
182 |
||
183 |
ListView { |
|
184 |
id: articleList
|
|
185 |
||
186 |
clip: true |
|
187 |
width: mainView.isTabletMode ? units.gu(50) : parent.width |
|
188 |
height: parent.height |
|
189 |
visible: true |
|
190 |
model: listViewModel |
|
191 |
||
192 |
delegate: listModeDelegate |
|
193 |
||
194 |
section { |
|
195 |
criteria: ViewSection.FullString |
|
196 |
property: isShorts ? "tagId" : "feedId" |
|
197 |
// labelPositioning: ViewSection.CurrentLabelAtStart | ViewSection.InlineLabels
|
|
198 |
||
199 |
delegate: ListItems.Standard { |
|
200 |
||
201 |
ListItems.ThinDivider {} |
|
202 |
||
203 |
height: units.gu(5) |
|
204 |
text: textBySection() |
|
205 |
||
206 |
function textBySection() { |
|
207 |
var s = section |
|
208 |
||
209 |
if (listViewModel == null) { |
|
210 |
return "" |
|
211 |
}
|
|
212 |
||
213 |
if (isShorts) { |
|
214 |
for (var i = 0; i < listViewModel.count; i++) { |
|
215 |
if (listViewModel.get(i).tagId == s) { |
|
216 |
return listViewModel.get(i).tagName |
|
217 |
}
|
|
218 |
}
|
|
219 |
} else { |
|
220 |
for (var i = 0; i < listViewModel.count; i++) { |
|
221 |
if (listViewModel.get(i).feedId == s) { |
|
222 |
return listViewModel.get(i).feed_name |
|
223 |
}
|
|
224 |
}
|
|
225 |
}
|
|
226 |
||
227 |
return "" |
|
228 |
}
|
|
229 |
}
|
|
230 |
} // section |
|
231 |
} // ListView |
|
232 |
||
233 |
ArticleViewItem { |
|
234 |
id: listArticleView
|
|
235 |
||
236 |
height: parent.height |
|
237 |
anchors { |
|
238 |
left: articleList.right |
|
239 |
right: parent.right |
|
240 |
}
|
|
241 |
visible: mainView.isTabletMode |
|
242 |
||
243 |
// onVisibleChanged: if (visible) showArticle(0)
|
|
244 |
}
|
|
245 |
||
246 |
ToolbarItems { |
|
247 |
id: listModeTools
|
|
248 |
||
249 |
visible: mainView.isTabletMode |
|
250 |
||
251 |
back: ToolbarButton { |
|
252 |
objectName: "rsspagerefreshbutton" |
|
253 |
action: refreshAction |
|
254 |
}
|
|
255 |
||
256 |
ToolbarButton { |
|
257 |
objectName: "changemodebutton" |
|
258 |
action: changeModeAction |
|
259 |
}
|
|
260 |
||
261 |
ToolbarButton { |
|
262 |
id: addReadsBtn
|
|
263 |
objectName: "addreadsbutton" |
|
264 |
action: Action { |
|
265 |
text: i18n.tr("Add reads") |
|
266 |
iconSource: Qt.resolvedUrl("icons_tmp/add.svg") |
|
267 |
onTriggered: { |
|
268 |
PopupUtils.open(addReadsPopoverComp, addReadsBtn) |
|
269 |
}
|
|
270 |
}
|
|
271 |
}
|
|
272 |
||
273 |
ToolbarButton { |
|
274 |
objectName: "edittopicsbutton" |
|
275 |
action: editTopicsAction |
|
276 |
}
|
|
277 |
||
278 |
ToolbarButton { |
|
170.2.8
by Roman Shchekin
Convergence in list mode. |
279 |
id: readingOptionsButton
|
280 |
||
281 |
visible: true |
|
282 |
action: Action { |
|
283 |
text: i18n.tr("Options") |
|
284 |
iconSource: Qt.resolvedUrl("./icons_tmp/settings.svg") |
|
285 |
onTriggered: { |
|
286 |
PopupUtils.open(readingOptionsPopoverComponent, readingOptionsButton) |
|
287 |
}
|
|
288 |
}
|
|
289 |
}
|
|
290 |
||
291 |
ToolbarButton { |
|
170.2.7
by Roman Shchekin
List mode now correctly (almost) works on tablets! |
292 |
//visible: mainView.isTabletMode
|
293 |
objectName: "addRemoveFavor" |
|
170.2.8
by Roman Shchekin
Convergence in list mode. |
294 |
|
295 |
visible: listArticleView.rssItem != null |
|
170.2.7
by Roman Shchekin
List mode now correctly (almost) works on tablets! |
296 |
action: Action { |
297 |
id: addRemoveFavor
|
|
298 |
||
299 |
text: listArticleView.rssItem == null ? "" : (listArticleView.rssItem.favourite == "0" ? i18n.tr("Save") : i18n.tr("Remove")) |
|
300 |
iconSource: { |
|
301 |
if (listArticleView.rssItem == null || listArticleView.rssItem.favourite == "0") |
|
302 |
return Qt.resolvedUrl("icons_tmp/favorite-unselected.svg") |
|
303 |
else return Qt.resolvedUrl("icons_tmp/favorite-selected.svg") |
|
304 |
}
|
|
305 |
onTriggered: { |
|
306 |
var fav = (listArticleView.rssItem.favourite == "0" ? "1" : "0") |
|
307 |
var dbResult = DB.updateArticleFavourite(listArticleView.rssItem.id, fav) |
|
308 |
if (dbResult.rowsAffected == 1) { |
|
309 |
listArticleView.articleFavouriteChanged(listArticleView.rssItem, fav) |
|
310 |
}
|
|
311 |
}
|
|
312 |
}
|
|
313 |
}
|
|
314 |
||
315 |
ToolbarButton { |
|
316 |
//visible: mainView.isTabletMode
|
|
317 |
objectName: "openSiteAction" |
|
318 |
action: Action { |
|
319 |
id: openSiteAction
|
|
320 |
||
321 |
text: i18n.tr("Open site") |
|
322 |
iconSource: Qt.resolvedUrl("icons_tmp/go-to.svg") |
|
323 |
onTriggered: { |
|
324 |
Qt.openUrlExternally(listArticleView.rssItem.link) |
|
325 |
}
|
|
326 |
}
|
|
327 |
}
|
|
328 |
} // ToolBarItems |
|
329 |
||
170.2.8
by Roman Shchekin
Convergence in list mode. |
330 |
Component { |
331 |
id: readingOptionsPopoverComponent
|
|
332 |
||
333 |
ReadingOptions { } |
|
334 |
} // Comp |
|
335 |
||
170.2.7
by Roman Shchekin
List mode now correctly (almost) works on tablets! |
336 |
Connections { |
337 |
target: listArticleView |
|
338 |
||
339 |
onArticleStatusChanged: { |
|
340 |
tabstabs.updateStatusInModels(tagId, articleId, status) |
|
341 |
}
|
|
342 |
||
343 |
onArticleFavouriteChanged: { |
|
344 |
tabstabs.updateFavouriteInModels(article, favourite) |
|
345 |
}
|
|
346 |
}
|
|
347 |
} // Page |