@@ -16,154 +16,208 @@
1616
1717import QtQuick 2.0
1818import Ubuntu.Components 0.1
19+import Ubuntu.Components.ListItems 0.1 as ListItems
1920import "../../Components"
20−import "../../Components/ListItems" as ListItems
2121import ".."
22+import "../Previews"
2223
2324DashPreview {
2425 id: genericPreview
25−
26− previewWidthRatio: 0.6
27−
2826 property url url: previewData.image
2927
30− previewImages: UbuntuShape {
31− id: urlLoader
32− anchors.left: parent.left
33− anchors.right: parent.right
34− height: width * previewImage.sourceSize.height / previewImage.sourceSize.width
35− radius: "medium"
36− image: Image {
37− id: previewImage
38− asynchronous: true
39− source: genericPreview.url
40− fillMode: Image.PreserveAspectCrop
28+ previewImages: previewImagesComponent
29+ header: headerComponent
30+ actions: actionsComponent
31+ description: descriptionComponent
32+ ratings: ratingsComponent
33+
34+ Component {
35+ id: previewImagesComponent
36+ UbuntuShape {
37+ id: urlLoader
38+ anchors.left: parent.left
39+ anchors.right: parent.right
40+ height: width * previewImage.sourceSize.height / previewImage.sourceSize.width
41+ radius: "medium"
42+ visible: height > 0
43+ image: Image {
44+ id: previewImage
45+ asynchronous: true
46+ source: genericPreview.url
47+ fillMode: Image.PreserveAspectCrop
48+ }
4149 }
4250 }
4351
44− header: Column {
45− height: childrenRect.height
46−
47− Label {
48− id: title
49− objectName: "titleLabel"
50− anchors { left: parent.left; right: parent.right }
51−
52− elide: Text.ElideRight
53− fontSize: "large"
54− font.weight: Font.Light
55− color: Theme.palette.selected.backgroundText
56− opacity: 0.9
57− text: previewData.title
58− style: Text.Raised
59− styleColor: "black"
60− maximumLineCount: 2
61− wrapMode: Text.WordWrap
62− }
63−
64− Label {
65− anchors { left: parent.left; right: parent.right }
66− visible: text != ""
67− fontSize: "small"
68− opacity: 0.6
69− color: "white"
70− text: previewData.subtitle.replace(/[\r\n]+/g, "<br />")
71− style: Text.Raised
72− styleColor: "black"
73− wrapMode: Text.WordWrap
74− textFormat: Text.RichText
75− maximumLineCount: 1
76− // FIXME: workaround for https://bugreports.qt-project.org/browse/QTBUG-33020
77− onWidthChanged: { wrapMode = Text.NoWrap; wrapMode = Text.WordWrap }
52+ Component {
53+ id: headerComponent
54+ PreviewHeader {
55+ title: previewData.title
56+ rating: Math.round(root.previewData.rating * 10)
57+ reviews: root.previewData.numRatings
58+ rated: root.previewData.infoMap["rated"] ? root.previewData.infoMap["rated"].value : 0
7859 }
7960 }
80− actions: GridView {
81− id: buttons
82− model: genericPreview.previewData.actions
83−
84− property int buttonMaxWidth: units.gu(34)
85− property int numOfColumns: Math.ceil((width + spacing) / (buttonMaxWidth + spacing))
86− property int numOfRows: Math.ceil(count / numOfColumns)
87− property int spacing: units.gu(1)
88− height: Math.max(units.gu(4), units.gu(4)*numOfRows + spacing*(numOfRows - 1))
89−
90− cellWidth: width / numOfColumns
91− cellHeight: buttonHeight + spacing
92− property int buttonWidth: cellWidth - spacing / 2
93− property int buttonHeight: units.gu(4)
94−
95− delegate: Button {
96− width: Math.max(units.gu(4), buttons.buttonWidth)
97− height: buttons.buttonHeight
98− color: "#dd4814"
99− text: modelData.displayName
100− iconSource: modelData.iconHint
101− iconPosition: "right"
102− visible: true
103− onClicked: {
104− genericPreview.previewData.execute(modelData.id, { })
61+
62+ Component {
63+ id: actionsComponent
64+ GridView {
65+ id: buttons
66+ model: genericPreview.previewData.actions
67+
68+ property int buttonMaxWidth: units.gu(34)
69+ property int numOfColumns: Math.ceil((width + spacing) / (buttonMaxWidth + spacing))
70+ property int numOfRows: Math.ceil(count / numOfColumns)
71+ property int spacing: units.gu(1)
72+ height: Math.max(units.gu(4), units.gu(4)*numOfRows + spacing*(numOfRows - 1))
73+
74+ cellWidth: width / numOfColumns
75+ cellHeight: buttonHeight + spacing
76+ property int buttonWidth: cellWidth - spacing / 2
77+ property int buttonHeight: units.gu(4)
78+
79+ delegate: Button {
80+ width: Math.max(units.gu(4), buttons.buttonWidth)
81+ height: buttons.buttonHeight
82+ color: "#dd4814"
83+ text: modelData.displayName
84+ iconSource: modelData.iconHint
85+ iconPosition: "right"
86+ visible: true
87+ onClicked: {
88+ genericPreview.previewData.execute(modelData.id, { })
89+ }
10590 }
91+ focus: false
10692 }
107− focus: false
10893 }
10994
110− description: Column {
111− spacing: units.gu(2)
112−
113− Label {
114− id: descriptionLabel
115− anchors { left: parent.left; right: parent.right }
116− visible: text != ""
117− fontSize: "small"
118− opacity: 0.6
119− color: "white"
120− text: previewData.description.replace(/[\r\n]+/g, "<br />")
121− style: Text.Raised
122− styleColor: "black"
123− wrapMode: Text.WordWrap
124− textFormat: Text.RichText
125− // FIXME: workaround for https://bugreports.qt-project.org/browse/QTBUG-33020
126− onWidthChanged: { wrapMode = Text.NoWrap; wrapMode = Text.WordWrap }
95+ Component {
96+ id: descriptionComponent
97+ Column {
98+ spacing: units.gu(2)
99+
100+ Label {
101+ id: descriptionLabel
102+ anchors { left: parent.left; right: parent.right }
103+ visible: text != ""
104+ fontSize: "small"
105+ opacity: 0.6
106+ color: "white"
107+ text: previewData.description.replace(/[\r\n]+/g, "<br />")
108+ style: Text.Raised
109+ styleColor: "black"
110+ wrapMode: Text.WordWrap
111+ textFormat: Text.RichText
112+ // FIXME: workaround for https://bugreports.qt-project.org/browse/QTBUG-33020
113+ onWidthChanged: { wrapMode = Text.NoWrap; wrapMode = Text.WordWrap }
114+ }
115+
116+ Column {
117+ id: infoItem
118+ anchors {
119+ left: parent.left
120+ right: parent.right
121+ }
122+ Repeater {
123+ model: previewData.infoHints
124+
125+ delegate: Item {
126+ width: parent.width
127+ height: units.gu(5)
128+ Row {
129+ width: parent.width
130+ spacing: units.gu(1)
131+ property int columnWidth: (width - spacing) / 2
132+ anchors.verticalCenter: parent.verticalCenter
133+
134+ Label {
135+ visible: directedLabel.visible
136+ fontSize: "small"
137+ opacity: 0.9
138+ color: "white"
139+ horizontalAlignment: Text.AlignLeft
140+ width: parent.columnWidth
141+ text: modelData.displayName
142+ style: Text.Raised
143+ styleColor: "black"
144+ }
145+ Label {
146+ id: directedLabel
147+ visible: modelData.value != ""
148+ fontSize: "small"
149+ opacity: 0.6
150+ color: "white"
151+ horizontalAlignment: Text.AlignRight
152+ width: parent.columnWidth
153+ text: modelData.value ? modelData.value : ""
154+ style: Text.Raised
155+ styleColor: "black"
156+ wrapMode: Text.WordWrap
157+ }
158+ }
159+ ListItems.ThinDivider {
160+ anchors {
161+ left: parent.left
162+ bottom: parent.bottom
163+ right: parent.right
164+ }
165+ }
166+ }
167+ }
168+ }
127169 }
170+ }
128171
172+ Component {
173+ id: ratingsComponent
129174 Column {
130− id: infoItem
131− anchors {
132− left: parent.left
133− right: parent.right
175+ visible: root.previewData.rating >= 0
176+ spacing: units.gu(1)
177+ height: childrenRect.height
178+
179+ ListItems.ThinDivider { }
180+
181+ Item {
182+ anchors { left: parent.left; right: parent.right }
183+ height: rateLabel.height
184+
185+ Label {
186+ id: rateLabel
187+ fontSize: "medium"
188+ color: "white"
189+ style: Text.Raised
190+ styleColor: "black"
191+ opacity: .9
192+ text: i18n.tr("Rate this")
193+
194+ anchors.left: parent.left
195+ anchors.verticalCenter: parent.verticalCenter
196+ }
197+
198+ // FIXME these need to be made interactive and connected to the scope
199+ RatingStars {
200+ anchors.right: parent.right
201+ anchors.verticalCenter: parent.verticalCenter
202+ }
134203 }
135− Repeater {
136− model: previewData.infoHints
137−
138− delegate: Grid {
139− columns: 2
140− width: parent.width
141− spacing: units.gu(1)
142−
143− Label {
144− visible: directedLabel.visible
145− fontSize: "small"
146− opacity: 0.9
147− color: "white"
148− horizontalAlignment: Text.AlignLeft
149− width: infoItem.width / 2
150− text: modelData.displayName
151− style: Text.Raised
152− styleColor: "black"
153− }
154− Label {
155− id: directedLabel
156− visible: modelData.value != ""
157− fontSize: "small"
158− opacity: 0.6
159− color: "white"
160− horizontalAlignment: Text.AlignRight
161− width: infoItem.width / 2
162− text: modelData.value ? modelData.value : ""
163− style: Text.Raised
164− styleColor: "black"
165− wrapMode: Text.WordWrap
166− }
204+
205+ ListItems.ThinDivider { }
206+
207+ Reviews {
208+ id: appReviews
209+ objectName: "appReviews"
210+ // TODO: This should make this visible when the feature for reviews/comments is complete.
211+ visible: false; height: 0
212+
213+ anchors { left: parent.left; right: parent.right }
214+
215+ model: root.previewData.infoMap["comments"] ? root.previewData.infoMap["comments"].value : undefined
216+
217+ onSendReview: root.sendUserReview(review);
218+
219+ onEditing: {
220+ root.ensureVisible(appReviews.textArea);
167221 }
168222 }
169223 }