diff --git a/discover/qml/ReviewDelegate.qml b/discover/qml/ReviewDelegate.qml index 94699e17..f26ba711 100644 --- a/discover/qml/ReviewDelegate.qml +++ b/discover/qml/ReviewDelegate.qml @@ -1,109 +1,189 @@ /* * Copyright (C) 2012 Aleix Pol Gonzalez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library/Lesser General Public License * version 2, or (at your option) any later version, as published by the * Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library/Lesser General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import QtQuick 2.1 import QtQuick.Layouts 1.1 import QtQuick.Controls 2.1 import org.kde.discover 2.0 import org.kde.kirigami 2.0 as Kirigami RowLayout { id: item visible: model.shouldShow property bool compact: false property bool separator: true signal markUseful(bool useful) - function usefulnessToString(favorable, total) - { - return total===0 - ? i18n("Tell us about this review!") - : i18n("%1 out of %2 people found this review useful", favorable, total) - } - + // Spacers to indent nested comments/replies Repeater { model: depth - delegate: Rectangle { + delegate: Item { Layout.fillHeight: true Layout.minimumWidth: Kirigami.Units.largeSpacing Layout.maximumWidth: Kirigami.Units.largeSpacing - color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.8)) - Rectangle { - anchors { - top: parent.top - bottom: parent.bottom - left: parent.left - } - width: 1 - color: Kirigami.Theme.backgroundColor - } } } - ColumnLayout - { - RowLayout { - Layout.fillWidth: true + + Rectangle { + id: reviewBox + color: "transparent" + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.85)) + border.width: 1 + radius: Kirigami.Units.largeSpacing + + Layout.fillWidth: true + implicitHeight: reviewLayout.implicitHeight + (Kirigami.Units.largeSpacing * 2) + + ColumnLayout { + id: reviewLayout + anchors.fill: parent + spacing: 0 + + // Header with stars and date of review + RowLayout { + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.largeSpacing + Layout.rightMargin: Kirigami.Units.largeSpacing + Layout.topMargin: Kirigami.Units.largeSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + + Rating { + id: rating + rating: model.rating + starSize: content.font.pointSize + } + + Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + text: date.toLocaleDateString(Qt.locale(), "MMMM d yyyy") + elide: Text.ElideRight + opacity: 0.6 + } + } + + // Review title and author Label { id: content Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.largeSpacing + Layout.rightMargin: Kirigami.Units.largeSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + elide: Text.ElideRight readonly property string author: reviewer ? reviewer : i18n("unknown reviewer") text: summary ? i18n("%1 by %2", summary, author) : i18n("Comment by %1", author) } - Rating { - id: rating - rating: model.rating - starSize: content.font.pointSize + + // Review text + Label { + Layout.fillWidth: true + Layout.leftMargin: Kirigami.Units.largeSpacing + Layout.rightMargin: Kirigami.Units.largeSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + + text: display + maximumLineCount: item.compact ? 3 : undefined + wrapMode: Text.Wrap } - } - Label { - Layout.fillWidth: true - text: display - maximumLineCount: item.compact ? 3 : undefined - wrapMode: Text.Wrap - } - Label { - visible: !item.compact - text: item.usefulnessToString(usefulnessFavorable, usefulnessTotal) - } - Label { - visible: !item.compact - Layout.alignment: Qt.AlignRight - text: { - switch(usefulChoice) { - case ReviewsModel.Yes: - i18n("Useful? Yes/No") - break; - case ReviewsModel.No: - i18n("Useful? Yes/No") - break; - default: - i18n("Useful? Yes/No") - break; + // Gray bar at the bottom + its content layout + Rectangle { + color: Kirigami.Theme.backgroundColor + Layout.fillWidth: true + // To make the background color rect touch the outline of the box + Layout.leftMargin: reviewBox.border.width + Layout.rightMargin: reviewBox.border.width + implicitHeight: rateTheReviewLayout.implicitHeight + radius: Kirigami.Units.largeSpacing + visible: !item.compact + + // This fills in the rounded top corners, because you can't have a + // rectangle with only a few corners rounded + Rectangle { + color: Kirigami.Theme.backgroundColor + border.color: Qt.tint(Kirigami.Theme.textColor, Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 0.85)) + anchors.left: parent.left + anchors.leftMargin: -1 + anchors.right: parent.right + anchors.rightMargin: -1 + anchors.top: parent.top + anchors.topMargin: -1 + z: -1 + height: reviewBox.radius + } + + RowLayout { + id: rateTheReviewLayout + anchors.fill: parent + anchors.leftMargin: Kirigami.Units.largeSpacing + anchors.rightMargin: Kirigami.Units.smallSpacing + + Label { + visible: usefulnessTotal !== 0 + text: i18n("Votes: %1 out of %2", usefulnessFavorable, usefulnessTotal) + } + + Label { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + // Change this to "Was this review useful?" once Kirigami fixes + // https://bugs.kde.org/show_bug.cgi?id=415677 + text: i18n("Useful?") + elide: Text.ElideLeft + } + + // Useful/Not Useful buttons + Button { + id: yesButton + Layout.maximumWidth: Kirigami.Units.gridUnit * 3 + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + Layout.alignment: Qt.AlignVCenter + + text: i18nc("Keep this string as short as humanly possible", "Yes") + + checkable: true + checked: usefulChoice === ReviewsModel.Yes + onClicked: { + noButton.checked = false + item.markUseful(true) + } + } + Button { + id: noButton + Layout.maximumWidth: Kirigami.Units.gridUnit * 3 + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Kirigami.Units.smallSpacing + Layout.alignment: Qt.AlignVCenter + + text: i18nc("Keep this string as short as humanly possible", "No") + + checkable: true + checked: usefulChoice === ReviewsModel.No + onClicked: { + yesButton.checked = false + item.markUseful(false) + } + } } } - onLinkActivated: item.markUseful(link=='true') - } - Kirigami.Separator { - visible: item.separator - Layout.fillWidth: true } } } diff --git a/discover/qml/ReviewsPage.qml b/discover/qml/ReviewsPage.qml index 5a6f152c..b4cc3112 100644 --- a/discover/qml/ReviewsPage.qml +++ b/discover/qml/ReviewsPage.qml @@ -1,81 +1,84 @@ /*************************************************************************** * Copyright © 2012 Aleix Pol Gonzalez * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 2 of * * the License or (at your option) version 3 or any later version * * accepted by the membership of KDE e.V. (or its successor approved * * by the membership of KDE e.V.), which shall act as a proxy * * defined in Section 14 of version 3 of the license. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * ***************************************************************************/ import QtQuick 2.1 import QtQuick.Controls 2.1 import org.kde.discover 2.0 import org.kde.discover.app 1.0 import org.kde.kirigami 2.0 as Kirigami Kirigami.OverlaySheet { id: page + property alias model: reviewsView.model readonly property QtObject reviewsBackend: resource.backend.reviewsBackend readonly property var resource: model.resource readonly property var rd: ReviewDialog { id: reviewDialog application: page.resource parent: overlay backend: page.reviewsBackend onAccepted: backend.submitReview(resource, summary, review, rating) } function openReviewDialog() { reviewDialog.sheetOpen = true page.sheetOpen = false } ListView { id: reviewsView clip: true spacing: Kirigami.Units.smallSpacing cacheBuffer: Math.max(0, contentHeight) header: Item { width: parent.width height: reviewButton.implicitHeight + 2 * Kirigami.Units.largeSpacing Button { id: reviewButton anchors { verticalCenter: parent.verticalCenter left: parent.left leftMargin: Kirigami.Units.largeSpacing } visible: page.reviewsBackend != null enabled: page.resource.isInstalled text: i18n("Review...") onClicked: page.openReviewDialog() } } delegate: ReviewDelegate { anchors { left: parent.left right: parent.right + topMargin: Kirigami.Units.largeSpacing + bottomMargin: Kirigami.Units.largeSpacing } separator: index != ListView.view.count-1 onMarkUseful: page.model.markUseful(index, useful) } } }