Warning, /network/tokodon/src/content/ui/AccountInfo.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu> 0002 // SPDX-License-Identifier: GPL-3.0-only 0003 0004 import QtQuick 2.15 0005 import org.kde.kirigami 2.19 as Kirigami 0006 import QtQuick.Controls 2.15 as QQC2 0007 import QtQml.Models 2.15 0008 import QtQuick.Layouts 1.15 0009 import QtQuick.Dialogs 1.3 0010 import org.kde.kmasto 1.0 0011 0012 TimelinePage { 0013 id: accountInfo 0014 0015 required property string accountId 0016 0017 property var postsBar 0018 0019 readonly property var currentIndex: postsBar ? postsBar.currentIndex : 0 0020 readonly property bool onPostsTab: accountInfo.currentIndex === 0 0021 readonly property bool onRepliesTab: accountInfo.currentIndex === 1 0022 readonly property bool onMediaTab: accountInfo.currentIndex === 2 0023 0024 readonly property bool canExcludeBoosts: accountInfo.onPostsTab || accountInfo.onRepliesTab 0025 property bool excludeBoosts: false 0026 0027 model: AccountModel { 0028 id: model 0029 0030 accountId: accountInfo.accountId 0031 0032 excludeReplies: !accountInfo.onRepliesTab 0033 excludeBoosts: accountInfo.excludeBoosts || accountInfo.onMediaTab 0034 excludePinned: !accountInfo.onPostsTab 0035 onlyMedia: accountInfo.onMediaTab 0036 } 0037 0038 listViewHeader: QQC2.Pane { 0039 width: parent.width 0040 Kirigami.Theme.colorSet: Kirigami.Theme.Window 0041 Kirigami.Theme.inherit: false 0042 leftPadding: 0 0043 rightPadding: 0 0044 bottomPadding: 0 0045 topPadding: 0 0046 0047 contentItem: Loader { 0048 active: model.identity 0049 sourceComponent: ColumnLayout { 0050 spacing: 0 0051 Rectangle { 0052 Layout.preferredHeight: Kirigami.Units.gridUnit * 7 0053 Layout.fillWidth: true 0054 clip: true 0055 color: Kirigami.Theme.backgroundColor 0056 Kirigami.Theme.colorSet: Kirigami.Theme.View 0057 0058 Image { 0059 anchors.centerIn: parent 0060 source: model.identity.backgroundUrl 0061 fillMode: Image.PreserveAspectFit 0062 visible: model.identity.backgroundUrl 0063 } 0064 0065 QQC2.Control { 0066 visible: accountInfo.model.identity.relationship && accountInfo.model.identity.relationship.followedBy 0067 x: Kirigami.Units.smallSpacing 0068 y: Kirigami.Units.smallSpacing 0069 contentItem: QQC2.Label { 0070 text: i18n("Follows you") 0071 color: '#fafafa' 0072 } 0073 0074 background: Rectangle { 0075 radius: 3 0076 color: '#090b0d' 0077 } 0078 } 0079 } 0080 RowLayout { 0081 Layout.leftMargin: Kirigami.Units.largeSpacing 0082 Layout.rightMargin: Kirigami.Units.largeSpacing 0083 Layout.topMargin: Kirigami.Units.smallSpacing 0084 Layout.bottomMargin: Kirigami.Units.smallSpacing 0085 Item { 0086 Layout.minimumWidth: Kirigami.Units.gridUnit * 5 0087 Layout.alignment: Qt.AlignBottom 0088 Kirigami.Avatar { 0089 anchors { 0090 left: parent.left 0091 bottom: parent.bottom 0092 } 0093 cache: true 0094 source: model.identity.avatarUrl 0095 width: Kirigami.Units.gridUnit * 5 0096 height: Kirigami.Units.gridUnit * 5 0097 } 0098 } 0099 Kirigami.ActionToolBar { 0100 Layout.fillWidth: true 0101 Layout.minimumHeight: Kirigami.Units.gridUnit * 2 0102 Layout.alignment: Qt.AlignBottom 0103 alignment: Qt.AlignRight 0104 flat: false 0105 actions: [ 0106 Kirigami.Action { 0107 displayHint: Kirigami.DisplayHint.KeepVisible 0108 text: { 0109 if (model.identity.relationship && model.identity.relationship.requested) { 0110 return i18n("Requested"); 0111 } 0112 if (model.identity.relationship && model.identity.relationship.following) { 0113 return i18n("Following"); 0114 } 0115 return i18n("Follow"); 0116 } 0117 onTriggered: { 0118 if (model.identity.relationship.requested 0119 || model.identity.relationship.following) { 0120 model.account.unfollowAccount(model.identity); 0121 } else { 0122 model.account.followAccount(model.identity); 0123 } 0124 } 0125 visible: !model.isSelf 0126 }, 0127 Kirigami.Action { 0128 displayHint: Kirigami.DisplayHint.KeepVisible 0129 icon.name: { 0130 if (model.identity.relationship && model.identity.relationship.notifying) { 0131 return "notifications"; 0132 } else { 0133 return "notifications-disabled"; 0134 } 0135 } 0136 0137 visible: model.identity.relationship && model.identity.relationship.following && !model.isSelf 0138 tooltip: { 0139 if (model.identity.relationship && model.identity.relationship.notifying) { 0140 return i18n("Stop notifying me when %1 posts", '@' + model.identity.account); 0141 } else { 0142 return i18n("Notify me when %1 posts", '@' + model.identity.account); 0143 } 0144 } 0145 onTriggered: { 0146 if (model.identity.relationship && model.identity.relationship.notifying) { 0147 model.account.followAccount(model.identity, model.identity.relationship.showingReblogs, false); 0148 } else { 0149 model.account.followAccount(model.identity, model.identity.relationship.showingReblogs, true); 0150 } 0151 } 0152 }, 0153 Kirigami.Action { 0154 icon.name: "view-hidden" 0155 displayHint: Kirigami.DisplayHint.AlwaysHide 0156 visible: model.identity.relationship && model.identity.relationship.following && !model.isSelf 0157 text: { 0158 if (model.identity.relationship && model.identity.relationship.showingReblogs) { 0159 return i18n("Hide Boosts from %1", '@' + model.identity.account); 0160 } else { 0161 return i18n("Stop Hiding Boosts from %1", '@' + model.identity.account); 0162 } 0163 } 0164 onTriggered: { 0165 if (model.identity.relationship && model.identity.relationship.showingReblogs) { 0166 model.account.followAccount(model.identity, false, model.identity.relationship.notifying); 0167 } else { 0168 model.account.followAccount(model.identity, true, model.identity.relationship.notifying); 0169 } 0170 } 0171 }, 0172 Kirigami.Action { 0173 icon.name: "favorite" 0174 displayHint: Kirigami.DisplayHint.AlwaysHide 0175 visible: model.identity.relationship && !model.isSelf 0176 text: { 0177 if (model.identity.relationship && model.identity.relationship.endorsed) { 0178 return i18n("Stop Featuring on Profile"); 0179 } else { 0180 return i18n("Feature on Profile"); 0181 } 0182 } 0183 onTriggered: { 0184 if (model.identity.relationship && model.identity.relationship.endorsed) { 0185 model.account.unpin(model.identity); 0186 } else { 0187 model.account.pin(model.identity); 0188 } 0189 } 0190 }, 0191 Kirigami.Action { 0192 icon.name: "dialog-cancel" 0193 displayHint: Kirigami.DisplayHint.AlwaysHide 0194 visible: model.identity.relationship && !model.isSelf 0195 text: { 0196 if (model.identity.relationship && model.identity.relationship.muting) { 0197 return i18n("Stop Muting"); 0198 } else { 0199 return i18n("Mute"); 0200 } 0201 } 0202 onTriggered: { 0203 if (model.identity.relationship && model.identity.relationship.muting) { 0204 model.account.unmuteAccount(model.identity); 0205 } else { 0206 model.account.muteAccount(model.identity); 0207 } 0208 } 0209 }, 0210 Kirigami.Action { 0211 icon.name: "im-ban-kick-user" 0212 displayHint: Kirigami.DisplayHint.AlwaysHide 0213 visible: model.identity.relationship && !model.isSelf 0214 text: { 0215 if (model.identity.relationship && model.identity.relationship.blocking) { 0216 return i18n("Stop Blocking"); 0217 } else { 0218 return i18n("Block"); 0219 } 0220 } 0221 onTriggered: { 0222 if (model.identity.relationship && model.identity.relationship.blocking) { 0223 model.account.unblock(model.identity); 0224 } else { 0225 model.account.block(model.identity); 0226 } 0227 } 0228 }, 0229 Kirigami.Action { 0230 icon.name: "user-group-properties" 0231 displayHint: Kirigami.DisplayHint.AlwaysHide 0232 visible: model.isSelf 0233 text: i18n("Edit Profile") 0234 onTriggered: pageStack.push('qrc:/content/ui/Settings/ProfileEditor.qml', { 0235 account: model.account 0236 }, { 0237 title: i18n("Account editor") 0238 }) 0239 }, 0240 Kirigami.Action { 0241 icon.name: "settings-configure" 0242 displayHint: Kirigami.DisplayHint.AlwaysHide 0243 visible: model.isSelf 0244 text: i18n("Settings") 0245 onTriggered: pageStack.pushDialogLayer('qrc:/content/ui/Settings/SettingsPage.qml', {}, { title: i18n("Configure") }) 0246 }, 0247 Kirigami.Action { 0248 icon.name: "list-add-user" 0249 displayHint: Kirigami.DisplayHint.AlwaysHide 0250 visible: model.isSelf 0251 text: i18n("Follow Requests") 0252 onTriggered: pageStack.push(socialGraphComponent, { name: "request" }); 0253 }, 0254 Kirigami.Action { 0255 icon.name: "microphone-sensitivity-muted" 0256 displayHint: Kirigami.DisplayHint.AlwaysHide 0257 visible: model.isSelf 0258 text: i18n("Muted Accounts") 0259 onTriggered: pageStack.push(socialGraphComponent, { name: "mutes" }); 0260 }, 0261 Kirigami.Action { 0262 icon.name: "cards-block" 0263 displayHint: Kirigami.DisplayHint.AlwaysHide 0264 visible: model.isSelf 0265 text: i18n("Blocked Accounts") 0266 onTriggered: pageStack.push(socialGraphComponent, { name: "blocks" }); 0267 }, 0268 Kirigami.Action { 0269 icon.name: "favorite" 0270 displayHint: Kirigami.DisplayHint.AlwaysHide 0271 visible: model.isSelf 0272 text: i18n("Featured Accounts") 0273 onTriggered: pageStack.push(socialGraphComponent, { name: "featured" }); 0274 }, 0275 Kirigami.Action { 0276 icon.name: "edit-copy" 0277 displayHint: Kirigami.DisplayHint.AlwaysHide 0278 text: i18n("Copy Link to This Profile") 0279 onTriggered: { 0280 Clipboard.saveText(model.identity.url) 0281 applicationWindow().showPassiveNotification(i18n("Post link copied.")); 0282 } 0283 }, 0284 ShareAction { 0285 id: shareAction 0286 0287 displayHint: Kirigami.DisplayHint.AlwaysHide 0288 0289 inputData: { 0290 'urls': [model.identity.url.toString()], 0291 'title': "Profile", 0292 } 0293 } 0294 ] 0295 } 0296 } 0297 0298 Kirigami.Heading { 0299 Layout.fillWidth: true 0300 Layout.leftMargin: Kirigami.Units.largeSpacing 0301 Layout.rightMargin: Kirigami.Units.largeSpacing 0302 text: model.identity.displayName 0303 } 0304 QQC2.TextArea { 0305 text: "@" + model.identity.account 0306 color: Kirigami.Theme.disabledTextColor 0307 textFormat: TextEdit.PlainText 0308 readOnly: true 0309 Layout.fillWidth: true 0310 background: null 0311 topPadding: 0 0312 } 0313 Repeater { 0314 model: accountInfo.model.identity.fields 0315 ColumnLayout { 0316 Layout.fillWidth: true 0317 spacing: 0 0318 Kirigami.Separator { 0319 Layout.fillWidth: true 0320 } 0321 RowLayout { 0322 spacing: 0 0323 QQC2.Pane { 0324 contentItem: QQC2.Label { 0325 text: modelData.name 0326 wrapMode: Text.WordWrap 0327 } 0328 Layout.minimumWidth: Kirigami.Units.gridUnit * 7 0329 Layout.maximumWidth: Kirigami.Units.gridUnit * 7 0330 Kirigami.Theme.colorSet: Kirigami.Theme.View 0331 leftPadding: Kirigami.Units.largeSpacing 0332 rightPadding: Kirigami.Units.largeSpacing 0333 bottomPadding: 0 0334 topPadding: 0 0335 } 0336 0337 QQC2.TextArea { 0338 Layout.fillWidth: true 0339 Layout.fillHeight: true 0340 readOnly: true 0341 wrapMode: Text.WordWrap 0342 background: Rectangle { 0343 color: modelData.verified_at !== null ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor 0344 } 0345 textFormat: TextEdit.RichText 0346 text: modelData.value 0347 onLinkActivated: Qt.openUrlExternally(link) 0348 MouseArea { 0349 anchors.fill: parent 0350 acceptedButtons: Qt.NoButton // don't eat clicks on the Text 0351 cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor 0352 } 0353 } 0354 } 0355 } 0356 } 0357 Kirigami.Separator { 0358 Layout.fillWidth: true 0359 } 0360 RowLayout { 0361 visible: accountInfo.model.identity.relationship 0362 Kirigami.Heading { 0363 Layout.fillWidth: true 0364 Layout.leftMargin: Kirigami.Units.largeSpacing 0365 Layout.rightMargin: Kirigami.Units.largeSpacing 0366 Layout.topMargin: Kirigami.Units.smallSpacing 0367 Layout.bottomMargin: Kirigami.Units.smallSpacing 0368 text: i18n("Note") 0369 level: 4 0370 } 0371 0372 QQC2.Control { 0373 id: savedNotification 0374 visible: false 0375 contentItem: QQC2.Label { 0376 text: i18n("Saved") 0377 color: Kirigami.Theme.positiveTextColor 0378 } 0379 0380 background: Rectangle { 0381 radius: 3 0382 color: Kirigami.Theme.positiveBackgroundColor 0383 } 0384 } 0385 } 0386 QQC2.TextArea { 0387 id: noteField 0388 visible: accountInfo.model.identity.relationship 0389 Layout.fillWidth: true 0390 background: Item {} 0391 placeholderText: i18n("Click to add a note") 0392 textFormat: TextEdit.PlainText 0393 text: accountInfo.model.identity.relationship ? accountInfo.model.identity.relationship.note : '' 0394 Layout.leftMargin: 0 0395 Layout.rightMargin: 0 0396 Layout.topMargin: Kirigami.Units.smallSpacing 0397 Layout.bottomMargin: Kirigami.Units.smallSpacing 0398 property string lastSavedText: '' 0399 onActiveFocusChanged: { 0400 lastSavedText = text; 0401 if (activeFocus) { 0402 autoSaveTimer.start() 0403 } else { 0404 accountInfo.model.account.addNote(accountInfo.model.identity, text); 0405 savedNotification.visible = true; 0406 savedNotificationTimer.restart(); 0407 lastSavedText = text; 0408 autoSaveTimer.stop() 0409 } 0410 } 0411 Timer { 0412 id: autoSaveTimer 0413 running: false 0414 repeat: true 0415 interval: 5000 0416 onTriggered: if (noteField.lastSavedText !== noteField.text) { 0417 accountInfo.model.account.addNote(accountInfo.model.identity, noteField.text); 0418 savedNotification.visible = true; 0419 noteField.lastSavedText = noteField.text; 0420 savedNotificationTimer.restart(); 0421 } 0422 } 0423 0424 Timer { 0425 id: savedNotificationTimer 0426 running: false 0427 interval: 5000 0428 onTriggered: savedNotification.visible = false 0429 } 0430 } 0431 Kirigami.Separator { 0432 Layout.fillWidth: true 0433 visible: noteField.visible 0434 } 0435 QQC2.TextArea { 0436 text: accountInfo.model.identity.bio 0437 textFormat: TextEdit.RichText 0438 readOnly: true 0439 Layout.fillWidth: true 0440 Layout.leftMargin: Kirigami.Units.largeSpacing 0441 Layout.rightMargin: Kirigami.Units.largeSpacing 0442 Layout.topMargin: Kirigami.Units.smallSpacing 0443 Layout.bottomMargin: Kirigami.Units.smallSpacing 0444 leftPadding: 0 0445 rightPadding: 0 0446 bottomPadding: 0 0447 topPadding: 0 0448 background: null 0449 wrapMode: Text.WordWrap 0450 onLinkActivated: Qt.openUrlExternally(link) 0451 MouseArea { 0452 anchors.fill: parent 0453 acceptedButtons: Qt.NoButton // don't eat clicks on the Text 0454 cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor 0455 } 0456 } 0457 RowLayout { 0458 Layout.leftMargin: Kirigami.Units.largeSpacing 0459 Layout.topMargin: Kirigami.Units.largeSpacing 0460 Layout.bottomMargin: Kirigami.Units.largeSpacing 0461 Layout.rightMargin: Kirigami.Units.largeSpacing 0462 0463 Kirigami.Chip { 0464 closable: false 0465 enabled: false 0466 0467 text: i18nc("@label User's number of statuses", "<b>%1</b> posts", model.identity.statusesCount) 0468 } 0469 Kirigami.Chip { 0470 closable: false 0471 checkable: false 0472 0473 onClicked: { 0474 pageStack.push(socialGraphComponent, { 0475 name: "followers", 0476 accountId: accountId, 0477 }); 0478 } 0479 text: i18nc("@label User's number of followers", "<b>%1</b> followers", model.identity.followersCount) 0480 } 0481 Kirigami.Chip { 0482 closable: false 0483 checkable: false 0484 0485 onClicked: { 0486 pageStack.push(socialGraphComponent, { 0487 name: "following", 0488 accountId: accountId, 0489 }); 0490 } 0491 text: i18nc("@label User's number of followed accounts", "<b>%1</b> following", model.identity.followingCount) 0492 } 0493 } 0494 QQC2.TabBar { 0495 id: bar 0496 0497 Component.onCompleted: accountInfo.postsBar = bar 0498 0499 Layout.alignment: Qt.AlignHCenter 0500 Layout.fillWidth: true 0501 0502 QQC2.TabButton { 0503 text: i18nc("@item:inmenu Profile Post Filter", "Posts") 0504 implicitWidth: bar.width / 3 0505 } 0506 QQC2.TabButton { 0507 text: i18nc("@item:inmenu Profile Post Filter", "Posts && Replies") 0508 implicitWidth: bar.width / 3 0509 } 0510 QQC2.TabButton { 0511 text: i18nc("@item:inmenu Profile Post Filter", "Media") 0512 implicitWidth: bar.width / 3 0513 } 0514 } 0515 Rectangle { 0516 Layout.fillWidth: true 0517 0518 implicitHeight: extraLayout.implicitHeight + Kirigami.Units.largeSpacing * 2 0519 0520 Kirigami.Theme.inherit: false 0521 Kirigami.Theme.colorSet: Kirigami.Theme.Header 0522 0523 color: Kirigami.Theme.backgroundColor 0524 0525 RowLayout { 0526 id: extraLayout 0527 0528 anchors { 0529 fill: parent 0530 0531 topMargin: Kirigami.Units.largeSpacing 0532 leftMargin: Kirigami.Units.largeSpacing 0533 rightMargin: Kirigami.Units.largeSpacing 0534 bottomMargin: Kirigami.Units.largeSpacing 0535 } 0536 0537 QQC2.Switch { 0538 text: i18nc("@option:check", "Hide boosts") 0539 0540 onToggled: accountInfo.excludeBoosts = checked 0541 0542 enabled: accountInfo.canExcludeBoosts 0543 } 0544 } 0545 } 0546 Kirigami.Separator { 0547 Layout.fillWidth: true 0548 } 0549 } 0550 } 0551 } 0552 }