From efb70287b9ba1aa386900b9b185a8dbfb6207876 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Fri, 4 Jun 2021 23:55:57 +0200 Subject: [PATCH] Add setting page --- CMakeLists.txt | 2 +- .../Component/Timeline/ReplyComponent.qml | 1 + .../Component/Timeline/TextDelegate.qml | 3 - .../Component/Timeline/TimelineContainer.qml | 31 +- imports/NeoChat/Page/AccountsPage.qml | 5 +- imports/NeoChat/Page/RoomPage.qml | 14 +- imports/NeoChat/Page/SettingsPage.qml | 268 ++---------------- .../Settings/AppearanceSettingsPage.qml | 209 ++++++++++++++ .../NeoChat/Settings/GeneralSettingsPage.qml | 72 +++++ qml/main.qml | 24 +- res.qrc | 2 + src/CMakeLists.txt | 3 +- src/controller.cpp | 31 ++ src/controller.h | 5 + src/neochatconfig.kcfg | 4 + 15 files changed, 374 insertions(+), 300 deletions(-) create mode 100644 imports/NeoChat/Settings/AppearanceSettingsPage.qml create mode 100644 imports/NeoChat/Settings/GeneralSettingsPage.qml diff --git a/CMakeLists.txt b/CMakeLists.txt index d8171fe23..2b30999f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,7 +68,7 @@ if(ANDROID) ) else() find_package(Qt5 ${QT_MIN_VERSION} COMPONENTS Widgets) - find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle ConfigWidgets KIO Sonnet) + find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle ConfigWidgets KIO Sonnet WindowSystem) set_package_properties(KF5QQC2DesktopStyle PROPERTIES TYPE RUNTIME ) diff --git a/imports/NeoChat/Component/Timeline/ReplyComponent.qml b/imports/NeoChat/Component/Timeline/ReplyComponent.qml index 79321e551..efe4f16a2 100644 --- a/imports/NeoChat/Component/Timeline/ReplyComponent.qml +++ b/imports/NeoChat/Component/Timeline/ReplyComponent.qml @@ -25,6 +25,7 @@ MouseArea { id: replyLeftBorder width: Kirigami.Units.smallSpacing height: parent.height + x: Config.compactLayout ? Kirigami.Units.largeSpacing : 0 color: Kirigami.Theme.highlightColor } diff --git a/imports/NeoChat/Component/Timeline/TextDelegate.qml b/imports/NeoChat/Component/Timeline/TextDelegate.qml index 61b9109bb..37b08b962 100644 --- a/imports/NeoChat/Component/Timeline/TextDelegate.qml +++ b/imports/NeoChat/Component/Timeline/TextDelegate.qml @@ -11,9 +11,6 @@ import org.kde.kirigami 2.15 as Kirigami TextEdit { id: contentLabel - Layout.margins: Kirigami.Units.largeSpacing - Layout.topMargin: 0 - readonly property var isEmoji: /^()?(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(<\/span>)?$/ property bool isEmote: false diff --git a/imports/NeoChat/Component/Timeline/TimelineContainer.qml b/imports/NeoChat/Component/Timeline/TimelineContainer.qml index 61aab17cc..f8d934e46 100644 --- a/imports/NeoChat/Component/Timeline/TimelineContainer.qml +++ b/imports/NeoChat/Component/Timeline/TimelineContainer.qml @@ -21,7 +21,7 @@ QQC2.ItemDelegate { property bool isEmote: false property bool cardBackground: true - readonly property int bubbleMaxWidth: !Config.showAvatarInTimeline ? width : Math.min(width - Kirigami.Units.gridUnit * 2 - Kirigami.Units.largeSpacing * 4, Kirigami.Units.gridUnit * 20) + readonly property int bubbleMaxWidth: Config.compactLayout && !Config.showAvatarInTimeline ? width : (Config.compactLayout ? width - Kirigami.Units.gridUnit * 2 - Kirigami.Units.largeSpacing * 4 : Math.min(width - Kirigami.Units.gridUnit * 2 - Kirigami.Units.largeSpacing * 6, Kirigami.Units.gridUnit * 20)) signal saveFileAs() signal openExternally() @@ -48,7 +48,7 @@ QQC2.ItemDelegate { } } - height: sectionDelegate.height + Math.max(avatar.height, bubble.implicitHeight) + loader.height + (model.showAuthor ? Kirigami.Units.smallSpacing : 0) - (Config.showAvatarInTimeline ? 0 : Kirigami.Units.largeSpacing) + height: sectionDelegate.height + Math.max(model.showAuthor ? avatar.height : 0, bubble.implicitHeight) + loader.height + (showAuthor ? Kirigami.Units.largeSpacing : 0) SectionDelegate { id: sectionDelegate @@ -67,7 +67,7 @@ QQC2.ItemDelegate { sourceSize.height: width anchors { top: sectionDelegate.bottom - topMargin: model.showAuthor ? Kirigami.Units.smallSpacing * 2 : Kirigami.Units.smallSpacing + topMargin: model.showAuthor ? Kirigami.Units.largeSpacing : 0 left: parent.left leftMargin: Kirigami.Units.largeSpacing } @@ -94,18 +94,20 @@ QQC2.ItemDelegate { QQC2.Control { id: bubble - topPadding: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 - bottomPadding: 0 - leftPadding: 0 - rightPadding: 0 + topPadding: !Config.compactLayout ? Kirigami.Units.largeSpacing : 0 + bottomPadding: !Config.compactLayout ? Kirigami.Units.largeSpacing : 0 + leftPadding: Kirigami.Units.smallSpacing + rightPadding: Config.compactLayout ? Kirigami.Units.largeSpacing : Kirigami.Units.smallSpacing hoverEnabled: true + + state: Config.compactLayout ? "compactLayout" : "default" anchors { top: avatar.top left: avatar.right - leftMargin: Kirigami.Units.smallSpacing - right: Config.showAvatarInTimeline ? undefined : parent.right - rightMargin: Config.showAvatarInTimeline ? undefined : Kirigami.Units.largeSpacing + leftMargin: Kirigami.Units.largeSpacing } + // HACK: anchoring didn't reset anchors.right when switching from parent.right to undefined reliably + width: Config.compactLayout ? messageDelegate.width - (Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 : 0) + Kirigami.Units.largeSpacing * 2 : implicitWidth contentItem: ColumnLayout { id: column @@ -116,7 +118,7 @@ QQC2.ItemDelegate { Layout.fillWidth: true Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 Layout.rightMargin: Kirigami.Units.largeSpacing - Layout.preferredWidth: nameLabel.implicitWidth + timeLabel.implicitWidth + Kirigami.Units.largeSpacing + Layout.preferredWidth: nameLabel.implicitWidth + timeLabel.implicitWidth + Kirigami.Units.largeSpacing * 2 Layout.maximumWidth: bubbleMaxWidth implicitHeight: visible ? nameLabel.implicitHeight : 0 @@ -160,7 +162,8 @@ QQC2.ItemDelegate { active: model.reply !== undefined source: 'qrc:imports/NeoChat/Component/Timeline/ReplyComponent.qml' visible: active - Layout.bottomMargin: Kirigami.Units.smallSpacing + Layout.topMargin: Kirigami.Units.smallSpacing + Layout.bottomMargin: Config.compactLayout ? 0 : Kirigami.Units.smallSpacing Connections { target: replyLoader.item @@ -172,7 +175,7 @@ QQC2.ItemDelegate { } background: Kirigami.ShadowedRectangle { - visible: cardBackground && Config.showAvatarInTimeline + visible: cardBackground && !Config.compactLayout color: model.isHighlighted ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor radius: Kirigami.Units.smallSpacing shadow.size: Kirigami.Units.smallSpacing @@ -188,7 +191,7 @@ QQC2.ItemDelegate { left: bubble.left right: parent.right top: bubble.bottom - topMargin: active && Config.showAvatarInTimeline ? Kirigami.Units.smallSpacing : 0 + topMargin: active && !Config.compactLayout ? Kirigami.Units.smallSpacing : 0 } height: active ? item.implicitHeight : 0 //Layout.bottomMargin: readMarker ? Kirigami.Units.smallSpacing : 0 diff --git a/imports/NeoChat/Page/AccountsPage.qml b/imports/NeoChat/Page/AccountsPage.qml index 61f79614d..3eb85631f 100644 --- a/imports/NeoChat/Page/AccountsPage.qml +++ b/imports/NeoChat/Page/AccountsPage.qml @@ -97,11 +97,10 @@ Kirigami.ScrollablePage { } Kirigami.FormLayout { - anchors.top: passwordsMessage.bottom RowLayout { Kirigami.Avatar { id: avatar - source: userEditSheet.connection.localUser.avatarMediaId ? ("image://mxc/" + userEditSheet.connection.localUser.avatarMediaId) : "" + source: userEditSheet.connection && userEditSheet.connection.localUser.avatarMediaId ? ("image://mxc/" + userEditSheet.connection.localUser.avatarMediaId) : "" MouseArea { id: mouseArea @@ -138,7 +137,7 @@ Kirigami.ScrollablePage { } Controls.TextField { id: name - text: userEditSheet.connection.localUser.displayName + text: userEditSheet.connection ? userEditSheet.connection.localUser.displayName : "" Kirigami.FormData.label: i18n("Name:") } Controls.TextField { diff --git a/imports/NeoChat/Page/RoomPage.qml b/imports/NeoChat/Page/RoomPage.qml index 0532bab05..414321801 100644 --- a/imports/NeoChat/Page/RoomPage.qml +++ b/imports/NeoChat/Page/RoomPage.qml @@ -165,7 +165,7 @@ Kirigami.ScrollablePage { interval: 200 onTriggered: hoverActions.visible = hoverActions.visibleDelayed; } - x: bubble ? (bubble.x + Kirigami.Units.largeSpacing + Math.max(bubble.width - childWidth, 0)) : 0 + x: bubble ? (bubble.x + Kirigami.Units.largeSpacing + Math.max(bubble.width - childWidth, 0) - (Config.compactLayout ? Kirigami.Units.gridUnit * 3 : 0)) : 0 y: bubble ? bubble.mapToItem(page, 0, -Kirigami.Units.largeSpacing - hoverActions.childHeight * 1.5).y : 0 visible: false @@ -228,7 +228,7 @@ Kirigami.ScrollablePage { readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1 readonly property bool isLoaded: page.width * page.height > 10 - spacing: Kirigami.Units.smallSpacing + spacing: Config.compactLayout ? 1 : Kirigami.Units.smallSpacing reuseItems: true verticalLayoutDirection: ListView.BottomToTop @@ -365,11 +365,10 @@ Kirigami.ScrollablePage { innerObject: TextDelegate { isEmote: true - Layout.fillWidth: !Config.showAvatarInTimeline + Layout.fillWidth: Config.compactLayout Layout.maximumWidth: emoteContainer.bubbleMaxWidth Layout.rightMargin: Kirigami.Units.largeSpacing Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 - Layout.bottomMargin: Kirigami.Units.largeSpacing * 2 TapHandler { acceptedButtons: Qt.RightButton onTapped: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText) @@ -392,10 +391,9 @@ Kirigami.ScrollablePage { hoverComponent: hoverActions innerObject: TextDelegate { - Layout.fillWidth: !Config.showAvatarInTimeline + Layout.fillWidth: Config.compactLayout Layout.maximumWidth: messageContainer.bubbleMaxWidth Layout.rightMargin: Kirigami.Units.largeSpacing - Layout.bottomMargin: Kirigami.Units.largeSpacing Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 TapHandler { acceptedButtons: Qt.RightButton @@ -418,11 +416,10 @@ Kirigami.ScrollablePage { onReplyClicked: goToEvent(eventID) innerObject: TextDelegate { - Layout.fillWidth: !Config.showAvatarInTimeline + Layout.fillWidth: !Config.compactLayout Layout.maximumWidth: noticeContainer.bubbleMaxWidth Layout.rightMargin: Kirigami.Units.largeSpacing Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 - Layout.bottomMargin: Kirigami.Units.largeSpacing * 2 } } } @@ -439,7 +436,6 @@ Kirigami.ScrollablePage { innerObject: ImageDelegate { Layout.preferredWidth: Kirigami.Units.gridUnit * 15 Layout.maximumWidth: imageContainer.bubbleMaxWidth - Layout.bottomMargin: Kirigami.Units.largeSpacing Layout.preferredHeight: info.h / info.w * width Layout.maximumHeight: Kirigami.Units.gridUnit * 20 TapHandler { diff --git a/imports/NeoChat/Page/SettingsPage.qml b/imports/NeoChat/Page/SettingsPage.qml index 2af2f9d03..cc108790f 100644 --- a/imports/NeoChat/Page/SettingsPage.qml +++ b/imports/NeoChat/Page/SettingsPage.qml @@ -1,5 +1,6 @@ // SPDX-FileCopyrightText: 2020 Tobias Fella -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2021 Carl Schwan +// SPDX-License-Identifier: LGPL-2.0-or-later import QtQuick 2.15 import QtQuick.Controls 2.15 as QQC2 @@ -40,12 +41,22 @@ Kirigami.ScrollablePage { Kirigami.Action { text: i18n("General") icon.name: "org.kde.neochat" - onTriggered: pageSettingStack.push(generalSettings) + onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Settings/GeneralSettingsPage.qml") }, Kirigami.Action { text: i18n("Appearance") icon.name: "preferences-desktop-theme-global" - onTriggered: pageSettingStack.push(appearanceSettings) + onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Settings/AppearanceSettingsPage.qml") + }, + Kirigami.Action { + text: i18n("Account") + icon.name: "preferences-system-users" + onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Page/AccountsPage.qml") + }, + Kirigami.Action { + text: i18n("About NeoChat") + icon.name: "help-about" + onTriggered: pageSettingStack.push(aboutPage) } ] model: actions @@ -57,254 +68,9 @@ Kirigami.ScrollablePage { } Component { - id: generalSettings - Kirigami.ScrollablePage { - Kirigami.FormLayout { - QQC2.CheckBox { - Kirigami.FormData.label: i18n("General settings:") - text: i18n("Close to system tray") - checked: Config.systemTray - visible: Controller.supportSystemTray - onToggled: { - Config.systemTray = checked - Config.save() - } - } - QQC2.CheckBox { - // TODO: When there are enough notification and timeline event - // settings, make 2 separate groups with FormData labels. - Kirigami.FormData.label: i18n("Notifications and events:") - text: i18n("Show notifications") - checked: Config.showNotifications - onToggled: { - Config.showNotifications = checked - Config.save() - } - } - QQC2.CheckBox { - text: i18n("Show leave and join events") - checked: Config.showLeaveJoinEvent - onToggled: { - Config.showLeaveJoinEvent = checked - Config.save() - } - } - QQC2.RadioButton { - Kirigami.FormData.label: i18n("Rooms and private chats:") - text: i18n("Separated") - checked: !Config.mergeRoomList - onToggled: { - Config.mergeRoomList = false - Config.save() - } - } - QQC2.RadioButton { - text: i18n("Intermixed") - checked: Config.mergeRoomList - onToggled: { - Config.mergeRoomList = true - Config.save() - } - } - QQC2.CheckBox { - text: i18n("Use s/text/replacement syntax to edit your last message") - checked: Config.allowQuickEdit - onToggled: { - Config.allowQuickEdit = checked - Config.save() - } - } - } - } - } - - Component { - id: appearanceSettings - Kirigami.ScrollablePage { - ColumnLayout { - RowLayout { - Layout.alignment: Qt.AlignCenter - spacing: Kirigami.Units.gridUnit * 2 - ThemeRadioButton { - innerObject: [ - RowLayout { - Layout.fillWidth: true - Kirigami.Avatar { - color: "blue" - Layout.alignment: Qt.AlignTop - visible: Config.showAvatarInTimeline - Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 - Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 - } - QQC2.Control { - Layout.fillWidth: true - contentItem: ColumnLayout { - QQC2.Label { - Layout.fillWidth: true - font.weight: Font.Bold - font.pixelSize: 7 - text: "Paul Müller" - color: "blue" - wrapMode: Text.Wrap - } - QQC2.Label { - Layout.fillWidth: true - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt." - wrapMode: Text.Wrap - font.pixelSize: 7 - } - } - background: Kirigami.ShadowedRectangle { - color: Kirigami.Theme.backgroundColor - radius: Kirigami.Units.smallSpacing - shadow.size: Kirigami.Units.smallSpacing - shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10) - border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) - border.width: Kirigami.Units.devicePixelRatio - } - } - }, - RowLayout { - Layout.fillWidth: true - Kirigami.Avatar { - color: "red" - Layout.alignment: Qt.AlignTop - visible: Config.showAvatarInTimeline - Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 - Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 - } - QQC2.Control { - Layout.fillWidth: true - contentItem: ColumnLayout { - QQC2.Label { - Layout.fillWidth: true - font.weight: Font.Bold - font.pixelSize: 7 - text: "Jean Paul" - color: "red" - wrapMode: Text.Wrap - } - QQC2.Label { - Layout.fillWidth: true - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta , quis sem suscipit tincidunt." - wrapMode: Text.Wrap - font.pixelSize: 7 - } - } - background: Kirigami.ShadowedRectangle { - color: Kirigami.Theme.backgroundColor - radius: Kirigami.Units.smallSpacing - shadow.size: Kirigami.Units.smallSpacing - shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10) - border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) - border.width: Kirigami.Units.devicePixelRatio - } - } - } - ] - - text: i18n("Bubbles") - checked: !Config.compactLayout - QQC2.ButtonGroup.group: themeGroup - - onToggled: { - Config.compactLayout = !checked; - Config.save(); - } - } - ThemeRadioButton { - innerObject: [ - RowLayout { - Layout.fillWidth: true - Kirigami.Avatar { - color: "blue" - Layout.alignment: Qt.AlignTop - visible: Config.showAvatarInTimeline - Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 - Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 - } - ColumnLayout { - Layout.fillWidth: true - QQC2.Label { - Layout.fillWidth: true - font.weight: Font.Bold - font.pixelSize: 7 - text: "Paul Müller" - color: "blue" - wrapMode: Text.Wrap - } - QQC2.Label { - Layout.fillWidth: true - text: "Lorem ipsum dolor sit amet, consectetur elit. Vivamus facilisis porta mauris, finibus sem suscipit tincidunt." - wrapMode: Text.Wrap - font.pixelSize: 7 - } - } - }, - RowLayout { - Layout.fillWidth: true - Kirigami.Avatar { - color: "red" - Layout.alignment: Qt.AlignTop - visible: Config.showAvatarInTimeline - Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 - Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 - } - ColumnLayout { - Layout.fillWidth: true - QQC2.Label { - Layout.fillWidth: true - font.weight: Font.Bold - font.pixelSize: 7 - text: "Jean Paul" - color: "red" - wrapMode: Text.Wrap - } - QQC2.Label { - Layout.fillWidth: true - text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt." - wrapMode: Text.Wrap - font.pixelSize: 7 - } - } - } - ] - text: i18n("Compact") - checked: Config.compactLayout - QQC2.ButtonGroup.group: themeGroup - - onToggled: { - Config.compactLayout = checked; - Config.save(); - } - } - } - Kirigami.FormLayout { - QQC2.CheckBox { - text: i18n("Show User Avatar") - checked: Config.showAvatarInTimeline - onToggled: { - Config.showAvatarInTimeline = checked; - Config.save(); - } - } - - QQC2.CheckBox { - text: i18n("Show Fancy Effects") - checked: Config.showFancyEffects - onToggled: { - Config.showFancyEffects = checked; - Config.save(); - } - } - Loader { - visible: item !== null - Kirigami.FormData.label: item ? i18n("Theme:") : "" - Kirigami.FormData.buddyFor: item ? item.slider : null - source: "qrc:/imports/NeoChat/Settings/ColorScheme.qml" - } - } - } + id: aboutPage + Kirigami.AboutPage { + aboutData: Controller.aboutData } } } diff --git a/imports/NeoChat/Settings/AppearanceSettingsPage.qml b/imports/NeoChat/Settings/AppearanceSettingsPage.qml new file mode 100644 index 000000000..7cee9d795 --- /dev/null +++ b/imports/NeoChat/Settings/AppearanceSettingsPage.qml @@ -0,0 +1,209 @@ +// SPDX-FileCopyrightText: 2020 Tobias Fella +// SPDX-FileCopyrightText: 2021 Carl Schwan +// SPDX-License-Identifier: GPL-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 { + ColumnLayout { + RowLayout { + Layout.alignment: Qt.AlignCenter + spacing: Kirigami.Units.gridUnit * 2 + QQC2.ButtonGroup { id: themeGroup } + ThemeRadioButton { + innerObject: [ + RowLayout { + Layout.fillWidth: true + Kirigami.Avatar { + color: "blue" + Layout.alignment: Qt.AlignTop + visible: Config.showAvatarInTimeline + Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 + Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 + } + QQC2.Control { + Layout.fillWidth: true + contentItem: ColumnLayout { + QQC2.Label { + Layout.fillWidth: true + font.weight: Font.Bold + font.pixelSize: 7 + text: "Paul Müller" + color: "blue" + wrapMode: Text.Wrap + } + QQC2.Label { + Layout.fillWidth: true + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt." + wrapMode: Text.Wrap + font.pixelSize: 7 + } + } + background: Kirigami.ShadowedRectangle { + color: Kirigami.Theme.backgroundColor + radius: Kirigami.Units.smallSpacing + shadow.size: Kirigami.Units.smallSpacing + shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10) + border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) + border.width: Kirigami.Units.devicePixelRatio + } + } + }, + RowLayout { + Layout.fillWidth: true + Kirigami.Avatar { + color: "red" + Layout.alignment: Qt.AlignTop + visible: Config.showAvatarInTimeline + Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 + Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 + } + QQC2.Control { + Layout.fillWidth: true + contentItem: ColumnLayout { + QQC2.Label { + Layout.fillWidth: true + font.weight: Font.Bold + font.pixelSize: 7 + text: "Jean Paul" + color: "red" + wrapMode: Text.Wrap + } + QQC2.Label { + Layout.fillWidth: true + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta , quis sem suscipit tincidunt." + wrapMode: Text.Wrap + font.pixelSize: 7 + } + } + background: Kirigami.ShadowedRectangle { + color: Kirigami.Theme.backgroundColor + radius: Kirigami.Units.smallSpacing + shadow.size: Kirigami.Units.smallSpacing + shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10) + border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) + border.width: Kirigami.Units.devicePixelRatio + } + } + } + ] + + text: i18n("Bubbles") + checked: !Config.compactLayout + QQC2.ButtonGroup.group: themeGroup + + onToggled: { + Config.compactLayout = !checked; + Config.save(); + } + } + ThemeRadioButton { + innerObject: [ + RowLayout { + Layout.fillWidth: true + Kirigami.Avatar { + color: "blue" + Layout.alignment: Qt.AlignTop + visible: Config.showAvatarInTimeline + Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 + Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 + } + ColumnLayout { + Layout.fillWidth: true + QQC2.Label { + Layout.fillWidth: true + font.weight: Font.Bold + font.pixelSize: 7 + text: "Paul Müller" + color: "blue" + wrapMode: Text.Wrap + } + QQC2.Label { + Layout.fillWidth: true + text: "Lorem ipsum dolor sit amet, consectetur elit. Vivamus facilisis porta mauris, finibus sem suscipit tincidunt." + wrapMode: Text.Wrap + font.pixelSize: 7 + } + } + }, + RowLayout { + Layout.fillWidth: true + Kirigami.Avatar { + color: "red" + Layout.alignment: Qt.AlignTop + visible: Config.showAvatarInTimeline + Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0 + Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 + } + ColumnLayout { + Layout.fillWidth: true + QQC2.Label { + Layout.fillWidth: true + font.weight: Font.Bold + font.pixelSize: 7 + text: "Jean Paul" + color: "red" + wrapMode: Text.Wrap + } + QQC2.Label { + Layout.fillWidth: true + text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt." + wrapMode: Text.Wrap + font.pixelSize: 7 + } + } + } + ] + text: i18n("Compact") + checked: Config.compactLayout + QQC2.ButtonGroup.group: themeGroup + + onToggled: { + Config.compactLayout = checked; + Config.save(); + } + } + } + Kirigami.FormLayout { + QQC2.CheckBox { + text: i18n("Show User Avatar") + checked: Config.showAvatarInTimeline + onToggled: { + Config.showAvatarInTimeline = checked; + Config.save(); + } + } + + QQC2.CheckBox { + text: i18n("Show Fancy Effects") + checked: Config.showFancyEffects + onToggled: { + Config.showFancyEffects = checked; + Config.save(); + } + } + Loader { + visible: item !== null + Kirigami.FormData.label: item ? i18n("Theme:") : "" + source: "qrc:/imports/NeoChat/Settings/ColorScheme.qml" + } + QQC2.CheckBox { + visible: Controller.hasWindowSystem + text: i18n("Use transparent chat page") + enabled: !Config.compactLayout + checked: Config.blur + onToggled: { + Config.blur = checked; + Config.save(); + } + } + } + } +} diff --git a/imports/NeoChat/Settings/GeneralSettingsPage.qml b/imports/NeoChat/Settings/GeneralSettingsPage.qml new file mode 100644 index 000000000..1ba8c280d --- /dev/null +++ b/imports/NeoChat/Settings/GeneralSettingsPage.qml @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: 2020 Tobias Fella +// SPDX-FileCopyrightText: 2021 Carl Schwan +// SPDX-License-Identifier: GPL-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 + +Kirigami.ScrollablePage { + ColumnLayout { + Kirigami.FormLayout { + QQC2.CheckBox { + Kirigami.FormData.label: i18n("General settings:") + text: i18n("Close to system tray") + checked: Config.systemTray + visible: Controller.supportSystemTray + onToggled: { + Config.systemTray = checked + Config.save() + } + } + QQC2.CheckBox { + // TODO: When there are enough notification and timeline event + // settings, make 2 separate groups with FormData labels. + Kirigami.FormData.label: i18n("Notifications and events:") + text: i18n("Show notifications") + checked: Config.showNotifications + onToggled: { + Config.showNotifications = checked + Config.save() + } + } + QQC2.CheckBox { + text: i18n("Show leave and join events") + checked: Config.showLeaveJoinEvent + onToggled: { + Config.showLeaveJoinEvent = checked + Config.save() + } + } + QQC2.RadioButton { + Kirigami.FormData.label: i18n("Rooms and private chats:") + text: i18n("Separated") + checked: !Config.mergeRoomList + onToggled: { + Config.mergeRoomList = false + Config.save() + } + } + QQC2.RadioButton { + text: i18n("Intermixed") + checked: Config.mergeRoomList + onToggled: { + Config.mergeRoomList = true + Config.save() + } + } + QQC2.CheckBox { + text: i18n("Use s/text/replacement syntax to edit your last message") + checked: Config.allowQuickEdit + onToggled: { + Config.allowQuickEdit = checked + Config.save() + } + } + } + } +} diff --git a/qml/main.qml b/qml/main.qml index 321ec6b8c..0401ab054 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -195,13 +195,6 @@ Kirigami.ApplicationWindow { shortcut: StandardKey.New enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0 }, - Kirigami.Action { - text: i18n("Accounts") - icon.name: "im-user" - onTriggered: pushReplaceLayer("qrc:/imports/NeoChat/Page/AccountsPage.qml") - enabled: pageStack.layers.currentItem.title !== i18n("Accounts") && Controller.accountCount > 0 - - }, Kirigami.Action { text: i18n("Devices") iconName: "network-connect" @@ -215,12 +208,6 @@ Kirigami.ApplicationWindow { enabled: pageStack.layers.currentItem.title !== i18n("Settings") shortcut: StandardKey.Preferences }, - Kirigami.Action { - text: i18n("About NeoChat") - icon.name: "help-about" - onTriggered: pushReplaceLayer(aboutPage) - enabled: pageStack.layers.currentItem.title !== i18n("About") - }, Kirigami.Action { text: i18n("Logout") icon.name: "list-remove-user" @@ -236,13 +223,14 @@ Kirigami.ApplicationWindow { ] } - Component { - id: aboutPage - Kirigami.AboutPage { - aboutData: Controller.aboutData - } + Component.onCompleted: Controller.setBlur(pageStack, Config.blur && !Config.compactLayout); + Connections { + target: Config + onBlurChanged: Controller.setBlur(pageStack, Config.blur && !Config.compactLayout); + onCompactLayoutChanged: Controller.setBlur(pageStack, Config.blur && !Config.compactLayout); } + color: Config.blur && !Config.compactLayout ? "transparent" : Kirigami.Theme.backgroundColor Component { id: roomListComponent RoomListPage { diff --git a/res.qrc b/res.qrc index 9043202b2..24a0e0663 100644 --- a/res.qrc +++ b/res.qrc @@ -67,6 +67,8 @@ imports/NeoChat/Component/confetti.png imports/NeoChat/Settings/ThemeRadioButton.qml imports/NeoChat/Settings/ColorScheme.qml + imports/NeoChat/Settings/GeneralSettingsPage.qml + imports/NeoChat/Settings/AppearanceSettingsPage.qml imports/NeoChat/Settings/qmldir diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 975e163a5..6d2b96d2c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,8 +44,9 @@ target_sources(neochat PRIVATE ${NEOCHAT_ICON}) if(NOT ANDROID) target_sources(neochat PRIVATE trayicon.cpp colorschemer.cpp spellcheckhighlighter.cpp) - target_link_libraries(neochat PRIVATE KF5::ConfigWidgets KF5::SonnetCore) + target_link_libraries(neochat PRIVATE KF5::ConfigWidgets KF5::SonnetCore KF5::WindowSystem) target_compile_definitions(neochat PRIVATE -DHAVE_COLORSCHEME) + target_compile_definitions(neochat PRIVATE -DHAVE_WINDOWSYSTEM) endif() target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR}) diff --git a/src/controller.cpp b/src/controller.cpp index 79d653707..fa1f232de 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -10,6 +10,9 @@ #include #include #include +#ifdef HAVE_WINDOWSYSTEM +#include +#endif #include #include @@ -20,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -615,3 +619,30 @@ QString Controller::formatDuration(quint64 msecs, KFormat::DurationFormatOptions { return KFormat().formatDuration(msecs, options); } + +void Controller::setBlur(QQuickItem *item, bool blur) +{ +#ifdef HAVE_WINDOWSYSTEM + auto setWindows = [item, blur]() { + auto reg = QRect(QPoint(0, 0), item->window()->size()); + KWindowEffects::enableBackgroundContrast(item->window(), blur, 1, 1, 1, reg); + KWindowEffects::enableBlurBehind(item->window(), blur, reg); + }; + + disconnect(item->window(), &QQuickWindow::heightChanged, this, nullptr); + disconnect(item->window(), &QQuickWindow::widthChanged, this, nullptr); + connect(item->window(), &QQuickWindow::heightChanged, this, setWindows); + connect(item->window(), &QQuickWindow::widthChanged, this, setWindows); + setWindows(); +#endif +} + +bool Controller::hasWindowSystem() const +{ +#ifdef HAVE_WINDOWSYSTEM + return true; +#else + return false; +#endif +} + diff --git a/src/controller.h b/src/controller.h index 0b44bcb00..ffd822c96 100644 --- a/src/controller.h +++ b/src/controller.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include @@ -33,6 +34,7 @@ class Controller : public QObject Q_PROPERTY(bool busy READ busy WRITE setBusy NOTIFY busyChanged) Q_PROPERTY(KAboutData aboutData READ aboutData WRITE setAboutData NOTIFY aboutDataChanged) Q_PROPERTY(bool supportSystemTray READ supportSystemTray CONSTANT) + Q_PROPERTY(bool hasWindowSystem READ hasWindowSystem CONSTANT) Q_PROPERTY(bool isOnline READ isOnline NOTIFY isOnlineChanged) public: @@ -87,6 +89,8 @@ public: Q_INVOKABLE QString formatByteSize(double size, int precision = 1) const; Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user); + + Q_INVOKABLE void setBlur(QQuickItem *item, bool blur); private: explicit Controller(QObject *parent = nullptr); ~Controller() override; @@ -102,6 +106,7 @@ private: void saveSettings() const; KAboutData m_aboutData; + bool hasWindowSystem() const; private Q_SLOTS: void invokeLogin(); diff --git a/src/neochatconfig.kcfg b/src/neochatconfig.kcfg index b3a215221..462c01d0a 100644 --- a/src/neochatconfig.kcfg +++ b/src/neochatconfig.kcfg @@ -17,6 +17,10 @@ + + + false + true