565 lines
16 KiB
QML
565 lines
16 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.Window 2.2
|
|
import QtQuick.Controls 2.4
|
|
import QtQuick.Layouts 1.3
|
|
import QtPurchasing 1.12
|
|
|
|
import com.itsblue.digitalRockRanking 1.0
|
|
import de.itsblue.blueRock 2.0
|
|
|
|
import "./Pages"
|
|
import "./Components"
|
|
|
|
Window {
|
|
visible: true
|
|
width: 540
|
|
height: 960
|
|
title: qsTr("blueROCK")
|
|
|
|
Page {
|
|
id: app
|
|
|
|
property int errorCode: -1
|
|
|
|
anchors.fill: parent
|
|
|
|
Component.onCompleted: {
|
|
//app.openAthlete(53139) // dorian: 53139 , rustam: 6933 , helen: 53300
|
|
//openWidget({nation:'GER'})
|
|
//mainStack.push("Pages/AthleteSearchPage.qml")
|
|
}
|
|
|
|
Shortcut {
|
|
sequences: ["Esc", "Back"]
|
|
enabled: mainStack.depth > 1
|
|
onActivated: {
|
|
if(!mainStack.currentItem.locked){
|
|
mainStack.pop()
|
|
}
|
|
}
|
|
}
|
|
|
|
BRController {
|
|
id: brController
|
|
}
|
|
|
|
ServerConn {
|
|
id: serverConn
|
|
}
|
|
|
|
AppSettings {
|
|
id: appSettings
|
|
}
|
|
|
|
StackView {
|
|
id: mainStack
|
|
|
|
//enabled: !loadingDl.opened
|
|
|
|
anchors {
|
|
top: toolBar.bottom
|
|
left: parent.left
|
|
right: parent.right
|
|
bottom: parent.bottom
|
|
}
|
|
|
|
initialItem: startPgComp
|
|
|
|
Component {
|
|
id: startPgComp
|
|
StartPage {}
|
|
}
|
|
|
|
popEnter: Transition {
|
|
XAnimator {
|
|
from: (mainStack.mirrored ? -1 : 1) * -mainStack.width
|
|
to: 0
|
|
duration: 500
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
popExit: Transition {
|
|
XAnimator {
|
|
from: 0
|
|
to: (mainStack.mirrored ? -1 : 1) * mainStack.width
|
|
duration: 500
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
pushEnter: Transition {
|
|
XAnimator {
|
|
from: (mainStack.mirrored ? -1 : 1) * mainStack.width
|
|
to: 0
|
|
duration: 500
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
pushExit: Transition {
|
|
XAnimator {
|
|
from: 0
|
|
to: (mainStack.mirrored ? -1 : 1) * -mainStack.width
|
|
duration: 500
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
}
|
|
|
|
AppToolBar {
|
|
id: toolBar
|
|
|
|
anchors {
|
|
top: parent.top
|
|
left: parent.left
|
|
right: parent.right
|
|
topMargin: -height
|
|
}
|
|
|
|
height: 50
|
|
|
|
showErrorBar: true
|
|
|
|
RowLayout {
|
|
|
|
anchors.fill: parent
|
|
|
|
spacing: width * 0.02
|
|
|
|
ToolButton {
|
|
id:toolButton
|
|
|
|
height: parent.height
|
|
|
|
onClicked: {
|
|
if(!mainStack.currentItem.locked){
|
|
mainStack.pop()
|
|
}
|
|
}
|
|
|
|
icon.name: "back"
|
|
}
|
|
|
|
Column {
|
|
|
|
Layout.fillWidth: true
|
|
|
|
height: childrenRect.height
|
|
width: parent.width - extraComponentLoader.width - toolButton.width - 3 * parent.spacing
|
|
|
|
Label {
|
|
id: toolBarTitleLa
|
|
|
|
width: parent.width
|
|
|
|
scale: 1
|
|
|
|
elide: "ElideRight"
|
|
|
|
font.bold: true
|
|
verticalAlignment: Text.AlignVCenter
|
|
|
|
color: "black"
|
|
|
|
text: getText()
|
|
|
|
function getText(){
|
|
var titleString = "";
|
|
|
|
if(!mainStack.currentItem.titleIsPageTitle){
|
|
for(var i=1; i<mainStack.depth; i++){
|
|
if(i > 1){
|
|
titleString += " > "
|
|
}
|
|
|
|
titleString += mainStack.get(i).title
|
|
}
|
|
}
|
|
else {
|
|
titleString = mainStack.currentItem.title
|
|
}
|
|
|
|
return(titleString)
|
|
}
|
|
|
|
Behavior on text {
|
|
FadeAnimation {
|
|
target: toolBarTitleLa
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
id: toolBarSubTitleLa
|
|
|
|
width: parent.width
|
|
height: text !== "" ? undefined:0
|
|
|
|
elide: "ElideRight"
|
|
|
|
font.bold: false
|
|
|
|
color: "black"
|
|
|
|
text: getText()
|
|
|
|
function getText(){
|
|
var titleString = "";
|
|
|
|
if(mainStack.currentItem.subTitle !== undefined){
|
|
titleString = mainStack.currentItem.subTitle
|
|
}
|
|
|
|
return(titleString)
|
|
}
|
|
|
|
Behavior on text {
|
|
FadeAnimation {
|
|
target: toolBarSubTitleLa
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Loader {
|
|
id: extraComponentLoader
|
|
|
|
property int maximumWidth: parent.width * 0.4 - toolButton.width - 3
|
|
|
|
height: parent.height
|
|
|
|
Layout.alignment: Layout.Right
|
|
|
|
onStatusChanged: {
|
|
//console.log("loader status changed: " + status)
|
|
|
|
if(status == 0){
|
|
extraComponentLoader.Layout.preferredWidth = 0
|
|
}
|
|
else {
|
|
extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
|
|
extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.width
|
|
widthChangedCon.target = extraComponentLoader.item
|
|
}
|
|
|
|
//console.log("set loader width to: " + extraComponentLoader.Layout.preferredWidth + " for a item width of: " + extraComponentLoader.item.implicitWidth)
|
|
}
|
|
|
|
//sourceComponent: mainStack.currentItem.headerComponent
|
|
|
|
Connections {
|
|
target: mainStack
|
|
onCurrentItemChanged: {
|
|
secondCon.target = mainStack.currentItem
|
|
disappearNa.start()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
id: secondCon
|
|
onHeaderComponentChanged: {
|
|
disappearNa.start()
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
id: widthChangedCon
|
|
onImplicitWidthChanged:{
|
|
extraComponentLoader.item.width = extraComponentLoader.item.implicitWidth
|
|
extraComponentLoader.Layout.preferredWidth = extraComponentLoader.item.implicitWidth
|
|
}
|
|
}
|
|
|
|
ParallelAnimation {
|
|
id: appearNa
|
|
|
|
NumberAnimation {
|
|
|
|
target: extraComponentLoader
|
|
property: "opacity"
|
|
|
|
from: 0
|
|
to: 1
|
|
|
|
duration: 150
|
|
}
|
|
|
|
NumberAnimation {
|
|
|
|
target: extraComponentLoader
|
|
property: "scale"
|
|
|
|
from: 0.9
|
|
to: 1
|
|
|
|
duration: 150
|
|
}
|
|
}
|
|
|
|
ParallelAnimation {
|
|
id: disappearNa
|
|
|
|
NumberAnimation {
|
|
|
|
target: extraComponentLoader
|
|
property: "opacity"
|
|
|
|
from: 1
|
|
to: 0
|
|
|
|
duration: 150
|
|
}
|
|
|
|
NumberAnimation {
|
|
|
|
target: extraComponentLoader
|
|
property: "scale"
|
|
|
|
from: 1
|
|
to: 0.9
|
|
|
|
duration: 150
|
|
}
|
|
|
|
onRunningChanged: {
|
|
if(!running){
|
|
extraComponentLoader.sourceComponent = mainStack.currentItem.headerComponent
|
|
appearNa.start()
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Behavior on anchors.topMargin {
|
|
NumberAnimation {
|
|
duration: 500
|
|
easing.type: Easing.OutCubic
|
|
}
|
|
}
|
|
|
|
states: [
|
|
State {
|
|
name: "closed"
|
|
when: mainStack.depth === 1
|
|
PropertyChanges {
|
|
target: toolBar
|
|
anchors.topMargin: -height
|
|
}
|
|
},
|
|
State {
|
|
name: "open"
|
|
when: mainStack.depth > 1
|
|
PropertyChanges {
|
|
target: toolBar
|
|
anchors.topMargin: 0
|
|
}
|
|
}
|
|
]
|
|
}
|
|
|
|
Dialog {
|
|
id: loadingDl
|
|
|
|
x: ( app.width - width ) / 2
|
|
y: ( app.height - height ) / 2
|
|
|
|
modal: true
|
|
closePolicy: Dialog.NoAutoClose
|
|
|
|
contentItem: Column {
|
|
FancyBusyIndicator {
|
|
running: true
|
|
}
|
|
|
|
Label {
|
|
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
|
|
font.bold: true
|
|
|
|
text: "loading..."
|
|
}
|
|
}
|
|
}
|
|
|
|
Store {
|
|
Product {
|
|
id: speedFlowChartProduct
|
|
identifier: "speed_flowchart"
|
|
type: Product.Unlockable
|
|
|
|
onPurchaseRestored: {
|
|
appSettings.write("speedBackendPurchase", 1)
|
|
}
|
|
|
|
onPurchaseSucceeded: {
|
|
appSettings.write("speedBackendPurchase", 1)
|
|
}
|
|
|
|
onPurchaseFailed: {
|
|
appSettings.write("speedBackendPurchase", 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
function landscape(){
|
|
return app.height < app.width
|
|
}
|
|
|
|
function openWidget(params){
|
|
loadingDl.open()
|
|
|
|
console.log("OPENING COMP 2")
|
|
var calComp = Qt.createComponent("qrc:/Pages/WidgetPage.qml").createObject(null, {"params": params})
|
|
console.log("OPENING COMP 3")
|
|
app.errorCode = calComp.status
|
|
|
|
if(calComp.ready){
|
|
mainStack.push(calComp)
|
|
}
|
|
else {
|
|
delete(calComp)
|
|
}
|
|
|
|
loadingDl.close()
|
|
}
|
|
|
|
function openCalendar(federation) {
|
|
loadingDl.open()
|
|
var newPageComp = Qt.createComponent("qrc:/Pages/CalendarPage.qml").createObject(null, {"data": brController.getCalendar(federation)})
|
|
|
|
app.errorCode = newPageComp.status
|
|
|
|
if(newPageComp.ready){
|
|
mainStack.push(newPageComp)
|
|
}
|
|
else {
|
|
delete(newPageComp)
|
|
}
|
|
|
|
loadingDl.close()
|
|
}
|
|
|
|
function openResults(competition) {
|
|
loadingDl.open()
|
|
|
|
console.log("OPENING COMP 2")
|
|
var newPageComp = Qt.createComponent("qrc:/Pages/ResultPage.qml").createObject(null, {"data": competition})
|
|
|
|
console.log("OPENING COMP 3")
|
|
app.errorCode = newPageComp.status
|
|
|
|
if(newPageComp.ready){
|
|
mainStack.push(newPageComp)
|
|
}
|
|
else {
|
|
delete(newPageComp)
|
|
}
|
|
|
|
loadingDl.close()
|
|
}
|
|
|
|
function defaultString(string, defaultString){
|
|
if(string === undefined || string === null){
|
|
return defaultString
|
|
}
|
|
else {
|
|
return string
|
|
}
|
|
}
|
|
|
|
function getErrorInfo(errorCode) {
|
|
|
|
var infoLevel
|
|
// 0 - ok
|
|
// 1 - info
|
|
// 2 - error
|
|
|
|
var errorString
|
|
var errorDescription
|
|
|
|
switch(errorCode) {
|
|
case 0:
|
|
infoLevel = 2
|
|
errorString = "No connection to server"
|
|
errorDescription = "Please check your internet connection and try again."
|
|
break
|
|
case 200:
|
|
infoLevel = 0
|
|
errorString = "Success"
|
|
errorDescription = "The request was successfull"
|
|
break
|
|
case 401:
|
|
infoLevel = 2
|
|
errorString = "Authentication required"
|
|
errorDescription = "The server asked for user credentinals, please chack them and try again"
|
|
break
|
|
case 500:
|
|
infoLevel = 2
|
|
errorString = "Internal server error"
|
|
errorDescription = "The server was unable to process this request, this is probaply the servers fault. Please try again later."
|
|
break
|
|
case 900:
|
|
infoLevel = 2
|
|
errorString = "Internal error"
|
|
errorDescription = "Something went wron internally, this is probaply an inssue in the program code"
|
|
break
|
|
case 901:
|
|
infoLevel = 1
|
|
errorString = "No Data"
|
|
errorDescription = "There is currently no data available. Please try again later."
|
|
break
|
|
case 902:
|
|
infoLevel = 1
|
|
errorString = "Cached (old) data"
|
|
errorDescription = "Es konnte keine Verbindung zum Server hergestellt werden, aber es sind noch alte Daten gespeichert."
|
|
break
|
|
case 903:
|
|
infoLevel = 1
|
|
errorString = "Ungültiger Aufruf"
|
|
errorDescription = "Die aufgerufene Funktion ist momentan nicht verfügbar, bitte versuche es später erneut."
|
|
break
|
|
case 904:
|
|
infoLevel = 2
|
|
errorString = "Incompatible API"
|
|
errorDescription = "Please make shure that you are using the latest version of this app and try again."
|
|
break
|
|
case 905:
|
|
infoLevel = 1
|
|
errorString = "Loading..."
|
|
errorDescription = "Please wait while we're loading some data"
|
|
break
|
|
default:
|
|
infoLevel = 2
|
|
errorString = "Unexpected error ("+errorCode+")"
|
|
errorDescription = "Unexpected error while getting data from the server. Please try again later."
|
|
}
|
|
|
|
return([infoLevel, errorString, errorDescription])
|
|
}
|
|
|
|
}
|
|
}
|