Make room settings pane scrollable
The new Base/ButtonLayout components will be used in the near future to refactor other HBox-based components
This commit is contained in:
parent
48faac9a32
commit
3314489a26
|
@ -62,6 +62,8 @@ and this project adheres to
|
|||
|
||||
### Fixed
|
||||
|
||||
- The room settings pane is now scrollable
|
||||
|
||||
- Avoid potential error if the room list data model is initialized after an
|
||||
initial sync has already been completed
|
||||
|
||||
|
|
13
TODO.md
13
TODO.md
|
@ -3,7 +3,6 @@
|
|||
## Refactoring
|
||||
|
||||
- Rewrite account settings using `HTabbedContainer`
|
||||
- Get rid of all `currentSpacing` stuff
|
||||
- Use new default/reset controls system
|
||||
- Display name field text should be colored
|
||||
|
||||
|
@ -16,9 +15,13 @@
|
|||
## Issues
|
||||
|
||||
- Don't send typing notification when switching to a room where the composer
|
||||
has loaded text
|
||||
has preloaded text
|
||||
|
||||
- Popups and room settings can't be scrolled when not enough height to show all
|
||||
- When calling `Backend.update_room_read_marker()` for a recent message,
|
||||
the marker will only be updated for accounts that have already received
|
||||
it (server lag)
|
||||
|
||||
- Popups can't be scrolled when not enough height to show all
|
||||
- `TextArea`s in Popups grow past window height instead of being scrollable
|
||||
|
||||
- Jumping between accounts (clicking in account bar or alt+(Shift+)N) is
|
||||
|
@ -37,8 +40,8 @@
|
|||
|
||||
- After forgetting a room, it comes back because of the "you left" event
|
||||
|
||||
- `code` and links in quote ("> http://example.com") aren't properly colored
|
||||
in room "last message" subtitle
|
||||
- `code`, mentions and links in quote ("> http://example.com") aren't properly
|
||||
colored in room delegate "last message" subtitle
|
||||
|
||||
- `Timer` and `Animation` are bound to framerate
|
||||
- Can't use `QQmlApplicationEngine`, problem with QApplication?
|
||||
|
|
14
src/gui/Base/ButtonLayout/ApplyButton.qml
Normal file
14
src/gui/Base/ButtonLayout/ApplyButton.qml
Normal file
|
@ -0,0 +1,14 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
|
||||
HButton {
|
||||
implicitHeight: theme.baseElementsHeight
|
||||
text: qsTr("Apply")
|
||||
icon.name: "apply"
|
||||
icon.color: theme.colors.positiveBackground
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
23
src/gui/Base/ButtonLayout/ButtonLayout.qml
Normal file
23
src/gui/Base/ButtonLayout/ButtonLayout.qml
Normal file
|
@ -0,0 +1,23 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
|
||||
HGridLayout {
|
||||
readonly property int summedImplicitWidth: {
|
||||
const widths = []
|
||||
|
||||
for (let i = 0; i < visibleChildren.length; i++) {
|
||||
const item = visibleChildren[i]
|
||||
if (item) widths.push(item.width > 0 ? item.implicitWidth : 0)
|
||||
}
|
||||
|
||||
return utils.sum(widths)
|
||||
}
|
||||
|
||||
flow:
|
||||
width >= summedImplicitWidth ?
|
||||
GridLayout.LeftToRight :
|
||||
GridLayout.TopToBottom
|
||||
}
|
14
src/gui/Base/ButtonLayout/CancelButton.qml
Normal file
14
src/gui/Base/ButtonLayout/CancelButton.qml
Normal file
|
@ -0,0 +1,14 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
|
||||
HButton {
|
||||
implicitHeight: theme.baseElementsHeight
|
||||
text: qsTr("Cancel")
|
||||
icon.name: "cancel"
|
||||
icon.color: theme.colors.negativeBackground
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
|
@ -103,8 +103,6 @@ Rectangle {
|
|||
Keys.onUpPressed: previous.forceActiveFocus()
|
||||
Keys.onRightPressed: next.forceActiveFocus()
|
||||
Keys.onDownPressed: next.forceActiveFocus()
|
||||
Keys.onReturnPressed: if (button.enabled) button.clicked()
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
|
||||
Component.onCompleted:
|
||||
if (name === focusButton) forceActiveFocus()
|
||||
|
|
|
@ -41,6 +41,10 @@ Button {
|
|||
buttonTheme: theme.controls.button
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: if (enabled) clicked()
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
activeFocusOnTab: true
|
||||
|
||||
|
||||
readonly property alias iconItem: contentItem.icon
|
||||
readonly property alias label: contentItem.label
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
import QtQuick 2.12
|
||||
|
||||
HPage {
|
||||
id: page
|
||||
|
||||
|
||||
default property alias columnData: column.data
|
||||
|
||||
|
||||
|
|
|
@ -4,8 +4,16 @@ import QtQuick 2.12
|
|||
import "../ShortcutBundles"
|
||||
|
||||
HPage {
|
||||
property alias flickable: flickable
|
||||
id: page
|
||||
|
||||
|
||||
default property alias columnData: column.data
|
||||
property alias column: column
|
||||
property alias flickable: flickable
|
||||
property alias flickShortcuts: flickShortcuts
|
||||
|
||||
|
||||
padding: 0
|
||||
|
||||
|
||||
HFlickable {
|
||||
|
@ -16,14 +24,20 @@ HPage {
|
|||
contentHeight: column.childrenRect.height
|
||||
|
||||
FlickShortcuts {
|
||||
id: flickShortcuts
|
||||
active: ! mainUI.debugConsole.visible
|
||||
flickable: flickable
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
id: column
|
||||
width: flickable.width
|
||||
height: flickable.height
|
||||
x: padding
|
||||
y: padding
|
||||
width: flickable.width - padding * 2
|
||||
height: flickable.height - padding * 2
|
||||
|
||||
property int padding:
|
||||
page.currentSpacing < theme.spacing ? 0 : page.currentSpacing
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,17 @@ import QtQuick 2.12
|
|||
import QtQuick.Controls 2.12
|
||||
|
||||
Page {
|
||||
leftPadding: currentSpacing < theme.spacing ? 0 : currentSpacing
|
||||
rightPadding: leftPadding
|
||||
padding: currentSpacing < theme.spacing ? 0 : currentSpacing
|
||||
background: null
|
||||
|
||||
|
||||
property bool useVariableSpacing: true
|
||||
|
||||
property int currentSpacing:
|
||||
Math.min(theme.spacing * width / 400, theme.spacing)
|
||||
useVariableSpacing ?
|
||||
Math.min(theme.spacing * width / 400, theme.spacing) :
|
||||
theme.spacing
|
||||
|
||||
|
||||
Behavior on leftPadding { HNumberAnimation {} }
|
||||
Behavior on padding { HNumberAnimation {} }
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ Item {
|
|||
readonly property alias loader: loader
|
||||
readonly property alias roomPane: roomPaneLoader.item
|
||||
|
||||
readonly property bool composerHasFocus:
|
||||
Boolean(loader.item && loader.item.composer.hasFocus)
|
||||
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.leaveRoom
|
||||
|
|
|
@ -10,8 +10,7 @@ import "Timeline"
|
|||
|
||||
HColumnPage {
|
||||
id: chatPage
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
padding: 0
|
||||
|
||||
onLoadEventListChanged: if (loadEventList) loadedOnce = true
|
||||
Component.onDestruction: if (loadMembersFuture) loadMembersFuture.cancel()
|
||||
|
|
|
@ -7,6 +7,7 @@ import "../../../Base"
|
|||
|
||||
Rectangle {
|
||||
property alias eventList: messageArea.eventList
|
||||
readonly property bool hasFocus: messageArea.activeFocus
|
||||
|
||||
|
||||
function takeFocus() { messageArea.forceActiveFocus() }
|
||||
|
|
|
@ -76,7 +76,7 @@ MultiviewPane {
|
|||
}
|
||||
|
||||
MemberView {}
|
||||
SettingsView { fillAvailableHeight: true }
|
||||
SettingsView {}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.toggleFocusRoomPane
|
||||
|
|
|
@ -3,66 +3,9 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../../../Base"
|
||||
import "../../../Base/ButtonLayout"
|
||||
|
||||
HBox {
|
||||
color: theme.chat.roomPane.roomSettings.background
|
||||
|
||||
buttonModel: [
|
||||
{
|
||||
name: "apply",
|
||||
text: qsTr("Save"),
|
||||
iconName: "apply",
|
||||
enabled: anyChange,
|
||||
loading: saveFuture !== null,
|
||||
disableWhileLoading: false,
|
||||
},
|
||||
{
|
||||
name: "cancel",
|
||||
text: qsTr("Cancel"),
|
||||
iconName: "cancel",
|
||||
enabled: anyChange || saveFuture !== null,
|
||||
},
|
||||
]
|
||||
|
||||
buttonCallbacks: ({
|
||||
apply: button => {
|
||||
if (saveFuture) saveFuture.cancel()
|
||||
|
||||
const args = [
|
||||
chat.roomId,
|
||||
nameField.item.changed ? nameField.item.text : undefined,
|
||||
topicArea.item.changed ? topicArea.item.text : undefined,
|
||||
encryptCheckBox.changed ? true : undefined,
|
||||
|
||||
requireInviteCheckbox.changed ?
|
||||
requireInviteCheckbox.checked : undefined,
|
||||
|
||||
forbidGuestsCheckBox.changed ?
|
||||
forbidGuestsCheckBox.checked : undefined,
|
||||
]
|
||||
|
||||
function onDone() { saveFuture = null }
|
||||
|
||||
saveFuture = py.callClientCoro(
|
||||
chat.userId, "room_set", args, onDone, onDone,
|
||||
)
|
||||
},
|
||||
|
||||
cancel: button => {
|
||||
if (saveFuture) {
|
||||
saveFuture.cancel()
|
||||
saveFuture = null
|
||||
}
|
||||
|
||||
nameField.item.reset()
|
||||
topicArea.item.reset()
|
||||
encryptCheckBox.reset()
|
||||
requireInviteCheckbox.reset()
|
||||
forbidGuestsCheckBox.reset()
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
HFlickableColumnPage {
|
||||
property var saveFuture: null
|
||||
|
||||
readonly property bool anyChange:
|
||||
|
@ -73,6 +16,69 @@ HBox {
|
|||
readonly property Item keybindFocusItem: nameField.item
|
||||
|
||||
|
||||
function save() {
|
||||
if (saveFuture) saveFuture.cancel()
|
||||
|
||||
const args = [
|
||||
chat.roomId,
|
||||
nameField.item.changed ? nameField.item.text : undefined,
|
||||
topicArea.item.changed ? topicArea.item.text : undefined,
|
||||
encryptCheckBox.changed ? true : undefined,
|
||||
|
||||
requireInviteCheckbox.changed ?
|
||||
requireInviteCheckbox.checked : undefined,
|
||||
|
||||
forbidGuestsCheckBox.changed ?
|
||||
forbidGuestsCheckBox.checked : undefined,
|
||||
]
|
||||
|
||||
function onDone() { saveFuture = null }
|
||||
|
||||
saveFuture = py.callClientCoro(
|
||||
chat.userId, "room_set", args, onDone, onDone,
|
||||
)
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
if (saveFuture) {
|
||||
saveFuture.cancel()
|
||||
saveFuture = null
|
||||
}
|
||||
|
||||
nameField.item.reset()
|
||||
topicArea.item.reset()
|
||||
encryptCheckBox.reset()
|
||||
requireInviteCheckbox.reset()
|
||||
forbidGuestsCheckBox.reset()
|
||||
}
|
||||
|
||||
|
||||
useVariableSpacing: false
|
||||
column.spacing: theme.spacing * 1.5
|
||||
|
||||
flickShortcuts.active:
|
||||
! mainUI.debugConsole.visible && ! chat.composerHasFocus
|
||||
|
||||
background: Rectangle {
|
||||
color: theme.chat.roomPane.roomSettings.background
|
||||
}
|
||||
|
||||
footer: ButtonLayout {
|
||||
ApplyButton {
|
||||
enabled: anyChange
|
||||
loading: saveFuture !== null
|
||||
disableWhileLoading: false
|
||||
onClicked: save()
|
||||
|
||||
}
|
||||
|
||||
CancelButton {
|
||||
enabled: anyChange || saveFuture !== null
|
||||
onClicked: cancel()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRoomAvatar {
|
||||
id: avatar
|
||||
roomId: chat.roomId
|
||||
|
@ -108,6 +114,7 @@ HBox {
|
|||
Layout.fillWidth: true
|
||||
|
||||
HTextArea {
|
||||
// TODO: limit height
|
||||
width: parent.width
|
||||
placeholderText: qsTr("This room is about...")
|
||||
defaultText: chat.roomInfo.plain_topic
|
||||
|
|
|
@ -175,7 +175,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
FlickShortcuts {
|
||||
active: ! mainUI.debugConsole.visible
|
||||
active: chat.composerHasFocus
|
||||
flickable: eventList
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user