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 QtQuick.Controls
|
||||||
|
|
||||||
import Util
|
import Util
|
||||||
|
import "Login"
|
||||||
import "PStyle"
|
import "PStyle"
|
||||||
|
|
||||||
Window {
|
Window {
|
||||||
@@ -15,28 +16,8 @@ Window {
|
|||||||
PBackground {
|
PBackground {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
ColumnLayout {
|
Login {
|
||||||
anchors.centerIn: parent
|
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 {
|
ColumnLayout {
|
||||||
property alias label: lbl.text
|
property alias label: lbl.text
|
||||||
property alias placeholderText: tf.placeholderText
|
property alias placeholderText: tf.placeholderText
|
||||||
|
property alias tfText: tf.text
|
||||||
|
property alias pTf: tf
|
||||||
spacing: 2
|
spacing: 2
|
||||||
|
|
||||||
|
signal tfChanged(text: string)
|
||||||
|
signal tfAccepted()
|
||||||
|
|
||||||
PText {
|
PText {
|
||||||
id: lbl
|
id: lbl
|
||||||
font.pointSize: 10
|
font.pointSize: 10
|
||||||
@@ -14,5 +19,8 @@ ColumnLayout {
|
|||||||
PTextField {
|
PTextField {
|
||||||
id: tf
|
id: tf
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
onTextEdited: tfChanged(text)
|
||||||
|
onAccepted: tfAccepted()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,10 +9,10 @@ Button {
|
|||||||
|
|
||||||
background: PBackground {
|
background: PBackground {
|
||||||
id: background
|
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.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: [
|
states: [
|
||||||
@@ -66,6 +66,7 @@ Button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
enabled: btn.enabled
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
anchors.fill: btn
|
anchors.fill: btn
|
||||||
onEntered: {
|
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/PRawButton.qml">PStyle/PRawButton.qml</file>
|
||||||
<file alias="PStyle/PIconButton.qml">PStyle/PIconButton.qml</file>
|
<file alias="PStyle/PIconButton.qml">PStyle/PIconButton.qml</file>
|
||||||
<file alias="PStyle/PIcon.qml">PStyle/PIcon.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>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
@@ -2,9 +2,16 @@
|
|||||||
<qresource prefix="/">
|
<qresource prefix="/">
|
||||||
<file alias="Splash.qml">Gui/Splash.qml</file>
|
<file alias="Splash.qml">Gui/Splash.qml</file>
|
||||||
|
|
||||||
|
<!-- util -->
|
||||||
<file alias="Util/Http.qml">Gui/Util/Http.qml</file>
|
<file alias="Util/Http.qml">Gui/Util/Http.qml</file>
|
||||||
<file alias="Util/qmldir">Gui/Util/qmldir</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>
|
<file alias="Icons/arrow-right.svg">Icons/arrow-right.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
Reference in New Issue
Block a user