Warning, /network/tokodon/src/content/ui/Settings/ProfileEditor.qml is written in an unsupported language. File is not indexed.

0001 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
0002 // SPDX-License-Identifier: LGPL-2.1-or-later
0003 
0004 import QtQuick
0005 import QtQuick.Controls 2 as QQC2
0006 import QtQuick.Layouts
0007 import org.kde.kirigami 2 as Kirigami
0008 import org.kde.tokodon
0009 import QtQuick.Dialogs
0010 import org.kde.kirigamiaddons.formcard 1 as FormCard
0011 import org.kde.kirigamiaddons.components 1 as KirigamiComponents
0012 import Qt5Compat.GraphicalEffects
0013 import ".."
0014 
0015 FormCard.FormCardPage {
0016     id: root
0017 
0018     property var account
0019 
0020     readonly property ProfileEditorBackend backend : ProfileEditorBackend {
0021         account: root.account
0022         onSendNotification: applicationWindow().showPassiveNotification(message)
0023     }
0024 
0025     title: i18n("Edit Account")
0026 
0027     data: Component {
0028         id: openFileDialog
0029         FileDialog {
0030             signal chosen(string path)
0031             title: i18n("Please choose a file")
0032             currentFolder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
0033             onAccepted: chosen(selectedFile)
0034         }
0035     }
0036 
0037     FormCard.FormCard {
0038         Layout.topMargin: Kirigami.Units.largeSpacing
0039 
0040         Rectangle {
0041             Layout.preferredHeight: Kirigami.Units.gridUnit * 9
0042             Layout.fillWidth: true
0043             clip: true
0044             color: Kirigami.Theme.backgroundColor
0045             Kirigami.Theme.colorSet: Kirigami.Theme.View
0046 
0047             Image {
0048                 anchors.centerIn: parent
0049                 source: backend.backgroundUrl
0050                 fillMode: Image.PreserveAspectFit
0051                 visible: backend.backgroundUrl
0052             }
0053 
0054             QQC2.Pane {
0055                 id: pane
0056                 background: Item {
0057                     // Background image
0058                     Image {
0059                         id: bg
0060                         width: pane.width
0061                         height: pane.height
0062                         source: backend.backgroundUrl
0063                     }
0064 
0065                     FastBlur {
0066                         id: blur
0067                         source: bg
0068                         radius: 48
0069                         width: pane.width
0070                         height: pane.height
0071                     }
0072                     ColorOverlay {
0073                         width: pane.width
0074                         height: pane.height
0075                         source: blur
0076                         color: "#66808080"
0077                     }
0078                     Rectangle {
0079                         id: strip
0080                         color: "#66F0F0F0"
0081                         anchors.bottom: parent.bottom;
0082                         height: 2 * Kirigami.Units.gridUnit
0083                         width: parent.width
0084                         visible: children.length > 0
0085                     }
0086                 }
0087                 anchors.bottom: parent.bottom
0088                 anchors.left: parent.left
0089                 anchors.right: parent.right
0090                 contentItem: RowLayout {
0091                     implicitHeight: Kirigami.Units.gridUnit * 5
0092                     KirigamiComponents.Avatar {
0093                         source: backend.avatarUrl
0094                     }
0095 
0096                     Column {
0097                         Layout.fillWidth: true
0098                         Kirigami.Heading {
0099                             level: 5
0100                             text: backend.displayNameHtml
0101                             type: Kirigami.Heading.Primary
0102                             textFormat: Text.RichText
0103                         }
0104                         QQC2.Label {
0105                             text: '@' + account.username + '@' + account.instanceName
0106                         }
0107                     }
0108                 }
0109             }
0110         }
0111 
0112         FormCard.FormTextFieldDelegate {
0113             label: i18n("Display Name")
0114             text: backend.displayName
0115             onTextChanged: backend.displayName = text
0116         }
0117 
0118         FormCard.FormDelegateSeparator {}
0119 
0120         FormCard.AbstractFormDelegate {
0121             background: null
0122             Layout.fillWidth: true
0123 
0124             onClicked: bioField.clicked()
0125             onActiveFocusChanged: if (activeFocus) {
0126                 bioField.forceActiveFocus();
0127             }
0128 
0129             contentItem: ColumnLayout {
0130                 QQC2.Label {
0131                     text: i18n("Bio")
0132                     Layout.fillWidth: true
0133                 }
0134                 QQC2.TextArea {
0135                     id: bioField
0136                     Layout.fillWidth: true
0137                     wrapMode: TextEdit.Wrap
0138                     text: backend.note
0139                     onTextChanged: backend.note = text
0140                     activeFocusOnTab: false
0141 
0142                     KeyNavigation.tab: nextItemInFocusChain(true)
0143                     KeyNavigation.priority: KeyNavigation.BeforeItem
0144                 }
0145             }
0146         }
0147 
0148         FormCard.FormDelegateSeparator {}
0149 
0150         FormCard.AbstractFormDelegate {
0151             id: headerDelegate
0152 
0153             background: null
0154             Layout.fillWidth: true
0155             contentItem: ColumnLayout {
0156                 QQC2.Label {
0157                     text: i18n("Header")
0158                     Layout.fillWidth: true
0159                 }
0160 
0161                 RowLayout {
0162                     Layout.fillWidth: true
0163                     QQC2.RoundButton {
0164                         id: headerUpload
0165                         icon.name: 'cloud-upload'
0166                         property var fileDialog: null;
0167                         Layout.alignment: Qt.AlignHCenter
0168                         onClicked: {
0169                             if (fileDialog !== null) {
0170                                 return;
0171                             }
0172 
0173                             fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.Overlay)
0174 
0175                             fileDialog.onAccepted.connect(function() {
0176                                 const receivedSource = headerUpload.fileDialog.selectedFile;
0177                                 headerUpload.fileDialog = null;
0178                                 if (!receivedSource) {
0179                                     return;
0180                                 }
0181                                 backend.backgroundUrl = receivedSource;
0182                             });
0183                             fileDialog.onRejected.connect(function() {
0184                                 headerUpload.fileDialog = null;
0185                             });
0186                             fileDialog.open();
0187                         }
0188                     }
0189                     QQC2.Label {
0190                         Layout.alignment: Qt.AlignHCenter
0191                         Layout.fillWidth: true
0192                         text: i18n("PNG, GIF or JPG. At most 2 MB. Will be downscaled to 1500x500px")
0193                         wrapMode: Text.WordWrap
0194                     }
0195                 }
0196                 QQC2.Label {
0197                     Layout.fillWidth: true
0198                     visible: text.length > 0
0199                     color: Kirigami.Theme.negativeTextColor
0200                     text: backend.backgroundUrlError
0201                     wrapMode: Text.WordWrap
0202                 }
0203 
0204                 Kirigami.LinkButton {
0205                     text: i18n("Delete")
0206                     color: Kirigami.Theme.negativeTextColor
0207                     Layout.bottomMargin: Kirigami.Units.largeSpacing
0208                     onClicked: backend.backgroundUrl = ''
0209                 }
0210             }
0211         }
0212 
0213         FormCard.FormDelegateSeparator { below: headerDelegate }
0214 
0215         FormCard.AbstractFormDelegate {
0216             background: null
0217             Layout.fillWidth: true
0218             contentItem: ColumnLayout {
0219                 QQC2.Label {
0220                     text: i18n("Avatar")
0221                     Layout.fillWidth: true
0222                 }
0223 
0224                 RowLayout {
0225                     QQC2.RoundButton {
0226                         id: avatarUpload
0227                         icon.name: 'cloud-upload'
0228                         property var fileDialog: null;
0229                         Layout.alignment: Qt.AlignHCenter
0230                         onClicked: {
0231                             if (fileDialog !== null) {
0232                                 return;
0233                             }
0234 
0235                             fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.Overlay)
0236 
0237                             fileDialog.chosen.connect(function(receivedSource) {
0238                                 avatarUpload.fileDialog = null;
0239                                 if (!receivedSource) {
0240                                     return;
0241                                 }
0242                                 backend.avatarUrl = receivedSource;
0243                             });
0244                             fileDialog.onRejected.connect(function() {
0245                                 avatarUpload.fileDialog = null;
0246                             });
0247                             fileDialog.open();
0248                         }
0249                     }
0250                     QQC2.Label {
0251                         Layout.alignment: Qt.AlignHCenter
0252                         Layout.fillWidth: true
0253                         text: i18n("PNG, GIF or JPG. At most 2 MB. Will be downscaled to 400x400px")
0254                         wrapMode: Text.WordWrap
0255                     }
0256                 }
0257 
0258                 QQC2.Label {
0259                     visible: text.length > 0
0260                     Layout.fillWidth: true
0261                     text: backend.avatarUrlError
0262                     wrapMode: Text.WordWrap
0263                     color: Kirigami.Theme.negativeTextColor
0264                 }
0265 
0266                 Kirigami.LinkButton {
0267                     text: i18n("Delete")
0268                     Layout.bottomMargin: Kirigami.Units.largeSpacing
0269                     color: Kirigami.Theme.negativeTextColor
0270                     onClicked: backend.avatarUrl = ''
0271                 }
0272             }
0273         }
0274     }
0275 
0276     FormCard.FormCard {
0277         Layout.topMargin: Kirigami.Units.largeSpacing
0278         Layout.fillWidth: true
0279 
0280         FormCard.FormCheckDelegate {
0281             text: i18n("Require approval of follow requests")
0282             checked: backend.locked
0283             onCheckedChanged: backend.locked = checked
0284         }
0285 
0286         FormCard.FormDelegateSeparator {}
0287 
0288         FormCard.FormCheckDelegate {
0289             text: i18n("This is a bot account")
0290             checked: backend.bot
0291             onCheckedChanged: backend.bot = checked
0292         }
0293 
0294         FormCard.FormDelegateSeparator {}
0295 
0296         FormCard.FormCheckDelegate {
0297             text: i18n("Suggest account to others")
0298             checked: backend.discoverable
0299             onCheckedChanged: backend.discoverable = checked
0300         }
0301 
0302         FormCard.FormDelegateSeparator {}
0303 
0304         FormCard.FormSwitchDelegate {
0305             text: i18nc("@label Account preferences", "Mark uploaded media as sensitive by default")
0306             checked: AccountManager.selectedAccount.preferences.defaultSensitive
0307             onToggled: AccountManager.selectedAccount.preferences.defaultSensitive = checked
0308         }
0309 
0310         FormCard.FormDelegateSeparator {}
0311 
0312         FormCard.FormButtonDelegate {
0313             text: i18nc("@label Account preferences", "Default post language")
0314             description: Qt.locale(AccountManager.selectedAccount.preferences.defaultLanguage).nativeLanguageName
0315 
0316             onClicked: languageSelect.open()
0317 
0318             LanguageSelector {
0319                 id: languageSelect
0320 
0321                 onAboutToShow: {
0322                     const sourceIndex = listView.model.sourceModel.indexOfValue(AccountManager.selectedAccount.preferences.defaultLanguage);
0323                     listView.currentIndex = listView.model.mapFromSource(sourceIndex).row;
0324                 }
0325                 onCodeSelected: code => AccountManager.selectedAccount.preferences.defaultLanguage = code
0326             }
0327         }
0328 
0329         FormCard.FormDelegateSeparator {}
0330 
0331         FormCard.FormComboBoxDelegate {
0332             Layout.fillWidth: true
0333             id: postVisibility
0334             text: i18nc("@label Account preferences", "Default post visibility")
0335             model: [
0336                 i18nc("@item:inlistbox Default post visibility rule", "Public"),
0337                 i18nc("@item:inlistbox Default post visibility rule", "Unlisted"),
0338                 i18nc("@item:inlistbox Default post visibility rule", "Private")
0339             ]
0340             Component.onCompleted: currentIndex = AccountManager.selectedAccount.preferences.defaultVisibility
0341             onCurrentValueChanged: AccountManager.selectedAccount.preferences.defaultVisibility = currentIndex
0342         }
0343     }
0344 
0345     footer: QQC2.ToolBar {
0346         height: visible ? implicitHeight : 0
0347         contentItem: RowLayout {
0348             Item {
0349                 Layout.fillWidth: true
0350             }
0351 
0352             QQC2.Button {
0353                 text: i18n("Reset")
0354                 icon.name: 'edit-reset'
0355                 Layout.margins: Kirigami.Units.smallSpacing
0356                 onClicked: backend.fetchAccountInfo()
0357             }
0358 
0359             QQC2.Button {
0360                 text: i18n("Apply")
0361                 icon.name: 'dialog-ok'
0362                 enabled: backend.backgroundUrlError.length === 0 && backend.avatarUrlError.length === 0
0363                 Layout.margins: Kirigami.Units.smallSpacing
0364                 onClicked: backend.save()
0365             }
0366         }
0367     }
0368 }