Add setting page

This commit is contained in:
Carl Schwan
2021-06-04 23:55:57 +02:00
parent 8f309ca958
commit efb70287b9
15 changed files with 374 additions and 300 deletions

View File

@@ -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
)

View File

@@ -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
}

View File

@@ -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: /^(<span style='.*'>)?(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(<\/span>)?$/
property bool isEmote: false

View File

@@ -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

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
// SPDX-License-Identifier: GPL-2.0-or-later
// 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
@@ -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
}
}
}

View File

@@ -0,0 +1,209 @@
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
// 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();
}
}
}
}
}

View File

@@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
// 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()
}
}
}
}
}

View File

@@ -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 {

View File

@@ -67,6 +67,8 @@
<file>imports/NeoChat/Component/confetti.png</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/AppearanceSettingsPage.qml</file>
<file>imports/NeoChat/Settings/qmldir</file>
</qresource>
</RCC>

View File

@@ -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})

View File

@@ -10,6 +10,9 @@
#include <KConfigGroup>
#include <KLocalizedString>
#include <KWindowConfig>
#ifdef HAVE_WINDOWSYSTEM
#include <KWindowEffects>
#endif
#include <QAuthenticator>
#include <QClipboard>
@@ -20,6 +23,7 @@
#include <QElapsedTimer>
#include <QFile>
#include <QFileInfo>
#include <QQuickItem>
#include <QGuiApplication>
#include <QMovie>
#include <QNetworkConfigurationManager>
@@ -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
}

View File

@@ -4,6 +4,7 @@
#pragma once
#include <QMediaPlayer>
#include <QQuickItem>
#include <QObject>
#include <KAboutData>
@@ -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();

View File

@@ -17,6 +17,10 @@
<entry name="ColorScheme" type="String">
<label>Color scheme</label>
</entry>
<entry name="Blur" type="bool">
<label>Make NeoChat blurry</label>
<default>false</default>
</entry>
<entry name="ShowNotifications" type="bool">
<label>Show notifications</label>
<default>true</default>