303 lines
12 KiB
QML
303 lines
12 KiB
QML
// SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
|
|
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
import QtQuick 2.15
|
|
import QtQuick.Controls 2.15 as QQC2
|
|
import QtQuick.Layouts 1.15
|
|
import Qt.labs.qmlmodels 1.0
|
|
|
|
import org.kde.kirigami 2.19 as Kirigami
|
|
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
|
|
|
|
import org.kde.neochat 1.0
|
|
|
|
Kirigami.ScrollablePage {
|
|
id: root
|
|
property var connection
|
|
|
|
property alias keyword: identifierField.text
|
|
property string server
|
|
|
|
title: i18n("Explore Rooms")
|
|
|
|
Component.onCompleted: identifierField.forceActiveFocus()
|
|
|
|
header: QQC2.Control {
|
|
padding: Kirigami.Units.largeSpacing
|
|
|
|
background: Rectangle {
|
|
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
|
Kirigami.Theme.inherit: false
|
|
|
|
color: Kirigami.Theme.backgroundColor
|
|
}
|
|
|
|
contentItem: RowLayout {
|
|
Kirigami.SearchField {
|
|
id: identifierField
|
|
property bool isRoomAlias: text.match(/#(.+):(.+)/g)
|
|
property NeoChatRoom room: isRoomAlias ? connection.roomByAlias(text) : null
|
|
property bool isJoined: room != null
|
|
|
|
Layout.fillWidth: true
|
|
|
|
placeholderText: i18n("Find a room...")
|
|
}
|
|
|
|
QQC2.Button {
|
|
id: joinButton
|
|
|
|
visible: identifierField.isRoomAlias
|
|
|
|
text: identifierField.isJoined ? i18n("View") : i18n("Join")
|
|
highlighted: true
|
|
|
|
onClicked: {
|
|
if (!identifierField.isJoined) {
|
|
Controller.joinRoom(identifierField.text);
|
|
// When joining the room, the room will be opened
|
|
}
|
|
applicationWindow().pageStack.layers.pop();
|
|
}
|
|
}
|
|
|
|
QQC2.ComboBox {
|
|
id: serverField
|
|
|
|
// TODO: in KF6 we should be able to switch to using implicitContentWidthPolicy
|
|
Layout.preferredWidth: Kirigami.Units.gridUnit * 10
|
|
|
|
Component.onCompleted: currentIndex = 0
|
|
|
|
textRole: "url"
|
|
valueRole: "url"
|
|
model: ServerListModel {
|
|
id: serverListModel
|
|
}
|
|
|
|
delegate: Kirigami.BasicListItem {
|
|
id: serverItem
|
|
|
|
label: isAddServerDelegate ? i18n("Add New Server") : url
|
|
subtitle: isHomeServer ? i18n("Home Server") : ""
|
|
|
|
onClicked: if (isAddServerDelegate) {
|
|
addServerSheet.open()
|
|
}
|
|
|
|
trailing: QQC2.ToolButton {
|
|
visible: isAddServerDelegate || isDeletable
|
|
icon.name: isAddServerDelegate ? "list-add" : "dialog-close"
|
|
text: i18n("Add new server")
|
|
Accessible.name: text
|
|
display: QQC2.AbstractButton.IconOnly
|
|
|
|
onClicked: {
|
|
if (serverField.currentIndex === index && isDeletable) {
|
|
serverField.currentIndex = 0
|
|
server = serverField.currentValue
|
|
serverField.popup.close()
|
|
}
|
|
if (isAddServerDelegate) {
|
|
addServerSheet.open()
|
|
serverItem.clicked()
|
|
} else {
|
|
serverListModel.removeServerAtIndex(index)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
onActivated: {
|
|
if (currentIndex !== count - 1) {
|
|
server = currentValue
|
|
}
|
|
}
|
|
|
|
Kirigami.OverlaySheet {
|
|
id: addServerSheet
|
|
|
|
parent: applicationWindow().overlay
|
|
|
|
title: i18nc("@title:window", "Add server")
|
|
|
|
onSheetOpenChanged: if (!serverUrlField.isValidServer && !sheetOpen) {
|
|
serverField.currentIndex = 0
|
|
server = serverField.currentValue
|
|
} else if (sheetOpen) {
|
|
serverUrlField.forceActiveFocus()
|
|
}
|
|
|
|
contentItem: Kirigami.FormLayout {
|
|
QQC2.Label {
|
|
Layout.minimumWidth: Kirigami.Units.gridUnit * 20
|
|
|
|
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")
|
|
color: serverUrlField.length > 0 ? (serverUrlField.acceptableInput ? (serverUrlField.isValidServer ? Kirigami.Theme.positiveTextColor : Kirigami.Theme.negativeTextColor) : Kirigami.Theme.negativeTextColor) : Kirigami.Theme.textColor
|
|
}
|
|
QQC2.TextField {
|
|
id: serverUrlField
|
|
|
|
property bool isValidServer: false
|
|
|
|
Kirigami.FormData.label: i18n("Server URL")
|
|
onTextChanged: {
|
|
if(acceptableInput) {
|
|
serverListModel.checkServer(text)
|
|
}
|
|
}
|
|
|
|
validator: RegularExpressionValidator {
|
|
regularExpression: /^[a-zA-Z0-9-]{1,61}\.([a-zA-Z]{2,}|[a-zA-Z0-9-]{2,}\.[a-zA-Z]{2,3})$/
|
|
}
|
|
|
|
Connections {
|
|
target: serverListModel
|
|
function onServerCheckComplete(url, valid) {
|
|
if (url == serverUrlField.text && valid) {
|
|
serverUrlField.isValidServer = true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
QQC2.Button {
|
|
id: okButton
|
|
|
|
text: i18nc("@action:button", "Ok")
|
|
enabled: serverUrlField.acceptableInput && serverUrlField.isValidServer
|
|
onClicked: {
|
|
serverListModel.addServer(serverUrlField.text)
|
|
serverField.currentIndex = serverField.indexOfValue(serverUrlField.text)
|
|
// console.log(serverField.delegate.label)
|
|
server = serverField.currentValue
|
|
serverUrlField.text = ""
|
|
addServerSheet.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
Kirigami.Separator {
|
|
z: 999
|
|
anchors {
|
|
left: parent.left
|
|
right: parent.right
|
|
top: parent.bottom
|
|
}
|
|
}
|
|
}
|
|
|
|
ListView {
|
|
id: publicRoomsListView
|
|
clip: true
|
|
model: PublicRoomListModel {
|
|
id: publicRoomListModel
|
|
|
|
connection: root.connection
|
|
server: root.server
|
|
keyword: root.keyword
|
|
}
|
|
|
|
onContentYChanged: {
|
|
if(publicRoomListModel.hasMore && contentHeight - contentY < publicRoomsListView.height + 200)
|
|
publicRoomListModel.next();
|
|
}
|
|
delegate: Kirigami.AbstractListItem {
|
|
property bool justJoined: false
|
|
width: publicRoomsListView.width
|
|
onClicked: {
|
|
if (!isJoined) {
|
|
Controller.joinRoom(roomID)
|
|
justJoined = true;
|
|
} else {
|
|
RoomManager.enterRoom(connection.room(roomID))
|
|
}
|
|
applicationWindow().pageStack.layers.pop();
|
|
}
|
|
contentItem: RowLayout {
|
|
KirigamiComponents.Avatar {
|
|
Layout.preferredWidth: Kirigami.Units.gridUnit * 2
|
|
Layout.preferredHeight: Kirigami.Units.gridUnit * 2
|
|
|
|
source: model.avatar ? ("image://mxc/" + model.avatar) : ""
|
|
name: model.name
|
|
}
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Kirigami.Heading {
|
|
Layout.fillWidth: true
|
|
level: 4
|
|
text: name
|
|
font.bold: true
|
|
textFormat: Text.PlainText
|
|
elide: Text.ElideRight
|
|
wrapMode: Text.NoWrap
|
|
}
|
|
QQC2.Label {
|
|
visible: isJoined || justJoined
|
|
text: i18n("Joined")
|
|
color: Kirigami.Theme.linkColor
|
|
}
|
|
}
|
|
QQC2.Label {
|
|
Layout.fillWidth: true
|
|
visible: text
|
|
text: topic ? topic.replace(/(\r\n\t|\n|\r\t)/gm," ") : ""
|
|
textFormat: Text.PlainText
|
|
elide: Text.ElideRight
|
|
wrapMode: Text.NoWrap
|
|
}
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
Kirigami.Icon {
|
|
source: "user"
|
|
color: Kirigami.Theme.disabledTextColor
|
|
implicitHeight: Kirigami.Units.iconSizes.small
|
|
implicitWidth: Kirigami.Units.iconSizes.small
|
|
}
|
|
QQC2.Label {
|
|
text: memberCount + " " + (alias ?? roomID)
|
|
color: Kirigami.Theme.disabledTextColor
|
|
elide: Text.ElideRight
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
footer: RowLayout {
|
|
width: parent.width
|
|
|
|
QQC2.ProgressBar {
|
|
visible: publicRoomsListView.model.loading && publicRoomsListView.count !== 0
|
|
indeterminate: true
|
|
padding: Kirigami.Units.largeSpacing * 2
|
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
|
Layout.topMargin: Kirigami.Units.largeSpacing
|
|
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
|
Layout.leftMargin: Kirigami.Units.largeSpacing
|
|
Layout.rightMargin: Kirigami.Units.largeSpacing
|
|
}
|
|
}
|
|
|
|
Kirigami.LoadingPlaceholder {
|
|
anchors.centerIn: parent
|
|
visible: publicRoomsListView.model.loading && publicRoomsListView.count === 0
|
|
}
|
|
|
|
Kirigami.PlaceholderMessage {
|
|
anchors.centerIn: parent
|
|
visible: !publicRoomsListView.model.loading && publicRoomsListView.count === 0
|
|
text: i18nc("@info:label", "No rooms found")
|
|
}
|
|
}
|
|
}
|