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 }