Add setting page
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
209
imports/NeoChat/Settings/AppearanceSettingsPage.qml
Normal file
209
imports/NeoChat/Settings/AppearanceSettingsPage.qml
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
imports/NeoChat/Settings/GeneralSettingsPage.qml
Normal file
72
imports/NeoChat/Settings/GeneralSettingsPage.qml
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
qml/main.qml
24
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 {
|
||||
|
||||
2
res.qrc
2
res.qrc
@@ -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>
|
||||
|
||||
@@ -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})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user