Add join room page

This commit is contained in:
Carl Schwan
2020-11-10 17:08:13 +00:00
parent 9de51fc77e
commit b0700726f9
11 changed files with 244 additions and 303 deletions

View File

@@ -1,269 +0,0 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import org.kde.kirigami 2.13 as Kirigami
import NeoChat.Component 2.0
import NeoChat.Effect 2.0
import NeoChat.Setting 0.1
import org.kde.neochat 0.1
Dialog {
property var connection
property string keyword
property string server
anchors.centerIn: parent
width: 480
height: Math.min(window.height - 100, 800)
id: root
title: "Explore Rooms"
contentItem: ColumnLayout {
spacing: 0
RowLayout {
Layout.fillWidth: true
AutoTextField {
property bool isRoomAlias: text.match(/#(.+):(.+)/g)
property var room: isRoomAlias ? connection.roomByAlias(text) : null
property bool isJoined: room != null
Layout.fillWidth: true
id: identifierField
placeholderText: "Find a room..."
onEditingFinished: {
keyword = text
}
}
Button {
id: joinButton
visible: identifierField.isRoomAlias
text: identifierField.isJoined ? "View" : "Join"
highlighted: true
flat: identifierField.isJoined
onClicked: {
if (identifierField.isJoined) {
roomListForm.joinRoom(identifierField.room)
} else {
Controller.joinRoom(connection, identifierField.text)
}
}
}
ComboBox {
Layout.maximumWidth: 120
id: serverField
editable: currentIndex == 1
model: ["Local", "Global", "matrix.org"]
onCurrentIndexChanged: {
if (currentIndex == 0) {
server = ""
} else if (currentIndex == 2) {
server = "matrix.org"
}
}
Keys.onReturnPressed: {
if (currentIndex == 1) {
server = editText
}
}
}
}
MenuSeparator {
Layout.fillWidth: true
}
AutoListView {
Layout.fillWidth: true
Layout.fillHeight: true
id: publicRoomsListView
clip: true
spacing: 4
model: PublicRoomListModel {
id: publicRoomListModel
connection: root.connection
server: root.server
keyword: root.keyword
}
delegate: Control {
width: publicRoomsListView.width
height: 48
padding: 8
contentItem: RowLayout {
spacing: 8
Kirigami.Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
source: model.avatarMediaId ? "image://mxc/" + model.avatarMediaId : ""
hint: name
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
RowLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 4
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: name
color: MPalette.foreground
font.pixelSize: 13
textFormat: Text.PlainText
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
visible: allowGuests
text: "GUESTS CAN JOIN"
color: MPalette.lighter
font.pixelSize: 10
padding: 4
background: Rectangle {
color: MPalette.banner
}
}
Label {
visible: worldReadable
text: "WORLD READABLE"
color: MPalette.lighter
font.pixelSize: 10
padding: 4
background: Rectangle {
color: MPalette.banner
}
}
}
Label {
Layout.fillWidth: true
Layout.fillHeight: true
visible: text
text: topic ? topic.replace(/(\r\n\t|\n|\r\t)/gm," ") : ""
color: MPalette.lighter
font.pixelSize: 10
textFormat: Text.PlainText
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
MaterialIcon {
Layout.preferredWidth: 16
Layout.preferredHeight: 16
icon: "\ue7fc"
color: MPalette.lighter
font.pixelSize: 16
}
Label {
Layout.preferredWidth: 36
text: memberCount
color: MPalette.lighter
font.pixelSize: 12
}
Control {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
visible: isJoined
contentItem: MaterialIcon {
icon: "\ue89e"
color: MPalette.lighter
font.pixelSize: 20
}
background: RippleEffect {
circular: true
onClicked: {
roomListForm.joinRoom(connection.room(roomID))
root.close()
}
}
}
Control {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
visible: !isJoined
contentItem: MaterialIcon {
icon: "\ue7f0"
color: MPalette.lighter
font.pixelSize: 20
}
background: RippleEffect {
circular: true
onClicked: {
Controller.joinRoom(connection, roomID)
root.close()
}
}
}
}
}
ScrollBar.vertical: ScrollBar {}
onContentYChanged: {
if(publicRoomListModel.hasMore && contentHeight - contentY < publicRoomsListView.height + 200)
publicRoomListModel.next();
}
}
}
onClosed: destroy()
}

View File

@@ -4,7 +4,6 @@ UserDetailDialog 2.0 UserDetailDialog.qml
MessageSourceDialog 2.0 MessageSourceDialog.qml
LoginDialog 2.0 LoginDialog.qml
CreateRoomDialog 2.0 CreateRoomDialog.qml
JoinRoomDialog 2.0 JoinRoomDialog.qml
InviteUserDialog 2.0 InviteUserDialog.qml
AcceptInvitationDialog 2.0 AcceptInvitationDialog.qml
FontFamilyDialog 2.0 FontFamilyDialog.qml

