2026-02-23 11:15:19 +04:00

203 lines
4.7 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtCore
import Logos.Theme
// qmllint disable unqualified
// Application flow overview:
// On startup, the onboarding screen is shown by default.
// If the storage backend emits a ready event and onboarding is already
// complete, the onboarding screen is immediately replaced by the
// storageComponent.
// Onboarding offers two choices:
// 1. UPnP : the user proceeds directly to the startNodeComponent.
// 2. Port forwarding : the user selects a TCP port before proceeding
// to the startNodeComponent.
// The startNodeComponent waits for the node to start and verifies that
// it is reachable. If the node is unreachable, the user is prompted to
// edit the configuration. Once reachable, clicking "Next" marks
// onboarding as complete.
Item {
id: root
implicitWidth: 800
implicitHeight: 800
Layout.fillWidth: true
Layout.fillHeight: true
property var backend: mockBackend
Connections {
target: root.backend
// When the onboarding is completed,
// the user should have a config save in his
// home folder.
// After the config is loaded, the node will be
// started and the storeComponent will replace
// the stackView item immediatly.
function onReady() {
if (settings.onboardingCompleted) {
root.backend.loadUserConfig()
stackView.replace(storageComponent, StackView.Immediate)
}
}
// If there is any error, display it in a toast view
function onError(message) {
errorToast.show("Error", message)
}
}
Settings {
id: settings
category: "Storage"
property bool onboardingCompleted: false
}
StackView {
id: stackView
anchors.fill: parent
initialItem: modeSelectorComponent
}
Component {
id: modeSelectorComponent
ModeSelector {
onCompleted: function (isGuide) {
if (isGuide) {
stackView.push(onboardingComponent)
} else {
stackView.push(advancedSetupComponent)
}
}
}
}
Component {
id: onboardingComponent
OnBoarding {
backend: root.backend
onBack: stackView.pop()
onCompleted: function (upnpEnabled) {
if (upnpEnabled) {
stackView.push(startNodeComponent)
} else {
stackView.push(portForwardingComponent)
}
}
}
}
Component {
id: advancedSetupComponent
AdvancedSetup {
backend: root.backend
onBack: stackView.pop()
onCompleted: function () {
settings.onboardingCompleted = true
stackView.replace(storageComponent, StackView.Immediate)
}
}
}
Component {
id: storageComponent
StorageView {
backend: root.backend
}
}
Component {
id: startNodeComponent
StartNode {
backend: root.backend
onBack: {
stackView.pop()
}
onNext: {
settings.onboardingCompleted = true
stackView.push(storageComponent)
}
}
}
Component {
id: portForwardingComponent
PortForwarding {
backend: root.backend
loading: false
onBack: {
stackView.pop()
}
onCompleted: function () {
stackView.push(startNodeComponent)
}
}
}
ErrorToast {
id: errorToast
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Theme.spacing.medium
}
QtObject {
id: mockBackend
readonly property bool isMock: true
property int status
signal startCompleted
signal startFailed
signal ready
signal error
signal natExtConfigCompleted
signal nodeIsUp
signal nodeIsntUp
function start() {
console.log("mock start called")
}
function saveUserConfig() {}
function loadUserConfig() {}
function reloadIfChanged() {}
function enableUpnpConfig() {}
function enableNatExtConfig() {
natExtConfigCompleted()
}
function saveCurrentConfig() {}
function stop() {}
function checkNodeIsUp() {}
function guessResolution() {
return ""
}
}
}