Initial login logic
- Get instance general information - Add BusyIndicator
This commit is contained in:
69
src/Gui/Login/InstanceInput.qml
Normal file
69
src/Gui/Login/InstanceInput.qml
Normal file
@@ -0,0 +1,69 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
import "../PStyle"
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
||||
signal tryInstance(url: string)
|
||||
|
||||
Timer {
|
||||
id: focusTimer
|
||||
running: true
|
||||
onTriggered: instanceInput.pTf.forceActiveFocus()
|
||||
repeat: false
|
||||
interval: 250
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("QutePleroma")
|
||||
font: PStyle.getFont(36)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
Layout.bottomMargin: 8
|
||||
text: "https://"
|
||||
}
|
||||
|
||||
PInputField {
|
||||
id: instanceInput
|
||||
Layout.preferredWidth: 200
|
||||
label: qsTr("Instance URL")
|
||||
placeholderText: "ak.gensokyo.shop"
|
||||
|
||||
onTfChanged: (text) => {
|
||||
let url;
|
||||
|
||||
try {
|
||||
url = new URL(`https://${text}`)
|
||||
} catch (_) {
|
||||
btn.enabled = false
|
||||
return
|
||||
}
|
||||
|
||||
btn.enabled = true
|
||||
}
|
||||
|
||||
onTfAccepted: getInstanceInfo()
|
||||
}
|
||||
|
||||
PIconButton {
|
||||
id: btn
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
pIcon.name: "arrow-right"
|
||||
enabled: false
|
||||
|
||||
onPressed: getInstanceInfo()
|
||||
}
|
||||
}
|
||||
|
||||
function getInstanceInfo() {
|
||||
btn.enabled = false
|
||||
const instanceUrl = `https://${instanceInput.tfText}`
|
||||
tryInstance(instanceUrl)
|
||||
}
|
||||
}
|
||||
20
src/Gui/Login/LoadingInfo.qml
Normal file
20
src/Gui/Login/LoadingInfo.qml
Normal file
@@ -0,0 +1,20 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
import "../PStyle"
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 32
|
||||
|
||||
PBusyIndicator {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredHeight: 48
|
||||
running: true
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Loading instance information...")
|
||||
}
|
||||
}
|
||||
125
src/Gui/Login/Login.qml
Normal file
125
src/Gui/Login/Login.qml
Normal file
@@ -0,0 +1,125 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQml
|
||||
|
||||
import Util
|
||||
import "../PStyle"
|
||||
|
||||
PStackView {
|
||||
id: login
|
||||
initialItem: instanceInput
|
||||
|
||||
property var instanceInfo
|
||||
|
||||
Component {
|
||||
id: instanceInput
|
||||
|
||||
Rectangle {
|
||||
InstanceInput {
|
||||
anchors.centerIn: parent
|
||||
|
||||
onTryInstance: (instanceUrl) => {
|
||||
login.push(loadInstance)
|
||||
|
||||
Http.getRequest(
|
||||
`${instanceUrl}/api/v1/instance`,
|
||||
(body) => {
|
||||
const json = JSON.parse(body)
|
||||
print(`Instance name: ${json.title}`)
|
||||
print(`Instance description: ${json.description}`)
|
||||
instanceInfo = json
|
||||
login.replace(infoScreen)
|
||||
},
|
||||
(err) => {
|
||||
print(err)
|
||||
login.pop()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: loadInstance
|
||||
|
||||
Rectangle {
|
||||
LoadingInfo {
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: infoScreen
|
||||
|
||||
Rectangle {
|
||||
ColumnLayout {
|
||||
id: info
|
||||
anchors.centerIn: parent
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: instanceInfo.title
|
||||
font: PStyle.getFont(36)
|
||||
}
|
||||
|
||||
Image {
|
||||
id: instanceLogo
|
||||
|
||||
source: instanceInfo.thumbnail
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.maximumWidth: 120
|
||||
Layout.maximumHeight: Layout.maximumWidth
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: instanceInfo.description
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `uri: ${instanceInfo.uri}`
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `version: ${instanceInfo.version}`
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `known domains: ${instanceInfo.stats.domain_count}`
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `known users: ${instanceInfo.stats.remote_user_count}`
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `status count: ${instanceInfo.stats.status_count}`
|
||||
}
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: `user count: ${instanceInfo.stats.user_count}`
|
||||
}
|
||||
|
||||
PTextButton {
|
||||
text: qsTr("Back")
|
||||
enabled: true
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
onClicked: {
|
||||
login.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
import Util
|
||||
import "Login"
|
||||
import "PStyle"
|
||||
|
||||
Window {
|
||||
@@ -15,28 +16,8 @@ Window {
|
||||
PBackground {
|
||||
anchors.fill: parent
|
||||
|
||||
ColumnLayout {
|
||||
Login {
|
||||
anchors.centerIn: parent
|
||||
|
||||
PText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("QutePleroma")
|
||||
font: PStyle.getFont(36)
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
PInputField {
|
||||
Layout.preferredWidth: 200
|
||||
label: qsTr("Instance URL")
|
||||
placeholderText: "ak.gensokyo.shop"
|
||||
}
|
||||
|
||||
PIconButton {
|
||||
id: btn
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
pIcon.name: "arrow-right"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/Gui/Style/PStyle/PBusyIndicator.qml
Normal file
66
src/Gui/Style/PStyle/PBusyIndicator.qml
Normal file
@@ -0,0 +1,66 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
import "."
|
||||
|
||||
BusyIndicator {
|
||||
id: control
|
||||
|
||||
contentItem: Item {
|
||||
width: height
|
||||
height: control.height
|
||||
|
||||
Item {
|
||||
id: item
|
||||
|
||||
x: 0
|
||||
y: 0
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
opacity: control.running ? 1 : 0
|
||||
|
||||
Behavior on opacity {
|
||||
OpacityAnimator {
|
||||
duration: PStyle.animationDuration
|
||||
}
|
||||
}
|
||||
|
||||
RotationAnimator {
|
||||
target: item
|
||||
running: control.running && control.visible
|
||||
from: 0
|
||||
to: 360
|
||||
loops: Animation.Infinite
|
||||
duration: PStyle.animationDuration * 12
|
||||
}
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
model: 5
|
||||
|
||||
Rectangle {
|
||||
id: delegate
|
||||
x: item.width / 2 - width / 2
|
||||
y: item.height / 2 - height / 2
|
||||
implicitWidth: 8
|
||||
implicitHeight: 8
|
||||
radius: width / 2
|
||||
color: Qt.darker(PStyle.foreColor, 1.2)
|
||||
|
||||
required property int index
|
||||
|
||||
transform: [
|
||||
Translate {
|
||||
y: -Math.min(item.width, item.height) * 0.5 + 5
|
||||
},
|
||||
Rotation {
|
||||
angle: delegate.index / repeater.count * 360
|
||||
origin.x: 5
|
||||
origin.y: 5
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,13 @@ import "."
|
||||
ColumnLayout {
|
||||
property alias label: lbl.text
|
||||
property alias placeholderText: tf.placeholderText
|
||||
property alias tfText: tf.text
|
||||
property alias pTf: tf
|
||||
spacing: 2
|
||||
|
||||
signal tfChanged(text: string)
|
||||
signal tfAccepted()
|
||||
|
||||
PText {
|
||||
id: lbl
|
||||
font.pointSize: 10
|
||||
@@ -14,5 +19,8 @@ ColumnLayout {
|
||||
PTextField {
|
||||
id: tf
|
||||
Layout.fillWidth: true
|
||||
|
||||
onTextEdited: tfChanged(text)
|
||||
onAccepted: tfAccepted()
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,10 @@ Button {
|
||||
|
||||
background: PBackground {
|
||||
id: background
|
||||
color: Qt.darker(PStyle.backColor, 1.8)
|
||||
color: btn.enabled ? Qt.darker(PStyle.backColor, 1.8) : Qt.lighter(PStyle.backColor, 2.4)
|
||||
|
||||
border.width: 1
|
||||
border.color: PStyle.foreColor
|
||||
border.color: btn.enabled ? PStyle.foreColor : Qt.darker(PStyle.foreColor, 1.4) // Qt.hsva(0, 1, 0.5, 1)
|
||||
}
|
||||
|
||||
states: [
|
||||
@@ -66,6 +66,7 @@ Button {
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
enabled: btn.enabled
|
||||
hoverEnabled: true
|
||||
anchors.fill: btn
|
||||
onEntered: {
|
||||
|
||||
41
src/Gui/Style/PStyle/PStackView.qml
Normal file
41
src/Gui/Style/PStyle/PStackView.qml
Normal file
@@ -0,0 +1,41 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import "."
|
||||
|
||||
StackView {
|
||||
pushEnter: Transition {
|
||||
PropertyAnimation {
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: PStyle.animationDuration
|
||||
}
|
||||
}
|
||||
|
||||
pushExit: Transition {
|
||||
PropertyAnimation {
|
||||
property: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: PStyle.animationDuration
|
||||
}
|
||||
}
|
||||
|
||||
popEnter: Transition {
|
||||
PropertyAnimation {
|
||||
property: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: PStyle.animationDuration
|
||||
}
|
||||
}
|
||||
|
||||
popExit: Transition {
|
||||
PropertyAnimation {
|
||||
property: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: PStyle.animationDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,7 @@
|
||||
<file alias="PStyle/PRawButton.qml">PStyle/PRawButton.qml</file>
|
||||
<file alias="PStyle/PIconButton.qml">PStyle/PIconButton.qml</file>
|
||||
<file alias="PStyle/PIcon.qml">PStyle/PIcon.qml</file>
|
||||
<file alias="PStyle/PBusyIndicator.qml">PStyle/PBusyIndicator.qml</file>
|
||||
<file alias="PStyle/PStackView.qml">PStyle/PStackView.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -2,9 +2,16 @@
|
||||
<qresource prefix="/">
|
||||
<file alias="Splash.qml">Gui/Splash.qml</file>
|
||||
|
||||
<!-- util -->
|
||||
<file alias="Util/Http.qml">Gui/Util/Http.qml</file>
|
||||
<file alias="Util/qmldir">Gui/Util/qmldir</file>
|
||||
|
||||
<!-- login -->
|
||||
<file alias="Login/Login.qml">Gui/Login/Login.qml</file>
|
||||
<file alias="Login/InstanceInput.qml">Gui/Login/InstanceInput.qml</file>
|
||||
<file alias="Login/LoadingInfo.qml">Gui/Login/LoadingInfo.qml</file>
|
||||
|
||||
<!-- resources -->
|
||||
<file alias="Icons/arrow-right.svg">Icons/arrow-right.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
Reference in New Issue
Block a user