View File

@@ -0,0 +1,173 @@
/**
* SPDX-FileCopyrightText: 2019 Black Hat <bhat@encom.eu.org>
* SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
*
* SPDX-LicenseIdentifier: GPL-3.0-only
*/
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import org.kde.kirigami 2.13 as Kirigami
import NeoChat 2.0
import NeoChat.Component 2.0
import NeoChat.Effect 2.0
import NeoChat.Setting 0.1
import org.kde.neochat 0.1
Kirigami.ScrollablePage {
id: root
property var connection
property string keyword
property string server
signal joinRoom(string room)
title: i18n("Explore Rooms")
header: Control {
padding: Kirigami.Units.largeSpacing
contentItem: RowLayout {
Kirigami.SearchField {
property bool isRoomAlias: text.match(/#(.+):(.+)/g)
property var room: isRoomAlias ? connection.roomByAlias(text) : null
property bool isJoined: room != null
Layout.fillWidth: true
id: identifierField
placeholderText: i18n("Find a room...")
onEditingFinished: {
keyword = text
}
}
Button {
id: joinButton
visible: identifierField.isRoomAlias
text: identifierField.isJoined ? i18n("View") : i18n("Join")
highlighted: true
onClicked: {
if (!identifierField.isJoined) {
Controller.joinRoom(connection, identifierField.text);
}
RoomManager.enterRoom(connection.room(identifierField.room));
applicationWindow().pageStack.layers.pop();
}
}
ComboBox {
Layout.maximumWidth: 120
id: serverField
editable: currentIndex == 1
model: [i18n("Local"), i18n("Global"), "matrix.org"]
onCurrentIndexChanged: {
if (currentIndex == 0) {
server = ""
} else if (currentIndex == 2) {
server = "matrix.org"
}
}
Keys.onReturnPressed: {
if (currentIndex == 1) {
server = editText
}
}
}
}
}
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(connection, roomID)
justJoined = true;
} else {
RoomManager.enterRoom(connection.room(roomID))
applicationWindow().pageStack.layers.pop();
}
}
contentItem: RowLayout {
Kirigami.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.huge
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
source: model.avatar ? "image://mxc/" + model.avatar : ""
name: 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
}
Label {
visible: isJoined || justJoined
text: i18n("Joined")
color: Kirigami.Theme.linkColor
}
}
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
}
Label {
text: memberCount + " " + (alias ?? roomID)
color: Kirigami.Theme.disabledTextColor
elide: Text.ElideRight
Layout.fillWidth: true
}
}
}
}
}
}
}

View File

@@ -12,6 +12,7 @@ import org.kde.kirigami 2.13 as Kirigami
import org.kde.kitemmodels 1.0
import org.kde.neochat 0.1
import NeoChat 2.0
import NeoChat.Component 2.0
import NeoChat.Menu 2.0
@@ -121,17 +122,10 @@ Kirigami.ScrollablePage {
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
onClicked: {
console.log(mouse.button)
if (mouse.button == Qt.RightButton) {
roomListContextMenu.createObject(parent, {"room": currentRoom}).popup()
} else {
if (enteredRoom) {
leaveRoom(enteredRoom)
}
enteredRoom = currentRoom
enterRoom(enteredRoom)
RoomManager.enterRoom(currentRoom)
}
}
}

View File

@@ -3,3 +3,4 @@ LoadingPage 2.0 LoadingPage.qml
LoginPage 2.0 LoginPage.qml
RoomListPage 2.0 RoomListPage.qml
RoomPage 2.0 RoomPage.qml
JoinRoomPage 2.0 JoinRoomPage.qml

View File

@@ -0,0 +1,40 @@
/**
* SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
*
* SPDX-LicenseIdentifier: GPL-2.0-or-later
*/
pragma Singleton
import QtQuick 2.14
import NeoChat.Page 2.0
/**
* Manage opening and close rooms
*/
Item {
id: openRoomAction
property var currentRoom: null
property var pageStack: null
readonly property bool hasOpenRoom: currentRoom != null
signal leaveRoom(string room);
signal openRoom(string room);
function enterRoom(room) {
if (currentRoom != null) {
currentRoom = null;
pageStack.removePage(pageStack.lastItem);
}
pageStack.push(roomPage, {"currentRoom": room});
currentRoom = room;
}
Component {
id: roomPage
RoomPage {}
}
}

1
imports/NeoChat/qmldir Normal file
View File

@@ -0,0 +1 @@
singleton RoomManager 2.0 RoomManager.qml

View File

