Compare commits
21 Commits
work/tfell
...
work/purpo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a27a1e70f | ||
|
|
f2cf82ee8e | ||
|
|
a146fab5a0 | ||
|
|
fb6745b49a | ||
|
|
6c3ae87340 | ||
|
|
6afeaf1619 | ||
|
|
890860df92 | ||
|
|
6b8358874a | ||
|
|
fc9f37d4a4 | ||
|
|
48e410196c | ||
|
|
65cc392805 | ||
|
|
a6dd5b9a57 | ||
|
|
1d7c20e1c7 | ||
|
|
22609b21df | ||
|
|
6c5ca0ac9d | ||
|
|
b22ebf3671 | ||
|
|
ec1cc34855 | ||
|
|
a5aafde331 | ||
|
|
d42ad85b30 | ||
|
|
8648b4a3bf | ||
|
|
bdca636fb8 |
@@ -79,6 +79,7 @@ MouseArea {
|
||||
id: replyText
|
||||
textMessage: reply.display
|
||||
textFormat: Text.RichText
|
||||
hasContextMenu: false
|
||||
width: Math.min(implicitWidth, bubbleMaxWidth - Kirigami.Units.largeSpacing * 3)
|
||||
x: Kirigami.Units.smallSpacing * 3 + replyAvatar.width
|
||||
}
|
||||
|
||||
@@ -17,8 +17,17 @@ TextEdit {
|
||||
property bool isEmote: false
|
||||
property string textMessage: model.display
|
||||
property bool spoilerRevealed: !hasSpoiler.test(textMessage)
|
||||
|
||||
property bool hasContextMenu: true
|
||||
|
||||
signal requestOpenMessageContext()
|
||||
|
||||
ListView.onReused: Qt.binding(() => !hasSpoiler.test(textMessage))
|
||||
|
||||
Layout.fillWidth: Config.compactLayout
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
|
||||
|
||||
text: "<style>
|
||||
table {
|
||||
width:100%;
|
||||
@@ -53,8 +62,6 @@ a{
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: Text.RichText
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
onLinkActivated: RoomManager.openResource(link)
|
||||
onHoveredLinkChanged: if (hoveredLink.length > 0) {
|
||||
applicationWindow().hoverLinkIndicator.text = hoveredLink;
|
||||
@@ -70,4 +77,16 @@ a{
|
||||
enabled: !parent.hoveredLink && !spoilerRevealed
|
||||
onTapped: spoilerRevealed = true
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openMessageContext(model, parent.selectedText)
|
||||
enabled: hasContextMenu
|
||||
}
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: requestOpenMessageContext()
|
||||
enabled: hasContextMenu
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,7 @@ Kirigami.OverlaySheet {
|
||||
|
||||
parent: applicationWindow().overlay
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Create a Room")
|
||||
}
|
||||
title: i18n("Create a Room")
|
||||
|
||||
contentItem: Kirigami.FormLayout {
|
||||
TextField {
|
||||
|
||||
@@ -1,206 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2019-2020 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component 1.0
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: root
|
||||
|
||||
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")
|
||||
|
||||
parent: applicationWindow().overlay
|
||||
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18nc("%1 is the room name", "Room Settings - %1", room.displayName)
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: 16
|
||||
|
||||
Kirigami.Avatar {
|
||||
Layout.preferredWidth: 72
|
||||
Layout.preferredHeight: 72
|
||||
Layout.alignment: Qt.AlignTop
|
||||
|
||||
name: room.name
|
||||
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
enabled: canChangeAvatar
|
||||
|
||||
onClicked: {
|
||||
var fileDialog = openFileDialog.createObject(ApplicationWindow.overlay)
|
||||
|
||||
fileDialog.chosen.connect(function(path) {
|
||||
if (!path) return
|
||||
|
||||
room.changeAvatar(path)
|
||||
})
|
||||
|
||||
fileDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.FormLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
TextField {
|
||||
id: roomNameField
|
||||
text: room.name
|
||||
Kirigami.FormData.label: i18n("Room Name:")
|
||||
enabled: canChangeName
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: roomTopicField
|
||||
Layout.fillWidth: true
|
||||
text: room.topic
|
||||
Kirigami.FormData.label: i18n("Room topic:")
|
||||
enabled: canChangeTopic
|
||||
}
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
|
||||
visible: canChangeName || canChangeTopic
|
||||
|
||||
text: i18n("Save")
|
||||
highlighted: true
|
||||
|
||||
onClicked: {
|
||||
if (room.name != roomNameField.text) {
|
||||
room.setName(roomNameField.text)
|
||||
}
|
||||
|
||||
if (room.topic != roomTopicField.text) {
|
||||
room.setTopic(roomTopicField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: canonicalAliasComboBox.visible || altAlias.visible
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: canonicalAliasComboBox
|
||||
visible: room.aliases && room.aliases.length
|
||||
Kirigami.FormData.label: i18n("Canonical Alias:")
|
||||
popup.z: 999; // HACK This is an absolute hack, but combos inside OverlaySheets have their popups show up underneath, because of fun z ordering stuff
|
||||
|
||||
enabled: canChangeCanonicalAlias
|
||||
|
||||
model: room.aliases
|
||||
|
||||
currentIndex: room.aliases.indexOf(room.canonicalAlias)
|
||||
onCurrentIndexChanged: {
|
||||
if (room.canonicalAlias != room.aliases[currentIndex]) {
|
||||
room.setCanonicalAlias(room.aliases[currentIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: altAlias
|
||||
Kirigami.FormData.label: i18n("Other Aliases:")
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.altAliases && room.altAliases.length
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: room.altAliases
|
||||
|
||||
delegate: RowLayout {
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
Label {
|
||||
text: modelData
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
icon.name: ""
|
||||
onClicked: room.removeLocalAlias(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: next.visible || prev.visible
|
||||
}
|
||||
|
||||
Control {
|
||||
id: next
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.predecessorId && room.connection.room(room.predecessorId)
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: Kirigami.InlineMessage {
|
||||
text: i18n("This room continues another conversation.")
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See older messages...")
|
||||
onTriggered: {
|
||||
roomListForm.enteredRoom = Controller.activeConnection.room(room.predecessorId)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Control {
|
||||
id: prev
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.successorId && room.connection.room(room.successorId)
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: Kirigami.InlineMessage {
|
||||
text: i18n("This room has been replaced.")
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See new room...")
|
||||
onTriggered: {
|
||||
roomListForm.enteredRoom = Controller.activeConnection.room(room.successorId)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: openFileDialog
|
||||
|
||||
OpenFileDialog {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,7 @@ Kirigami.OverlaySheet {
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
|
||||
header: Kirigami.Heading {
|
||||
id: heading
|
||||
text: i18nc("@title:menu Account detail dialog", "Account detail")
|
||||
elide: Text.ElideRight
|
||||
QQC2.ToolTip.visible: truncated && hovered
|
||||
QQC2.ToolTip.text: text
|
||||
}
|
||||
title: i18nc("@title:menu Account detail dialog", "Account detail")
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
module NeoChat.Dialog
|
||||
RoomSettingsDialog 1.0 RoomSettingsDialog.qml
|
||||
UserDetailDialog 1.0 UserDetailDialog.qml
|
||||
LoginDialog 1.0 LoginDialog.qml
|
||||
CreateRoomDialog 1.0 CreateRoomDialog.qml
|
||||
|
||||
@@ -28,7 +28,7 @@ Labs.MenuBar {
|
||||
text: i18nc("menu", "Preferences…")
|
||||
|
||||
shortcut: StandardKey.Preferences
|
||||
onTriggered: pushReplaceLayer("qrc:/imports/NeoChat/Page/SettingsPage.qml")
|
||||
onTriggered: pageStack.pushDialogLayer("qrc:/imports/NeoChat/Settings/SettingsPage.qml")
|
||||
}
|
||||
Labs.MenuItem {
|
||||
text: i18nc("menu", "Quit NeoChat")
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Page 1.0
|
||||
|
||||
@@ -16,11 +18,15 @@ Menu {
|
||||
property var room
|
||||
|
||||
MenuItem {
|
||||
id: newWindow
|
||||
text: i18n("Open in new window")
|
||||
onTriggered: RoomManager.openWindow(room);
|
||||
visible: !Kirigami.Settings.isMobile
|
||||
}
|
||||
|
||||
MenuSeparator {}
|
||||
MenuSeparator {
|
||||
visible: newWindow.visible
|
||||
}
|
||||
|
||||
MenuItem {
|
||||
text: room.isFavourite ? i18n("Remove from Favourites") : i18n("Add to Favourites")
|
||||
|
||||
@@ -43,7 +43,7 @@ Loader {
|
||||
Kirigami.Action {
|
||||
text: i18n("Copy")
|
||||
icon.name: "edit-copy"
|
||||
onTriggered: Clipboard.saveText(message)
|
||||
onTriggered: Clipboard.saveText(loadRoot.selectedText === "" ? loadRoot.message : loadRoot.selectedText)
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("View Source")
|
||||
|
||||
@@ -12,9 +12,7 @@ Kirigami.OverlaySheet {
|
||||
|
||||
property string sourceText
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Message Source")
|
||||
}
|
||||
title: i18n("Message Source")
|
||||
|
||||
TextArea {
|
||||
id: sourceTextArea
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
// SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.12 as QQC2
|
||||
import org.kde.kirigami 2.12 as Kirigami
|
||||
|
||||
Kirigami.Page {
|
||||
title: i18n("Loading")
|
||||
|
||||
QQC2.BusyIndicator {
|
||||
Kirigami.PlaceholderMessage {
|
||||
id: loadingIndicator
|
||||
anchors.centerIn: parent
|
||||
text: i18n("Loading")
|
||||
QQC2.BusyIndicator {
|
||||
running: loadingIndicator.visible
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,6 @@ Kirigami.ScrollablePage {
|
||||
}
|
||||
}
|
||||
|
||||
actions.main: Kirigami.Action {
|
||||
text: i18n("New room")
|
||||
icon.name: "list-add"
|
||||
}
|
||||
|
||||
function goToNextRoom() {
|
||||
do {
|
||||
listView.incrementCurrentIndex();
|
||||
@@ -75,7 +70,8 @@ Kirigami.ScrollablePage {
|
||||
Component {
|
||||
id: searchField
|
||||
Kirigami.SearchField {
|
||||
Layout.margins: Kirigami.Units.smallSpacing
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
onTextChanged: sortFilterRoomListModel.filterText = text
|
||||
@@ -275,7 +271,6 @@ Kirigami.ScrollablePage {
|
||||
id: configButton
|
||||
visible: roomListItem.hovered || Kirigami.Settings.isMobile
|
||||
Accessible.name: i18n("Configure room")
|
||||
flat: true
|
||||
|
||||
action: Kirigami.Action {
|
||||
id: optionAction
|
||||
|
||||
@@ -229,7 +229,6 @@ Kirigami.ScrollablePage {
|
||||
|
||||
ListView {
|
||||
id: messageListView
|
||||
pixelAligned: true
|
||||
visible: !invitation.visible
|
||||
|
||||
readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1
|
||||
@@ -372,18 +371,8 @@ Kirigami.ScrollablePage {
|
||||
|
||||
innerObject: TextDelegate {
|
||||
isEmote: true
|
||||
Layout.fillWidth: Config.compactLayout
|
||||
Layout.maximumWidth: emoteContainer.bubbleMaxWidth
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText)
|
||||
}
|
||||
onRequestOpenMessageContext: openMessageContext(model, parent.selectedText)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -398,18 +387,8 @@ Kirigami.ScrollablePage {
|
||||
hoverComponent: hoverActions
|
||||
|
||||
innerObject: TextDelegate {
|
||||
Layout.fillWidth: Config.compactLayout
|
||||
Layout.maximumWidth: messageContainer.bubbleMaxWidth
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText)
|
||||
}
|
||||
onRequestOpenMessageContext: openMessageContext(model, parent.selectedText)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -424,9 +403,8 @@ Kirigami.ScrollablePage {
|
||||
|
||||
innerObject: TextDelegate {
|
||||
Layout.fillWidth: !Config.compactLayout
|
||||
hasContextMenu: false
|
||||
Layout.maximumWidth: noticeContainer.bubbleMaxWidth
|
||||
Layout.rightMargin: Kirigami.Units.largeSpacing
|
||||
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -447,13 +425,19 @@ Kirigami.ScrollablePage {
|
||||
Layout.maximumHeight: Kirigami.Units.gridUnit * 20
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onTapped: openFileContext(model, parent)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onLongPressed: openFileContext(model, parent)
|
||||
onTapped: {
|
||||
fullScreenImage.createObject(parent, {"filename": eventId, "localPath": currentRoom.urlToDownload(eventId), "blurhash": model.content.info["xyz.amorgan.blurhash"], "imageWidth": content.info.w, "imageHeight": content.info.h}).showFullScreen()
|
||||
fullScreenImage.createObject(parent, {
|
||||
filename: eventId,
|
||||
localPath: currentRoom.urlToDownload(eventId),
|
||||
blurhash: model.content.info["xyz.amorgan.blurhash"],
|
||||
imageWidth: content.info.w,
|
||||
imageHeight: content.info.h
|
||||
}).showFullScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -492,11 +476,11 @@ Kirigami.ScrollablePage {
|
||||
Layout.maximumWidth: audioContainer.bubbleMaxWidth
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onTapped: openFileContext(model, parent)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onLongPressed: openFileContext(model, parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,11 +504,11 @@ Kirigami.ScrollablePage {
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onTapped: openFileContext(model, parent)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onLongPressed: openFileContext(model, parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -543,11 +527,11 @@ Kirigami.ScrollablePage {
|
||||
Layout.maximumWidth: fileContainer.bubbleMaxWidth
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
onTapped: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onTapped: openFileContext(model, parent)
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onLongPressed: openFileContext(author, model.display, eventId, toolTip, progressInfo, parent)
|
||||
onLongPressed: openFileContext(model, parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -887,28 +871,28 @@ Kirigami.ScrollablePage {
|
||||
}
|
||||
|
||||
/// Open message context dialog for file and videos
|
||||
function openFileContext(author, message, eventId, source, progressInfo, file) {
|
||||
function openFileContext(event, file) {
|
||||
const contextMenu = fileDelegateContextMenu.createObject(page, {
|
||||
author: author,
|
||||
message: message,
|
||||
eventId: eventId,
|
||||
source: source,
|
||||
author: event.author,
|
||||
message: event.message,
|
||||
eventId: event.eventId,
|
||||
source: event.toolTip,
|
||||
file: file,
|
||||
progressInfo: progressInfo,
|
||||
progressInfo: event.progressInfo,
|
||||
});
|
||||
contextMenu.open();
|
||||
}
|
||||
|
||||
/// Open context menu for normal message
|
||||
function openMessageContext(author, message, eventId, source, eventType, formattedBody, selectedText) {
|
||||
function openMessageContext(event, selectedText) {
|
||||
const contextMenu = messageDelegateContextMenu.createObject(page, {
|
||||
selectedText: selectedText,
|
||||
author: author,
|
||||
message: message,
|
||||
eventId: eventId,
|
||||
formattedBody: formattedBody,
|
||||
source: source,
|
||||
eventType: eventType
|
||||
author: event.author,
|
||||
message: event.message,
|
||||
eventId: event.eventId,
|
||||
formattedBody: event.formattedBody,
|
||||
source: event.toolTip,
|
||||
eventType: event.eventType
|
||||
});
|
||||
contextMenu.open();
|
||||
}
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Settings 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18n("Settings")
|
||||
bottomPadding: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
|
||||
onBackRequested: {
|
||||
if (pageSettingStack.depth > 1 && !pageSettingStack.wideMode && pageSettingStack.currentIndex !== 0) {
|
||||
event.accepted = true;
|
||||
pageSettingStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.PageRow {
|
||||
id: pageSettingStack
|
||||
anchors.fill: parent
|
||||
columnView.columnWidth: Kirigami.Units.gridUnit * 12
|
||||
initialPage: Kirigami.ScrollablePage {
|
||||
bottomPadding: 0
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
topPadding: 0
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
ListView {
|
||||
Component.onCompleted: if (pageSettingStack.wideMode) {
|
||||
actions[0].trigger();
|
||||
}
|
||||
property list<Kirigami.Action> actions: [
|
||||
Kirigami.Action {
|
||||
text: i18n("General")
|
||||
icon.name: "org.kde.neochat"
|
||||
onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Settings/GeneralSettingsPage.qml")
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Appearance")
|
||||
icon.name: "preferences-desktop-theme-global"
|
||||
onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Settings/AppearanceSettingsPage.qml")
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Accounts")
|
||||
icon.name: "preferences-system-users"
|
||||
onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Page/AccountsPage.qml")
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Custom Emoji")
|
||||
icon.name: "preferences-desktop-emoticons"
|
||||
onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Settings/Emoticons.qml")
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Devices")
|
||||
iconName: "network-connect"
|
||||
onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Page/DevicesPage.qml")
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("About NeoChat")
|
||||
icon.name: "help-about"
|
||||
onTriggered: pageSettingStack.push(aboutPage)
|
||||
}
|
||||
]
|
||||
model: actions
|
||||
delegate: Kirigami.BasicListItem {
|
||||
action: modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: aboutPage
|
||||
Kirigami.AboutPage {
|
||||
aboutData: Controller.aboutData
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,5 @@ RoomPage 1.0 RoomPage.qml
|
||||
RoomWindow 1.0 RoomWindow.qml
|
||||
JoinRoomPage 1.0 JoinRoomPage.qml
|
||||
InviteUserPage 1.0 InviteUserPage.qml
|
||||
SettingsPage 1.0 SettingsPage.qml
|
||||
ImageEditorPage 1.0 ImageEditorPage.qml
|
||||
|
||||
|
||||
@@ -18,6 +18,46 @@ Kirigami.OverlayDrawer {
|
||||
id: roomDrawer
|
||||
readonly property var room: RoomManager.currentRoom
|
||||
|
||||
width: modal ? undefined : actualWidth
|
||||
readonly property int minWidth: Kirigami.Units.gridUnit * 15
|
||||
readonly property int maxWidth: Kirigami.Units.gridUnit * 25
|
||||
readonly property int defaultWidth: Kirigami.Units.gridUnit * 20
|
||||
property int actualWidth: {
|
||||
if (Config.roomDrawerWidth === -1) {
|
||||
return Kirigami.Units.gridUnit * 20;
|
||||
} else {
|
||||
return Config.roomDrawerWidth
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: undefined
|
||||
width: 2
|
||||
z: 500
|
||||
cursorShape: !Kirigami.Settings.isMobile ? Qt.SplitHCursor : undefined
|
||||
enabled: true
|
||||
visible: true
|
||||
onPressed: _lastX = mapToGlobal(mouseX, mouseY).x
|
||||
onReleased: {
|
||||
Config.roomDrawerWidth = roomDrawer.actualWidth;
|
||||
Config.save();
|
||||
}
|
||||
property real _lastX: -1
|
||||
|
||||
onPositionChanged: {
|
||||
if (_lastX === -1) {
|
||||
return;
|
||||
}
|
||||
if (Qt.application.layoutDirection === Qt.RightToLeft) {
|
||||
roomDrawer.actualWidth = Math.min(roomDrawer.maxWidth, Math.max(roomDrawer.minWidth, Config.roomDrawerWidth - _lastX + mapToGlobal(mouseX, mouseY).x))
|
||||
} else {
|
||||
roomDrawer.actualWidth = Math.min(roomDrawer.maxWidth, Math.max(roomDrawer.minWidth, Config.roomDrawerWidth + _lastX - mapToGlobal(mouseX, mouseY).x))
|
||||
}
|
||||
}
|
||||
}
|
||||
enabled: true
|
||||
|
||||
edge: Qt.application.layoutDirection == Qt.RightToLeft ? Qt.LeftEdge : Qt.RightEdge
|
||||
@@ -30,7 +70,6 @@ Kirigami.OverlayDrawer {
|
||||
active: roomDrawer.drawerOpen
|
||||
sourceComponent: ColumnLayout {
|
||||
id: columnLayout
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
Kirigami.AbstractApplicationHeader {
|
||||
Layout.fillWidth: true
|
||||
@@ -47,7 +86,7 @@ Kirigami.OverlayDrawer {
|
||||
icon.name: "list-add-user"
|
||||
text: i18n("Invite")
|
||||
onClicked: {
|
||||
applicationWindow().pageStack.layers.push("qrc:/imports/NeoChat/Page/InviteUserPage.qml", {"room": room})
|
||||
applicationWindow().pageStack.layers.push("qrc:/imports/NeoChat/Page/InviteUserPage.qml", {room: room})
|
||||
roomDrawer.close();
|
||||
}
|
||||
}
|
||||
@@ -69,12 +108,7 @@ Kirigami.OverlayDrawer {
|
||||
ToolButton {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
icon.name: 'settings-configure'
|
||||
onClicked: {
|
||||
roomSettingDialog.createObject(ApplicationWindow.overlay, {"room": room}).open()
|
||||
if (!wideScreen) {
|
||||
roomDrawer.close();
|
||||
}
|
||||
}
|
||||
onClicked: ApplicationWindow.window.pageStack.pushDialogLayer('qrc:/imports/NeoChat/RoomSettings/Categories.qml', {room: room})
|
||||
|
||||
ToolTip {
|
||||
text: i18n("Room settings")
|
||||
@@ -83,67 +117,61 @@ Kirigami.OverlayDrawer {
|
||||
}
|
||||
}
|
||||
|
||||
Control {
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
contentItem: ColumnLayout {
|
||||
id: infoLayout
|
||||
Layout.margins: Kirigami.Units.largeSpacing
|
||||
Kirigami.Heading {
|
||||
text: i18n("Room information")
|
||||
level: 3
|
||||
}
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Kirigami.Heading {
|
||||
text: i18n("Room information")
|
||||
level: 3
|
||||
Layout.margins: Kirigami.Units.largeSpacing
|
||||
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
Kirigami.Avatar {
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 3.5
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 3.5
|
||||
|
||||
name: room ? room.name : i18n("No name")
|
||||
source: room ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
}
|
||||
RowLayout {
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: Kirigami.Units.largeSpacing
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 0
|
||||
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
Kirigami.Avatar {
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 3.5
|
||||
Layout.preferredHeight: Kirigami.Units.gridUnit * 3.5
|
||||
|
||||
name: room ? room.name : i18n("No name")
|
||||
source: room ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.Heading {
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 9
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
spacing: 0
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 9
|
||||
Layout.fillWidth: true
|
||||
level: 1
|
||||
font.bold: true
|
||||
wrapMode: Label.Wrap
|
||||
text: room ? room.displayName : i18n("No name")
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: room && room.canonicalAlias ? room.canonicalAlias : i18n("No Canonical Alias")
|
||||
}
|
||||
level: 1
|
||||
font.bold: true
|
||||
wrapMode: Label.Wrap
|
||||
text: room ? room.displayName : i18n("No name")
|
||||
}
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: room && room.canonicalAlias ? room.canonicalAlias : i18n("No Canonical Alias")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TextEdit {
|
||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 13
|
||||
Layout.preferredWidth: Kirigami.Units.gridUnit * 13
|
||||
Layout.fillWidth: true
|
||||
text: room && room.topic ? room.topic.replace(replaceLinks, "<a href=\"$1\">$1</a>") : i18n("No Topic")
|
||||
readonly property var replaceLinks: /\(https:\/\/[^ ]*\)/
|
||||
textFormat: TextEdit.MarkdownText
|
||||
wrapMode: Text.WordWrap
|
||||
selectByMouse: true
|
||||
color: Kirigami.Theme.textColor
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
readOnly: true
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
|
||||
}
|
||||
TextEdit {
|
||||
Layout.fillWidth: true
|
||||
text: room && room.topic ? room.topic.replace(replaceLinks, "<a href=\"$1\">$1</a>") : i18n("No Topic")
|
||||
readonly property var replaceLinks: /\(https:\/\/[^ ]*\)/
|
||||
textFormat: TextEdit.MarkdownText
|
||||
wrapMode: Text.WordWrap
|
||||
selectByMouse: true
|
||||
color: Kirigami.Theme.textColor
|
||||
onLinkActivated: Qt.openUrlExternally(link)
|
||||
readOnly: true
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +181,7 @@ Kirigami.OverlayDrawer {
|
||||
activeFocusOnTab: false
|
||||
Label {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
text: room ? i18np("%1 Member", "%1 Members", room.totalMemberCount) : i18n("No Member Count")
|
||||
text: room ? i18np("%1 Member", "%1 Members", room.joinedCount) : i18n("No Member Count")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,6 +189,11 @@ Kirigami.OverlayDrawer {
|
||||
padding: Kirigami.Units.smallSpacing
|
||||
implicitWidth: parent.width
|
||||
z: 2
|
||||
background: Rectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
}
|
||||
contentItem: Kirigami.SearchField {
|
||||
id: userListSearchField
|
||||
onAccepted: sortedMessageEventModel.filterString = text;
|
||||
@@ -187,6 +220,7 @@ Kirigami.OverlayDrawer {
|
||||
|
||||
sortRole: "perm"
|
||||
filterRole: "name"
|
||||
filterCaseSensitivity: Qt.CaseInsensitive
|
||||
}
|
||||
|
||||
delegate: Kirigami.AbstractListItem {
|
||||
@@ -254,12 +288,6 @@ Kirigami.OverlayDrawer {
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: roomSettingDialog
|
||||
|
||||
RoomSettingsDialog {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: userDetailDialog
|
||||
|
||||
|
||||
35
imports/NeoChat/RoomSettings/Categories.qml
Normal file
35
imports/NeoChat/RoomSettings/Categories.qml
Normal file
@@ -0,0 +1,35 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import org.kde.kirigami 2.18 as Kirigami
|
||||
import QtQuick.Controls 2.15 as Controls
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Kirigami.CategorizedSettings {
|
||||
id: root
|
||||
required property var room
|
||||
objectName: "settingsPage"
|
||||
actions: [
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("General")
|
||||
icon.name: "settings-configure"
|
||||
page: Qt.resolvedUrl("General.qml")
|
||||
initialProperties: {
|
||||
return {
|
||||
room: root.room
|
||||
}
|
||||
}
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Security")
|
||||
icon.name: "security-low"
|
||||
page: Qt.resolvedUrl("Security.qml")
|
||||
initialProperties: {
|
||||
return {
|
||||
room: root.room
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
202
imports/NeoChat/RoomSettings/General.qml
Normal file
202
imports/NeoChat/RoomSettings/General.qml
Normal file
@@ -0,0 +1,202 @@
|
||||
// SPDX-FileCopyrightText: 2019-2020 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component 1.0
|
||||
import NeoChat.Dialog 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: root
|
||||
|
||||
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")
|
||||
|
||||
title: i18n('General')
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
Kirigami.Avatar {
|
||||
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||
|
||||
name: room.name
|
||||
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
|
||||
|
||||
RoundButton {
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
height: Kirigami.Units.gridUnits
|
||||
width: Kirigami.Units.gridUnits
|
||||
icon.name: 'cloud-upload'
|
||||
Accessible.name: i18n("Update avatar")
|
||||
enabled: canChangeAvatar
|
||||
onClicked: {
|
||||
const fileDialog = openFileDialog.createObject(ApplicationWindow.overlay)
|
||||
|
||||
fileDialog.chosen.connect(function(path) {
|
||||
if (!path) return
|
||||
|
||||
room.changeAvatar(path)
|
||||
})
|
||||
|
||||
fileDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
id: roomNameField
|
||||
text: room.name
|
||||
Kirigami.FormData.label: i18n("Room Name:")
|
||||
enabled: canChangeName
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: roomTopicField
|
||||
Layout.fillWidth: true
|
||||
text: room.topic
|
||||
Kirigami.FormData.label: i18n("Room topic:")
|
||||
enabled: canChangeTopic
|
||||
}
|
||||
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: canonicalAliasComboBox.visible || altAlias.visible
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
id: canonicalAliasComboBox
|
||||
visible: room.aliases && room.aliases.length
|
||||
Kirigami.FormData.label: i18n("Canonical Alias:")
|
||||
popup.z: 999; // HACK This is an absolute hack, but combos inside OverlaySheets have their popups show up underneath, because of fun z ordering stuff
|
||||
|
||||
enabled: canChangeCanonicalAlias
|
||||
|
||||
model: room.aliases
|
||||
|
||||
currentIndex: room.aliases.indexOf(room.canonicalAlias)
|
||||
onCurrentIndexChanged: {
|
||||
if (room.canonicalAlias != room.aliases[currentIndex]) {
|
||||
room.setCanonicalAlias(room.aliases[currentIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: altAlias
|
||||
Kirigami.FormData.label: i18n("Other Aliases:")
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.altAliases && room.altAliases.length
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: room.altAliases
|
||||
|
||||
delegate: RowLayout {
|
||||
Layout.maximumWidth: parent.width
|
||||
|
||||
Label {
|
||||
text: modelData
|
||||
}
|
||||
|
||||
ToolButton {
|
||||
icon.name: ""
|
||||
onClicked: room.removeLocalAlias(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Separator {
|
||||
Layout.fillWidth: true
|
||||
visible: next.visible || prev.visible
|
||||
}
|
||||
|
||||
Control {
|
||||
id: next
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.predecessorId && room.connection.room(room.predecessorId)
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: Kirigami.InlineMessage {
|
||||
text: i18n("This room continues another conversation.")
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See older messages...")
|
||||
onTriggered: {
|
||||
roomListForm.enteredRoom = Controller.activeConnection.room(room.predecessorId)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Control {
|
||||
id: prev
|
||||
Layout.fillWidth: true
|
||||
|
||||
visible: room.successorId && room.connection.room(room.successorId)
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
contentItem: Kirigami.InlineMessage {
|
||||
text: i18n("This room has been replaced.")
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("See new room...")
|
||||
onTriggered: {
|
||||
roomListForm.enteredRoom = Controller.activeConnection.room(room.successorId)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: openFileDialog
|
||||
|
||||
OpenFileDialog {}
|
||||
}
|
||||
}
|
||||
|
||||
footer: ToolBar {
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
enabled: room.name !== roomNameField.text || room.topic !== roomTopicField.text
|
||||
text: i18n("Apply")
|
||||
onClicked: {
|
||||
if (room.name != roomNameField.text) {
|
||||
room.setName(roomNameField.text)
|
||||
}
|
||||
|
||||
if (room.topic != roomTopicField.text) {
|
||||
room.setTopic(roomTopicField.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
69
imports/NeoChat/RoomSettings/Security.qml
Normal file
69
imports/NeoChat/RoomSettings/Security.qml
Normal file
@@ -0,0 +1,69 @@
|
||||
// SPDX-FileCopyrightText: 2019-2020 Black Hat <bhat@encom.eu.org>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component 1.0
|
||||
import NeoChat.Dialog 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: root
|
||||
|
||||
property var room
|
||||
|
||||
title: i18n('Security')
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
Layout.fillWidth: true
|
||||
|
||||
CheckBox {
|
||||
text: i18nc("@option:check", "Private (invite only)")
|
||||
Kirigami.FormData.label: i18nc("@option:check", "Access:")
|
||||
checked: room.joinRule === "invite"
|
||||
enabled: false
|
||||
}
|
||||
Label {
|
||||
text: i18n("Only invited people can join.")
|
||||
font: Kirigami.Theme.smallFont
|
||||
}
|
||||
CheckBox {
|
||||
text: i18nc("@option:check", "Space members")
|
||||
checked: room.joinRule === "restricted"
|
||||
enabled: false
|
||||
}
|
||||
Label {
|
||||
text: i18n("Anyone in a space can find and join.")
|
||||
font: Kirigami.Theme.smallFont
|
||||
}
|
||||
CheckBox {
|
||||
text: i18nc("@option:check", "Public")
|
||||
checked: room.joinRule === "public"
|
||||
enabled: false
|
||||
}
|
||||
Label {
|
||||
text: i18nc("@option:check", "Anyone can find and join.") + room.joinRule
|
||||
font: Kirigami.Theme.smallFont
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: ToolBar {
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
enabled: false
|
||||
text: i18n("Apply")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
imports/NeoChat/Settings/About.qml
Normal file
12
imports/NeoChat/Settings/About.qml
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.AboutPage {
|
||||
title: i18nc('@title:window', 'About NeoChat')
|
||||
aboutData: Controller.aboutData
|
||||
}
|
||||
@@ -133,9 +133,7 @@ Kirigami.Page {
|
||||
|
||||
property var connection
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Edit Account")
|
||||
}
|
||||
title: i18n("Edit Account")
|
||||
|
||||
Kirigami.FormLayout {
|
||||
RowLayout {
|
||||
@@ -12,6 +12,7 @@ import org.kde.neochat 1.0
|
||||
import NeoChat.Settings 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18nc('@title:window', 'Appearance')
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
@@ -82,9 +82,7 @@ Kirigami.Page {
|
||||
|
||||
property var index
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Remove device")
|
||||
}
|
||||
title: i18n("Remove device")
|
||||
Kirigami.FormLayout {
|
||||
Controls.TextField {
|
||||
id: passwordField
|
||||
@@ -107,9 +105,7 @@ Kirigami.Page {
|
||||
property int index
|
||||
property string name
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Edit device")
|
||||
}
|
||||
title: i18n("Edit device")
|
||||
Kirigami.FormLayout {
|
||||
Controls.TextField {
|
||||
id: nameField
|
||||
@@ -14,6 +14,7 @@ import NeoChat.Component 1.0 as Components
|
||||
import NeoChat.Dialog 1.0
|
||||
|
||||
Kirigami.Page {
|
||||
title: i18nc('@title:window', 'Custom Emojis')
|
||||
|
||||
leftPadding: pageSettingStack.wideMode ? Kirigami.Units.smallSpacing : 0
|
||||
topPadding: pageSettingStack.wideMode ? Kirigami.Units.smallSpacing : 0
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18nc('@title:window', 'General')
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
QQC2.CheckBox {
|
||||
|
||||
43
imports/NeoChat/Settings/SettingsPage.qml
Normal file
43
imports/NeoChat/Settings/SettingsPage.qml
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import org.kde.kirigami 2.18 as Kirigami
|
||||
import QtQuick.Controls 2.15 as Controls
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Kirigami.CategorizedSettings {
|
||||
objectName: "settingsPage"
|
||||
actions: [
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("General")
|
||||
icon.name: "org.kde.neochat"
|
||||
page: Qt.resolvedUrl("GeneralSettingsPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Appearance")
|
||||
icon.name: "preferences-desktop-theme-global"
|
||||
page: Qt.resolvedUrl("AppearanceSettingsPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Accounts")
|
||||
icon.name: "preferences-system-users"
|
||||
page: Qt.resolvedUrl("AccountsPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Custom Emoji")
|
||||
icon.name: "preferences-desktop-emoticons"
|
||||
page: Qt.resolvedUrl("Emoticons.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Devices")
|
||||
iconName: "network-connect"
|
||||
page: Qt.resolvedUrl("DevicesPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("About NeoChat")
|
||||
icon.name: "help-about"
|
||||
page: Qt.resolvedUrl("About.qml")
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,2 +1,3 @@
|
||||
module NeoChat.Settings
|
||||
ThemeRadioButton 1.0 ThemeRadioButton.qml
|
||||
SettingsPage 1.0 SettingsPage.qml
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<p xml:lang="zh-CN">Matrix 是一个分布式通讯协议,使用户重新得到控制权。 目前,NeoChat 实现了协议的大部分,除了加密聊天和视频聊天。</p>
|
||||
<p>NeoChat works both on mobile and desktop while providing a consistent user experience.</p>
|
||||
<p xml:lang="az">Vahid istifadəçi interfeysi ilə təmin olunan NeoChat, həm mobil telefonda həm də kompyuterlərdə işləyir.</p>
|
||||
<p xml:lang="ca">El NeoChat funciona en el mòbils i a l'escriptori, proporcionant un experiència d'usuari coherent.</p>
|
||||
<p xml:lang="ca">El NeoChat funciona en els mòbils i a l'escriptori, proporcionant una experiència d'usuari coherent.</p>
|
||||
<p xml:lang="ca-valencia">El NeoChat funciona en el mòbils i a l'escriptori, proporcionant un experiència d'usuari coherent.</p>
|
||||
<p xml:lang="de">NeoChat funktioniert sowohl auf dem Mobiltelefon als auch auf dem Arbeitsfläche und bietet ein einheitliches Benutzererlebnis. </p>
|
||||
<p xml:lang="en-GB">NeoChat works both on mobile and desktop while providing a consistent user experience.</p>
|
||||
|
||||
145
qml/main.qml
145
qml/main.qml
@@ -6,7 +6,7 @@ import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
import NeoChat.Component 1.0
|
||||
@@ -151,7 +151,6 @@ Kirigami.ApplicationWindow {
|
||||
|
||||
contextDrawer: RoomDrawer {
|
||||
id: contextDrawer
|
||||
contentItem.implicitWidth: columnWidth
|
||||
edge: Qt.application.layoutDirection == Qt.RightToLeft ? Qt.LeftEdge : Qt.RightEdge
|
||||
modal: !root.wideScreen || !enabled
|
||||
onEnabledChanged: drawerOpen = enabled && !modal
|
||||
@@ -224,6 +223,56 @@ Kirigami.ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
globalDrawer: Kirigami.GlobalDrawer {
|
||||
property bool hasLayer
|
||||
contentItem.implicitWidth: columnWidth
|
||||
isMenu: true
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
text: i18n("Explore rooms")
|
||||
icon.name: "compass"
|
||||
onTriggered: pushReplaceLayer("qrc:/imports/NeoChat/Page/JoinRoomPage.qml", {"connection": Controller.activeConnection})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Explore Rooms") && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Start a Chat")
|
||||
icon.name: "irc-join-channel"
|
||||
onTriggered: pushReplaceLayer("qrc:/imports/NeoChat/Page/StartChatPage.qml", {"connection": Controller.activeConnection})
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Create a Room")
|
||||
icon.name: "irc-join-channel"
|
||||
onTriggered: {
|
||||
let dialog = createRoomDialog.createObject(root.overlay);
|
||||
dialog.open();
|
||||
}
|
||||
shortcut: StandardKey.New
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Settings")
|
||||
icon.name: "settings-configure"
|
||||
onTriggered: pageStack.pushDialogLayer("qrc:/imports/NeoChat/Settings/SettingsPage.qml")
|
||||
enabled: pageStack.layers.currentItem.title !== i18n("Settings")
|
||||
shortcut: StandardKey.Preferences
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Logout")
|
||||
icon.name: "list-remove-user"
|
||||
enabled: Controller.accountCount > 0
|
||||
onTriggered: Controller.logout(Controller.activeConnection, true)
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Quit")
|
||||
icon.name: "gtk-quit"
|
||||
shortcut: StandardKey.Quit
|
||||
onTriggered: Qt.quit()
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Component.onCompleted: Controller.setBlur(pageStack, Config.blur && !Config.compactLayout);
|
||||
Connections {
|
||||
target: Config
|
||||
@@ -242,6 +291,23 @@ Kirigami.ApplicationWindow {
|
||||
background: Rectangle {
|
||||
color: Config.blur && !Config.compactLayout ? Qt.rgba(Kirigami.Theme.backgroundColor.r, Kirigami.Theme.backgroundColor.g, Kirigami.Theme.backgroundColor.b, 1 - Config.transparency) : "transparent"
|
||||
}
|
||||
|
||||
Component {
|
||||
id: roomListComponent
|
||||
RoomListPage {
|
||||
id: roomList
|
||||
|
||||
Connections {
|
||||
target: root.roomPage
|
||||
function onSwitchRoomUp() {
|
||||
roomList.goToNextRoom();
|
||||
}
|
||||
function onSwitchRoomDown() {
|
||||
roomList.goToPreviousRoom();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Controller
|
||||
@@ -294,9 +360,7 @@ Kirigami.ApplicationWindow {
|
||||
|
||||
property string url: ""
|
||||
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("User consent")
|
||||
}
|
||||
title: i18n("User consent")
|
||||
|
||||
QQC2.Label {
|
||||
id: label
|
||||
@@ -335,9 +399,7 @@ Kirigami.ApplicationWindow {
|
||||
required property var user;
|
||||
|
||||
parent: QQC2.ApplicationWindow.overlay
|
||||
header: Kirigami.Heading {
|
||||
text: i18n("Start a chat")
|
||||
}
|
||||
title: i18n("Start a chat")
|
||||
contentItem: QQC2.Label {
|
||||
text: i18n("Do you want to start a chat with %1?", user.displayName)
|
||||
wrapMode: Text.WordWrap
|
||||
@@ -354,7 +416,7 @@ Kirigami.ApplicationWindow {
|
||||
}
|
||||
|
||||
property Item hoverLinkIndicator: QQC2.Control {
|
||||
parent: overlay.parent
|
||||
parent: overlay.parent
|
||||
property alias text: linkText.text
|
||||
opacity: text.length > 0 ? 1 : 0
|
||||
|
||||
@@ -369,69 +431,4 @@ Kirigami.ApplicationWindow {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: settingsPageComponent
|
||||
SettingsPage {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: roomListComponent
|
||||
RoomListPage {
|
||||
id: roomList
|
||||
|
||||
Connections {
|
||||
target: root.roomPage
|
||||
function onSwitchRoomUp() {
|
||||
roomList.goToNextRoom();
|
||||
}
|
||||
function onSwitchRoomDown() {
|
||||
roomList.goToPreviousRoom();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: Kirigami.NavigationTabBar {
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
icon.name: "globe"
|
||||
text: "Spaces"
|
||||
checked: fooPage.visble
|
||||
onTriggered: {
|
||||
console.warn("foo")
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
icon.name: "dialog-messages"
|
||||
text: "Rooms"
|
||||
checked: fooPage.visble
|
||||
onTriggered: {
|
||||
while (pageStack.depth > 0) {
|
||||
pageStack.pop();
|
||||
}
|
||||
pageStack.push(roomListComponent);
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
icon.name: "document-open-recent-symbolic"
|
||||
text: "Recent"
|
||||
checked: fooPage.visble
|
||||
onTriggered: {
|
||||
console.warn("foo")
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
icon.name: "settings-configure"
|
||||
text: "Settings"
|
||||
checked: fooPage.visble
|
||||
onTriggered: {
|
||||
while (pageStack.depth > 0) {
|
||||
pageStack.pop();
|
||||
}
|
||||
pageStack.push(settingsPageComponent);
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
11
res.qrc
11
res.qrc
@@ -6,14 +6,14 @@
|
||||
<file>imports/NeoChat/Page/RoomListPage.qml</file>
|
||||
<file>imports/NeoChat/Page/RoomPage.qml</file>
|
||||
<file>imports/NeoChat/Page/RoomWindow.qml</file>
|
||||
<file>imports/NeoChat/Page/AccountsPage.qml</file>
|
||||
<file>imports/NeoChat/Page/JoinRoomPage.qml</file>
|
||||
<file>imports/NeoChat/Page/InviteUserPage.qml</file>
|
||||
<file>imports/NeoChat/Page/SettingsPage.qml</file>
|
||||
<file>imports/NeoChat/Page/StartChatPage.qml</file>
|
||||
<file>imports/NeoChat/Page/ImageEditorPage.qml</file>
|
||||
<file>imports/NeoChat/Page/DevicesPage.qml</file>
|
||||
<file>imports/NeoChat/Page/WelcomePage.qml</file>
|
||||
<file>imports/NeoChat/RoomSettings/General.qml</file>
|
||||
<file>imports/NeoChat/RoomSettings/Security.qml</file>
|
||||
<file>imports/NeoChat/RoomSettings/Categories.qml</file>
|
||||
<file>imports/NeoChat/Component/qmldir</file>
|
||||
<file>imports/NeoChat/Component/FullScreenImage.qml</file>
|
||||
<file>imports/NeoChat/Component/FancyEffectsContainer.qml</file>
|
||||
@@ -57,7 +57,6 @@
|
||||
<file>imports/NeoChat/Panel/qmldir</file>
|
||||
<file>imports/NeoChat/Panel/RoomDrawer.qml</file>
|
||||
<file>imports/NeoChat/Dialog/qmldir</file>
|
||||
<file>imports/NeoChat/Dialog/RoomSettingsDialog.qml</file>
|
||||
<file>imports/NeoChat/Dialog/UserDetailDialog.qml</file>
|
||||
<file>imports/NeoChat/Dialog/CreateRoomDialog.qml</file>
|
||||
<file>imports/NeoChat/Dialog/EmojiDialog.qml</file>
|
||||
@@ -73,11 +72,15 @@
|
||||
<file>qtquickcontrols2.conf</file>
|
||||
<file>imports/NeoChat/Component/glowdot.png</file>
|
||||
<file>imports/NeoChat/Component/confetti.png</file>
|
||||
<file>imports/NeoChat/Settings/SettingsPage.qml</file>
|
||||
<file>imports/NeoChat/Settings/ThemeRadioButton.qml</file>
|
||||
<file>imports/NeoChat/Settings/ColorScheme.qml</file>
|
||||
<file>imports/NeoChat/Settings/GeneralSettingsPage.qml</file>
|
||||
<file>imports/NeoChat/Settings/Emoticons.qml</file>
|
||||
<file>imports/NeoChat/Settings/AppearanceSettingsPage.qml</file>
|
||||
<file>imports/NeoChat/Settings/AccountsPage.qml</file>
|
||||
<file>imports/NeoChat/Settings/DevicesPage.qml</file>
|
||||
<file>imports/NeoChat/Settings/About.qml</file>
|
||||
<file>imports/NeoChat/Settings/qmldir</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -36,6 +36,7 @@ add_executable(neochat
|
||||
spellcheckhighlighter.cpp
|
||||
blurhash.cpp
|
||||
blurhashimageprovider.cpp
|
||||
joinrulesevent.cpp
|
||||
../res.qrc
|
||||
)
|
||||
|
||||
@@ -63,6 +64,18 @@ target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
|
||||
target_link_libraries(neochat PRIVATE Qt::Quick Qt::Qml Qt::Gui Qt::Network Qt::QuickControls2 KF5::I18n KF5::Kirigami2 KF5::Notifications KF5::ConfigCore KF5::ConfigGui KF5::CoreAddons Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::QCoro)
|
||||
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
|
||||
|
||||
if(TARGET KF5::Purpose)
|
||||
function(add_share_plugin name)
|
||||
kcoreaddons_add_plugin(${name} SOURCES ${ARGN} INSTALL_NAMESPACE "kf5/purpose")
|
||||
target_link_libraries(${name} Qt5::Core KF5::Purpose)
|
||||
set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/kf5/purpose")
|
||||
endfunction()
|
||||
|
||||
add_share_plugin(neochatpurposeplugin neochatpurposeplugin.cpp)
|
||||
target_link_libraries(neochatpurposeplugin KF5::I18n KF5::Service)
|
||||
endif()
|
||||
|
||||
|
||||
if(NEOCHAT_FLATPAK)
|
||||
target_compile_definitions(neochat PRIVATE NEOCHAT_FLATPAK)
|
||||
endif()
|
||||
|
||||
@@ -106,7 +106,20 @@ void ActionsHandler::postMessage(const QString &text,
|
||||
CustomEmojiModel *cem)
|
||||
{
|
||||
QString rawText = text;
|
||||
QString cleanedText = text;
|
||||
auto stringList = text.split(QStringLiteral("```"));
|
||||
QString cleanedText;
|
||||
const auto count = stringList.count();
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (i % 2 == 0) {
|
||||
if (i + 1 != count) {
|
||||
cleanedText += stringList[i].toHtmlEscaped() + QStringLiteral("```");
|
||||
} else {
|
||||
cleanedText += stringList[i].toHtmlEscaped();
|
||||
}
|
||||
} else {
|
||||
cleanedText += stringList[i] + QStringLiteral("```");
|
||||
}
|
||||
}
|
||||
|
||||
auto preprocess = [cem](const QString &it) -> QString {
|
||||
if (cem == nullptr) {
|
||||
|
||||
16
src/joinrulesevent.cpp
Normal file
16
src/joinrulesevent.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 2019 Kitsune Ral <Kitsune-Ral@users.sf.net>
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include "joinrulesevent.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
QString JoinRulesEvent::joinRule() const
|
||||
{
|
||||
return fromJson<QString>(contentJson()["join_rule"_ls]);
|
||||
}
|
||||
|
||||
QJsonArray JoinRulesEvent::allow() const
|
||||
{
|
||||
return contentJson()["allow"_ls].toArray();
|
||||
}
|
||||
29
src/joinrulesevent.h
Normal file
29
src/joinrulesevent.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <events/stateevent.h>
|
||||
#include <quotient_common.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class JoinRulesEvent : public StateEventBase
|
||||
{
|
||||
public:
|
||||
DEFINE_EVENT_TYPEID("m.room.join_rules", JoinRulesEvent)
|
||||
|
||||
explicit JoinRulesEvent()
|
||||
: StateEventBase(typeId(), matrixTypeId())
|
||||
{
|
||||
}
|
||||
explicit JoinRulesEvent(const QJsonObject &obj)
|
||||
: StateEventBase(typeId(), obj)
|
||||
{
|
||||
}
|
||||
|
||||
QString joinRule() const;
|
||||
QJsonArray allow() const;
|
||||
};
|
||||
REGISTER_EVENT_TYPE(JoinRulesEvent)
|
||||
} // namespace Quotient
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "devicesmodel.h"
|
||||
#include "emojimodel.h"
|
||||
#include "filetypesingleton.h"
|
||||
#include "joinrulesevent.h"
|
||||
#include "login.h"
|
||||
#include "matriximageprovider.h"
|
||||
#include "messageeventmodel.h"
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
<entry name="RoomListPageWidth" type="int">
|
||||
<default>-1</default>
|
||||
</entry>
|
||||
<entry name="RoomDrawerWidth" type="int">
|
||||
<default>-1</default>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Timeline">
|
||||
<entry name="ShowAvatarInTimeline" type="bool">
|
||||
|
||||
54
src/neochatpurposeplugin.cpp
Normal file
54
src/neochatpurposeplugin.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#include <purpose/pluginbase.h>
|
||||
|
||||
#include <KApplicationTrader>
|
||||
#include <KLocalizedString>
|
||||
#include <KPluginFactory>
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QJsonArray>
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QUrl>
|
||||
#include <QUrlQuery>
|
||||
|
||||
EXPORT_SHARE_VERSION
|
||||
|
||||
namespace
|
||||
{
|
||||
class NeoChatShareJob : public Purpose::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NeoChatShareJob(QObject *parent = nullptr)
|
||||
: Purpose::Job(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void start() override
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class Q_DECL_EXPORT NeoChatPurposePlugin : public Purpose::PluginBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NeoChatPurposePlugin(QObject *parent, const QVariantList &)
|
||||
: Purpose::PluginBase(parent)
|
||||
{
|
||||
}
|
||||
|
||||
Purpose::Job *createJob() const override
|
||||
{
|
||||
return new NeoChatShareJob(nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
K_PLUGIN_CLASS_WITH_JSON(NeoChatPurposePlugin, "neochatpurposeplugin.json")
|
||||
|
||||
#include "neochatpurposeplugin.moc"
|
||||
|
||||
22
src/neochatpurposeplugin.json
Normal file
22
src/neochatpurposeplugin.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"KPlugin": {
|
||||
"Authors": [
|
||||
{
|
||||
"Name": "Carl Schwan"
|
||||
}
|
||||
],
|
||||
"Category": "Utilities",
|
||||
|
||||
"Description": "Send vith NeoChat",
|
||||
"Icon": "mail-message",
|
||||
"License": "GPL",
|
||||
"Name": "Send with NeoChat",
|
||||
"X-Purpose-ActionDisplay": "Send with NeoChat..."
|
||||
},
|
||||
"X-Purpose-Configuration": [],
|
||||
"X-Purpose-Constraints": [],
|
||||
"X-Purpose-PluginTypes": [
|
||||
"Export",
|
||||
"ShareUrl"
|
||||
]
|
||||
}
|
||||
@@ -462,6 +462,9 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
|
||||
return e.isUpgrade() ? i18n("upgraded the room to version %1", e.version().isEmpty() ? "1" : e.version().toHtmlEscaped())
|
||||
: i18n("created the room, version %1", e.version().isEmpty() ? "1" : e.version().toHtmlEscaped());
|
||||
},
|
||||
[](const RoomPowerLevelsEvent &) {
|
||||
return i18nc("'power level' means permission level", "changed the power levels for this room");
|
||||
},
|
||||
[](const StateEventBase &e) {
|
||||
if (e.matrixType() == QLatin1String("m.room.server_acl")) {
|
||||
return i18n("changed the server access control lists for this room");
|
||||
@@ -732,6 +735,11 @@ void NeoChatRoom::deleteMessagesByUser(const QString &user)
|
||||
doDeleteMessagesByUser(user);
|
||||
}
|
||||
|
||||
QString NeoChatRoom::joinRule() const
|
||||
{
|
||||
return getCurrentState<JoinRulesEvent>()->joinRule();
|
||||
}
|
||||
|
||||
QCoro::Task<void> NeoChatRoom::doDeleteMessagesByUser(const QString &user)
|
||||
{
|
||||
QStringList events;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "joinrulesevent.h"
|
||||
#include <events/encryptionevent.h>
|
||||
#include <events/redactionevent.h>
|
||||
#include <events/roomavatarevent.h>
|
||||
@@ -33,6 +34,7 @@ class NeoChatRoom : public Room
|
||||
Q_PROPERTY(bool readMarkerLoaded READ readMarkerLoaded NOTIFY readMarkerLoadedChanged)
|
||||
Q_PROPERTY(QDateTime lastActiveTime READ lastActiveTime NOTIFY lastActiveTimeChanged)
|
||||
Q_PROPERTY(bool isInvite READ isInvite NOTIFY isInviteChanged)
|
||||
Q_PROPERTY(QString joinRule READ joinRule CONSTANT)
|
||||
Q_PROPERTY(QString htmlSafeDisplayName READ htmlSafeDisplayName NOTIFY displayNameChanged)
|
||||
|
||||
public:
|
||||
@@ -66,6 +68,8 @@ public:
|
||||
|
||||
bool isEventHighlighted(const Quotient::RoomEvent *e) const;
|
||||
|
||||
[[nodiscard]] QString joinRule() const;
|
||||
|
||||
[[nodiscard]] bool hasFileUploading() const
|
||||
{
|
||||
return m_hasFileUploading;
|
||||
|
||||
@@ -104,7 +104,7 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
|
||||
return UserType::Member;
|
||||
}
|
||||
|
||||
if (userPl < pl->powerLevelForState("m.room.message")) {
|
||||
if (userPl < pl->powerLevelForEvent("m.room.message")) {
|
||||
return UserType::Muted;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user