2023-07-30 08:49:34 -04:00
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
2023-09-16 18:15:11 -04:00
import QtQuick
import QtQuick . Controls as QQC2
2023-09-20 16:44:43 -04:00
import QtQuick . Window
2023-09-16 18:15:11 -04:00
import QtQuick . Layouts
import org . kde . kirigami as Kirigami
import org . kde . kirigamiaddons . formcard as FormCard
import zone . xiv . astra
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormCardPage {
2023-07-30 08:49:34 -04:00
id: page
property var account
2023-09-20 15:30:50 -04:00
title: i18nc ( "@title:window" , "Edit Account" )
2023-07-30 08:49:34 -04:00
2024-03-26 17:42:52 -04:00
actions: [
2024-04-19 20:50:14 -04:00
Kirigami . Action {
text: i18n ( "Open User Folder…" )
tooltip: i18n ( "The user folder contains saved appearance data and character settings for this account." )
icon.name: "folder-open-symbolic"
onTriggered: Qt . openUrlExternally ( "file://" + page . account . getConfigPath ( ) )
} ,
2024-03-26 17:42:52 -04:00
Kirigami . Action {
2024-04-01 15:19:15 -04:00
text: i18n ( "Delete Account…" )
2024-03-26 17:42:52 -04:00
tooltip: ! enabled ? i18n ( "Cannot delete the only account." ) : ""
icon.name: "delete"
enabled: LauncherCore . accountManager . canDelete ( page . account )
onTriggered: deletePrompt . open ( )
}
]
2024-07-28 22:40:54 -04:00
header: Kirigami . NavigationTabBar {
width: parent . width
actions: [
Kirigami . Action {
id: generalAction
text: i18n ( "General" )
} ,
Kirigami . Action {
id: accountAction
text: i18n ( "Account" )
} ,
Kirigami . Action {
id: loginAction
text: i18n ( "Login" )
2025-03-17 19:14:20 -04:00
} ,
Kirigami . Action {
id: developerAction
text: i18n ( "Developer" )
2024-07-28 22:40:54 -04:00
}
]
Component.onCompleted: actions [ 0 ] . checked = true
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormCard {
2024-07-28 22:40:54 -04:00
visible: generalAction . checked
2023-08-19 10:30:52 -04:00
Layout.fillWidth: true
2025-02-01 10:05:01 -05:00
Layout.topMargin: Kirigami . Units . largeSpacing * 4
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormTextFieldDelegate {
id: usernameDelegate
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
label: i18n ( "Username" )
2025-03-17 18:27:17 -04:00
text: page . account . config . name
onTextChanged: page . account . config . name = text
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormDelegateSeparator {
above: usernameDelegate
2023-10-08 13:23:18 -04:00
below: languageDelegate
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-10-08 13:23:18 -04:00
FormCard . FormComboBoxDelegate {
id: languageDelegate
text: i18n ( "Language" )
description: i18n ( "The language used in the game client." )
model: [ "Japanese" , "English" , "German" , "French" ]
2025-03-17 18:27:17 -04:00
currentIndex: page . account . config . language
onCurrentIndexChanged: page . account . config . language = currentIndex
2023-10-08 13:23:18 -04:00
}
}
FormCard . FormCard {
2025-03-17 19:40:27 -04:00
visible: accountAction . checked
2023-10-08 13:23:18 -04:00
Layout.fillWidth: true
2025-02-01 10:05:01 -05:00
Layout.topMargin: Kirigami . Units . largeSpacing * 4
2023-10-08 13:23:18 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormComboBoxDelegate {
id: licenseField
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
text: i18n ( "License" )
description: i18n ( "If the account holds multiple licenses, choose the preferred one." )
model: [ "Windows" , "Steam" , "macOS" ]
2025-03-17 18:27:17 -04:00
currentIndex: page . account . config . license
onCurrentIndexChanged: page . account . config . license = currentIndex
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormDelegateSeparator {
above: licenseField
below: freeTrialField
}
2023-07-31 19:01:58 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormCheckDelegate {
id: freeTrialField
text: i18n ( "Free trial" )
2023-10-08 13:23:18 -04:00
description: i18n ( "If the account has a free trial license." )
2025-03-17 18:27:17 -04:00
checked: page . account . config . isFreeTrial
onCheckedChanged: page . account . config . isFreeTrial = checked
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormDelegateSeparator {
above: freeTrialField
below: needOTPField
}
FormCard . FormCheckDelegate {
id: needOTPField
text: i18n ( "Needs a one-time password" )
2023-10-08 13:23:18 -04:00
description: i18n ( "Prompt for the one-time password when logging in." )
2025-03-17 18:27:17 -04:00
checked: page . account . config . useOTP
onCheckedChanged: page . account . config . useOTP = checked
2023-08-19 10:30:52 -04:00
}
FormCard . FormDelegateSeparator {
above: needOTPField
below: lodestoneDelegate
}
2023-07-31 19:01:58 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormButtonDelegate {
id: lodestoneDelegate
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
text: i18n ( "Set Lodestone Character" )
2023-10-08 13:23:18 -04:00
description: i18n ( "Associate a character's avatar with this account for easier identification." )
2023-08-19 10:30:52 -04:00
icon.name: "actor"
Kirigami . PromptDialog {
id: lodestoneDialog
title: i18n ( "Enter Lodestone Id" )
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
standardButtons: Kirigami . Dialog . Ok | Kirigami . Dialog . Cancel
2023-07-30 08:49:34 -04:00
2025-03-17 18:27:17 -04:00
onAccepted: page . account . config . lodestoneId = lodestoneIdField . text
2023-07-30 08:49:34 -04:00
2023-09-16 18:15:11 -04:00
QQC2 . TextField {
2023-08-19 10:30:52 -04:00
id: lodestoneIdField
2025-03-17 18:27:17 -04:00
text: page . account . config . lodestoneId
2023-08-19 10:30:52 -04:00
placeholderText: qsTr ( "123456..." )
2023-07-30 08:49:34 -04:00
}
}
2023-08-19 10:30:52 -04:00
onClicked: lodestoneDialog . open ( )
2023-07-30 08:49:34 -04:00
}
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormCard {
2024-07-28 22:40:54 -04:00
visible: loginAction . checked
2023-08-19 10:30:52 -04:00
Layout.fillWidth: true
2025-02-01 10:05:01 -05:00
Layout.topMargin: Kirigami . Units . largeSpacing * 4
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormCheckDelegate {
id: rememberPasswordDelegate
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
text: i18n ( "Remember password" )
2023-10-08 13:23:18 -04:00
description: i18n ( "Stores the password on the device, using it's existing secure credential storage." )
2025-03-17 18:27:17 -04:00
checked: page . account . config . rememberPassword
onCheckedChanged: page . account . config . rememberPassword = checked
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormDelegateSeparator {
above: rememberPasswordDelegate
below: generateOTPField
}
2023-07-31 19:01:58 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormCheckDelegate {
id: generateOTPField
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
text: i18n ( "Automatically generate one-time passwords" )
2023-10-08 13:23:18 -04:00
description: i18n ( "Stores the one-time password secret on this device, making it inherently insecure. Only use this feature if you understand the risks." )
2025-03-17 18:27:17 -04:00
checked: page . account . config . rememberOTP
onCheckedChanged: page . account . config . rememberOTP = checked
enabled: page . account . config . useOTP
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
FormCard . FormDelegateSeparator {
above: generateOTPField
below: otpSecretDelegate
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
visible: generateOTPField . visible
}
FormCard . FormButtonDelegate {
id: otpSecretDelegate
text: i18n ( "Enter OTP Secret" )
icon.name: "list-add-symbolic"
2025-03-17 18:27:17 -04:00
enabled: page . account . config . rememberOTP
2023-08-19 10:30:52 -04:00
visible: generateOTPField . visible
Kirigami . PromptDialog {
id: otpDialog
title: i18n ( "Enter OTP Secret" )
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
standardButtons: Kirigami . Dialog . Ok | Kirigami . Dialog . Cancel
2023-07-30 08:49:34 -04:00
2023-08-19 10:30:52 -04:00
onAccepted: page . account . setOTPSecret ( otpSecretField . text )
2023-07-30 08:49:34 -04:00
2023-09-16 18:15:11 -04:00
QQC2 . TextField {
2023-08-19 10:30:52 -04:00
id: otpSecretField
placeholderText: qsTr ( "ABCD EFGH..." )
2023-07-30 08:49:34 -04:00
}
}
2023-08-19 10:30:52 -04:00
onClicked: otpDialog . open ( )
2023-07-30 08:49:34 -04:00
}
2023-08-19 10:30:52 -04:00
}
2023-07-30 08:49:34 -04:00
2025-03-17 19:14:20 -04:00
FormCard . FormCard {
visible: developerAction . checked
Layout.fillWidth: true
Layout.topMargin: Kirigami . Units . largeSpacing * 4
FormCard . FormTextFieldDelegate {
id: preferredProtocolDelegate
label: i18n ( "Preferred Protocol" )
text: page . account . config . preferredProtocol
onTextChanged: page . account . config . preferredProtocol = text
}
FormCard . FormDelegateSeparator {
above: preferredProtocolDelegate
below: squareMainServerDelegate
}
FormCard . FormTextFieldDelegate {
id: squareMainServerDelegate
label: i18n ( "SE Main Server (ffxiv.com)" )
text: page . account . config . squareEnixServer
onTextChanged: page . account . config . squareEnixServer = text
}
FormCard . FormDelegateSeparator {
above: squareMainServerDelegate
below: loginServerDelegate
}
FormCard . FormTextFieldDelegate {
id: loginServerDelegate
label: i18n ( "SE Login Server (square-enix.com)" )
text: page . account . config . squareEnixLoginServer
onTextChanged: page . account . config . squareEnixLoginServer = text
}
FormCard . FormDelegateSeparator {
above: loginServerDelegate
below: mainServerDelegate
}
FormCard . FormTextFieldDelegate {
id: mainServerDelegate
label: i18n ( "Main Server (finalfantasyxiv.com)" )
text: page . account . config . mainServer
onTextChanged: page . account . config . mainServer = text
}
FormCard . FormDelegateSeparator {
above: mainServerDelegate
below: gmServerDelegate
}
FormCard . FormTextFieldDelegate {
id: gmServerDelegate
label: i18n ( "GM Server (leave blank for default)" )
text: page . account . config . gMServerHost
onTextChanged: page . account . config . gMServerHost = text
}
FormCard . FormDelegateSeparator {
above: gmServerDelegate
below: gameServerDelegate
}
FormCard . FormTextFieldDelegate {
id: gameServerDelegate
label: i18n ( "Lobby Server (leave blank for default)" )
text: page . account . config . lobbyHost
onTextChanged: page . account . config . lobbyHost = text
}
FormCard . FormDelegateSeparator {
above: gameServerDelegate
below: gameServerPortDelegate
}
FormCard . FormSpinBoxDelegate {
id: gameServerPortDelegate
label: i18n ( "Lobby Server Port" )
value: page . account . config . lobbyHostPort
onValueChanged: page . account . config . lobbyHostPort = value
from: 1
to: 999999
}
}
2024-03-26 17:42:52 -04:00
Kirigami . PromptDialog {
id: deletePrompt
2023-08-19 10:30:52 -04:00
2024-03-26 17:42:52 -04:00
title: i18nc ( "@title" , "Delete Account" )
subtitle: i18nc ( "@label" , "Are you sure you want to delete this account?" )
standardButtons: Kirigami . Dialog . Ok | Kirigami . Dialog . Cancel
showCloseButton: false
2023-08-19 10:53:41 -04:00
2024-03-26 17:42:52 -04:00
onAccepted: {
LauncherCore . accountManager . deleteAccount ( page . account ) ;
page . Window . window . pageStack . layers . pop ( ) ;
2023-07-30 08:49:34 -04:00
}
}
2025-02-01 10:05:01 -05:00
}