@@ -5,20 +5,25 @@
* SPDX-LicenseIdentifier: GPL-3.0-only
*/
import QtQuick 2.14
import QtQuick.Controls 2.14 as Controls
import QtQuick.Controls 2.14 as QQC2
import QtQuick.Layouts 1.14
import org.kde.kirigami 2.12 as Kirigami
import org.kde.neochat 0.1
import NeoChat 2.0
import NeoChat.Component 2.0
import NeoChat.Panel 2.0
import NeoChat.Dialog 2.0
import NeoChat.Page 2.0
import NeoChat.Page 2.0
Kirigami.ApplicationWindow {
id: root
property var currentRoom: null
Component.onCompleted: RoomManager.pageStack = root.pageStack
contextDrawer: RoomDrawer {
id: contextDrawer
enabled: root.currentRoomm !== null
@@ -30,16 +35,22 @@ Kirigami.ApplicationWindow {
isMenu: true
actions: [
Kirigami.Action {
text: i18n("About Neochat")
iconName: "help-about"
onTriggered: pageStack.layers.push(aboutPage)
enabled: pageStack.layers.currentItem.title !== i18n("About")
text: i18n("Explore rooms")
iconName: "compass"
onTriggered: pageStack.layers.push("qrc:/imports/NeoChat/Page/JoinRoomPage.qml", {"connection": Controller.connection})
enabled: pageStack.layers.currentItem.title !== i18n("Explore Rooms")
},
Kirigami.Action {
text: i18n("Accounts")
iconName: "im-user"
onTriggered: pageStack.layers.push("qrc:/imports/NeoChat/Page/AccountsPage.qml")
enabled: pageStack.layers.currentItem.title !== i18n("Accounts")
},
Kirigami.Action {
text: i18n("About Neochat")
iconName: "help-about"
onTriggered: pageStack.layers.push(aboutPage)
enabled: pageStack.layers.currentItem.title !== i18n("About")
}
]
}
@@ -58,17 +69,6 @@ Kirigami.ApplicationWindow {
RoomListPage {
id: roomList
roomListModel: spectralRoomListModel
onEnterRoom: {
applicationWindow().pageStack.push(roomPanelComponent, {"currentRoom": room});
root.currentRoom = room;
}
onLeaveRoom: {
var stack = applicationWindow().pageStack;
roomList.enteredRoom = null;
stack.removePage(stack.lastItem);
}
}
}
@@ -103,12 +103,4 @@ Kirigami.ApplicationWindow {
connection: Controller.connection
}
Component {
id: roomPanelComponent
RoomPage {
currentRoom: root.currentRoom
}
}
}

View File

@@ -3,12 +3,15 @@
<file>assets/img/matrix.svg</file>
<file>assets/img/icon.png</file>
<file>qml/main.qml</file>
<file>imports/NeoChat/qmldir</file>
<file>imports/NeoChat/RoomManager.qml</file>
<file>imports/NeoChat/Page/qmldir</file>
<file>imports/NeoChat/Page/LoginPage.qml</file>
<file>imports/NeoChat/Page/LoadingPage.qml</file>
<file>imports/NeoChat/Page/RoomListPage.qml</file>
<file>imports/NeoChat/Page/RoomPage.qml</file>
<file>imports/NeoChat/Page/AccountsPage.qml</file>
<file>imports/NeoChat/Page/JoinRoomPage.qml</file>
<file>imports/NeoChat/Component/qmldir</file>
<file>imports/NeoChat/Component/ChatTextInput.qml</file>
<file>imports/NeoChat/Component/AutoMouseArea.qml</file>
@@ -47,7 +50,6 @@
<file>imports/NeoChat/Dialog/UserDetailDialog.qml</file>
<file>imports/NeoChat/Dialog/MessageSourceDialog.qml</file>
<file>imports/NeoChat/Dialog/CreateRoomDialog.qml</file>
<file>imports/NeoChat/Dialog/JoinRoomDialog.qml</file>
<file>imports/NeoChat/Dialog/InviteUserDialog.qml</file>
<file>imports/NeoChat/Dialog/AcceptInvitationDialog.qml</file>
<file>imports/NeoChat/Dialog/StartChatDialog.qml</file>

View File

@@ -177,6 +177,12 @@ QVariant PublicRoomListModel::data(const QModelIndex &index, int role) const
if (role == RoomIDRole) {
return room.roomId;
}
if (role == AliasRole) {
if (!room.canonicalAlias.isEmpty()) {
return room.canonicalAlias;
}
return {};
}
if (role == MemberCountRole) {
return room.numJoinedMembers;
}
@@ -208,6 +214,7 @@ QHash<int, QByteArray> PublicRoomListModel::roleNames() const
roles[AllowGuestsRole] = "allowGuests";
roles[WorldReadableRole] = "worldReadable";
roles[IsJoinedRole] = "isJoined";
roles[AliasRole] = "alias";
return roles;
}

View File

@@ -24,6 +24,7 @@ public:
AvatarRole,
TopicRole,
RoomIDRole,
AliasRole,
MemberCountRole,
AllowGuestsRole,
WorldReadableRole,