Warning, /network/neochat/src/qml/JoinRoomPage.qml is written in an unsupported language. File is not indexed.
0001 // SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org> 0002 // SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu> 0003 // SPDX-License-Identifier: GPL-3.0-only 0004 0005 import QtQuick 0006 import QtQuick.Controls as QQC2 0007 import QtQuick.Layouts 0008 import Qt.labs.qmlmodels 0009 0010 import org.kde.kirigami as Kirigami 0011 import org.kde.kirigamiaddons.delegates as Delegates 0012 0013 import org.kde.neochat 0014 0015 Kirigami.ScrollablePage { 0016 id: root 0017 0018 required property NeoChatConnection connection 0019 0020 property bool showOnlySpaces: false 0021 0022 property alias keyword: identifierField.text 0023 property string server 0024 0025 /** 0026 * @brief Signal emitted when a room is selected. 0027 * 0028 * The signal contains all the room's info so that it can be acted 0029 * upon as required, e.g. joinng or entering the room or adding the room as 0030 * the child of a space. 0031 */ 0032 signal roomSelected(string roomId, 0033 string displayName, 0034 url avatarUrl, 0035 string alias, 0036 string topic, 0037 int memberCount, 0038 bool isJoined) 0039 0040 title: i18n("Explore Rooms") 0041 0042 Component.onCompleted: identifierField.forceActiveFocus() 0043 0044 header: QQC2.Control { 0045 padding: Kirigami.Units.largeSpacing 0046 0047 background: Rectangle { 0048 Kirigami.Theme.colorSet: Kirigami.Theme.Window 0049 Kirigami.Theme.inherit: false 0050 0051 color: Kirigami.Theme.backgroundColor 0052 } 0053 0054 contentItem: RowLayout { 0055 Kirigami.SearchField { 0056 id: identifierField 0057 Layout.fillWidth: true 0058 placeholderText: i18n("Find a room...") 0059 } 0060 QQC2.ComboBox { 0061 id: serverField 0062 0063 // TODO: in KF6 we should be able to switch to using implicitContentWidthPolicy 0064 Layout.preferredWidth: Kirigami.Units.gridUnit * 10 0065 0066 Component.onCompleted: currentIndex = 0 0067 0068 textRole: "url" 0069 valueRole: "url" 0070 model: ServerListModel { 0071 id: serverListModel 0072 connection: root.connection 0073 } 0074 0075 delegate: Delegates.RoundedItemDelegate { 0076 id: serverItem 0077 0078 required property int index 0079 required property string url 0080 required property bool isAddServerDelegate 0081 required property bool isHomeServer 0082 required property bool isDeletable 0083 0084 text: isAddServerDelegate ? i18n("Add New Server") : url 0085 highlighted: false 0086 0087 topInset: index === 0 ? Kirigami.Units.smallSpacing : Math.round(Kirigami.Units.smallSpacing / 2) 0088 bottomInset: index === ListView.view.count - 1 ? Kirigami.Units.smallSpacing : Math.round(Kirigami.Units.smallSpacing / 2) 0089 0090 onClicked: if (isAddServerDelegate) { 0091 addServerSheet.open() 0092 } 0093 0094 contentItem: RowLayout { 0095 spacing: Kirigami.Units.smallSpacing 0096 0097 Delegates.SubtitleContentItem { 0098 itemDelegate: serverItem 0099 subtitle: serverItem.isHomeServer ? i18n("Home Server") : "" 0100 Layout.fillWidth: true 0101 } 0102 0103 QQC2.ToolButton { 0104 visible: serverItem.isAddServerDelegate || serverItem.isDeletable 0105 icon.name: serverItem.isAddServerDelegate ? "list-add" : "dialog-close" 0106 text: i18nc("@action:button", "Add new server") 0107 Accessible.name: text 0108 display: QQC2.AbstractButton.IconOnly 0109 0110 onClicked: { 0111 if (serverField.currentIndex === serverItem.index && serverItem.isDeletable) { 0112 serverField.currentIndex = 0; 0113 server = serverField.currentValue; 0114 serverField.popup.close(); 0115 } 0116 if (serverItem.isAddServerDelegate) { 0117 addServerSheet.open(); 0118 serverItem.clicked(); 0119 } else { 0120 serverListModel.removeServerAtIndex(serverItem.index); 0121 } 0122 } 0123 } 0124 } 0125 } 0126 0127 onActivated: { 0128 if (currentIndex !== count - 1) { 0129 server = currentValue 0130 } 0131 } 0132 0133 Kirigami.OverlaySheet { 0134 id: addServerSheet 0135 0136 parent: applicationWindow().overlay 0137 0138 title: i18nc("@title:window", "Add server") 0139 0140 onOpened: if (!serverUrlField.isValidServer && !addServerSheet.opened) { 0141 serverField.currentIndex = 0 0142 server = serverField.currentValue 0143 } else if (addServerSheet.opened) { 0144 serverUrlField.forceActiveFocus() 0145 } 0146 0147 contentItem: Kirigami.FormLayout { 0148 QQC2.Label { 0149 Layout.minimumWidth: Kirigami.Units.gridUnit * 20 0150 0151 text: serverUrlField.length > 0 ? (serverUrlField.acceptableInput ? (serverUrlField.isValidServer ? i18n("Valid server entered") : i18n("This server cannot be resolved or has already been added")) : i18n("The entered text is not a valid url")) : i18n("Enter server url e.g. kde.org") 0152 color: serverUrlField.length > 0 ? (serverUrlField.acceptableInput ? (serverUrlField.isValidServer ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.negativeTextColor) : Kirigami.Theme.negativeTextColor) : Kirigami.Theme.textColor 0153 } 0154 QQC2.TextField { 0155 id: serverUrlField 0156 0157 property bool isValidServer: false 0158 0159 Kirigami.FormData.label: i18n("Server URL") 0160 onTextChanged: { 0161 if(acceptableInput) { 0162 serverListModel.checkServer(text) 0163 } 0164 } 0165 0166 validator: RegularExpressionValidator { 0167 regularExpression: /^[a-zA-Z0-9-]{1,61}\.([a-zA-Z]{2,}|[a-zA-Z0-9-]{2,}\.[a-zA-Z]{2,3})$/ 0168 } 0169 0170 Connections { 0171 target: serverListModel 0172 function onServerCheckComplete(url, valid) { 0173 if (url == serverUrlField.text && valid) { 0174 serverUrlField.isValidServer = true 0175 } 0176 } 0177 } 0178 } 0179 0180 QQC2.Button { 0181 id: okButton 0182 0183 text: i18nc("@action:button", "Ok") 0184 enabled: serverUrlField.acceptableInput && serverUrlField.isValidServer 0185 onClicked: { 0186 serverListModel.addServer(serverUrlField.text) 0187 serverField.currentIndex = serverField.indexOfValue(serverUrlField.text) 0188 server = serverField.currentValue 0189 serverUrlField.text = "" 0190 addServerSheet.close(); 0191 } 0192 } 0193 } 0194 } 0195 0196 } 0197 } 0198 0199 Kirigami.Separator { 0200 z: 999 0201 anchors { 0202 left: parent.left 0203 right: parent.right 0204 top: parent.bottom 0205 } 0206 } 0207 } 0208 0209 ListView { 0210 id: publicRoomsListView 0211 0212 topMargin: Math.round(Kirigami.Units.smallSpacing / 2) 0213 bottomMargin: Math.round(Kirigami.Units.smallSpacing / 2) 0214 0215 model: PublicRoomListModel { 0216 id: publicRoomListModel 0217 0218 connection: root.connection 0219 server: root.server 0220 keyword: root.keyword 0221 showOnlySpaces: root.showOnlySpaces 0222 } 0223 0224 onContentYChanged: { 0225 if(publicRoomListModel.hasMore && contentHeight - contentY < publicRoomsListView.height + 200) 0226 publicRoomListModel.next(); 0227 } 0228 delegate: ExplorerDelegate { 0229 onRoomSelected: (roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => { 0230 root.roomSelected(roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined); 0231 root.closeDialog(); 0232 } 0233 } 0234 0235 header: Delegates.RoundedItemDelegate { 0236 Layout.fillWidth: true 0237 onClicked: _private.openManualRoomDialog() 0238 0239 text: i18n("Enter a room address") 0240 icon.name: "compass" 0241 icon.width: Kirigami.Units.gridUnit * 2 0242 icon.height: Kirigami.Units.gridUnit * 2 0243 } 0244 0245 footer: QQC2.ProgressBar { 0246 width: parent.width 0247 visible: publicRoomsListView.count !== 0 && publicRoomsListView.model.loading 0248 indeterminate: true 0249 padding: Kirigami.Units.largeSpacing * 2 0250 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter 0251 Layout.topMargin: Kirigami.Units.largeSpacing 0252 Layout.bottomMargin: Kirigami.Units.largeSpacing 0253 Layout.leftMargin: Kirigami.Units.largeSpacing 0254 Layout.rightMargin: Kirigami.Units.largeSpacing 0255 } 0256 0257 Kirigami.LoadingPlaceholder { 0258 anchors.centerIn: parent 0259 visible: publicRoomsListView.model.loading && publicRoomsListView.count === 0 0260 } 0261 0262 Kirigami.PlaceholderMessage { 0263 anchors.centerIn: parent 0264 visible: !publicRoomsListView.model.loading && publicRoomsListView.count === 0 0265 text: i18nc("@info:label", "No public rooms found") 0266 } 0267 } 0268 0269 Component { 0270 id: manualRoomDialog 0271 ManualRoomDialog {} 0272 } 0273 0274 QtObject { 0275 id: _private 0276 function openManualRoomDialog() { 0277 let dialog = manualRoomDialog.createObject(applicationWindow().overlay, {connection: root.connection}); 0278 dialog.roomSelected.connect((roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined) => { 0279 root.roomSelected(roomId, displayName, avatarUrl, alias, topic, memberCount, isJoined); 0280 root.closeDialog(); 0281 }); 0282 dialog.open(); 0283 } 0284 } 0285 }