app/resources/qml/Widgets/ProfileWidget.qml

414 lines
13 KiB
QML

/*
blueROCK - for digital rock
Copyright (C) 2019 Dorian Zedler
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 3 of the License, or
(at your option) any later version.
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 <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.9
import QtQuick.Controls 2.4
import QtQuick.Controls.Material 2.3
import QtGraphicalEffects 1.0
import "../Components"
Page {
id: control
title: widgetData["firstname"] + " " + widgetData["lastname"]
property bool titleIsPageTitle: true
property bool ready
property int status: -1
property int perId: -1
property var widgetData: currentWidgetData
Component.onCompleted: {
control.ready = true
control.status = 200
}
ScrollView {
id: mainSv
anchors.fill: parent
anchors.margins: 20
contentWidth: parent.width - anchors.margins * 2
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
Column {
id: mainCol
width: parent.width
Row {
height: control.height * 0.3
width: parent.width
spacing: photoContainerItem.width * 0.1
Item {
id: photoContainerItem
anchors.verticalCenter: parent.verticalCenter
height: parent.height * 0.9
width: photo.status === Image.Null || photo.status === Image.Error ? 0:parent.width * 0.4
RectangularGlow {
id: effect
visible: photo.ready
anchors.fill: photo
glowRadius: 1
opacity: 0.4
color: "black"
cornerRadius: photo.width * 0.2
}
Image {
id: photo
property bool ready: photo.status === Image.Ready
anchors.centerIn: parent
height: parent.height * 0.9
width: height * 0.7
fillMode: Image.PreserveAspectCrop
mipmap: true
source: widgetData["photo"] === undefined ?
"":
widgetData["photo"].replace("https", "http")
asynchronous: true
FancyBusyIndicator {
height: width
anchors.centerIn: parent
opacity: photo.status === Image.Loading
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: Item {
width: photo.width
height: photo.height
Rectangle {
anchors.centerIn: parent
width: photo.width
height: photo.height
radius: photo.width * 0.2
}
}
}
}
}
Column {
anchors.verticalCenter: parent.verticalCenter
height: parent.height * 0.9
width: parent.width - photoContainerItem.width * 1.1
Label {
height: parent.height * 0.2
width: parent.width
font.pixelSize: height * 0.6
font.bold: true
minimumPixelSize: 1
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: widgetData["firstname"] + " " + widgetData["lastname"]
}
Label {
height: parent.height * 0.2
width: parent.width
font.pixelSize: height * 0.6
font.bold: false
minimumPixelSize: 1
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: widgetData["nation"]
}
Label {
height: parent.height * 0.15
width: parent.width
font.pixelSize: height * 0.6
font.bold: false
minimumPixelSize: 1
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: "<html><a href='" + widgetData["fed_url"] + "'>" + widgetData["federation"] + "</a>"
onLinkActivated: {
Qt.openUrlExternally(link)
}
}
Label {
height: parent.height * 0.15
width: parent.width
font.pixelSize: height * 0.6
font.bold: false
minimumPixelSize: 1
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: qsTr("age") + ": " + widgetData["age"]
}
Label {
height: parent.height * 0.15
width: parent.width
font.pixelSize: height * 0.6
font.bold: false
minimumPixelSize: 1
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: qsTr("year of birth") + ": " + widgetData["birthdate"]
}
Label {
height: parent.height * 0.15
width: parent.width
font.pixelSize: height * 0.6
font.bold: false
minimumPixelSize: 1
fontSizeMode: Text.Fit
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: qsTr("city") + ": " + widgetData["city"]
}
}
}
Label {
anchors.horizontalCenter: parent.horizontalCenter
visible: bestResultsRep.model > 0
width: parent.width
wrapMode: Label.Wrap
text: widgetData["freetext"] === undefined ?
"":
(widgetData["freetext"] + "<br>")
}
Rectangle {
id: separatorLine
anchors.horizontalCenter: parent.horizontalCenter
height: 1
width: parent.width
color: Material.foreground
}
Button {
id: toggleAllResultsBt
anchors.horizontalCenter: parent.horizontalCenter
visible: bestResultsRep.model > 0
flat: true
text: bestResultsRep.showAllResults ? qsTr("show best results"):qsTr("show all results")
onClicked: {
bestResultsRep.showAllResults = !bestResultsRep.showAllResults
}
Behavior on text {
FadeAnimation {
target: toggleAllResultsBt
fadeDuration: 150
}
}
}
Repeater {
id: bestResultsRep
property var bestResults: showAllResults ? getAllResults() : getBestResults()
property bool showAllResults: false
function getBestResults(){
var allResults = control.widgetData["results"]
allResults.sort(function(a, b) {
// sort results by weight
var year = new Date().getFullYear();
var weightA = a.rank/2 + (year-parseInt(a.date)) + 4*!a.nation;
var weightB = b.rank/2 + (year-parseInt(b.date)) + 4*!b.nation;
return weightA - weightB;
});
var bestResults = allResults.slice(0,12)
bestResults.sort(function(a, b) {
// sort results by date
var aTs = Date.fromLocaleString(Qt.locale(), a["date"], "yyyy-MM-dd").getTime()
var bTs = Date.fromLocaleString(Qt.locale(), b["date"], "yyyy-MM-dd").getTime()
return bTs - aTs;
});
return bestResults
}
function getAllResults() {
var allResults = control.widgetData["results"]
allResults.sort(function(a, b) {
// sort results by date
var aTs = Date.fromLocaleString(Qt.locale(), a["date"], "yyyy-MM-dd").getTime()
var bTs = Date.fromLocaleString(Qt.locale(), b["date"], "yyyy-MM-dd").getTime()
return bTs - aTs;
});
return allResults
}
width: parent.width
model: bestResults.length
delegate: Row {
id: bestResultRow
property var thisData: bestResultsRep.bestResults[index]
width: parent.width
height: 50
spacing: width * 0.05
opacity: 0
scale: 0.9
onThisDataChanged: {
fadeInPa.start()
}
ParallelAnimation {
id: fadeInPa
NumberAnimation { target: bestResultRow; property: "opacity"; from: 0; to: 1.0; duration: 400 }
NumberAnimation { target: bestResultRow; property: "scale"; from: 0.8; to: 1.0; duration: 400 }
}
Label {
id: bestResultRankLa
width: parent.width * 0.1
height: parent.height
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
fontSizeMode: Text.Fit
minimumPixelSize: 1
font.pixelSize: height * 0.6
text: bestResultsRep.bestResults[index]["rank"]
}
Label {
id: bestResultCompLa
width: parent.width * 0.6
height: parent.height
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
fontSizeMode: Text.Fit
minimumPixelSize: height * 0.3
font.pixelSize: height * 0.3
elide: "ElideRight"
text: "<html><a href='#'>" + bestResultsRep.bestResults[index]["name"] + "</a></html>"
onLinkActivated: {
app.openWidget( { comp: bestResultsRep.bestResults[index]["WetId"], cat: bestResultsRep.bestResults[index]["GrpId"] } )
}
}
Label {
id: bestResultDateLa
width: parent.width * 0.2
height: parent.height
scale: 0.8
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignRight
fontSizeMode: Text.Fit
minimumPixelSize: 1
font.pixelSize: height * 0.6
text: bestResultsRep.bestResults[index]["date"]
}
}
}
}
}
}