Warning, /network/tokodon/src/content/ui/TimelinePage.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.14 as Kirigami
0006 import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
0007 import QtQuick.Controls 2.15 as QQC2
0008 import QtQuick.Layouts 1.15
0009 import org.kde.kmasto 1.0
0010 import './StatusDelegate'
0011 import './StatusComposer'
0012 
0013 Kirigami.ScrollablePage {
0014     id: root
0015 
0016     property var dialog: null
0017     required property var model
0018     property bool expandedPost: false
0019     property alias listViewHeader: listview.header
0020     property alias showPostAction: postAction.visible
0021 
0022     title: model.displayName
0023     titleDelegate: Kirigami.Heading {
0024         // identical to normal Kirigami headers
0025         Layout.fillWidth: true
0026         Layout.maximumWidth: implicitWidth + 1
0027         Layout.minimumWidth: 0
0028         maximumLineCount: 1
0029         elide: Text.ElideRight
0030 
0031         text: root.title
0032 
0033         textFormat: TextEdit.RichText
0034     }
0035 
0036     header: KirigamiComponents.Banner {
0037         id: message
0038         type: Kirigami.MessageType.Error
0039         width: parent.width
0040 
0041         showCloseButton: true
0042 
0043         actions: Kirigami.Action {
0044             text: i18n("Settings")
0045             icon.name: "settings-configure"
0046             onTriggered: pageStack.pushDialogLayer('qrc:/content/ui/Settings/SettingsPage.qml', {}, { title: i18n("Configure") })
0047         }
0048     }
0049 
0050     globalToolBarStyle: Kirigami.ApplicationHeaderStyle.ToolBar
0051 
0052     onBackRequested: if (dialog) {
0053         dialog.close();
0054         dialog = null;
0055         event.accepted = true;
0056     }
0057 
0058     actions.main: Kirigami.Action {
0059         id: postAction
0060         icon.name: "list-add"
0061         text: i18n("Post")
0062         enabled: AccountManager.hasAccounts
0063         onTriggered: Navigation.openStatusComposer()
0064     }
0065 
0066     Connections {
0067         target: Navigation
0068         function onOpenFullScreenImage(attachments, identity, currentIndex) {
0069             if (root.isCurrentPage) {
0070                 root.dialog = fullScreenImage.createObject(parent, {
0071                     attachments: attachments,
0072                     identity: identity,
0073                     initialIndex: currentIndex,
0074                 });
0075                 root.dialog.open();
0076             }
0077         }
0078     }
0079 
0080     Connections {
0081         target: Controller
0082         function onNetworkErrorOccurred(error) {
0083             message.text = i18nc("@info:status Network status", "Failed to contact server: %1. Please check your settings.", error)
0084             message.visible = true
0085         }
0086     }
0087 
0088     Connections {
0089         target: root.model
0090         function onPostSourceReady(backend, isEdit) {
0091             pageStack.layers.push("./StatusComposer/StatusComposer.qml", {
0092                 purpose: isEdit ? StatusComposer.Edit : StatusComposer.Redraft,
0093                 backend: backend
0094             });
0095         }
0096     }
0097 
0098     ListView {
0099         id: listview
0100         model: root.model
0101 
0102         // HACK: Temporary workaround to help with performance issues
0103         cacheBuffer: 100
0104         Component {
0105             id: fullScreenImage
0106             FullScreenImage {}
0107         }
0108 
0109         delegate: StatusDelegate {
0110             id: status
0111 
0112             timelineModel: root.model
0113             expandedPost: root.expandedPost
0114             showSeparator: index !== ListView.view.count - 1
0115             loading: listview.model.loading
0116             Layout.fillWidth: true
0117 
0118             Connections {
0119                 target: listview
0120 
0121                 function onContentYChanged() {
0122                     const aMin = status.y
0123                     const aMax = status.y + status.height
0124 
0125                     const bMin = listview.contentY
0126                     const bMax = listview.contentY + listview.height
0127 
0128                     if (!root.isCurrentPage) {
0129                         status.inViewPort = false
0130                         return
0131                     }
0132 
0133                     let topEdgeVisible
0134                     let bottomEdgeVisible
0135 
0136                     // we are still checking two rectangles, but if one is bigger than the other
0137                     // just switch which one should be checked.
0138                     if (status.height > listview.height) {
0139                         topEdgeVisible = bMin > aMin && bMin < aMax
0140                         bottomEdgeVisible = bMax > aMin && bMax < aMax
0141                     } else {
0142                         topEdgeVisible = aMin > bMin && aMin < bMax
0143                         bottomEdgeVisible = aMax > bMin && aMax < bMax
0144                     }
0145 
0146                     status.inViewPort = topEdgeVisible || bottomEdgeVisible
0147                 }
0148             }
0149 
0150             Connections {
0151                 target: root
0152 
0153                 function onIsCurrentPageChanged() {
0154                     if (!root.isCurrentPage) {
0155                         status.inViewPort = false
0156                     } else {
0157                         listview.onContentYChanged()
0158                     }
0159                 }
0160             }
0161 
0162             Connections {
0163                 target: appwindow
0164 
0165                 function onIsShowingFullScreenImageChanged() {
0166                     if (appwindow.isShowingFullScreenImage) {
0167                         status.inViewPort = false
0168                     } else {
0169                         listview.onContentYChanged()
0170                     }
0171                 }
0172             }
0173         }
0174 
0175         QQC2.ProgressBar {
0176             visible: listview.model.loading && listview.count === 0
0177             anchors.centerIn: parent
0178             indeterminate: true
0179             anchors.verticalCenterOffset: listViewHeader && listViewHeader.height !== 0 ? Kirigami.Units.gridUnit * 8 : 0
0180         }
0181 
0182         Kirigami.PlaceholderMessage {
0183             anchors.centerIn: parent
0184             text: i18n("No posts")
0185             visible: !listview.model.loading && listview.count === 0
0186             width: parent.width - Kirigami.Units.gridUnit * 4
0187         }
0188     }
0189 }