Rebrand files names Spectral -> NeoChat

This commit is contained in:
Carl Schwan
2020-11-08 23:17:30 +01:00
parent c2c49c69fe
commit 122a7cdd2f
71 changed files with 787 additions and 273 deletions

View File

@@ -0,0 +1,50 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
Dialog {
property var room
anchors.centerIn: parent
width: 360
id: root
title: "Invitation Received"
modal: true
contentItem: Label {
text: "Accept this invitation?"
}
footer: DialogButtonBox {
Button {
text: "Accept"
flat: true
onClicked: {
room.acceptInvitation()
close()
}
}
Button {
text: "Reject"
flat: true
onClicked: {
room.forget()
close()
}
}
Button {
text: "Cancel"
flat: true
onClicked: close()
}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,350 @@
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 org.kde.neochat 0.1
import NeoChat.Setting 0.1
Dialog {
anchors.centerIn: parent
width: 480
id: root
contentItem: Column {
id: detailColumn
spacing: 0
ListView {
width: parent.width
height: 48
clip: true
orientation: ListView.Horizontal
spacing: 16
model: AccountListModel{ }
delegate: Kirigami.Avatar {
width: 48
height: 48
source: urser.avatarMediaId ? "image://mxc/" + user.avatarMediaId : ""
name: user.displayName ?? ""
Menu {
id: contextMenu
MenuItem {
text: "Mark all as read"
onClicked: Controller.markAllMessagesAsRead(connection)
}
MenuItem {
text: "Logout"
onClicked: Controller.logout(connection)
}
}
RippleEffect {
anchors.fill: parent
circular: true
onPrimaryClicked: Controller.connection = connection
onSecondaryClicked: contextMenu.popup()
}
}
}
RowLayout {
width: parent.width
MenuSeparator {
Layout.fillWidth: true
}
ToolButton {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
contentItem: MaterialIcon {
icon: "\ue145"
color: MPalette.lighter
}
onClicked: loginDialog.createObject(ApplicationWindow.overlay).open()
}
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue5d2"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Explore Rooms"
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: {
joinRoomDialog.createObject(ApplicationWindow.overlay, {"connection": Controller.connection}).open()
root.close()
}
}
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue7ff"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Start a Chat"
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: {
startChatDialog.createObject(ApplicationWindow.overlay, {"connection": Controller.connection}).open()
root.close()
}
}
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue7fc"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Create a Room"
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: createRoomDialog.createObject(ApplicationWindow.overlay).open()
}
}
MenuSeparator {
width: parent.width
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue3a9"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Night Mode"
}
Switch {
id: darkThemeSwitch
checked: MSettings.darkTheme
onCheckedChanged: MSettings.darkTheme = checked
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: darkThemeSwitch.checked = !darkThemeSwitch.checked
}
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue8f8"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Show Join/Leave"
}
Switch {
id: showJoinLeaveSwitch
checked: MSettings.value("UI/show_joinleave", true)
onCheckedChanged: MSettings.setValue("UI/show_joinleave", checked)
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: showJoinLeaveSwitch.checked = !showJoinLeaveSwitch.checked
}
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue5d2"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Enable System Tray"
}
Switch {
id: trayIconSwitch
checked: MSettings.showTray
onCheckedChanged: MSettings.showTray = checked
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: trayIconSwitch.checked = !trayIconSwitch.checked
}
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue7f5"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Enable Notifications"
}
Switch {
id: notificationsSwitch
checked: MSettings.showNotification
onCheckedChanged: MSettings.showNotification = checked
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: notificationsSwitch.checked = !notificationsSwitch.checked
}
}
MenuSeparator {
width: parent.width
}
Control {
width: parent.width
contentItem: RowLayout {
MaterialIcon {
Layout.preferredWidth: 48
Layout.preferredHeight: 48
color: MPalette.foreground
icon: "\ue167"
}
Label {
Layout.fillWidth: true
color: MPalette.foreground
text: "Font Family"
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: fontFamilyDialog.createObject(ApplicationWindow.overlay).open()
}
}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,40 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import NeoChat.Component 2.0
import org.kde.neochat 0.1
Dialog {
anchors.centerIn: parent
width: 360
id: root
title: "Create a Room"
contentItem: ColumnLayout {
AutoTextField {
Layout.fillWidth: true
id: roomNameField
placeholderText: "Room Name"
}
AutoTextField {
Layout.fillWidth: true
id: roomTopicField
placeholderText: "Room Topic"
}
}
standardButtons: Dialog.Ok | Dialog.Cancel
onAccepted: Controller.createRoom(Controller.connection, roomNameField.text, roomTopicField.text)
onClosed: destroy()
}

View File

@@ -0,0 +1,30 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import NeoChat.Component 2.0
import NeoChat.Setting 0.1
Dialog {
anchors.centerIn: parent
width: 360
id: root
title: "Enter Font Family"
contentItem: AutoTextField {
Layout.fillWidth: true
id:fontFamilyField
text: MSettings.fontFamily
placeholderText: "Font Family"
}
standardButtons: Dialog.Ok | Dialog.Cancel
onAccepted: MSettings.fontFamily = fontFamilyField.text
onClosed: destroy()
}

View File

@@ -0,0 +1,170 @@
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 room
anchors.centerIn: parent
width: 360
height: Math.min(window.height - 100, 640)
id: root
title: "Invite a User"
contentItem: ColumnLayout {
spacing: 0
RowLayout {
Layout.fillWidth: true
AutoTextField {
property bool isUserID: text.match(/@(.+):(.+)/g)
Layout.fillWidth: true
id: identifierField
placeholderText: "Find a user..."
onAccepted: {
userDictListModel.search()
}
}
Button {
visible: identifierField.isUserID
text: "Add"
highlighted: true
onClicked: {
room.inviteToRoom(identifierField.text)
}
}
}
MenuSeparator {
Layout.fillWidth: true
}
AutoListView {
Layout.fillWidth: true
Layout.fillHeight: true
id: userDictListView
clip: true
spacing: 4
model: UserDirectoryListModel {
id: userDictListModel
connection: root.room.connection
keyword: identifierField.text
}
delegate: Control {
property bool inRoom: room && room.containsUser(userID)
width: userDictListView.width
height: 48
id: delegate
padding: 8
contentItem: RowLayout {
spacing: 8
Kirigami.Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
source: author.avatarMediaId ? "image://mxc/" + author.avatarMediaId : ""
name: name
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
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 {
Layout.fillWidth: true
Layout.fillHeight: true
text: userID
color: MPalette.lighter
font.pixelSize: 10
textFormat: Text.PlainText
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
Control {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
visible: inRoom
background: RippleEffect {
circular: true
}
}
Control {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
visible: !inRoom
background: RippleEffect {
circular: true
onClicked: {
room.inviteToRoom(userID)
}
}
}
}
}
ScrollBar.vertical: ScrollBar {}
Label {
anchors.centerIn: parent
visible: userDictListView.count < 1
text: "No users available"
color: MPalette.foreground
}
}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,269 @@
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

@@ -0,0 +1,27 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
Popup {
property string sourceText
anchors.centerIn: parent
width: 480
id: root
modal: true
padding: 16
closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside
contentItem: ScrollView {
clip: true
Label {
text: sourceText
}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,12 @@
import QtQuick 2.12
import Qt.labs.platform 1.1
FileDialog {
signal chosen(string path)
id: root
title: "Please choose a file"
onAccepted: chosen(file)
}

View File

@@ -0,0 +1,12 @@
import QtQuick 2.12
import Qt.labs.platform 1.1
FolderDialog {
signal chosen(string path)
id: root
title: "Please choose a folder"
onAccepted: chosen(folder)
}

View File

@@ -0,0 +1,298 @@
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 room
readonly property bool canChangeAvatar: room.canSendState("m.room.avatar")
readonly property bool canChangeName: room.canSendState("m.room.name")
readonly property bool canChangeTopic: room.canSendState("m.room.topic")
readonly property bool canChangeCanonicalAlias: room.canSendState("m.room.canonical_alias")
anchors.centerIn: parent
width: 480
height: window.height * 0.9
id: root
title: "Room Settings - " + room.displayName
modal: true
contentItem: ColumnLayout {
RowLayout {
Layout.fillWidth: true
spacing: 16
Kirigami.Avatar {
Layout.preferredWidth: 72
Layout.preferredHeight: 72
Layout.alignment: Qt.AlignTop
name: room.displayName
source: room.avatarMediaId ? "image://mxc/" + room.avatarMediaId : ""
RippleEffect {
anchors.fill: parent
circular: true
enabled: canChangeAvatar
onClicked: {
var fileDialog = openFileDialog.createObject(ApplicationWindow.overlay)
fileDialog.chosen.connect(function(path) {
if (!path) return
room.changeAvatar(path)
})
fileDialog.open()
}
}
}
ColumnLayout {
Layout.fillWidth: true
Layout.margins: 4
AutoTextField {
Layout.fillWidth: true
id: roomNameField
text: room.name
placeholderText: "Room Name"
enabled: canChangeName
}
AutoTextField {
Layout.fillWidth: true
id: roomTopicField
text: room.topic
placeholderText: "Room Topic"
enabled: canChangeTopic
}
}
}
Button {
Layout.alignment: Qt.AlignRight
visible: canChangeName || canChangeTopic
text: "Save"
highlighted: true
onClicked: {
if (room.name != roomNameField.text) {
room.setName(roomNameField.text)
}
if (room.topic != roomTopicField.text) {
room.setTopic(roomTopicField.text)
}
}
}
MenuSeparator {
Layout.fillWidth: true
}
ScrollView {
Layout.fillWidth: true
Layout.fillHeight: true
id: scrollview
clip: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
ColumnLayout {
width: scrollview.width
Control {
Layout.fillWidth: true
visible: room.predecessorId && room.connection.room(room.predecessorId)
padding: 8
contentItem: RowLayout {
ColumnLayout {
Layout.fillWidth: true
spacing: 0
Label {
Layout.fillWidth: true
font.bold: true
color: MPalette.foreground
text: "This room continues another conversation."
}
Label {
Layout.fillWidth: true
color: MPalette.lighter
text: "Click here to see older messages."
}
}
}
background: Rectangle {
color: MPalette.banner
RippleEffect {
anchors.fill: parent
onClicked: {
roomListForm.enteredRoom = Controller.connection.room(room.predecessorId)
root.close()
}
}
}
}
Control {
Layout.fillWidth: true
visible: room.successorId && room.connection.room(room.successorId)
padding: 8
contentItem: RowLayout {
ColumnLayout {
Layout.fillWidth: true
spacing: 0
Label {
Layout.fillWidth: true
font.bold: true
color: MPalette.foreground
text: "This room has been replaced."
}
Label {
Layout.fillWidth: true
color: MPalette.lighter
text: "The conversation continues here."
}
}
}
background: Rectangle {
color: MPalette.banner
RippleEffect {
anchors.fill: parent
onClicked: {
roomListForm.enteredRoom = Controller.connection.room(room.successorId)
root.close()
}
}
}
}
RowLayout {
Layout.fillWidth: true
Label {
Layout.preferredWidth: 100
wrapMode: Label.Wrap
text: "Canonical Alias"
color: MPalette.lighter
}
ComboBox {
Layout.fillWidth: true
id: canonicalAliasComboBox
enabled: canChangeCanonicalAlias
model: room.aliases
currentIndex: room.aliases.indexOf(room.canonicalAlias)
onCurrentIndexChanged: {
if (room.canonicalAlias != room.aliases[currentIndex]) {
room.setCanonicalAlias(room.aliases[currentIndex])
}
}
}
}
RowLayout {
Layout.fillWidth: true
visible: room.altAliases && room.altAliases.length
Label {
Layout.preferredWidth: 100
Layout.alignment: Qt.AlignTop
wrapMode: Label.Wrap
text: "Alt Aliases"
color: MPalette.lighter
}
ColumnLayout {
Layout.fillWidth: true
spacing: 0
Repeater {
model: room.altAliases
delegate: RowLayout {
Layout.maximumWidth: parent.width
Label {
text: modelData
font.pixelSize: 12
color: MPalette.lighter
}
ToolButton {
icon.name: ""
onClicked: room.removeLocalAlias(modelData)
}
}
}
}
}
}
}
}
Component {
id: openFileDialog
OpenFileDialog {}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,181 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
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
anchors.centerIn: parent
width: 360
height: Math.min(window.height - 100, 640)
id: root
title: "Start a Chat"
contentItem: ColumnLayout {
spacing: 0
RowLayout {
Layout.fillWidth: true
AutoTextField {
property bool isUserID: text.match(/@(.+):(.+)/g)
Layout.fillWidth: true
id: identifierField
placeholderText: "Find a user..."
onAccepted: {
userDictListModel.search()
}
}
Button {
visible: identifierField.isUserID
text: "Chat"
highlighted: true
onClicked: {
Controller.createDirectChat(connection, identifierField.text)
}
}
}
MenuSeparator {
Layout.fillWidth: true
}
AutoListView {
Layout.fillWidth: true
Layout.fillHeight: true
id: userDictListView
clip: true
spacing: 4
model: UserDirectoryListModel {
id: userDictListModel
connection: root.connection
keyword: identifierField.text
}
delegate: Control {
width: userDictListView.width
height: 48
padding: 8
contentItem: RowLayout {
spacing: 8
Kirigami.Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
source: avatar
name: name
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
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 {
Layout.fillWidth: true
Layout.fillHeight: true
text: userID
color: MPalette.lighter
font.pixelSize: 10
textFormat: Text.PlainText
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
Control {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
visible: directChats != null
contentItem: MaterialIcon {
icon: "\ue89e"
color: MPalette.lighter
font.pixelSize: 20
}
background: RippleEffect {
circular: true
onClicked: {
roomListForm.joinRoom(connection.room(directChats[0]))
root.close()
}
}
}
Control {
Layout.preferredWidth: 32
Layout.preferredHeight: 32
contentItem: MaterialIcon {
icon: "\ue7f0"
color: MPalette.lighter
font.pixelSize: 20
}
background: RippleEffect {
circular: true
onClicked: {
Controller.createDirectChat(connection, userID)
root.close()
}
}
}
}
}
ScrollBar.vertical: ScrollBar {}
Label {
anchors.centerIn: parent
visible: userDictListView.count < 1
text: "No users available"
color: MPalette.foreground
}
}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,160 @@
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
Dialog {
property var room
property var user
property string displayName: user.displayName
property string avatarMediaId: user.avatarMediaId
property string avatarUrl: user.avatarUrl
anchors.centerIn: parent
width: 360
id: root
modal: true
contentItem: ColumnLayout {
RowLayout {
Layout.fillWidth: true
spacing: 16
Kirigami.Avatar {
Layout.preferredWidth: 72
Layout.preferredHeight: 72
name: displayName
source: avatarMediaId ? "image://mxc/" + avatarMediaId : ""
RippleEffect {
anchors.fill: parent
circular: true
onPrimaryClicked: {
if (avatarMediaId) {
fullScreenImage.createObject(parent, {"filename": displayName, "localPath": room.urlToMxcUrl(avatarUrl)}).showFullScreen()
}
}
}
}
ColumnLayout {
Layout.fillWidth: true
Label {
Layout.fillWidth: true
font.pixelSize: 18
font.bold: true
elide: Text.ElideRight
wrapMode: Text.NoWrap
text: displayName
color: MPalette.foreground
}
Label {
Layout.fillWidth: true
text: "Online"
color: MPalette.lighter
}
}
}
MenuSeparator {
Layout.fillWidth: true
}
RowLayout {
Layout.fillWidth: true
spacing: 8
ColumnLayout {
Layout.fillWidth: true
Label {
Layout.fillWidth: true
elide: Text.ElideRight
wrapMode: Text.NoWrap
text: user.id
color: MPalette.accent
}
Label {
Layout.fillWidth: true
wrapMode: Label.Wrap
text: "User ID"
color: MPalette.lighter
}
}
}
MenuSeparator {
Layout.fillWidth: true
}
Control {
Layout.fillWidth: true
contentItem: RowLayout {
Label {
Layout.fillWidth: true
wrapMode: Label.Wrap
text: room.connection.isIgnored(user) ? "Unignore this user" : "Ignore this user"
color: MPalette.accent
}
}
background: RippleEffect {
onPrimaryClicked: {
root.close()
room.connection.isIgnored(user) ? room.connection.removeFromIgnoredUsers(user) : room.connection.addToIgnoredUsers(user)
}
}
}
Control {
Layout.fillWidth: true
contentItem: RowLayout {
Label {
Layout.fillWidth: true
wrapMode: Label.Wrap
text: "Kick this user"
color: MPalette.accent
}
}
background: RippleEffect {
onPrimaryClicked: room.kickMember(user.id)
}
}
}
Component {
id: fullScreenImage
FullScreenImage {}
}
onClosed: destroy()
}

View File

@@ -0,0 +1,15 @@
module NeoChat.Dialog
RoomSettingsDialog 2.0 RoomSettingsDialog.qml
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
AccountDetailDialog 2.0 AccountDetailDialog.qml
OpenFileDialog 2.0 OpenFileDialog.qml
OpenFolderDialog 2.0 OpenFolderDialog.qml
ImageClipboardDialog 2.0 ImageClipboardDialog.qml
StartChatDialog 2.0 StartChatDialog.qml