Compare commits
3 Commits
master
...
work/carl/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8177c1f1bc | ||
|
|
80171748d8 | ||
|
|
6aa2e586de |
@@ -26,8 +26,7 @@ QVariant StateModel::data(const QModelIndex &index, int role) const
|
|||||||
|
|
||||||
int StateModel::rowCount(const QModelIndex &parent) const
|
int StateModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(parent);
|
return !m_room || parent.isValid() ? 0 : m_room->currentState().events().size();
|
||||||
return m_room->currentState().events().size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NeoChatRoom *StateModel::room() const
|
NeoChatRoom *StateModel::room() const
|
||||||
@@ -37,8 +36,12 @@ NeoChatRoom *StateModel::room() const
|
|||||||
|
|
||||||
void StateModel::setRoom(NeoChatRoom *room)
|
void StateModel::setRoom(NeoChatRoom *room)
|
||||||
{
|
{
|
||||||
|
if (m_room == room) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_room = room;
|
m_room = room;
|
||||||
Q_EMIT roomChanged();
|
Q_EMIT roomChanged();
|
||||||
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_stateEvents.clear();
|
m_stateEvents.clear();
|
||||||
m_stateEvents = m_room->currentState().events().keys();
|
m_stateEvents = m_room->currentState().events().keys();
|
||||||
|
|||||||
@@ -6,107 +6,122 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
import org.kde.kitemmodels 1.0
|
import org.kde.kitemmodels 1.0
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
ColumnLayout {
|
FormCard.FormCardPage {
|
||||||
MobileForm.FormCard {
|
id: root
|
||||||
Layout.fillWidth: true
|
|
||||||
contentItem: ColumnLayout {
|
required property var room
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
FormCard.FormCard {
|
||||||
text: i18n("Room")
|
Layout.topMargin: Kirigami.Units.gridUnit
|
||||||
textRole: "displayName"
|
|
||||||
valueRole: "id"
|
FormCard.FormComboBoxDelegate {
|
||||||
model: RoomListModel {
|
id: roomChooser
|
||||||
id: roomListModel
|
text: i18n("Room")
|
||||||
connection: Controller.activeConnection
|
textRole: "displayName"
|
||||||
}
|
valueRole: "roomId"
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.id)
|
model: RoomListModel {
|
||||||
onCurrentValueChanged: room = roomListModel.roomByAliasOrId(currentValue)
|
id: roomListModel
|
||||||
|
connection: Controller.activeConnection
|
||||||
}
|
}
|
||||||
MobileForm.FormCheckDelegate {
|
onCurrentValueChanged: room = roomListModel.roomByAliasOrId(currentValue)
|
||||||
text: i18n("Show m.room.member events")
|
Component.onCompleted: currentIndex = indexOfValue(room.id)
|
||||||
checked: true
|
}
|
||||||
onToggled: {
|
|
||||||
if (checked) {
|
FormCard.FormDelegateSeparator { above: showRoomMember }
|
||||||
stateEventFilterModel.removeStateEventTypeFiltered("m.room.member");
|
|
||||||
} else {
|
FormCard.FormCheckDelegate {
|
||||||
stateEventFilterModel.addStateEventTypeFiltered("m.room.member");
|
id: showRoomMember
|
||||||
}
|
text: i18n("Show m.room.member events")
|
||||||
|
checked: true
|
||||||
|
onToggled: {
|
||||||
|
if (checked) {
|
||||||
|
stateEventFilterModel.removeStateEventTypeFiltered("m.room.member");
|
||||||
|
} else {
|
||||||
|
stateEventFilterModel.addStateEventTypeFiltered("m.room.member");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormCheckDelegate {
|
}
|
||||||
id: roomAccoutnDataVisibleCheck
|
|
||||||
text: i18n("Show room account data")
|
FormCard.FormDelegateSeparator { above: roomAccoutnDataVisibleCheck; below: showRoomMember }
|
||||||
checked: false
|
|
||||||
}
|
FormCard.FormCheckDelegate {
|
||||||
|
id: roomAccoutnDataVisibleCheck
|
||||||
|
text: i18n("Show room account data")
|
||||||
|
checked: false
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator { below: roomAccoutnDataVisibleCheck }
|
||||||
|
|
||||||
|
FormCard.FormTextDelegate {
|
||||||
|
text: i18n("Room id")
|
||||||
|
description: room.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
FormCard.FormHeader {
|
||||||
|
title: i18n("Room Account Data for %1", room.displayName)
|
||||||
visible: roomAccoutnDataVisibleCheck.checked
|
visible: roomAccoutnDataVisibleCheck.checked
|
||||||
contentItem: ColumnLayout {
|
}
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormCardHeader {
|
|
||||||
title: i18n("Room Account Data for %1 - %2", room.displayName, room.id)
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
FormCard.FormCard {
|
||||||
model: room.accountDataEventTypes
|
visible: roomAccoutnDataVisibleCheck.checked
|
||||||
delegate: MobileForm.FormTextDelegate {
|
|
||||||
text: modelData
|
Repeater {
|
||||||
onClicked: applicationWindow().pageStack.pushDialogLayer("qrc:/MessageSourceSheet.qml", {
|
model: room.accountDataEventTypes
|
||||||
"sourceText": room.roomAcountDataJson(text)
|
delegate: FormCard.FormTextDelegate {
|
||||||
}, {
|
text: modelData
|
||||||
"title": i18n("Event Source"),
|
onClicked: applicationWindow().pageStack.pushDialogLayer("qrc:/MessageSourceSheet.qml", {
|
||||||
"width": Kirigami.Units.gridUnit * 25
|
"sourceText": room.roomAcountDataJson(text)
|
||||||
})
|
}, {
|
||||||
}
|
"title": i18n("Event Source"),
|
||||||
|
"width": Kirigami.Units.gridUnit * 25
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
FormCard.FormHeader {
|
||||||
|
id: stateEventListHeader
|
||||||
|
title: i18n("Room State for %1", room.displayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormCardHeader {
|
|
||||||
id: stateEventListHeader
|
|
||||||
title: i18n("Room State for %1", room.displayName)
|
|
||||||
subtitle: room.id
|
|
||||||
}
|
|
||||||
QQC2.ScrollView {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
QQC2.ScrollView {
|
||||||
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.maximumHeight: Kirigami.Units.gridUnit * 20
|
||||||
|
|
||||||
ListView {
|
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
||||||
id: stateEventListView
|
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
||||||
clip: true
|
|
||||||
|
|
||||||
model: StateFilterModel {
|
ListView {
|
||||||
id: stateEventFilterModel
|
id: stateEventListView
|
||||||
sourceModel: StateModel {
|
clip: true
|
||||||
id: stateModel
|
|
||||||
room: devtoolsPage.room
|
model: StateFilterModel {
|
||||||
}
|
id: stateEventFilterModel
|
||||||
|
sourceModel: StateModel {
|
||||||
|
id: stateModel
|
||||||
|
room: root.room
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delegate: MobileForm.FormTextDelegate {
|
delegate: FormCard.FormTextDelegate {
|
||||||
text: model.type
|
text: model.type
|
||||||
description: model.stateKey
|
description: model.stateKey
|
||||||
onClicked: applicationWindow().pageStack.pushDialogLayer('qrc:/MessageSourceSheet.qml', {
|
onClicked: applicationWindow().pageStack.pushDialogLayer('qrc:/MessageSourceSheet.qml', {
|
||||||
sourceText: stateModel.stateEventJson(stateEventFilterModel.mapToSource(stateEventFilterModel.index(model.index, 0)))
|
sourceText: stateModel.stateEventJson(stateEventFilterModel.mapToSource(stateEventFilterModel.index(model.index, 0)))
|
||||||
}, {
|
}, {
|
||||||
title: i18n("Event Source"),
|
title: i18n("Event Source"),
|
||||||
width: Kirigami.Units.gridUnit * 25
|
width: Kirigami.Units.gridUnit * 25
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,58 +6,50 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
import org.kde.kitemmodels 1.0
|
import org.kde.kitemmodels 1.0
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
ColumnLayout {
|
FormCard.FormCardPage {
|
||||||
MobileForm.FormCard {
|
id: root
|
||||||
Layout.fillWidth: true
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormCardHeader {
|
|
||||||
title: i18n("Server Capabilities")
|
|
||||||
}
|
|
||||||
MobileForm.FormTextDelegate {
|
|
||||||
text: i18n("Can change password")
|
|
||||||
description: Controller.activeConnection.canChangePassword
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormCardHeader {
|
|
||||||
title: i18n("Default Room Version")
|
|
||||||
}
|
|
||||||
MobileForm.FormTextDelegate {
|
|
||||||
text: Controller.activeConnection.defaultRoomVersion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormCardHeader {
|
|
||||||
title: i18n("Available Room Versions")
|
|
||||||
}
|
|
||||||
Repeater {
|
|
||||||
model: Controller.getSupportedRoomVersions(room.connection)
|
|
||||||
|
|
||||||
delegate: MobileForm.FormTextDelegate {
|
FormCard.FormHeader {
|
||||||
text: modelData.id
|
title: i18n("Server Capabilities")
|
||||||
contentItem.children: QQC2.Label {
|
}
|
||||||
text: modelData.status
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
FormCard.FormCard {
|
||||||
}
|
FormCard.FormTextDelegate {
|
||||||
|
text: i18n("Can change password")
|
||||||
|
description: Controller.activeConnection.canChangePassword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormHeader {
|
||||||
|
title: i18n("Default Room Version")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
FormCard.FormTextDelegate {
|
||||||
|
text: Controller.activeConnection.defaultRoomVersion
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormHeader {
|
||||||
|
title: i18n("Available Room Versions")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Repeater {
|
||||||
|
model: Controller.getSupportedRoomVersions(room.connection)
|
||||||
|
|
||||||
|
delegate: FormCard.FormTextDelegate {
|
||||||
|
text: modelData.id
|
||||||
|
contentItem.children: QQC2.Label {
|
||||||
|
text: modelData.status
|
||||||
|
color: Kirigami.Theme.disabledTextColor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,41 +2,34 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
import QtQuick 2.15
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.15 as QQC2
|
|
||||||
import QtQuick.Layouts 1.15
|
|
||||||
|
|
||||||
import org.kde.kirigami 2.20 as Kirigami
|
import org.kde.kirigami 2.20 as Kirigami
|
||||||
|
import org.kde.kirigamiaddons.settings 1.0 as KirigamiSettings
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
Kirigami.Page {
|
KirigamiSettings.CategorizedSettings {
|
||||||
id: devtoolsPage
|
id: root
|
||||||
|
|
||||||
property NeoChatRoom room
|
property NeoChatRoom room
|
||||||
|
|
||||||
title: i18n("Developer Tools")
|
actions: [
|
||||||
|
KirigamiSettings.SettingAction {
|
||||||
leftPadding: 0
|
actionName: "roomData"
|
||||||
rightPadding: 0
|
text: i18n("Room Data")
|
||||||
|
icon.name: "datatype"
|
||||||
header: QQC2.TabBar {
|
page: "qrc:/RoomData.qml"
|
||||||
id: tabBar
|
initialProperties: {
|
||||||
|
return {
|
||||||
QQC2.TabButton {
|
room: root.room
|
||||||
text: qsTr("Room Data")
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
KirigamiSettings.SettingAction {
|
||||||
|
actionName: "serverData"
|
||||||
|
text: i18n("Server Info")
|
||||||
|
icon.name: "network-server-symbolic"
|
||||||
|
page: "qrc:/ServerData.qml"
|
||||||
}
|
}
|
||||||
QQC2.TabButton {
|
]
|
||||||
text: qsTr("Server Info")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StackLayout {
|
|
||||||
id: swipeView
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
currentIndex: tabBar.currentIndex
|
|
||||||
|
|
||||||
RoomData {}
|
|
||||||
ServerData {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,441 +6,439 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
|
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
|
||||||
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
|
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
|
||||||
import org.kde.kitemmodels 1.0
|
import org.kde.kitemmodels 1.0
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property NeoChatRoom room
|
property NeoChatRoom room
|
||||||
|
|
||||||
title: i18nc('@title:window', 'Permissions')
|
title: i18nc("@title:window", "Permissions")
|
||||||
topPadding: 0
|
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
|
|
||||||
UserListModel {
|
readonly property UserListModel userListModel: UserListModel {
|
||||||
id: userListModel
|
id: userListModel
|
||||||
room: root.room
|
room: root.room
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
readonly property ListModel powerLevelModel: ListModel {
|
||||||
id: powerLevelModel
|
id: powerLevelModel
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
FormCard.FormHeader {
|
||||||
spacing: 0
|
title: i18n("Privileged Users")
|
||||||
MobileForm.FormHeader {
|
}
|
||||||
Layout.fillWidth: true
|
|
||||||
title: i18n("Privileged Users")
|
FormCard.FormCard {
|
||||||
}
|
Layout.fillWidth: true
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
Repeater {
|
||||||
contentItem: ColumnLayout {
|
model: KSortFilterProxyModel {
|
||||||
spacing: 0
|
sourceModel: userListModel
|
||||||
Repeater {
|
sortRole: "powerLevel"
|
||||||
model: KSortFilterProxyModel {
|
sortOrder: Qt.DescendingOrder
|
||||||
sourceModel: userListModel
|
filterRowCallback: function(source_row, source_parent) {
|
||||||
sortRole: "powerLevel"
|
let powerLevelRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), UserListModel.PowerLevelRole)
|
||||||
sortOrder: Qt.DescendingOrder
|
return powerLevelRole > 0;
|
||||||
filterRowCallback: function(source_row, source_parent) {
|
|
||||||
let powerLevelRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), UserListModel.PowerLevelRole)
|
|
||||||
return powerLevelRole > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delegate: MobileForm.FormTextDelegate {
|
|
||||||
text: name
|
|
||||||
description: userId
|
|
||||||
contentItem.children: RowLayout {
|
|
||||||
spacing: Kirigami.Units.largeSpacing
|
|
||||||
QQC2.Label {
|
|
||||||
visible: !room.canSendState("m.room.power_levels")
|
|
||||||
text: powerLevelString
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
|
||||||
}
|
|
||||||
QQC2.ComboBox {
|
|
||||||
focusPolicy: Qt.NoFocus // provided by parent
|
|
||||||
model: powerLevelModel
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
visible: room.canSendState("m.room.power_levels")
|
|
||||||
Component.onCompleted: {
|
|
||||||
/**
|
|
||||||
* This is very silly but the only way to populate the model with
|
|
||||||
* translated strings. Done here because the model needs to be filled
|
|
||||||
* before the first delegate sets it's current index.
|
|
||||||
*/
|
|
||||||
if (powerLevelModel.count == 0) {
|
|
||||||
powerLevelModel.append({"text": i18n("Member (0)"), "powerLevel": 0});
|
|
||||||
powerLevelModel.append({"text": i18n("Moderator (50)"), "powerLevel": 50});
|
|
||||||
powerLevelModel.append({"text": i18n("Admin (100)"), "powerLevel": 100});
|
|
||||||
}
|
|
||||||
currentIndex = indexOfValue(powerLevel)
|
|
||||||
}
|
|
||||||
onActivated: {
|
|
||||||
room.setUserPowerLevel(userId, currentValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
MobileForm.FormDelegateSeparator { below: userListSearchCard }
|
}
|
||||||
MobileForm.AbstractFormDelegate {
|
delegate: FormCard.FormTextDelegate {
|
||||||
id: userListSearchCard
|
text: name
|
||||||
Layout.fillWidth: true
|
description: userId
|
||||||
visible: room.canSendState("m.room.power_levels")
|
contentItem.children: RowLayout {
|
||||||
|
spacing: Kirigami.Units.largeSpacing
|
||||||
contentItem: Kirigami.SearchField {
|
QQC2.Label {
|
||||||
id: userListSearchField
|
visible: !room.canSendState("m.room.power_levels")
|
||||||
|
text: powerLevelString
|
||||||
autoAccept: false
|
color: Kirigami.Theme.disabledTextColor
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Keys.onUpPressed: userListView.decrementCurrentIndex()
|
|
||||||
Keys.onDownPressed: userListView.incrementCurrentIndex()
|
|
||||||
|
|
||||||
onAccepted: {
|
|
||||||
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
|
|
||||||
currentUser.action.trigger();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
QQC2.Popup {
|
QQC2.ComboBox {
|
||||||
id: userListSearchPopup
|
focusPolicy: Qt.NoFocus // provided by parent
|
||||||
|
model: root.powerLevelModel
|
||||||
x: userListSearchField.x
|
textRole: "text"
|
||||||
y: userListSearchField.y - height
|
valueRole: "powerLevel"
|
||||||
width: userListSearchField.width
|
visible: room.canSendState("m.room.power_levels")
|
||||||
height: {
|
Component.onCompleted: {
|
||||||
let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3;
|
/**
|
||||||
let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2;
|
* This is very silly but the only way to populate the model with
|
||||||
let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2;
|
* translated strings. Done here because the model needs to be filled
|
||||||
|
* before the first delegate sets it's current index.
|
||||||
return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
|
*/
|
||||||
|
if (root.powerLevelModel.count == 0) {
|
||||||
|
root.powerLevelModel.append({"text": i18n("Member (0)"), "powerLevel": 0});
|
||||||
|
root.powerLevelModel.append({"text": i18n("Moderator (50)"), "powerLevel": 50});
|
||||||
|
root.powerLevelModel.append({"text": i18n("Admin (100)"), "powerLevel": 100});
|
||||||
|
}
|
||||||
|
currentIndex = indexOfValue(powerLevel)
|
||||||
}
|
}
|
||||||
padding: Kirigami.Units.smallSpacing
|
onActivated: {
|
||||||
leftPadding: Kirigami.Units.smallSpacing / 2
|
room.setUserPowerLevel(userId, currentValue)
|
||||||
rightPadding: Kirigami.Units.smallSpacing / 2
|
|
||||||
modal: false
|
|
||||||
onClosed: userListSearchField.text = ""
|
|
||||||
|
|
||||||
background: Kirigami.ShadowedRectangle {
|
|
||||||
property color borderColor: Kirigami.Theme.textColor
|
|
||||||
|
|
||||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
|
||||||
Kirigami.Theme.inherit: false
|
|
||||||
|
|
||||||
radius: 4
|
|
||||||
color: Kirigami.Theme.backgroundColor
|
|
||||||
|
|
||||||
border {
|
|
||||||
color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
|
|
||||||
width: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
shadow {
|
|
||||||
xOffset: 0
|
|
||||||
yOffset: 4
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.3)
|
|
||||||
size: 8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
contentItem: QQC2.ScrollView {
|
|
||||||
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
|
||||||
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
|
||||||
|
|
||||||
ListView {
|
|
||||||
id: userListView
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
model: UserFilterModel {
|
|
||||||
id: userListFilterModel
|
|
||||||
sourceModel: userListModel
|
|
||||||
filterText: userListSearchField.text
|
|
||||||
|
|
||||||
onFilterTextChanged: {
|
|
||||||
if (filterText.length > 0 && !userListSearchPopup.visible) {
|
|
||||||
userListSearchPopup.open()
|
|
||||||
} else if (filterText.length <= 0 && userListSearchPopup.visible) {
|
|
||||||
userListSearchPopup.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: Delegates.RoundedItemDelegate {
|
|
||||||
id: userListItem
|
|
||||||
|
|
||||||
required property string userId
|
|
||||||
required property string avatar
|
|
||||||
required property string name
|
|
||||||
required property int powerLevel
|
|
||||||
required property string powerLevelString
|
|
||||||
|
|
||||||
text: name
|
|
||||||
|
|
||||||
contentItem: RowLayout {
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
|
|
||||||
source: userListItem.avatar ? ("image://" + userListItem.avatar) : ""
|
|
||||||
name: userListItem.name
|
|
||||||
}
|
|
||||||
|
|
||||||
Delegates.SubtitleContentItem {
|
|
||||||
itemDelegate: userListItem
|
|
||||||
subtitle: userListItem.userId
|
|
||||||
labelItem.textFormat: Text.PlainText
|
|
||||||
subtitleItem.textFormat: Text.PlainText
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
visible: userListItem.powerLevel > 0
|
|
||||||
|
|
||||||
text: userListItem.powerLevelString
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
|
||||||
textFormat: Text.PlainText
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
action: Kirigami.Action {
|
|
||||||
id: editPowerLevelAction
|
|
||||||
onTriggered: {
|
|
||||||
userListSearchPopup.close()
|
|
||||||
let dialog = powerLevelDialog.createObject(applicationWindow().overlay, {
|
|
||||||
room: root.room,
|
|
||||||
userId: userListItem.userId,
|
|
||||||
powerLevel: userListItem.powerLevel
|
|
||||||
});
|
|
||||||
dialog.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: powerLevelDialog
|
|
||||||
PowerLevelDialog {
|
|
||||||
id: powerLevelDialog
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FormCard.FormDelegateSeparator { below: userListSearchCard }
|
||||||
|
FormCard.AbstractFormDelegate {
|
||||||
|
id: userListSearchCard
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
|
||||||
MobileForm.FormHeader {
|
contentItem: Kirigami.SearchField {
|
||||||
Layout.fillWidth: true
|
id: userListSearchField
|
||||||
visible: room.canSendState("m.room.power_levels")
|
|
||||||
title: i18n("Default permissions")
|
autoAccept: false
|
||||||
}
|
|
||||||
MobileForm.FormCard {
|
Layout.fillWidth: true
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: room.canSendState("m.room.power_levels")
|
Keys.onUpPressed: userListView.decrementCurrentIndex()
|
||||||
contentItem: ColumnLayout {
|
Keys.onDownPressed: userListView.incrementCurrentIndex()
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
onAccepted: {
|
||||||
text: i18n("Default user power level")
|
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
|
||||||
description: i18n("This is power level for all new users when joining the room")
|
currentUser.action.trigger();
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.defaultUserPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultUserPowerLevel = currentValue
|
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Default power level to set the room state")
|
|
||||||
description: i18n("This is used for all state events that do not have their own entry here")
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.statePowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.statePowerLevel = currentValue
|
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Default power level to send messages")
|
|
||||||
description: i18n("This is used for all message events that do not have their own entry here")
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.defaultEventPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultEventPowerLevel = currentValue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
QQC2.Popup {
|
||||||
|
id: userListSearchPopup
|
||||||
|
|
||||||
MobileForm.FormHeader {
|
x: userListSearchField.x
|
||||||
Layout.fillWidth: true
|
y: userListSearchField.y - height
|
||||||
visible: room.canSendState("m.room.power_levels")
|
width: userListSearchField.width
|
||||||
title: i18n("Basic permissions")
|
height: {
|
||||||
}
|
let maxHeight = userListSearchField.mapToGlobal(userListSearchField.x, userListSearchField.y).y - Kirigami.Units.largeSpacing * 3;
|
||||||
MobileForm.FormCard {
|
let minHeight = Kirigami.Units.gridUnit * 2 + userListSearchPopup.padding * 2;
|
||||||
Layout.fillWidth: true
|
let filterContentHeight = userListView.contentHeight + userListSearchPopup.padding * 2;
|
||||||
visible: room.canSendState("m.room.power_levels")
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Invite users")
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.invitePowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.invitePowerLevel = currentValue
|
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Kick users")
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.kickPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.kickPowerLevel = currentValue
|
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Ban users")
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.banPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.banPowerLevel = currentValue
|
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Remove message sent by other users")
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.redactPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.redactPowerLevel = currentValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MobileForm.FormHeader {
|
return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: room.canSendState("m.room.power_levels")
|
|
||||||
title: i18n("Event permissions")
|
|
||||||
}
|
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: room.canSendState("m.room.power_levels")
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Change user permissions")
|
|
||||||
description: "m.room.power_levels"
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.powerLevelPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.powerLevelPowerLevel = currentValue
|
|
||||||
}
|
}
|
||||||
MobileForm.FormComboBoxDelegate {
|
padding: Kirigami.Units.smallSpacing
|
||||||
text: i18n("Change the room name")
|
leftPadding: Kirigami.Units.smallSpacing / 2
|
||||||
description: "m.room.name"
|
rightPadding: Kirigami.Units.smallSpacing / 2
|
||||||
textRole: "text"
|
modal: false
|
||||||
valueRole: "powerLevel"
|
onClosed: userListSearchField.text = ""
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.namePowerLevel)
|
background: Kirigami.ShadowedRectangle {
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.namePowerLevel = currentValue
|
property color borderColor: Kirigami.Theme.textColor
|
||||||
|
|
||||||
|
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||||
|
Kirigami.Theme.inherit: false
|
||||||
|
|
||||||
|
radius: 4
|
||||||
|
color: Kirigami.Theme.backgroundColor
|
||||||
|
|
||||||
|
border {
|
||||||
|
color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
|
||||||
|
width: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
shadow {
|
||||||
|
xOffset: 0
|
||||||
|
yOffset: 4
|
||||||
|
color: Qt.rgba(0, 0, 0, 0.3)
|
||||||
|
size: 8
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Change the room avatar")
|
contentItem: QQC2.ScrollView {
|
||||||
description: "m.room.avatar"
|
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
||||||
textRole: "text"
|
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
ListView {
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.avatarPowerLevel)
|
id: userListView
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.avatarPowerLevel = currentValue
|
clip: true
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
model: UserFilterModel {
|
||||||
text: i18n("Change the room canonical alias")
|
id: userListFilterModel
|
||||||
description: "m.room.canonical_alias"
|
sourceModel: userListModel
|
||||||
textRole: "text"
|
filterText: userListSearchField.text
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
onFilterTextChanged: {
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.canonicalAliasPowerLevel)
|
if (filterText.length > 0 && !userListSearchPopup.visible) {
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.canonicalAliasPowerLevel = currentValue
|
userListSearchPopup.open()
|
||||||
}
|
} else if (filterText.length <= 0 && userListSearchPopup.visible) {
|
||||||
MobileForm.FormComboBoxDelegate {
|
userListSearchPopup.close()
|
||||||
text: i18n("Change the room topic")
|
}
|
||||||
description: "m.room.topic"
|
}
|
||||||
textRole: "text"
|
}
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
delegate: Delegates.RoundedItemDelegate {
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.topicPowerLevel)
|
id: userListItem
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.topicPowerLevel = currentValue
|
|
||||||
}
|
required property string userId
|
||||||
MobileForm.FormComboBoxDelegate {
|
required property string avatar
|
||||||
text: i18n("Enable encryption for the room")
|
required property string name
|
||||||
description: "m.room.encryption"
|
required property int powerLevel
|
||||||
textRole: "text"
|
required property string powerLevelString
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
text: name
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.encryptionPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.encryptionPowerLevel = currentValue
|
contentItem: RowLayout {
|
||||||
}
|
KirigamiComponents.Avatar {
|
||||||
MobileForm.FormComboBoxDelegate {
|
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
|
||||||
text: i18n("Change the room history visibility")
|
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
|
||||||
description: "m.room.history_visibility"
|
source: userListItem.avatar ? ("image://" + userListItem.avatar) : ""
|
||||||
textRole: "text"
|
name: userListItem.name
|
||||||
valueRole: "powerLevel"
|
}
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.historyVisibilityPowerLevel)
|
Delegates.SubtitleContentItem {
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.historyVisibilityPowerLevel = currentValue
|
itemDelegate: userListItem
|
||||||
}
|
subtitle: userListItem.userId
|
||||||
MobileForm.FormComboBoxDelegate {
|
labelItem.textFormat: Text.PlainText
|
||||||
text: i18n("Set pinned events")
|
subtitleItem.textFormat: Text.PlainText
|
||||||
description: "m.room.pinned_events"
|
Layout.fillWidth: true
|
||||||
textRole: "text"
|
}
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
QQC2.Label {
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.pinnedEventsPowerLevel)
|
visible: userListItem.powerLevel > 0
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.pinnedEventsPowerLevel = currentValue
|
|
||||||
}
|
text: userListItem.powerLevelString
|
||||||
MobileForm.FormComboBoxDelegate {
|
color: Kirigami.Theme.disabledTextColor
|
||||||
text: i18n("Upgrade the room")
|
textFormat: Text.PlainText
|
||||||
description: "m.room.tombstone"
|
wrapMode: Text.NoWrap
|
||||||
textRole: "text"
|
}
|
||||||
valueRole: "powerLevel"
|
}
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.tombstonePowerLevel)
|
action: Kirigami.Action {
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.tombstonePowerLevel = currentValue
|
id: editPowerLevelAction
|
||||||
}
|
onTriggered: {
|
||||||
MobileForm.FormComboBoxDelegate {
|
userListSearchPopup.close()
|
||||||
text: i18n("Set the room server access control list (ACL)")
|
let dialog = powerLevelDialog.createObject(applicationWindow().overlay, {
|
||||||
description: "m.room.server_acl"
|
room: root.room,
|
||||||
textRole: "text"
|
userId: userListItem.userId,
|
||||||
valueRole: "powerLevel"
|
powerLevel: userListItem.powerLevel
|
||||||
model: powerLevelModel
|
});
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.serverAclPowerLevel)
|
dialog.open();
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.serverAclPowerLevel = currentValue
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
visible: room.isSpace
|
Component {
|
||||||
text: i18n("Set the children of this space")
|
id: powerLevelDialog
|
||||||
description: "m.space.child"
|
PowerLevelDialog {
|
||||||
textRole: "text"
|
id: powerLevelDialog
|
||||||
valueRole: "powerLevel"
|
}
|
||||||
model: powerLevelModel
|
}
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
|
}
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceChildPowerLevel = currentValue
|
}
|
||||||
}
|
|
||||||
MobileForm.FormComboBoxDelegate {
|
|
||||||
text: i18n("Set the parent space of this room")
|
|
||||||
description: "m.space.parent"
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "powerLevel"
|
|
||||||
model: powerLevelModel
|
|
||||||
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
|
|
||||||
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceParentPowerLevel = currentValue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FormCard.FormHeader {
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
title: i18n("Default permissions")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Default user power level")
|
||||||
|
description: i18n("This is power level for all new users when joining the room")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.defaultUserPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultUserPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator {}
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Default power level to set the room state")
|
||||||
|
description: i18n("This is used for all state events that do not have their own entry here")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.statePowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.statePowerLevel = currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator {}
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Default power level to send messages")
|
||||||
|
description: i18n("This is used for all message events that do not have their own entry here")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.defaultEventPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.defaultEventPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormHeader {
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
title: i18n("Basic permissions")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Invite users")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.invitePowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.invitePowerLevel = currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator {}
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Kick users")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.kickPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.kickPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator {}
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Ban users")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.banPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.banPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator {}
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Remove message sent by other users")
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.redactPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.redactPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormHeader {
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
title: i18n("Event permissions")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
visible: room.canSendState("m.room.power_levels")
|
||||||
|
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Change user permissions")
|
||||||
|
description: "m.room.power_levels"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.powerLevelPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.powerLevelPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Change the room name")
|
||||||
|
description: "m.room.name"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.namePowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.namePowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Change the room avatar")
|
||||||
|
description: "m.room.avatar"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: roo.tpowerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.avatarPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.avatarPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Change the room canonical alias")
|
||||||
|
description: "m.room.canonical_alias"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.canonicalAliasPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.canonicalAliasPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Change the room topic")
|
||||||
|
description: "m.room.topic"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.topicPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.topicPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Enable encryption for the room")
|
||||||
|
description: "m.room.encryption"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.encryptionPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.encryptionPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Change the room history visibility")
|
||||||
|
description: "m.room.history_visibility"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.historyVisibilityPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.historyVisibilityPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Set pinned events")
|
||||||
|
description: "m.room.pinned_events"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.pinnedEventsPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.pinnedEventsPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Upgrade the room")
|
||||||
|
description: "m.room.tombstone"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.tombstonePowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.tombstonePowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Set the room server access control list (ACL)")
|
||||||
|
description: "m.room.server_acl"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.serverAclPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.serverAclPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
visible: room.isSpace
|
||||||
|
text: i18n("Set the children of this space")
|
||||||
|
description: "m.space.child"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceChildPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
FormCard.FormComboBoxDelegate {
|
||||||
|
text: i18n("Set the parent space of this room")
|
||||||
|
description: "m.space.parent"
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "powerLevel"
|
||||||
|
model: root.powerLevelModel
|
||||||
|
Component.onCompleted: currentIndex = indexOfValue(room.spaceChildPowerLevel)
|
||||||
|
onCurrentValueChanged: if(room.canSendState("m.room.power_levels")) room.spaceParentPowerLevel = currentValue
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,138 +6,123 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
import org.kde.kitemmodels 1.0
|
import org.kde.kitemmodels 1.0
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property NeoChatRoom room
|
property NeoChatRoom room
|
||||||
|
|
||||||
title: i18nc('@title:window', 'Notifications')
|
title: i18nc('@title:window', 'Notifications')
|
||||||
topPadding: 0
|
|
||||||
leftPadding: 0
|
FormCard.FormHeader {
|
||||||
rightPadding: 0
|
title: i18n("Room notifications setting")
|
||||||
ColumnLayout {
|
}
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormHeader {
|
FormCard.FormCard {
|
||||||
Layout.fillWidth: true
|
FormCard.FormRadioDelegate {
|
||||||
title: i18n("Room notifications setting")
|
text: i18n("Follow global setting")
|
||||||
}
|
checked: room.pushNotificationState === PushNotificationState.Default
|
||||||
MobileForm.FormCard {
|
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
||||||
Layout.fillWidth: true
|
onToggled: {
|
||||||
contentItem: ColumnLayout {
|
room.pushNotificationState = PushNotificationState.Default
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormRadioDelegate {
|
|
||||||
text: i18n("Follow global setting")
|
|
||||||
checked: room.pushNotificationState === PushNotificationState.Default
|
|
||||||
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
|
||||||
onToggled: {
|
|
||||||
room.pushNotificationState = PushNotificationState.Default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormRadioDelegate {
|
|
||||||
text: i18nc("As in 'notify for all messages'","All")
|
|
||||||
checked: room.pushNotificationState === PushNotificationState.All
|
|
||||||
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
|
||||||
onToggled: {
|
|
||||||
room.pushNotificationState = PushNotificationState.All
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormRadioDelegate {
|
|
||||||
text: i18nc("As in 'notify when the user is mentioned or the message contains a set keyword'","@Mentions and Keywords")
|
|
||||||
checked: room.pushNotificationState === PushNotificationState.MentionKeyword
|
|
||||||
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
|
||||||
onToggled: {
|
|
||||||
room.pushNotificationState = PushNotificationState.MentionKeyword
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormRadioDelegate {
|
|
||||||
text: i18nc("As in 'do not notify for any messages'","Off")
|
|
||||||
checked: room.pushNotificationState === PushNotificationState.Mute
|
|
||||||
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
|
||||||
onToggled: {
|
|
||||||
room.pushNotificationState = PushNotificationState.Mute
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FormCard.FormRadioDelegate {
|
||||||
|
text: i18nc("As in 'notify for all messages'","All")
|
||||||
|
checked: room.pushNotificationState === PushNotificationState.All
|
||||||
|
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
||||||
|
onToggled: {
|
||||||
|
room.pushNotificationState = PushNotificationState.All
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FormCard.FormRadioDelegate {
|
||||||
|
text: i18nc("As in 'notify when the user is mentioned or the message contains a set keyword'","@Mentions and Keywords")
|
||||||
|
checked: room.pushNotificationState === PushNotificationState.MentionKeyword
|
||||||
|
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
||||||
|
onToggled: {
|
||||||
|
room.pushNotificationState = PushNotificationState.MentionKeyword
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FormCard.FormRadioDelegate {
|
||||||
|
text: i18nc("As in 'do not notify for any messages'","Off")
|
||||||
|
checked: room.pushNotificationState === PushNotificationState.Mute
|
||||||
|
enabled: room.pushNotificationState !== PushNotificationState.Unknown
|
||||||
|
onToggled: {
|
||||||
|
room.pushNotificationState = PushNotificationState.Mute
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MobileForm.FormCard {
|
FormCard.FormHeader {
|
||||||
|
title: i18n("Keywords")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Repeater {
|
||||||
|
model: KSortFilterProxyModel {
|
||||||
|
sourceModel: Controller.pushRuleModel
|
||||||
|
|
||||||
|
filterRowCallback: function(source_row, source_parent) {
|
||||||
|
let sectionRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), PushRuleModel.SectionRole)
|
||||||
|
let roomIdRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), PushRuleModel.RoomIdRole)
|
||||||
|
return sectionRole == PushNotificationSection.RoomKeywords && roomIdRole == root.room.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ruleDelegate
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.AbstractFormDelegate {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
contentItem : RowLayout {
|
||||||
spacing: 0
|
Kirigami.ActionTextField {
|
||||||
|
id: keywordAddField
|
||||||
|
|
||||||
MobileForm.FormCardHeader {
|
|
||||||
title: i18n("Keywords")
|
|
||||||
}
|
|
||||||
Repeater {
|
|
||||||
model: KSortFilterProxyModel {
|
|
||||||
sourceModel: Controller.pushRuleModel
|
|
||||||
|
|
||||||
filterRowCallback: function(source_row, source_parent) {
|
|
||||||
let sectionRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), PushRuleModel.SectionRole)
|
|
||||||
let roomIdRole = sourceModel.data(sourceModel.index(source_row, 0, source_parent), PushRuleModel.RoomIdRole)
|
|
||||||
return sectionRole == PushNotificationSection.RoomKeywords && roomIdRole == root.room.id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: ruleDelegate
|
|
||||||
}
|
|
||||||
MobileForm.AbstractFormDelegate {
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
contentItem : RowLayout {
|
placeholderText: i18n("Keyword…")
|
||||||
Kirigami.ActionTextField {
|
enabled: NotificationsManager.keywordNotificationAction !== PushNotificationAction.Unknown
|
||||||
id: keywordAddField
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
rightActions: Kirigami.Action {
|
||||||
|
icon.name: "edit-clear"
|
||||||
placeholderText: i18n("Keyword…")
|
visible: keywordAddField.text.length > 0
|
||||||
enabled: NotificationsManager.keywordNotificationAction !== PushNotificationAction.Unknown
|
onTriggered: {
|
||||||
|
keywordAddField.text = ""
|
||||||
rightActions: Kirigami.Action {
|
|
||||||
icon.name: "edit-clear"
|
|
||||||
visible: keywordAddField.text.length > 0
|
|
||||||
onTriggered: {
|
|
||||||
keywordAddField.text = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccepted: {
|
|
||||||
Controller.pushRuleModel.addKeyword(keywordAddField.text, root.room.id)
|
|
||||||
keywordAddField.text = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
QQC2.Button {
|
|
||||||
id: addButton
|
|
||||||
|
|
||||||
text: i18n("Add keyword")
|
|
||||||
Accessible.name: text
|
|
||||||
icon.name: "list-add"
|
|
||||||
display: QQC2.AbstractButton.IconOnly
|
|
||||||
enabled: NotificationsManager.keywordNotificationAction !== PushNotificationAction.Unknown
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
Controller.pushRuleModel.addKeyword(keywordAddField.text, root.room.id)
|
|
||||||
keywordAddField.text = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.ToolTip {
|
|
||||||
text: addButton.text
|
|
||||||
delay: Kirigami.Units.toolTipDelay
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
Controller.pushRuleModel.addKeyword(keywordAddField.text, root.room.id)
|
||||||
|
keywordAddField.text = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
QQC2.Button {
|
||||||
|
id: addButton
|
||||||
|
|
||||||
|
text: i18n("Add keyword")
|
||||||
|
icon.name: "list-add"
|
||||||
|
display: QQC2.AbstractButton.IconOnly
|
||||||
|
enabled: NotificationsManager.keywordNotificationAction !== PushNotificationAction.Unknown
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
Controller.pushRuleModel.addKeyword(keywordAddField.text, root.room.id)
|
||||||
|
keywordAddField.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
QQC2.ToolTip.text: text
|
||||||
|
QQC2.ToolTip.visible: hovered
|
||||||
|
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
data: Component {
|
||||||
id: ruleDelegate
|
id: ruleDelegate
|
||||||
NotificationRuleItem {
|
NotificationRuleItem {
|
||||||
onDeleteRule: {
|
onDeleteRule: {
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
MobileForm.AboutPage {
|
FormCard.AboutPage {
|
||||||
title: i18nc("@title:window", "About NeoChat")
|
title: i18nc("@title:window", "About NeoChat")
|
||||||
aboutData: About
|
aboutData: About
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
// SPDX-FileCopyrightText: 2023 Joshua Goins <josh@redstrate.com>
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
|
|
||||||
MobileForm.AboutKDE {
|
FormCard.AboutKDE {
|
||||||
title: i18nc("@title:window", "About KDE")
|
title: i18nc("@title:window", "About KDE")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,344 +7,337 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
|
import org.kde.kirigamiaddons.components 1.0 as KirigamiComponents
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
FormCard.FormCardPage {
|
||||||
|
id: root
|
||||||
|
|
||||||
title: i18nc("@title:window", "Appearance")
|
title: i18nc("@title:window", "Appearance")
|
||||||
topPadding: 0
|
|
||||||
leftPadding: 0
|
FormCard.FormHeader {
|
||||||
rightPadding: 0
|
Layout.fillWidth: true
|
||||||
ColumnLayout {
|
title: i18n("General theme")
|
||||||
spacing: 0
|
}
|
||||||
MobileForm.FormHeader {
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
FormCard.AbstractFormDelegate {
|
||||||
|
id: timelineModeSetting
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
title: i18n("General theme")
|
background: Item {}
|
||||||
}
|
contentItem: RowLayout {
|
||||||
MobileForm.FormCard {
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.fillWidth: true
|
spacing: Kirigami.Units.largeSpacing
|
||||||
contentItem: ColumnLayout {
|
Item {
|
||||||
spacing: 0
|
|
||||||
MobileForm.AbstractFormDelegate {
|
|
||||||
id: timelineModeSetting
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
background: Item {}
|
|
||||||
contentItem: RowLayout {
|
|
||||||
Layout.alignment: Qt.AlignCenter
|
|
||||||
spacing: Kirigami.Units.largeSpacing
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
QQC2.ButtonGroup { id: themeGroup }
|
|
||||||
ThemeRadioButton {
|
|
||||||
thin: timelineModeSetting.width < Kirigami.Units.gridUnit * 22
|
|
||||||
innerObject: [
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
color: "#4a5bcc"
|
|
||||||
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: "#4a5bcc"
|
|
||||||
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: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
color: "#9f244b"
|
|
||||||
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: "#9f244b"
|
|
||||||
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: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
text: i18n("Bubbles")
|
|
||||||
checked: !Config.compactLayout
|
|
||||||
QQC2.ButtonGroup.group: themeGroup
|
|
||||||
enabled: !Config.isCompactLayoutImmutable
|
|
||||||
|
|
||||||
onToggled: {
|
|
||||||
Config.compactLayout = !checked;
|
|
||||||
Config.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ThemeRadioButton {
|
|
||||||
// Layout.alignment: Qt.AlignRight
|
|
||||||
thin: timelineModeSetting.width < Kirigami.Units.gridUnit * 22
|
|
||||||
innerObject: [
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
color: "#4a5bcc"
|
|
||||||
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: "#4a5bcc"
|
|
||||||
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
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
color: "#9f244b"
|
|
||||||
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: "#9f244b"
|
|
||||||
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
|
|
||||||
enabled: !Config.isCompactLayoutImmutable
|
|
||||||
|
|
||||||
onToggled: {
|
|
||||||
Config.compactLayout = checked;
|
|
||||||
Config.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
QQC2.ButtonGroup { id: themeGroup }
|
||||||
|
ThemeRadioButton {
|
||||||
|
thin: timelineModeSetting.width < Kirigami.Units.gridUnit * 22
|
||||||
|
innerObject: [
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
KirigamiComponents.Avatar {
|
||||||
|
color: "#4a5bcc"
|
||||||
|
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: "#4a5bcc"
|
||||||
|
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: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
RowLayout {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
KirigamiComponents.Avatar {
|
||||||
|
color: "#9f244b"
|
||||||
|
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: "#9f244b"
|
||||||
|
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: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
MobileForm.FormDelegateSeparator { below: compactRoomListDelegate }
|
text: i18n("Bubbles")
|
||||||
|
checked: !Config.compactLayout
|
||||||
|
QQC2.ButtonGroup.group: themeGroup
|
||||||
|
enabled: !Config.isCompactLayoutImmutable
|
||||||
|
|
||||||
MobileForm.FormCheckDelegate {
|
|
||||||
id: compactRoomListDelegate
|
|
||||||
text: i18n("Use compact room list")
|
|
||||||
checked: Config.compactRoomList
|
|
||||||
onToggled: {
|
onToggled: {
|
||||||
Config.compactRoomList = checked;
|
Config.compactLayout = !checked;
|
||||||
Config.save();
|
Config.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ThemeRadioButton {
|
||||||
MobileForm.FormDelegateSeparator { above: compactRoomListDelegate ; below: colorSchemeDelegate.item ; visible: colorSchemeDelegate.visible }
|
// Layout.alignment: Qt.AlignRight
|
||||||
|
thin: timelineModeSetting.width < Kirigami.Units.gridUnit * 22
|
||||||
Loader {
|
innerObject: [
|
||||||
id: colorSchemeDelegate
|
RowLayout {
|
||||||
visible: item !== null && Qt.platform.os !== "android"
|
Layout.fillWidth: true
|
||||||
source: "qrc:/ColorScheme.qml"
|
KirigamiComponents.Avatar {
|
||||||
|
color: "#4a5bcc"
|
||||||
|
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: "#4a5bcc"
|
||||||
|
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
|
||||||
|
KirigamiComponents.Avatar {
|
||||||
|
color: "#9f244b"
|
||||||
|
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: "#9f244b"
|
||||||
|
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
|
||||||
|
enabled: !Config.isCompactLayoutImmutable
|
||||||
|
|
||||||
|
onToggled: {
|
||||||
|
Config.compactLayout = checked;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileForm.FormCard {
|
FormCard.FormDelegateSeparator { below: compactRoomListDelegate }
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
id: compactRoomListDelegate
|
||||||
|
text: i18n("Use compact room list")
|
||||||
|
checked: Config.compactRoomList
|
||||||
|
onToggled: {
|
||||||
|
Config.compactRoomList = checked;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator { above: compactRoomListDelegate ; below: colorSchemeDelegate.item ; visible: colorSchemeDelegate.visible }
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: colorSchemeDelegate
|
||||||
|
visible: item !== null && Qt.platform.os !== "android"
|
||||||
|
source: "qrc:/ColorScheme.qml"
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Layout.topMargin: Kirigami.Units.largeSpacing * 2
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
id: showFancyEffectsDelegate
|
||||||
|
text: i18n("Show fancy effects in chat")
|
||||||
|
checked: Config.showFancyEffects
|
||||||
|
enabled: !Config.isShowFancyEffectsImmutable
|
||||||
|
onToggled: {
|
||||||
|
Config.showFancyEffects = checked;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator { above: showFancyEffectsDelegate ; below: hasWindowSystemDelegate }
|
||||||
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
id: hasWindowSystemDelegate
|
||||||
|
visible: Controller.hasWindowSystem
|
||||||
|
text: i18n("Use transparent chat page")
|
||||||
|
enabled: !Config.compactLayout && !Config.isBlurImmutable
|
||||||
|
checked: Config.blur
|
||||||
|
onToggled: {
|
||||||
|
Config.blur = checked;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator { above: hasWindowSystemDelegate; below: transparencyDelegate }
|
||||||
|
|
||||||
|
FormCard.AbstractFormDelegate {
|
||||||
|
id: transparencyDelegate
|
||||||
|
Layout.fillWidth: true
|
||||||
|
visible: Controller.hasWindowSystem && Config.blur
|
||||||
|
enabled: !Config.isTransparancyImmutable
|
||||||
|
background: Item {}
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
spacing: 0
|
QQC2.Label {
|
||||||
MobileForm.FormCheckDelegate {
|
text: i18n("Transparency")
|
||||||
id: showFancyEffectsDelegate
|
|
||||||
text: i18n("Show fancy effects in chat")
|
|
||||||
checked: Config.showFancyEffects
|
|
||||||
enabled: !Config.isShowFancyEffectsImmutable
|
|
||||||
onToggled: {
|
|
||||||
Config.showFancyEffects = checked;
|
|
||||||
Config.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MobileForm.FormDelegateSeparator { above: showFancyEffectsDelegate ; below: hasWindowSystemDelegate }
|
|
||||||
|
|
||||||
MobileForm.FormCheckDelegate {
|
|
||||||
id: hasWindowSystemDelegate
|
|
||||||
visible: Controller.hasWindowSystem
|
|
||||||
text: i18n("Use transparent chat page")
|
|
||||||
enabled: !Config.compactLayout && !Config.isBlurImmutable
|
|
||||||
checked: Config.blur
|
|
||||||
onToggled: {
|
|
||||||
Config.blur = checked;
|
|
||||||
Config.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MobileForm.FormDelegateSeparator { above: hasWindowSystemDelegate; below: transparencyDelegate }
|
|
||||||
|
|
||||||
MobileForm.AbstractFormDelegate {
|
|
||||||
id: transparencyDelegate
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
visible: Controller.hasWindowSystem && Config.blur
|
|
||||||
enabled: !Config.isTransparancyImmutable
|
|
||||||
background: Item {}
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
QQC2.Label {
|
|
||||||
text: i18n("Transparency")
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
QQC2.Slider {
|
|
||||||
enabled: !Config.compactLayout && Config.blur
|
|
||||||
from: 0
|
|
||||||
to: 1
|
|
||||||
stepSize: 0.05
|
|
||||||
value: Config.transparency
|
|
||||||
onMoved: {
|
|
||||||
Config.transparency = value;
|
|
||||||
Config.save();
|
|
||||||
}
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
HoverHandler { id: sliderHover }
|
|
||||||
QQC2.ToolTip.visible: sliderHover.hovered && !enabled
|
|
||||||
QQC2.ToolTip.text: i18n("Only enabled if the transparent chat page is enabled.")
|
|
||||||
}
|
|
||||||
QQC2.Label {
|
|
||||||
text: Math.round(Config.transparency * 100) + "%"
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
QQC2.Slider {
|
||||||
MobileForm.FormDelegateSeparator { above: transparencyDelegate; below: showLocalMessagesOnRightDelegate; visible: transparencyDelegate.visible }
|
enabled: !Config.compactLayout && Config.blur
|
||||||
|
from: 0
|
||||||
MobileForm.FormCheckDelegate {
|
to: 1
|
||||||
id: showLocalMessagesOnRightDelegate
|
stepSize: 0.05
|
||||||
text: i18n("Show your messages on the right")
|
value: Config.transparency
|
||||||
checked: Config.showLocalMessagesOnRight
|
onMoved: {
|
||||||
enabled: !Config.isShowLocalMessagesOnRightImmutable && !Config.compactLayout
|
Config.transparency = value;
|
||||||
onToggled: {
|
Config.save();
|
||||||
Config.showLocalMessagesOnRight = checked
|
|
||||||
Config.save()
|
|
||||||
}
|
}
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
HoverHandler { id: sliderHover }
|
||||||
|
QQC2.ToolTip.visible: sliderHover.hovered && !enabled
|
||||||
|
QQC2.ToolTip.text: i18n("Only enabled if the transparent chat page is enabled.")
|
||||||
}
|
}
|
||||||
|
QQC2.Label {
|
||||||
MobileForm.FormDelegateSeparator { above: showLocalMessagesOnRightDelegate; below: showLinkPreviewDelegate }
|
text: Math.round(Config.transparency * 100) + "%"
|
||||||
|
Layout.fillWidth: true
|
||||||
MobileForm.FormCheckDelegate {
|
|
||||||
id: showLinkPreviewDelegate
|
|
||||||
text: i18n("Show links preview in the chat messages")
|
|
||||||
checked: Config.showLinkPreview
|
|
||||||
onToggled: {
|
|
||||||
Config.showLinkPreview = checked
|
|
||||||
Config.save()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileForm.FormHeader {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
title: i18n("Show Avatar")
|
|
||||||
}
|
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
MobileForm.FormCheckDelegate {
|
|
||||||
text: i18n("In chat")
|
|
||||||
checked: Config.showAvatarInTimeline
|
|
||||||
onToggled: {
|
|
||||||
Config.showAvatarInTimeline = checked
|
|
||||||
Config.save()
|
|
||||||
}
|
|
||||||
enabled: !Config.isShowAvatarInTimelineImmutable
|
|
||||||
}
|
|
||||||
|
|
||||||
MobileForm.FormCheckDelegate {
|
FormCard.FormDelegateSeparator { above: transparencyDelegate; below: showLocalMessagesOnRightDelegate; visible: transparencyDelegate.visible }
|
||||||
text: i18n("In sidebar")
|
|
||||||
checked: Config.showAvatarInRoomDrawer
|
FormCard.FormCheckDelegate {
|
||||||
enabled: !Config.isShowAvatarInRoomDrawerImmutable
|
id: showLocalMessagesOnRightDelegate
|
||||||
onToggled: {
|
text: i18n("Show your messages on the right")
|
||||||
Config.showAvatarInRoomDrawer = checked
|
checked: Config.showLocalMessagesOnRight
|
||||||
Config.save()
|
enabled: !Config.isShowLocalMessagesOnRightImmutable && !Config.compactLayout
|
||||||
}
|
onToggled: {
|
||||||
}
|
Config.showLocalMessagesOnRight = checked
|
||||||
|
Config.save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormDelegateSeparator { above: showLocalMessagesOnRightDelegate; below: showLinkPreviewDelegate }
|
||||||
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
id: showLinkPreviewDelegate
|
||||||
|
text: i18n("Show links preview in the chat messages")
|
||||||
|
checked: Config.showLinkPreview
|
||||||
|
onToggled: {
|
||||||
|
Config.showLinkPreview = checked
|
||||||
|
Config.save()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormHeader {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
title: i18n("Show Avatar")
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
text: i18n("In chat")
|
||||||
|
checked: Config.showAvatarInTimeline
|
||||||
|
onToggled: {
|
||||||
|
Config.showAvatarInTimeline = checked
|
||||||
|
Config.save()
|
||||||
|
}
|
||||||
|
enabled: !Config.isShowAvatarInTimelineImmutable
|
||||||
|
}
|
||||||
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
text: i18n("In sidebar")
|
||||||
|
checked: Config.showAvatarInRoomDrawer
|
||||||
|
enabled: !Config.isShowAvatarInRoomDrawerImmutable
|
||||||
|
onToggled: {
|
||||||
|
Config.showAvatarInRoomDrawer = checked
|
||||||
|
Config.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.19 as Kirigami
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
MobileForm.AbstractFormDelegate {
|
FormCard.AbstractFormDelegate {
|
||||||
id: deviceDelegate
|
id: deviceDelegate
|
||||||
|
|
||||||
required property string id
|
required property string id
|
||||||
|
|||||||
@@ -7,80 +7,81 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.19 as Kirigami
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
FormCard.FormCardPage {
|
||||||
|
id: root
|
||||||
|
|
||||||
title: i18n("Devices")
|
title: i18n("Devices")
|
||||||
|
|
||||||
property alias connection: devicesModel.connection
|
property alias connection: devicesModel.connection
|
||||||
|
|
||||||
leftPadding: 0
|
DevicesCard {
|
||||||
rightPadding: 0
|
title: i18n("This Device")
|
||||||
|
type: DevicesModel.This
|
||||||
DevicesModel {
|
showVerifyButton: false
|
||||||
id: devicesModel
|
}
|
||||||
|
DevicesCard {
|
||||||
|
title: i18n("Verified Devices")
|
||||||
|
type: DevicesModel.Verified
|
||||||
|
showVerifyButton: true
|
||||||
|
}
|
||||||
|
DevicesCard {
|
||||||
|
title: i18n("Unverified Devices")
|
||||||
|
type: DevicesModel.Unverified
|
||||||
|
showVerifyButton: true
|
||||||
|
}
|
||||||
|
DevicesCard {
|
||||||
|
title: i18n("Devices without Encryption Support")
|
||||||
|
type: DevicesModel.Unencrypted
|
||||||
|
showVerifyButton: false
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
FormCard.AbstractFormDelegate {
|
||||||
DevicesCard {
|
Layout.fillWidth: true
|
||||||
title: i18n("This Device")
|
visible: Controller.activeConnection && devicesModel.count === 0 // We can assume 0 means loading since there is at least one device
|
||||||
type: DevicesModel.This
|
contentItem: Kirigami.LoadingPlaceholder { }
|
||||||
showVerifyButton: false
|
|
||||||
}
|
|
||||||
DevicesCard {
|
|
||||||
title: i18n("Verified Devices")
|
|
||||||
type: DevicesModel.Verified
|
|
||||||
showVerifyButton: true
|
|
||||||
}
|
|
||||||
DevicesCard {
|
|
||||||
title: i18n("Unverified Devices")
|
|
||||||
type: DevicesModel.Unverified
|
|
||||||
showVerifyButton: true
|
|
||||||
}
|
|
||||||
DevicesCard {
|
|
||||||
title: i18n("Devices without Encryption Support")
|
|
||||||
type: DevicesModel.Unencrypted
|
|
||||||
showVerifyButton: false
|
|
||||||
}
|
|
||||||
|
|
||||||
MobileForm.AbstractFormDelegate {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
visible: Controller.activeConnection && devicesModel.count === 0 // We can assume 0 means loading since there is at least one device
|
|
||||||
contentItem: Kirigami.LoadingPlaceholder { }
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.InlineMessage {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
text: i18n("Please login to view the signed-in devices for your account.")
|
|
||||||
type: Kirigami.MessageType.Information
|
|
||||||
visible: !Controller.activeConnection
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Kirigami.OverlaySheet {
|
Kirigami.InlineMessage {
|
||||||
id: passwordSheet
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: Kirigami.Units.gridUnit * 30
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
text: i18n("Please login to view the signed-in devices for your account.")
|
||||||
|
type: Kirigami.MessageType.Information
|
||||||
|
visible: !Controller.activeConnection
|
||||||
|
}
|
||||||
|
|
||||||
property string deviceId
|
data: [
|
||||||
|
DevicesModel {
|
||||||
|
id: devicesModel
|
||||||
|
},
|
||||||
|
Kirigami.PromptDialog {
|
||||||
|
id: passwordSheet
|
||||||
|
|
||||||
title: i18n("Remove device")
|
property string deviceId
|
||||||
Kirigami.FormLayout {
|
|
||||||
QQC2.TextField {
|
parent: applicationWindow().overlay
|
||||||
|
title: i18n("Remove device")
|
||||||
|
standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel
|
||||||
|
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
|
||||||
|
onAccepted: {
|
||||||
|
devicesModel.logout(passwordSheet.deviceId, passwordField.text)
|
||||||
|
passwordField.text = ""
|
||||||
|
passwordSheet.close()
|
||||||
|
}
|
||||||
|
FormCard.FormTextFieldDelegate {
|
||||||
id: passwordField
|
id: passwordField
|
||||||
Kirigami.FormData.label: i18n("Password:")
|
label: i18n("Password:")
|
||||||
echoMode: TextInput.Password
|
echoMode: TextInput.Password
|
||||||
}
|
}
|
||||||
QQC2.Button {
|
|
||||||
text: i18n("Confirm")
|
|
||||||
onClicked: {
|
|
||||||
devicesModel.logout(passwordSheet.deviceId, passwordField.text)
|
|
||||||
passwordField.text = ""
|
|
||||||
passwordSheet.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,104 +6,102 @@ import QtQuick.Controls 2.15 as QQC2
|
|||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
import org.kde.kirigami 2.15 as Kirigami
|
import org.kde.kirigami 2.15 as Kirigami
|
||||||
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
|
import org.kde.kirigamiaddons.formcard 1.0 as FormCard
|
||||||
|
|
||||||
import org.kde.neochat 1.0
|
import org.kde.neochat 1.0
|
||||||
|
|
||||||
Kirigami.ScrollablePage {
|
FormCard.FormCardPage {
|
||||||
title: i18nc("@title:window", "General")
|
id: root
|
||||||
|
|
||||||
property int currentType
|
property int currentType
|
||||||
property bool proxyConfigChanged: false
|
property bool proxyConfigChanged: false
|
||||||
|
|
||||||
topPadding: 0
|
title: i18nc("@title:window", "General")
|
||||||
leftPadding: 0
|
|
||||||
rightPadding: 0
|
FormCard.FormHeader {
|
||||||
ColumnLayout {
|
title: i18n("Network Proxy")
|
||||||
spacing: 0
|
}
|
||||||
MobileForm.FormHeader {
|
|
||||||
Layout.fillWidth: true
|
FormCard.FormCard {
|
||||||
title: i18n("Network Proxy")
|
FormCard.FormRadioDelegate {
|
||||||
|
text: i18n("System Default")
|
||||||
|
checked: currentType === 0
|
||||||
|
enabled: !Config.isProxyTypeImmutable
|
||||||
|
onToggled: {
|
||||||
|
currentType = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormCard {
|
FormCard.FormRadioDelegate {
|
||||||
Layout.fillWidth: true
|
text: i18n("HTTP")
|
||||||
contentItem: ColumnLayout {
|
checked: currentType === 1
|
||||||
spacing: 0
|
enabled: !Config.isProxyTypeImmutable
|
||||||
MobileForm.FormRadioDelegate {
|
onToggled: {
|
||||||
text: i18n("System Default")
|
currentType = 1
|
||||||
checked: currentType === 0
|
}
|
||||||
enabled: !Config.isProxyTypeImmutable
|
}
|
||||||
onToggled: {
|
FormCard.FormRadioDelegate {
|
||||||
currentType = 0
|
text: i18n("Socks5")
|
||||||
}
|
checked: currentType === 2
|
||||||
}
|
enabled: !Config.isProxyTypeImmutable
|
||||||
MobileForm.FormRadioDelegate {
|
onToggled: {
|
||||||
text: i18n("HTTP")
|
currentType = 2
|
||||||
checked: currentType === 1
|
}
|
||||||
enabled: !Config.isProxyTypeImmutable
|
}
|
||||||
onToggled: {
|
}
|
||||||
currentType = 1
|
|
||||||
}
|
FormCard.FormHeader {
|
||||||
}
|
title: i18n("Proxy Settings")
|
||||||
MobileForm.FormRadioDelegate {
|
}
|
||||||
text: i18n("Socks5")
|
|
||||||
checked: currentType === 2
|
FormCard.FormCard {
|
||||||
enabled: !Config.isProxyTypeImmutable
|
FormCard.FormTextFieldDelegate {
|
||||||
onToggled: {
|
id: hostField
|
||||||
currentType = 2
|
label: i18n("Host")
|
||||||
}
|
text: Config.proxyHost
|
||||||
}
|
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||||
|
onEditingFinished: {
|
||||||
|
proxyConfigChanged = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MobileForm.FormHeader {
|
FormCard.FormDelegateSeparator {}
|
||||||
Layout.fillWidth: true
|
|
||||||
title: i18n("Proxy Settings")
|
FormCard.FormSpinBoxDelegate {
|
||||||
|
id: portField
|
||||||
|
label: i18n("Port")
|
||||||
|
value: Config.proxyPort
|
||||||
|
from: 0
|
||||||
|
to: 65536
|
||||||
|
textFromValue: function(value, locale) {
|
||||||
|
return value // it will add a thousands separator if we don't do this, not sure why
|
||||||
|
}
|
||||||
|
onValueChanged: {
|
||||||
|
proxyConfigChanged = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
MobileForm.FormCard {
|
|
||||||
Layout.fillWidth: true
|
FormCard.FormDelegateSeparator {}
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
FormCard.FormTextFieldDelegate {
|
||||||
MobileForm.FormTextFieldDelegate {
|
id: userField
|
||||||
id: hostField
|
label: i18n("User")
|
||||||
label: i18n("Host")
|
text: Config.proxyUser
|
||||||
text: Config.proxyHost
|
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
onEditingFinished: {
|
||||||
onEditingFinished: {
|
proxyConfigChanged = true
|
||||||
proxyConfigChanged = true
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
MobileForm.FormSpinBoxDelegate {
|
FormCard.FormDelegateSeparator {}
|
||||||
id: portField
|
|
||||||
label: i18n("Port")
|
FormCard.FormTextFieldDelegate {
|
||||||
value: Config.proxyPort
|
id: passwordField
|
||||||
from: 0
|
label: i18n("Password")
|
||||||
to: 65536
|
text: Config.proxyPassword
|
||||||
textFromValue: function(value, locale) {
|
echoMode: TextInput.Password
|
||||||
return value // it will add a thousands separator if we don't do this, not sure why
|
inputMethodHints: Qt.ImhUrlCharactersOnly
|
||||||
}
|
onEditingFinished: {
|
||||||
onValueChanged: {
|
proxyConfigChanged = true
|
||||||
proxyConfigChanged = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormTextFieldDelegate {
|
|
||||||
id: userField
|
|
||||||
label: i18n("User")
|
|
||||||
text: Config.proxyUser
|
|
||||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
|
||||||
onEditingFinished: {
|
|
||||||
proxyConfigChanged = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MobileForm.FormTextFieldDelegate {
|
|
||||||
id: passwordField
|
|
||||||
label: i18n("Password")
|
|
||||||
text: Config.proxyPassword
|
|
||||||
echoMode: TextInput.Password
|
|
||||||
inputMethodHints: Qt.ImhUrlCharactersOnly
|
|
||||||
onEditingFinished: {
|
|
||||||
proxyConfigChanged = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user