diff --git a/android_release.keystore b/android_release.keystore
deleted file mode 100644
index f330509..0000000
Binary files a/android_release.keystore and /dev/null differ
diff --git a/qml/ProfilesDialog.qml b/qml/ProfilesDialog.qml
deleted file mode 100644
index 2cef0ea..0000000
--- a/qml/ProfilesDialog.qml
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- Speed Climbing Stopwatch - Simple Stopwatch for Climbers
- Copyright (C) 2018 Itsblue Development - Dorian Zeder
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, 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 Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see .
-*/
-
-import QtQuick 2.9
-import QtMultimedia 5.8
-import QtQuick.Window 2.2
-import QtQuick.Controls 2.4
-import QtQuick.Layouts 1.3
-import QtGraphicalEffects 1.0
-import com.itsblue.speedclimbingstopwatch 1.0
-import "./components"
-
-
-Popup {
- id: root
-
- modal: true
- dim: false
-
- opacity: 0
-
- enter: Transition {
- NumberAnimation { properties: "opacity"; to: 1; duration: 300; easing.type: Easing.InOutQuad }
- NumberAnimation { properties: "scale"; from: 0.9; to: 1; duration: 300; easing.type: Easing.InOutQuad }
- }
-
- exit: Transition {
- NumberAnimation { properties: "opacity"; to: 0; duration: 300; easing.type: Easing.InOutQuad }
- NumberAnimation { properties: "scale"; from: 1; to: 0.9; duration: 300; easing.type: Easing.InOutQuad }
- }
-
- background: Item {
- RectangularGlow {
- id: backgroundEffect
- glowRadius: 7
- spread: 0.02
- color: "black"
- opacity: 0.18
- anchors.fill: backgroundRect
- cornerRadius: backgroundRect.radius
- scale: 1
- }
-
- Rectangle {
- id: backgroundRect
- anchors.fill: parent
- radius: width * 0.1
- color: appTheme.style.viewColor
- }
- }
-
- StackView {
- id: profiles_stack
- property int text_pixelSize: headlineUnderline.width * 0.08
- //initialItem: profileListComp
- width: headlineUnderline.width
-
- anchors {
- top: topContainerItm.bottom
- left: parent.left
- leftMargin: ( parent.width - headlineUnderline.width ) / 2
- topMargin: headlineUnderline.anchors.topMargin * 1.2
- bottom: parent.bottom
- bottomMargin: topContainerItm.height * 0.3
- }
-
- Behavior on opacity {
- NumberAnimation {duration: 200}
- }
-
- Component.onCompleted: {
- profiles_stack.init()
- }
-
- Connections {
- target: root
- onOpened: {
- profiles_stack.init()
- }
- }
-
- onCurrentItemChanged: {
- currentItem.opened()
- }
-
- function init() {
- if(profiles_stack.depth === 0){
- profiles_stack.openAthletes()
- }
- else {
- profiles_stack.currentItem.opened()
- }
- }
-
- function openAthletes() {
- var athsComp = profileListComp.createObject(null, {})
- profiles_stack.push(athsComp)
- }
-
- function openResults( userName ){
- var resComp = resultViewComp.createObject(null, {"userName": userName})
- profiles_stack.push(resComp)
- }
-
- /*-----List of all profiles-----*/
- Component {
- id: profileListComp
-
- RemoteDataListView {
- id: profileList
-
- property int currentAthlete: -1
- property string title: "profiles"
- property string secondButt: "add"
-
- signal opened()
-
- onOpened: {
- profileList.loadData()
- }
-
- //anchors.fill: parent
- //anchors.topMargin: topContainerItm.height * 0.1
-
- loadData: function () {
- status = 905
- //listData = {}
- var retData = speedBackend.getAthletes()
-
- if(retData === undefined){
- status = 500
- return
- }
-
- listData = retData["allAthletes"]
- currentAthlete = retData["activeAthlete"]
- status = listData.lenght !== false ? 200:0
- }
-
- delegate: SwipeDelegate {
- id: swipeDelegate
-
- property bool active: profileList.currentAthlete === profileList.listData[index]["id"]
-
- text: profileList.listData[index]["fullName"]
- width: profileList.width - (swipeDelegate.x)
- height: profileList.height / 5
-
- font.pixelSize: profiles_stack.text_pixelSize
-
- function remove() {
- removeAnim.start()
- }
-
- onClicked: {
- profiles_stack.openResults(profileList.listData[index]["userName"])
- }
-
- contentItem: Text {
- visible: false
- }
-
- Text {
-
- anchors {
- verticalCenter: parent.verticalCenter
- left: parent.left
- leftMargin: swipeDelegate.width * 0.05
- right: parent.right
- rightMargin: swipeDelegate.rightPadding
- }
-
- text: swipeDelegate.text
- color: appTheme.style.textColor
-
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignLeft
-
- fontSizeMode: Text.Fit
-
- font.pixelSize: swipeDelegate.height * 0.4
-
- minimumPixelSize: 1
- }
-
- background: Rectangle {
- color: pressed ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
-
- Behavior on color {
-
- ColorAnimation {
- duration: 200
- }
- }
- }
-
- CheckBox {
- id: control
-
- anchors {
- verticalCenter: parent.verticalCenter
- right: parent.right
- rightMargin: 7
- }
-
- height: parent.height * 0.6
-
- checked: swipeDelegate.active
-
- onCheckedChanged: {
- if(checked && !swipeDelegate.active && speedBackend.selectAthlete(profileList.listData[index]["userName"])){
- profileList.loadData()
- }
- }
-
- indicator: Rectangle {
- implicitWidth: 26
- implicitHeight: 26
-
- height: parent.height
- width: height
-
- x: control.leftPadding
- y: parent.height / 2 - height / 2
-
- radius: width * 0.2
- border.color: control.down ? "#17a81a" : "#21be2b"
- color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
-
- Rectangle {
- width: parent.width * 0.65
- height: width
- anchors.centerIn: parent
- radius: control.checked ? width * 0.2:0
- color: control.down ? "#17a81a" : "#21be2b"
- opacity: control.checked ? 1:0
- scale: control.checked ? 0.9:0
-
- Behavior on color {
- ColorAnimation {
- duration: 200
- }
- }
-
- Behavior on radius {
- NumberAnimation {
- duration: 200
- }
- }
-
- Behavior on opacity {
- NumberAnimation {
- duration: 200
- }
- }
-
- Behavior on scale {
- NumberAnimation {
- duration: 200
- }
- }
- }
- }
- }
-
- Rectangle {
- color: "grey"
- height: 1
- width: parent.width * 0.9
- visible: index > 0
- anchors {
- horizontalCenter: parent.horizontalCenter
- top: parent.top
- }
- }
-
- NumberAnimation {
- id: removeAnim
- target: swipeDelegate
- property: "height"
- to: 0
- easing.type: Easing.InOutQuad
- onStopped: profileModel.model.remove(index)
- }
-
- swipe.transition: Transition {
- SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic }
- }
-
- swipe.left: Row {
- anchors.left: parent.left
- height: parent.height
-
- Label {
- id: deleteLabel
- text: qsTr("Delete")
- color: appTheme.style.textColor
- verticalAlignment: Label.AlignVCenter
- padding: 12
- height: parent.height
-
- SwipeDelegate.onClicked: {
- profileList.status = 905
- if(speedBackend.deleteAthlete(profileList.listData[index]["userName"])){
- profileList.loadData()
- return
- }
- profileList.status = 200
- }
-
- background: Rectangle {
- color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
- }
- }
- }
- }
- }
-
- }
-
- /*-----Option to add a profile-----*/
- Component {
- id: addProfileComp
- Column {
- property string title: "add profile"
- property string secondButt: "ok"
- property string newProfileName: ""
-
- Connections {
- target: head_add
-
- enabled: true
-
- onClicked: {
- if(speedBackend.createAthlete(userNameTf.text, fullNameTf.text)){
- profiles_stack.get(profiles_stack.depth - 2 ).opened()
- profiles_stack.pop()
- }
- }
- }
-
- TextField {
- id: fullNameTf
- width: parent.width
- placeholderText: "full name"
- onTextChanged: {
- parent.newProfileName = text
- }
- Keys.onReturnPressed: {
- }
- }
- TextField {
- id: userNameTf
- width: parent.width
- placeholderText: "username"
- onTextChanged: {
- parent.newProfileName = text
- }
- Keys.onReturnPressed: {
- }
- }
- }
- }
-
- // --- Result View ---
- Component {
- id: resultViewComp
- RemoteDataListView {
- id: resultView
-
- property string userName
- property string title: userName
- property string secondButt: "none"
-
- signal opened()
-
- anchors.margins: 10
-
- clip: true
-
- onOpened: {
- loadData()
- }
-
- loadData: function () {
- status = 905
- listData = {}
- listData = speedBackend.getResults(userName)
- status = listData.lenght !== false ? 200:0
- }
-
- delegate: SmoothItemDelegate {
- id: resultDel
-
- width: parent.width
- height: resultView.height / 4
-
- backgroundRect.radius: 0
-
- function getDateText(){
- var date = new Date(listData[index]["timestamp"]*1000).toLocaleString(Qt.locale(), "dddd, dd.MMM HH:mm")
- return date
- }
-
- Rectangle {
- color: "grey"
- height: 1
- width: parent.width * 0.9
- visible: index > 0
- anchors {
- horizontalCenter: parent.horizontalCenter
- top: parent.top
- }
- }
-
- Column {
- anchors.fill: parent
- anchors.leftMargin: parent.width * 0.05
-
- Label {
- id: dateLa
-
- height: parent.height / parent.children.length
-
- font.pixelSize: height * 0.8
- fontSizeMode: Text.Fit
-
- color: appTheme.style.textColor
-
- text: resultDel.getDateText()
- }
-
- Label {
- id: resultLa
-
- height: parent.height / parent.children.length
-
- font.pixelSize: height * 0.8
- fontSizeMode: Text.Fit
-
- color: appTheme.style.textColor
-
- text: qsTr("result: ") + (listData[index]["result"] / 1000).toFixed(3) + " s"
- }
-
- Label {
- id: reactionTimeLa
-
- height: parent.height / parent.children.length
-
- font.pixelSize: height * 0.8
- fontSizeMode: Text.Fit
-
- color: appTheme.style.textColor
-
- text: qsTr("reaction time: ") + listData[index]["reactionTime"].toFixed(0) + " ms"
- }
- }
- }
- }
- }
-
- /*-----Custom animations-----*/
- property int animationDuration: 200
- pushEnter: Transition {
- NumberAnimation {
- property: "opacity"
- from: 0
- to: 1
- duration: profiles_stack.animationDuration
- easing.type: Easing.InOutQuad
- }
-
- /*NumberAnimation {
- property: "x"
- from: width * 0.1
- to: 0
- duration: 300
- }*/
-
- NumberAnimation {
- property: "scale"
- from: 1.1
- to: 1
- duration: profiles_stack.animationDuration
- }
- }
- pushExit: Transition {
- NumberAnimation {
- property: "opacity"
- from: 1
- to: 0
- duration: profiles_stack.animationDuration
- easing.type: Easing.InOutQuad
- }
-
- /*NumberAnimation {
- property: "x"
- to: -width * 0.1
- from: 0
- duration: 300
- }*/
-
- NumberAnimation {
- property: "scale"
- from: 1
- to: 0.9
- duration: profiles_stack.animationDuration
- }
- }
-
- popExit: Transition {
- NumberAnimation {
- property: "opacity"
- from: 1
- to: 0
- duration: profiles_stack.animationDuration
- easing.type: Easing.InOutQuad
- }
-
- /*NumberAnimation {
- property: "x"
- to: width * 0.1
- from: 0
- duration: 300
- }*/
-
- NumberAnimation {
- property: "scale"
- from: 1
- to: 1.1
- duration: profiles_stack.animationDuration
- }
- }
- popEnter: Transition {
- NumberAnimation {
- property: "opacity"
- from: 0
- to: 1
- duration: profiles_stack.animationDuration
- easing.type: Easing.InOutQuad
- }
-
- /*NumberAnimation {
- property: "x"
- from: -width * 0.1
- to: 0
- duration: 300
- }*/
-
- NumberAnimation {
- property: "scale"
- from: 0.9
- to: 1
- duration: profiles_stack.animationDuration
- }
- }
- }
-
- Item {
- id: topContainerItm
-
- anchors {
- top: parent.top
- horizontalCenter: parent.horizontalCenter
- }
-
- height: parent.height * 0.15
- width: backgroundRect.width
-
- RectangularGlow {
- id: headerUnderlineEffect
- glowRadius: 7
- spread: 0.02
- color: "black"
- opacity: 0.18
- anchors.fill: headlineUnderline
- scale: 1
- }
-
- Rectangle {
- id: headlineUnderline
- height: 1
- width: parent.width
- color: "grey"
- anchors {
- bottom: parent.bottom
- left: parent.left
- right: parent.right
- }
- }
-
- Canvas {
-
- id: headerBackground
-
- anchors.fill: parent
-
- property color color: appTheme.style.viewColor
-
- onPaint: {
- var ctx = getContext("2d");
-
- var topMargin = backgroundRect.radius
-
-
- ctx.beginPath();
- ctx.fillStyle = headerBackground.color
- ctx.moveTo(width, topMargin);
- //
- //ctx.lineTo(width, topMargin);
- ctx.lineTo(width, height);
- ctx.lineTo(0, height);
- ctx.lineTo(0, topMargin)
-
- ctx.arc(topMargin, topMargin, topMargin, 1 * Math.PI, 1.5*Math.PI, false);
- ctx.lineTo(width-topMargin, 0)
- ctx.arc(width-topMargin, topMargin, topMargin, 1.5*Math.PI, 0, false)
- ctx.fill();
- }
- }
-
- Label {
- id: head_text
-
- anchors {
- centerIn: parent
- }
-
- width: parent.width * 0.8
- height: parent.height * 0.8
-
- fontSizeMode: Text.Fit
- font.pixelSize: headlineUnderline.width * 0.1
- minimumPixelSize: 0
-
- verticalAlignment: Text.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
-
- color: appTheme.style.textColor
-
- text: profiles_stack.currentItem.title
-
- }
-
- }
-
- FancyButton {
- id: head_back
-
- anchors {
- left: parent.left
- leftMargin: -height * 0.3
- top:parent.top
- topMargin: anchors.leftMargin
- }
-
- height: topContainerItm.height * 0.8
- width: height
-
- glowOpacity: Math.pow( root.opacity, 100 )
-
- backgroundColor: appTheme.style.buttonColor
-
- image: appTheme.style.backIcon
-
- onClicked: profiles_stack.depth > 1 ? profiles_stack.pop():root.close()
-
- }
-
- FancyButton {
- id: head_add
-
- anchors {
- right: parent.right
- rightMargin: -height * 0.3
- top:parent.top
- topMargin: anchors.rightMargin
- }
-
- height: topContainerItm.height * 0.8
- width: height
-
- opacity: root.opacity < 1 ? root.opacity : ["ok", "add"].indexOf(profiles_stack.currentItem.secondButt) >= 0 ? 1:0
-
- glowOpacity: opacity < 1 ? Math.pow( opacity, 100 ) : Math.pow( opacity, 100 )
-
- backgroundColor: appTheme.style.buttonColor
-
- image: appTheme.style.confirmIcon
- imageScale: profiles_stack.currentItem.secondButt === "ok" ? 1:0
-
- Label {
- anchors {
- top: parent.top
- topMargin: parent.height/2 - height*0.55
- left: parent.left
- leftMargin: parent.width/2 - width/2
- }
- opacity: profiles_stack.currentItem.secondButt === "add" ? 1:0
-
- color: appTheme.style.textColor
-
- text: "+"
- font.pixelSize: parent.height * 0.8
- }
-
- onClicked: {
- switch(profiles_stack.currentItem.secondButt){
- case "add":
- profiles_stack.push(addProfileComp)
- break
- case "ok":
- //speedBackend.createAthlete(fullNameTf.text, userNameTf.text)
- }
-
- }
-
- Behavior on opacity {
- enabled: root.opacity === 1
- NumberAnimation {
- duration: 200
- }
- }
- }
-
-}
diff --git a/qml/ProfilesDialog/AddProfilePage.qml b/qml/ProfilesDialog/AddProfilePage.qml
new file mode 100644
index 0000000..0617d96
--- /dev/null
+++ b/qml/ProfilesDialog/AddProfilePage.qml
@@ -0,0 +1,67 @@
+/*
+ Speed Climbing Stopwatch - Simple Stopwatch for Climbers
+ Copyright (C) 2018 - 2019 Itsblue Development - Dorian Zeder
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import QtQuick 2.9
+import QtMultimedia 5.8
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.0
+import com.itsblue.speedclimbingstopwatch 1.0
+
+import "../components"
+
+Column {
+ property string title: "add profile"
+ property string secondButt: "ok"
+ property string newProfileName: ""
+
+ Connections {
+ target: head_add
+
+ enabled: true
+
+ onClicked: {
+ if(speedBackend.createAthlete(userNameTf.text, fullNameTf.text)){
+ profilesStack.get(profilesStack.depth - 2 ).opened()
+ profilesStack.pop()
+ }
+ }
+ }
+
+ TextField {
+ id: fullNameTf
+ width: parent.width
+ placeholderText: "full name"
+ onTextChanged: {
+ parent.newProfileName = text
+ }
+ Keys.onReturnPressed: {
+ }
+ }
+ TextField {
+ id: userNameTf
+ width: parent.width
+ placeholderText: "username"
+ onTextChanged: {
+ parent.newProfileName = text
+ }
+ Keys.onReturnPressed: {
+ }
+ }
+}
+
diff --git a/qml/ProfilesDialog/ProfileListPage.qml b/qml/ProfilesDialog/ProfileListPage.qml
new file mode 100644
index 0000000..ae81eb8
--- /dev/null
+++ b/qml/ProfilesDialog/ProfileListPage.qml
@@ -0,0 +1,237 @@
+/*
+ Speed Climbing Stopwatch - Simple Stopwatch for Climbers
+ Copyright (C) 2018 - 2019 Itsblue Development - Dorian Zeder
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import QtQuick 2.9
+import QtMultimedia 5.8
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.0
+import com.itsblue.speedclimbingstopwatch 1.0
+
+import "../components"
+
+
+RemoteDataListView {
+ id: profileList
+
+ property int currentAthlete: -1
+ property string title: "profiles"
+ property string secondButt: "add"
+
+ signal opened()
+
+ onOpened: {
+ profileList.loadData()
+ }
+
+ //anchors.fill: parent
+ //anchors.topMargin: topContainerItm.height * 0.1
+
+ loadData: function () {
+ status = 905
+ //listData = {}
+ var retData = speedBackend.getAthletes()
+
+ if(retData === undefined){
+ status = 500
+ return
+ }
+
+ listData = retData["allAthletes"]
+ currentAthlete = retData["activeAthlete"]
+ status = listData.lenght !== false ? 200:0
+ }
+
+ delegate: SwipeDelegate {
+ id: swipeDelegate
+
+ property bool active: profileList.currentAthlete === profileList.listData[index]["id"]
+
+ text: profileList.listData[index]["fullName"]
+ width: profileList.width - (swipeDelegate.x)
+ height: profileList.height / 5
+
+ font.pixelSize: profilesStack.text_pixelSize
+
+ function remove() {
+ removeAnim.start()
+ }
+
+ onClicked: {
+ profilesStack.openResults(profileList.listData[index]["userName"])
+ }
+
+ contentItem: Text {
+ visible: false
+ }
+
+ Text {
+
+ anchors {
+ verticalCenter: parent.verticalCenter
+ left: parent.left
+ leftMargin: swipeDelegate.width * 0.05
+ right: parent.right
+ rightMargin: swipeDelegate.rightPadding
+ }
+
+ text: swipeDelegate.text
+ color: appTheme.style.textColor
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignLeft
+
+ fontSizeMode: Text.Fit
+
+ font.pixelSize: swipeDelegate.height * 0.4
+
+ minimumPixelSize: 1
+ }
+
+ background: Rectangle {
+ color: pressed ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
+
+ Behavior on color {
+
+ ColorAnimation {
+ duration: 200
+ }
+ }
+ }
+
+ CheckBox {
+ id: control
+
+ anchors {
+ verticalCenter: parent.verticalCenter
+ right: parent.right
+ rightMargin: 7
+ }
+
+ height: parent.height * 0.6
+
+ checked: swipeDelegate.active
+
+ onCheckedChanged: {
+ if(checked && !swipeDelegate.active && speedBackend.selectAthlete(profileList.listData[index]["userName"])){
+ profileList.loadData()
+ }
+ }
+
+ indicator: Rectangle {
+ implicitWidth: 26
+ implicitHeight: 26
+
+ height: parent.height
+ width: height
+
+ x: control.leftPadding
+ y: parent.height / 2 - height / 2
+
+ radius: width * 0.2
+ border.color: control.down ? "#17a81a" : "#21be2b"
+ color: control.down ? appTheme.style.delegatePressedColor : appTheme.style.delegateBackgroundColor
+
+ Rectangle {
+ width: parent.width * 0.65
+ height: width
+ anchors.centerIn: parent
+ radius: control.checked ? width * 0.2:0
+ color: control.down ? "#17a81a" : "#21be2b"
+ opacity: control.checked ? 1:0
+ scale: control.checked ? 0.9:0
+
+ Behavior on color {
+ ColorAnimation {
+ duration: 200
+ }
+ }
+
+ Behavior on radius {
+ NumberAnimation {
+ duration: 200
+ }
+ }
+
+ Behavior on opacity {
+ NumberAnimation {
+ duration: 200
+ }
+ }
+
+ Behavior on scale {
+ NumberAnimation {
+ duration: 200
+ }
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ color: "grey"
+ height: 1
+ width: parent.width * 0.9
+ visible: index > 0
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ }
+ }
+
+ NumberAnimation {
+ id: removeAnim
+ target: swipeDelegate
+ property: "height"
+ to: 0
+ easing.type: Easing.InOutQuad
+ onStopped: profileModel.model.remove(index)
+ }
+
+ swipe.transition: Transition {
+ SmoothedAnimation { velocity: 3; easing.type: Easing.InOutCubic }
+ }
+
+ swipe.left: Row {
+ anchors.left: parent.left
+ height: parent.height
+
+ Label {
+ id: deleteLabel
+ text: qsTr("Delete")
+ color: appTheme.style.textColor
+ verticalAlignment: Label.AlignVCenter
+ padding: 12
+ height: parent.height
+
+ SwipeDelegate.onClicked: {
+ profileList.status = 905
+ if(speedBackend.deleteAthlete(profileList.listData[index]["userName"])){
+ profileList.loadData()
+ return
+ }
+ profileList.status = 200
+ }
+
+ background: Rectangle {
+ color: deleteLabel.SwipeDelegate.pressed ? Qt.darker("tomato", 1.1) : "tomato"
+ }
+ }
+ }
+ }
+}
diff --git a/qml/ProfilesDialog/ProfilesDialog.qml b/qml/ProfilesDialog/ProfilesDialog.qml
new file mode 100644
index 0000000..3c652c3
--- /dev/null
+++ b/qml/ProfilesDialog/ProfilesDialog.qml
@@ -0,0 +1,263 @@
+/*
+ Speed Climbing Stopwatch - Simple Stopwatch for Climbers
+ Copyright (C) 2018 Itsblue Development - Dorian Zeder
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import QtQuick 2.9
+import QtMultimedia 5.8
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.0
+import com.itsblue.speedclimbingstopwatch 1.0
+import "../components"
+
+
+Popup {
+ id: root
+
+ modal: true
+ dim: false
+
+ opacity: 0
+
+ enter: Transition {
+ NumberAnimation { properties: "opacity"; to: 1; duration: 300; easing.type: Easing.InOutQuad }
+ NumberAnimation { properties: "scale"; from: 0.9; to: 1; duration: 300; easing.type: Easing.InOutQuad }
+ }
+
+ exit: Transition {
+ NumberAnimation { properties: "opacity"; to: 0; duration: 300; easing.type: Easing.InOutQuad }
+ NumberAnimation { properties: "scale"; from: 1; to: 0.9; duration: 300; easing.type: Easing.InOutQuad }
+ }
+
+ background: Item {
+ RectangularGlow {
+ id: backgroundEffect
+ glowRadius: 7
+ spread: 0.02
+ color: "black"
+ opacity: 0.18
+ anchors.fill: backgroundRect
+ cornerRadius: backgroundRect.radius
+ scale: 1
+ }
+
+ Rectangle {
+ id: backgroundRect
+ anchors.fill: parent
+ radius: width * 0.1
+ color: appTheme.style.viewColor
+ }
+ }
+
+ ProfilesStack {
+ id: profilesStack
+
+ width: headlineUnderline.width
+
+ anchors {
+ top: topContainerItm.bottom
+ left: parent.left
+ leftMargin: ( parent.width - width ) / 2
+ topMargin: headlineUnderline.anchors.topMargin * 1.2
+ bottom: parent.bottom
+ bottomMargin: topContainerItm.height * 0.3
+ }
+
+ Behavior on opacity {
+ NumberAnimation {duration: 200}
+ }
+
+ Component.onCompleted: {
+ profilesStack.init()
+ }
+
+ Connections {
+ target: root
+ onOpened: {
+ profilesStack.init()
+ }
+ }
+ }
+
+ Item {
+ id: topContainerItm
+
+ anchors {
+ top: parent.top
+ horizontalCenter: parent.horizontalCenter
+ }
+
+ height: parent.height * 0.15
+ width: backgroundRect.width
+
+ RectangularGlow {
+ id: headerUnderlineEffect
+ glowRadius: 7
+ spread: 0.02
+ color: "black"
+ opacity: 0.18
+ anchors.fill: headlineUnderline
+ scale: 1
+ }
+
+ Rectangle {
+ id: headlineUnderline
+ height: 1
+ width: parent.width
+ color: "grey"
+ anchors {
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+ }
+
+ Canvas {
+
+ id: headerBackground
+
+ anchors.fill: parent
+
+ property color color: appTheme.style.viewColor
+
+ onPaint: {
+ var ctx = getContext("2d");
+
+ var topMargin = backgroundRect.radius
+
+
+ ctx.beginPath();
+ ctx.fillStyle = headerBackground.color
+ ctx.moveTo(width, topMargin);
+ //
+ //ctx.lineTo(width, topMargin);
+ ctx.lineTo(width, height);
+ ctx.lineTo(0, height);
+ ctx.lineTo(0, topMargin)
+
+ ctx.arc(topMargin, topMargin, topMargin, 1 * Math.PI, 1.5*Math.PI, false);
+ ctx.lineTo(width-topMargin, 0)
+ ctx.arc(width-topMargin, topMargin, topMargin, 1.5*Math.PI, 0, false)
+ ctx.fill();
+ }
+ }
+
+ Label {
+ id: head_text
+
+ anchors {
+ centerIn: parent
+ }
+
+ width: parent.width * 0.8
+ height: parent.height * 0.8
+
+ fontSizeMode: Text.Fit
+ font.pixelSize: headlineUnderline.width * 0.1
+ minimumPixelSize: 0
+
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+
+ color: appTheme.style.textColor
+
+ text: profilesStack.currentItem.title
+
+ }
+
+ }
+
+ FancyButton {
+ id: head_back
+
+ anchors {
+ left: parent.left
+ leftMargin: -height * 0.3
+ top:parent.top
+ topMargin: anchors.leftMargin
+ }
+
+ height: topContainerItm.height * 0.8
+ width: height
+
+ glowOpacity: Math.pow( root.opacity, 100 )
+
+ backgroundColor: appTheme.style.buttonColor
+
+ image: appTheme.style.backIcon
+
+ onClicked: profilesStack.depth > 1 ? profilesStack.pop():root.close()
+
+ }
+
+ FancyButton {
+ id: head_add
+
+ anchors {
+ right: parent.right
+ rightMargin: -height * 0.3
+ top:parent.top
+ topMargin: anchors.rightMargin
+ }
+
+ height: topContainerItm.height * 0.8
+ width: height
+
+ opacity: root.opacity < 1 ? root.opacity : ["ok", "add"].indexOf(profilesStack.currentItem.secondButt) >= 0 ? 1:0
+
+ glowOpacity: opacity < 1 ? Math.pow( opacity, 100 ) : Math.pow( opacity, 100 )
+
+ backgroundColor: appTheme.style.buttonColor
+
+ image: appTheme.style.confirmIcon
+ imageScale: profilesStack.currentItem.secondButt === "ok" ? 1:0
+
+ Label {
+ anchors {
+ top: parent.top
+ topMargin: parent.height/2 - height*0.55
+ left: parent.left
+ leftMargin: parent.width/2 - width/2
+ }
+ opacity: profilesStack.currentItem.secondButt === "add" ? 1:0
+
+ color: appTheme.style.textColor
+
+ text: "+"
+ font.pixelSize: parent.height * 0.8
+ }
+
+ onClicked: {
+ switch(profilesStack.currentItem.secondButt){
+ case "add":
+ profilesStack.push(addProfileComp)
+ break
+ case "ok":
+ //speedBackend.createAthlete(fullNameTf.text, userNameTf.text)
+ }
+
+ }
+
+ Behavior on opacity {
+ enabled: root.opacity === 1
+ NumberAnimation {
+ duration: 200
+ }
+ }
+ }
+
+}
diff --git a/qml/ProfilesDialog/ProfilesStack.qml b/qml/ProfilesDialog/ProfilesStack.qml
new file mode 100644
index 0000000..6cb9ae1
--- /dev/null
+++ b/qml/ProfilesDialog/ProfilesStack.qml
@@ -0,0 +1,175 @@
+/*
+ Speed Climbing Stopwatch - Simple Stopwatch for Climbers
+ Copyright (C) 2018 - 2019 Itsblue Development - Dorian Zeder
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import QtQuick 2.9
+import QtMultimedia 5.8
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.0
+import com.itsblue.speedclimbingstopwatch 1.0
+
+import "../components"
+
+StackView {
+ id: profilesStack
+ property int text_pixelSize: width * 0.08
+ //initialItem: profileListComp
+
+ onCurrentItemChanged: {
+ currentItem.opened()
+ }
+
+ function init() {
+ if(profilesStack.depth === 0){
+ profilesStack.openAthletes()
+ }
+ else {
+ profilesStack.currentItem.opened()
+ }
+ }
+
+ function openAthletes() {
+ var athsComp = profileListComp.createObject(null, {})
+ profilesStack.push(athsComp)
+ }
+
+ function openResults( userName ){
+ var resComp = resultViewComp.createObject(null, {"userName": userName})
+ profilesStack.push(resComp)
+ }
+
+ /*-----List of all profiles-----*/
+ Component {
+ id: profileListComp
+
+ ProfileListPage {
+
+ }
+ }
+
+ /*-----Option to add a profile-----*/
+ Component {
+ id: addProfileComp
+
+ AddProfilePage {
+
+ }
+ }
+
+ // --- Result View ---
+ Component {
+ id: resultViewComp
+ ResultListPage {}
+ }
+
+ /*-----Custom animations-----*/
+ property int animationDuration: 200
+ pushEnter: Transition {
+ NumberAnimation {
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: profilesStack.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+
+ /*NumberAnimation {
+ property: "x"
+ from: width * 0.1
+ to: 0
+ duration: 300
+ }*/
+
+ NumberAnimation {
+ property: "scale"
+ from: 1.1
+ to: 1
+ duration: profilesStack.animationDuration
+ }
+ }
+ pushExit: Transition {
+ NumberAnimation {
+ property: "opacity"
+ from: 1
+ to: 0
+ duration: profilesStack.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+
+ /*NumberAnimation {
+ property: "x"
+ to: -width * 0.1
+ from: 0
+ duration: 300
+ }*/
+
+ NumberAnimation {
+ property: "scale"
+ from: 1
+ to: 0.9
+ duration: profilesStack.animationDuration
+ }
+ }
+
+ popExit: Transition {
+ NumberAnimation {
+ property: "opacity"
+ from: 1
+ to: 0
+ duration: profilesStack.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+
+ /*NumberAnimation {
+ property: "x"
+ to: width * 0.1
+ from: 0
+ duration: 300
+ }*/
+
+ NumberAnimation {
+ property: "scale"
+ from: 1
+ to: 1.1
+ duration: profilesStack.animationDuration
+ }
+ }
+ popEnter: Transition {
+ NumberAnimation {
+ property: "opacity"
+ from: 0
+ to: 1
+ duration: profilesStack.animationDuration
+ easing.type: Easing.InOutQuad
+ }
+
+ /*NumberAnimation {
+ property: "x"
+ from: -width * 0.1
+ to: 0
+ duration: 300
+ }*/
+
+ NumberAnimation {
+ property: "scale"
+ from: 0.9
+ to: 1
+ duration: profilesStack.animationDuration
+ }
+ }
+}
diff --git a/qml/ProfilesDialog/ResultListPage.qml b/qml/ProfilesDialog/ResultListPage.qml
new file mode 100644
index 0000000..a11ed7f
--- /dev/null
+++ b/qml/ProfilesDialog/ResultListPage.qml
@@ -0,0 +1,120 @@
+/*
+ Speed Climbing Stopwatch - Simple Stopwatch for Climbers
+ Copyright (C) 2018 - 2019 Itsblue Development - Dorian Zeder
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, 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 Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see .
+*/
+
+import QtQuick 2.9
+import QtMultimedia 5.8
+import QtQuick.Window 2.2
+import QtQuick.Controls 2.4
+import QtQuick.Layouts 1.3
+import QtGraphicalEffects 1.0
+import com.itsblue.speedclimbingstopwatch 1.0
+import "../components"
+
+RemoteDataListView {
+ id: resultView
+
+ property string userName
+ property string title: userName
+ property string secondButt: "none"
+
+ signal opened()
+
+ anchors.margins: 10
+
+ clip: true
+
+ onOpened: {
+ loadData()
+ }
+
+ loadData: function () {
+ status = 905
+ listData = {}
+ listData = speedBackend.getResults(userName)
+ status = listData.lenght !== false ? 200:0
+ }
+
+ delegate: SmoothItemDelegate {
+ id: resultDel
+
+ width: parent.width
+ height: resultView.height / 4
+
+ backgroundRect.radius: 0
+
+ function getDateText(){
+ var date = new Date(listData[index]["timestamp"]*1000).toLocaleString(Qt.locale(), "dddd, dd.MMM HH:mm")
+ return date
+ }
+
+ Rectangle {
+ color: "grey"
+ height: 1
+ width: parent.width * 0.9
+ visible: index > 0
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ }
+ }
+
+ Column {
+ anchors.fill: parent
+ anchors.leftMargin: parent.width * 0.05
+
+ Label {
+ id: dateLa
+
+ height: parent.height / parent.children.length
+
+ font.pixelSize: height * 0.8
+ fontSizeMode: Text.Fit
+
+ color: appTheme.style.textColor
+
+ text: resultDel.getDateText()
+ }
+
+ Label {
+ id: resultLa
+
+ height: parent.height / parent.children.length
+
+ font.pixelSize: height * 0.8
+ fontSizeMode: Text.Fit
+
+ color: appTheme.style.textColor
+
+ text: qsTr("result: ") + (listData[index]["result"] / 1000).toFixed(3) + " s"
+ }
+
+ Label {
+ id: reactionTimeLa
+
+ height: parent.height / parent.children.length
+
+ font.pixelSize: height * 0.8
+ fontSizeMode: Text.Fit
+
+ color: appTheme.style.textColor
+
+ text: qsTr("reaction time: ") + listData[index]["reactionTime"].toFixed(0) + " ms"
+ }
+ }
+ }
+}
+
diff --git a/qml/main.qml b/qml/main.qml
index 4b85415..9e01649 100644
--- a/qml/main.qml
+++ b/qml/main.qml
@@ -22,6 +22,7 @@ import QtQuick.Controls 2.2
import QtGraphicalEffects 1.0
import "."
import "./components"
+import "./ProfilesDialog"
//import QtQuick.Layouts 1.11
import com.itsblue.speedclimbingstopwatch 2.0
diff --git a/qml/qml.qrc b/qml/qml.qrc
index 1043b1e..db55f87 100644
--- a/qml/qml.qrc
+++ b/qml/qml.qrc
@@ -1,7 +1,6 @@
main.qml
- ProfilesDialog.qml
SettingsDialog.qml
components/ProgressCircle.qml
components/ConnectionDelegate.qml
@@ -16,5 +15,10 @@
components/SmoothSliderDelegate.qml
components/RemoteDataListView.qml
components/FancyBusyIndicator.qml
+ ProfilesDialog/ProfilesDialog.qml
+ ProfilesDialog/ProfilesStack.qml
+ ProfilesDialog/ProfileListPage.qml
+ ProfilesDialog/AddProfilePage.qml
+ ProfilesDialog/ResultListPage.qml
diff --git a/sources/climbingrace.cpp b/sources/climbingrace.cpp
index f827496..a3b174f 100644
--- a/sources/climbingrace.cpp
+++ b/sources/climbingrace.cpp
@@ -459,7 +459,7 @@ QVariant ClimbingRace::getAthletes() {
QVariantMap tmpAthletes = reply["data"].toMap();
- qDebug() << tmpAthletes;
+ //qDebug() << tmpAthletes;
return tmpAthletes;
}