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() else()
find_package(Qt5 ${QT_MIN_VERSION} COMPONENTS Widgets) 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 set_package_properties(KF5QQC2DesktopStyle PROPERTIES
TYPE RUNTIME TYPE RUNTIME
) )

View File

@@ -25,6 +25,7 @@ MouseArea {
id: replyLeftBorder id: replyLeftBorder
width: Kirigami.Units.smallSpacing width: Kirigami.Units.smallSpacing
height: parent.height height: parent.height
x: Config.compactLayout ? Kirigami.Units.largeSpacing : 0
color: Kirigami.Theme.highlightColor color: Kirigami.Theme.highlightColor
} }

View File

@@ -11,9 +11,6 @@ import org.kde.kirigami 2.15 as Kirigami
TextEdit { TextEdit {
id: contentLabel 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>)?$/ readonly property var isEmoji: /^(<span style='.*'>)?(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])+(<\/span>)?$/
property bool isEmote: false property bool isEmote: false

View File

@@ -21,7 +21,7 @@ QQC2.ItemDelegate {
property bool isEmote: false property bool isEmote: false
property bool cardBackground: true 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 saveFileAs()
signal openExternally() 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 { SectionDelegate {
id: sectionDelegate id: sectionDelegate
@@ -67,7 +67,7 @@ QQC2.ItemDelegate {
sourceSize.height: width sourceSize.height: width
anchors { anchors {
top: sectionDelegate.bottom top: sectionDelegate.bottom
topMargin: model.showAuthor ? Kirigami.Units.smallSpacing * 2 : Kirigami.Units.smallSpacing topMargin: model.showAuthor ? Kirigami.Units.largeSpacing : 0
left: parent.left left: parent.left
leftMargin: Kirigami.Units.largeSpacing leftMargin: Kirigami.Units.largeSpacing
} }
@@ -94,18 +94,20 @@ QQC2.ItemDelegate {
QQC2.Control { QQC2.Control {
id: bubble id: bubble
topPadding: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 topPadding: !Config.compactLayout ? Kirigami.Units.largeSpacing : 0
bottomPadding: 0 bottomPadding: !Config.compactLayout ? Kirigami.Units.largeSpacing : 0
leftPadding: 0 leftPadding: Kirigami.Units.smallSpacing
rightPadding: 0 rightPadding: Config.compactLayout ? Kirigami.Units.largeSpacing : Kirigami.Units.smallSpacing
hoverEnabled: true hoverEnabled: true
state: Config.compactLayout ? "compactLayout" : "default"
anchors { anchors {
top: avatar.top top: avatar.top
left: avatar.right left: avatar.right
leftMargin: Kirigami.Units.smallSpacing leftMargin: Kirigami.Units.largeSpacing
right: Config.showAvatarInTimeline ? undefined : parent.right
rightMargin: Config.showAvatarInTimeline ? undefined : 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 { contentItem: ColumnLayout {
id: column id: column
@@ -116,7 +118,7 @@ QQC2.ItemDelegate {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
Layout.rightMargin: Kirigami.Units.largeSpacing 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 Layout.maximumWidth: bubbleMaxWidth
implicitHeight: visible ? nameLabel.implicitHeight : 0 implicitHeight: visible ? nameLabel.implicitHeight : 0
@@ -160,7 +162,8 @@ QQC2.ItemDelegate {
active: model.reply !== undefined active: model.reply !== undefined
source: 'qrc:imports/NeoChat/Component/Timeline/ReplyComponent.qml' source: 'qrc:imports/NeoChat/Component/Timeline/ReplyComponent.qml'
visible: active visible: active
Layout.bottomMargin: Kirigami.Units.smallSpacing Layout.topMargin: Kirigami.Units.smallSpacing
Layout.bottomMargin: Config.compactLayout ? 0 : Kirigami.Units.smallSpacing
Connections { Connections {
target: replyLoader.item target: replyLoader.item
@@ -172,7 +175,7 @@ QQC2.ItemDelegate {
} }
background: Kirigami.ShadowedRectangle { background: Kirigami.ShadowedRectangle {
visible: cardBackground && Config.showAvatarInTimeline visible: cardBackground && !Config.compactLayout
color: model.isHighlighted ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor color: model.isHighlighted ? Kirigami.Theme.positiveBackgroundColor : Kirigami.Theme.backgroundColor
radius: Kirigami.Units.smallSpacing radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing shadow.size: Kirigami.Units.smallSpacing
@@ -188,7 +191,7 @@ QQC2.ItemDelegate {
left: bubble.left left: bubble.left
right: parent.right right: parent.right
top: bubble.bottom top: bubble.bottom
topMargin: active && Config.showAvatarInTimeline ? Kirigami.Units.smallSpacing : 0 topMargin: active && !Config.compactLayout ? Kirigami.Units.smallSpacing : 0
} }
height: active ? item.implicitHeight : 0 height: active ? item.implicitHeight : 0
//Layout.bottomMargin: readMarker ? Kirigami.Units.smallSpacing : 0 //Layout.bottomMargin: readMarker ? Kirigami.Units.smallSpacing : 0

View File

@@ -97,11 +97,10 @@ Kirigami.ScrollablePage {
} }
Kirigami.FormLayout { Kirigami.FormLayout {
anchors.top: passwordsMessage.bottom
RowLayout { RowLayout {
Kirigami.Avatar { Kirigami.Avatar {
id: 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 { MouseArea {
id: mouseArea id: mouseArea
@@ -138,7 +137,7 @@ Kirigami.ScrollablePage {
} }
Controls.TextField { Controls.TextField {
id: name id: name
text: userEditSheet.connection.localUser.displayName text: userEditSheet.connection ? userEditSheet.connection.localUser.displayName : ""
Kirigami.FormData.label: i18n("Name:") Kirigami.FormData.label: i18n("Name:")
} }
Controls.TextField { Controls.TextField {

View File

@@ -165,7 +165,7 @@ Kirigami.ScrollablePage {
interval: 200 interval: 200
onTriggered: hoverActions.visible = hoverActions.visibleDelayed; 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 y: bubble ? bubble.mapToItem(page, 0, -Kirigami.Units.largeSpacing - hoverActions.childHeight * 1.5).y : 0
visible: false visible: false
@@ -228,7 +228,7 @@ Kirigami.ScrollablePage {
readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1 readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1
readonly property bool isLoaded: page.width * page.height > 10 readonly property bool isLoaded: page.width * page.height > 10
spacing: Kirigami.Units.smallSpacing spacing: Config.compactLayout ? 1 : Kirigami.Units.smallSpacing
reuseItems: true reuseItems: true
verticalLayoutDirection: ListView.BottomToTop verticalLayoutDirection: ListView.BottomToTop
@@ -365,11 +365,10 @@ Kirigami.ScrollablePage {
innerObject: TextDelegate { innerObject: TextDelegate {
isEmote: true isEmote: true
Layout.fillWidth: !Config.showAvatarInTimeline Layout.fillWidth: Config.compactLayout
Layout.maximumWidth: emoteContainer.bubbleMaxWidth Layout.maximumWidth: emoteContainer.bubbleMaxWidth
Layout.rightMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
Layout.bottomMargin: Kirigami.Units.largeSpacing * 2
TapHandler { TapHandler {
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
onTapped: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText) onTapped: openMessageContext(author, model.message, eventId, toolTip, eventType, model.formattedBody, parent.selectedText)
@@ -392,10 +391,9 @@ Kirigami.ScrollablePage {
hoverComponent: hoverActions hoverComponent: hoverActions
innerObject: TextDelegate { innerObject: TextDelegate {
Layout.fillWidth: !Config.showAvatarInTimeline Layout.fillWidth: Config.compactLayout
Layout.maximumWidth: messageContainer.bubbleMaxWidth Layout.maximumWidth: messageContainer.bubbleMaxWidth
Layout.rightMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing
Layout.bottomMargin: Kirigami.Units.largeSpacing
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
TapHandler { TapHandler {
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
@@ -418,11 +416,10 @@ Kirigami.ScrollablePage {
onReplyClicked: goToEvent(eventID) onReplyClicked: goToEvent(eventID)
innerObject: TextDelegate { innerObject: TextDelegate {
Layout.fillWidth: !Config.showAvatarInTimeline Layout.fillWidth: !Config.compactLayout
Layout.maximumWidth: noticeContainer.bubbleMaxWidth Layout.maximumWidth: noticeContainer.bubbleMaxWidth
Layout.rightMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing
Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0 Layout.leftMargin: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing : 0
Layout.bottomMargin: Kirigami.Units.largeSpacing * 2
} }
} }
} }
@@ -439,7 +436,6 @@ Kirigami.ScrollablePage {
innerObject: ImageDelegate { innerObject: ImageDelegate {
Layout.preferredWidth: Kirigami.Units.gridUnit * 15 Layout.preferredWidth: Kirigami.Units.gridUnit * 15
Layout.maximumWidth: imageContainer.bubbleMaxWidth Layout.maximumWidth: imageContainer.bubbleMaxWidth
Layout.bottomMargin: Kirigami.Units.largeSpacing
Layout.preferredHeight: info.h / info.w * width Layout.preferredHeight: info.h / info.w * width
Layout.maximumHeight: Kirigami.Units.gridUnit * 20 Layout.maximumHeight: Kirigami.Units.gridUnit * 20
TapHandler { TapHandler {

View File

@@ -1,5 +1,6 @@
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de> // 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 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
@@ -40,12 +41,22 @@ Kirigami.ScrollablePage {
Kirigami.Action { Kirigami.Action {
text: i18n("General") text: i18n("General")
icon.name: "org.kde.neochat" icon.name: "org.kde.neochat"
onTriggered: pageSettingStack.push(generalSettings) onTriggered: pageSettingStack.push("qrc:/imports/NeoChat/Settings/GeneralSettingsPage.qml")
}, },
Kirigami.Action { Kirigami.Action {
text: i18n("Appearance") text: i18n("Appearance")
icon.name: "preferences-desktop-theme-global" 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 model: actions
@@ -57,254 +68,9 @@ Kirigami.ScrollablePage {
} }
Component { Component {
id: generalSettings id: aboutPage
Kirigami.ScrollablePage { Kirigami.AboutPage {
Kirigami.FormLayout { aboutData: Controller.aboutData
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"
}
}
}
} }
} }
} }

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 shortcut: StandardKey.New
enabled: pageStack.layers.currentItem.title !== i18n("Start a Chat") && Controller.accountCount > 0 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 { Kirigami.Action {
text: i18n("Devices") text: i18n("Devices")
iconName: "network-connect" iconName: "network-connect"
@@ -215,12 +208,6 @@ Kirigami.ApplicationWindow {
enabled: pageStack.layers.currentItem.title !== i18n("Settings") enabled: pageStack.layers.currentItem.title !== i18n("Settings")
shortcut: StandardKey.Preferences 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 { Kirigami.Action {
text: i18n("Logout") text: i18n("Logout")
icon.name: "list-remove-user" icon.name: "list-remove-user"
@@ -236,13 +223,14 @@ Kirigami.ApplicationWindow {
] ]
} }
Component { Component.onCompleted: Controller.setBlur(pageStack, Config.blur && !Config.compactLayout);
id: aboutPage Connections {
Kirigami.AboutPage { target: Config
aboutData: Controller.aboutData 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 { Component {
id: roomListComponent id: roomListComponent
RoomListPage { RoomListPage {

View File

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

View File

@@ -44,8 +44,9 @@ target_sources(neochat PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID) if(NOT ANDROID)
target_sources(neochat PRIVATE trayicon.cpp colorschemer.cpp spellcheckhighlighter.cpp) 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_COLORSCHEME)
target_compile_definitions(neochat PRIVATE -DHAVE_WINDOWSYSTEM)
endif() endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR}) target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})

View File

@@ -10,6 +10,9 @@
#include <KConfigGroup> #include <KConfigGroup>
#include <KLocalizedString> #include <KLocalizedString>
#include <KWindowConfig> #include <KWindowConfig>
#ifdef HAVE_WINDOWSYSTEM
#include <KWindowEffects>
#endif
#include <QAuthenticator> #include <QAuthenticator>
#include <QClipboard> #include <QClipboard>
@@ -20,6 +23,7 @@
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QQuickItem>
#include <QGuiApplication> #include <QGuiApplication>
#include <QMovie> #include <QMovie>
#include <QNetworkConfigurationManager> #include <QNetworkConfigurationManager>
@@ -615,3 +619,30 @@ QString Controller::formatDuration(quint64 msecs, KFormat::DurationFormatOptions
{ {
return KFormat().formatDuration(msecs, options); 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 #pragma once
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QQuickItem>
#include <QObject> #include <QObject>
#include <KAboutData> #include <KAboutData>
@@ -33,6 +34,7 @@ class Controller : public QObject
Q_PROPERTY(bool busy READ busy WRITE setBusy NOTIFY busyChanged) Q_PROPERTY(bool busy READ busy WRITE setBusy NOTIFY busyChanged)
Q_PROPERTY(KAboutData aboutData READ aboutData WRITE setAboutData NOTIFY aboutDataChanged) Q_PROPERTY(KAboutData aboutData READ aboutData WRITE setAboutData NOTIFY aboutDataChanged)
Q_PROPERTY(bool supportSystemTray READ supportSystemTray CONSTANT) Q_PROPERTY(bool supportSystemTray READ supportSystemTray CONSTANT)
Q_PROPERTY(bool hasWindowSystem READ hasWindowSystem CONSTANT)
Q_PROPERTY(bool isOnline READ isOnline NOTIFY isOnlineChanged) Q_PROPERTY(bool isOnline READ isOnline NOTIFY isOnlineChanged)
public: public:
@@ -87,6 +89,8 @@ public:
Q_INVOKABLE QString formatByteSize(double size, int precision = 1) const; Q_INVOKABLE QString formatByteSize(double size, int precision = 1) const;
Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user); Q_INVOKABLE void openOrCreateDirectChat(NeoChatUser *user);
Q_INVOKABLE void setBlur(QQuickItem *item, bool blur);
private: private:
explicit Controller(QObject *parent = nullptr); explicit Controller(QObject *parent = nullptr);
~Controller() override; ~Controller() override;
@@ -102,6 +106,7 @@ private:
void saveSettings() const; void saveSettings() const;
KAboutData m_aboutData; KAboutData m_aboutData;
bool hasWindowSystem() const;
private Q_SLOTS: private Q_SLOTS:
void invokeLogin(); void invokeLogin();

View File

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