Start restructuring how the account/room pane work
This commit is contained in:
parent
da6a54f0bf
commit
72c96b3ba5
5
TODO.md
5
TODO.md
|
@ -1,7 +1,8 @@
|
|||
# TODO
|
||||
|
||||
- fix alt+shift+j/k when going to the end of a list is taller than window
|
||||
- fix focusRoomAtIndex
|
||||
- message delegate too tall
|
||||
|
||||
- fix escape keybinds (filter rooms, message selection)
|
||||
- if last room event is a membership change, it won't be visible in timeline
|
||||
- use uiState instead of open_room
|
||||
|
||||
|
|
|
@ -5,5 +5,5 @@ import QtQuick 2.12
|
|||
Loader {
|
||||
id: loader
|
||||
asynchronous: true
|
||||
visible: status === Loader.Ready
|
||||
// visible: status === Loader.Ready
|
||||
}
|
||||
|
|
|
@ -12,8 +12,17 @@ SwipeView {
|
|||
saveEnabled = true
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: if (saveEnabled) window.saveState(this)
|
||||
onCurrentIndexChanged: {
|
||||
if (saveEnabled) window.saveState(this)
|
||||
|
||||
if (currentIndex < previousIndex) lastMove = HSwipeView.Move.ToPrevious
|
||||
if (currentIndex > previousIndex) lastMove = HSwipeView.Move.ToNext
|
||||
|
||||
previousIndex = currentIndex
|
||||
}
|
||||
|
||||
|
||||
enum Move { ToPrevious, ToNext }
|
||||
|
||||
property string saveName: ""
|
||||
property var saveId: "ALL"
|
||||
|
@ -22,7 +31,9 @@ SwipeView {
|
|||
// Prevent onCurrentIndexChanged from running before Component.onCompleted
|
||||
property bool saveEnabled: false
|
||||
|
||||
property int previousIndex: 0
|
||||
property int defaultIndex: 0
|
||||
property int lastMove: HSwipeView.Move.ToNext
|
||||
property bool changed: currentIndex !== defaultIndex
|
||||
|
||||
|
||||
|
|
|
@ -6,43 +6,30 @@ import Clipboard 0.1
|
|||
import "../Base"
|
||||
import "../Base/HTile"
|
||||
|
||||
HTileDelegate {
|
||||
HTile {
|
||||
id: account
|
||||
rightPadding: 0
|
||||
implicitHeight: theme.baseElementsHeight
|
||||
backgroundColor: theme.mainPane.listView.account.background
|
||||
opacity: collapsed && ! mainPane.filter ?
|
||||
theme.mainPane.listView.account.collapsedOpacity : 1
|
||||
padded: false
|
||||
|
||||
contentItem: ContentRow {
|
||||
tile: account
|
||||
spacing: 0
|
||||
|
||||
HUserAvatar {
|
||||
id: avatar
|
||||
userId: model.id
|
||||
displayName: model.display_name
|
||||
mxc: model.avatar_url
|
||||
compact: account.compact
|
||||
|
||||
radius:
|
||||
mainPane.small ?
|
||||
theme.mainPane.listView.account.collapsedAvatarRadius :
|
||||
theme.mainPane.listView.account.avatarRadius
|
||||
|
||||
Behavior on radius { HNumberAnimation {} }
|
||||
radius: 0
|
||||
}
|
||||
|
||||
TitleLabel {
|
||||
text: model.display_name || model.id
|
||||
font.pixelSize: theme.fontSize.big
|
||||
color:
|
||||
hovered ?
|
||||
utils.nameColor(model.display_name || model.id.substring(1)) :
|
||||
theme.mainPane.listView.account.name
|
||||
|
||||
Layout.leftMargin: theme.spacing
|
||||
Layout.rightMargin: theme.spacing
|
||||
|
||||
Behavior on color { HColorAnimation {} }
|
||||
}
|
||||
|
||||
|
@ -56,51 +43,15 @@ HTileDelegate {
|
|||
"AddChat/AddChat", {userId: model.id},
|
||||
)
|
||||
|
||||
leftPadding: theme.spacing / 2
|
||||
rightPadding: leftPadding
|
||||
|
||||
opacity: expand.loading ? 0 : 1
|
||||
visible: opacity > 0 && Layout.maximumWidth > 0
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth:
|
||||
account.width >= 100 * theme.uiScale ? implicitWidth : 0
|
||||
|
||||
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
}
|
||||
|
||||
HButton {
|
||||
id: expand
|
||||
loading:
|
||||
! model.first_sync_done || model.profile_updated < new Date(1)
|
||||
iconItem.small: true
|
||||
icon.name: "expand"
|
||||
backgroundColor: "transparent"
|
||||
toolTip.text: collapsed ? qsTr("Expand") : qsTr("Collapse")
|
||||
onClicked: account.toggleCollapse()
|
||||
|
||||
leftPadding: theme.spacing / 2
|
||||
rightPadding: theme.spacing
|
||||
|
||||
opacity: ! loading && mainPane.filter ? 0 : 1
|
||||
visible: opacity > 0 && Layout.maximumWidth > 0
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.maximumWidth:
|
||||
account.width >= 120 * theme.uiScale ? implicitWidth : 0
|
||||
|
||||
|
||||
iconItem.transform: Rotation {
|
||||
origin.x: expand.iconItem.width / 2
|
||||
origin.y: expand.iconItem.height / 2
|
||||
angle: expand.loading ? 0 : collapsed ? 180 : 90
|
||||
|
||||
Behavior on angle { HNumberAnimation {} }
|
||||
HShortcut {
|
||||
enabled: isCurrent
|
||||
sequences: window.settings.keys.addNewChat
|
||||
onActivated: addChat.clicked()
|
||||
}
|
||||
|
||||
Behavior on Layout.maximumWidth { HNumberAnimation {} }
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,33 +72,16 @@ HTileDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
onActivated: {
|
||||
onLeftClicked: {
|
||||
pageLoader.showPage(
|
||||
"AccountSettings/AccountSettings", { "userId": model.id }
|
||||
)
|
||||
mainPaneList.detachedCurrentIndex = false
|
||||
mainPaneList.centerToHighlight = false
|
||||
}
|
||||
|
||||
|
||||
readonly property alias addChat: addChat
|
||||
|
||||
readonly property bool collapsed:
|
||||
(window.uiState.collapseAccounts[model.id] || false) &&
|
||||
! mainPane.filter
|
||||
property bool isCurrent: false
|
||||
|
||||
|
||||
function setCollapse(collapse) {
|
||||
window.uiState.collapseAccounts[model.id] = collapse
|
||||
window.uiStateChanged()
|
||||
}
|
||||
|
||||
function toggleCollapse() {
|
||||
setCollapse(! collapsed)
|
||||
}
|
||||
|
||||
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
Behavior on leftPadding { HNumberAnimation {} }
|
||||
Behavior on topPadding { HNumberAnimation {} }
|
||||
|
||||
|
@ -165,4 +99,11 @@ HTileDelegate {
|
|||
value: theme.spacing
|
||||
when: mainPane.small
|
||||
}
|
||||
|
||||
|
||||
HShortcut {
|
||||
enabled: isCurrent
|
||||
sequences: window.settings.keys.accountSettings
|
||||
onActivated: leftClicked()
|
||||
}
|
||||
}
|
||||
|
|
73
src/gui/MainPane/AccountBar.qml
Normal file
73
src/gui/MainPane/AccountBar.qml
Normal file
|
@ -0,0 +1,73 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
import "../Base"
|
||||
import "../Base/HTile"
|
||||
|
||||
HColumnLayout {
|
||||
property RoomPane roomContainer
|
||||
|
||||
|
||||
HButton {
|
||||
id: settingsButton
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "settings"
|
||||
toolTip.text: qsTr("Open config folder")
|
||||
|
||||
onClicked: py.callCoro("get_config_dir", [], Qt.openUrlExternally)
|
||||
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
}
|
||||
|
||||
HListView {
|
||||
id: accountList
|
||||
model: ModelStore.get("accounts")
|
||||
currentIndex: roomContainer.currentIndex
|
||||
|
||||
delegate: HTileDelegate {
|
||||
id: tile
|
||||
width: accountList.width
|
||||
backgroundColor: theme.mainPane.listView.account.background
|
||||
leftPadding: 0
|
||||
rightPadding: leftPadding
|
||||
|
||||
contentItem: Item {
|
||||
implicitHeight: avatar.height
|
||||
|
||||
HUserAvatar {
|
||||
id: avatar
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
userId: model.id
|
||||
displayName: model.display_name
|
||||
mxc: model.avatar_url
|
||||
// compact: account.compact
|
||||
|
||||
radius: theme.mainPane.listView.account.avatarRadius
|
||||
}
|
||||
}
|
||||
|
||||
onLeftClicked: roomContainer.currentIndex = model.index
|
||||
}
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
id: addAccountButton
|
||||
icon.name: "add-account"
|
||||
toolTip.text: qsTr("Add another account")
|
||||
backgroundColor: theme.mainPane.bottomBar.settingsButtonBackground
|
||||
onClicked: pageLoader.showPage("AddAccount/AddAccount")
|
||||
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.addNewAccount
|
||||
onActivated: addAccountButton.clicked()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import SortFilterProxyModel 0.2
|
||||
import ".."
|
||||
import "../Base"
|
||||
|
||||
Column {
|
||||
id: accountRooms
|
||||
// visible: account.opacity > 0
|
||||
|
||||
|
||||
readonly property string userId: model.id
|
||||
readonly property bool firstSyncDone: model.first_sync_done
|
||||
readonly property HListView view: ListView.view
|
||||
readonly property int listIndex: index
|
||||
readonly property bool noFilterResults:
|
||||
mainPane.filter && roomList.model.count === 0
|
||||
|
||||
readonly property alias account: account
|
||||
readonly property alias collapsed: account.collapsed
|
||||
readonly property alias roomList: roomList
|
||||
|
||||
|
||||
Account {
|
||||
id: account
|
||||
width: parent.width
|
||||
view: accountRooms.view
|
||||
|
||||
opacity: collapsed || noFilterResults ?
|
||||
theme.mainPane.listView.account.collapsedOpacity : 1
|
||||
}
|
||||
|
||||
HListView {
|
||||
id: roomList
|
||||
width: parent.width
|
||||
height: contentHeight
|
||||
interactive: false
|
||||
|
||||
// https://github.com/oKcerG/SortFilterProxyModel/issues/75
|
||||
model:
|
||||
mainPane.filter ? proxy :
|
||||
account.collapsed ? null :
|
||||
proxy.sourceModel
|
||||
|
||||
delegate: HLoader {
|
||||
asynchronous: false
|
||||
active: index === 0 || (
|
||||
roomList.firstDelegateHeight !== 0 &&
|
||||
index >= roomList.firstIndexInView &&
|
||||
index <= roomList.lastIndexInView
|
||||
)
|
||||
|
||||
width: roomList.width
|
||||
height: roomList.firstDelegateHeight
|
||||
|
||||
readonly property var sourceModel: model
|
||||
|
||||
sourceComponent: Room {
|
||||
width: roomList.width
|
||||
userId: accountRooms.userId
|
||||
view: roomList
|
||||
model: sourceModel
|
||||
}
|
||||
}
|
||||
|
||||
highlight: null // managed by the AccountRoomsList
|
||||
|
||||
|
||||
// Delete 0 must *always* be loaded, and all delegates must have the
|
||||
// same height
|
||||
property int firstDelegateHeight:
|
||||
contentItem.visibleChildren[0] ?
|
||||
contentItem.visibleChildren[0].implicitHeight :
|
||||
0
|
||||
|
||||
readonly property int firstIndexInView:
|
||||
(mainPaneList.contentY - account.height - accountRooms.spacing) /
|
||||
firstDelegateHeight -
|
||||
accountRooms.y / firstDelegateHeight
|
||||
|
||||
readonly property int lastIndexInView:
|
||||
firstIndexInView + mainPaneList.height / firstDelegateHeight
|
||||
|
||||
readonly property bool hasActiveRoom:
|
||||
window.uiState.page === "Pages/Chat/Chat.qml" &&
|
||||
window.uiState.pageProperties.userId === userId
|
||||
|
||||
readonly property var activeRoomIndex:
|
||||
hasActiveRoom ?
|
||||
model.findIndex(window.uiState.pageProperties.roomId) : null
|
||||
|
||||
readonly property HSortFilterProxyModel proxy: HSortFilterProxyModel {
|
||||
sourceModel: ModelStore.get(accountRooms.userId, "rooms")
|
||||
|
||||
filters: ExpressionFilter {
|
||||
expression: utils.filterMatches(
|
||||
mainPane.filter, model.display_name,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Binding on currentIndex {
|
||||
value:
|
||||
roomList.hasActiveRoom ?
|
||||
(
|
||||
roomList.activeRoomIndex === null ?
|
||||
-1 : roomList.activeRoomIndex
|
||||
) : -1
|
||||
|
||||
when: ! view.detachedCurrentIndex
|
||||
}
|
||||
|
||||
Behavior on height { HNumberAnimation {} }
|
||||
}
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import ".."
|
||||
import "../Base"
|
||||
|
||||
HListView {
|
||||
id: mainPaneList
|
||||
model: ModelStore.get("accounts")
|
||||
spacing: mainPane.small ? theme.spacing : 0
|
||||
|
||||
delegate: AccountRoomsDelegate {
|
||||
width: mainPaneList.width
|
||||
height: childrenRect.height
|
||||
}
|
||||
|
||||
// Must handle the highlight's position and size manually because
|
||||
// of our nested lists
|
||||
highlightFollowsCurrentItem: false
|
||||
highlightRangeMode: ListView.NoHighlightRange
|
||||
|
||||
highlight: Rectangle {
|
||||
id: highlightRectangle
|
||||
y:
|
||||
! currentItem ?
|
||||
0 :
|
||||
|
||||
selectedRoom ?
|
||||
currentItem.y + currentItem.account.height +
|
||||
currentItem.roomList.currentItem.y :
|
||||
|
||||
currentItem.y
|
||||
|
||||
width: mainPaneList.width
|
||||
height:
|
||||
! currentItem ?
|
||||
0 :
|
||||
|
||||
selectedRoom ?
|
||||
currentItem.roomList.currentItem.height :
|
||||
currentItem.account.height
|
||||
|
||||
color:
|
||||
mainPane.small ?
|
||||
theme.controls.listView.smallPaneHighlight :
|
||||
theme.controls.listView.highlight
|
||||
|
||||
Behavior on y { HNumberAnimation { id: yAnimation } }
|
||||
Behavior on height { HNumberAnimation {} }
|
||||
Behavior on color { HColorAnimation {} }
|
||||
|
||||
Binding {
|
||||
target: mainPaneList
|
||||
property: "contentY"
|
||||
value: highlightRectangle.y + highlightRectangle.height / 2 -
|
||||
mainPaneList.height / 2
|
||||
delayed: true
|
||||
when: centerToHighlight && yAnimation.running
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: mainPaneList
|
||||
enabled: centerToHighlight && yAnimation.running
|
||||
onContentYChanged: mainPaneList.returnToBounds()
|
||||
}
|
||||
}
|
||||
|
||||
onMovingChanged: if (moving) centerToHighlight = false
|
||||
|
||||
|
||||
property bool detachedCurrentIndex: false
|
||||
property bool centerToHighlight: true
|
||||
|
||||
readonly property HLoader selectedRoom:
|
||||
currentItem ? currentItem.roomList.currentItem : null
|
||||
|
||||
readonly property bool hasActiveAccount:
|
||||
window.uiState.page === "Pages/Chat/Chat.qml" ||
|
||||
window.uiState.page === "Pages/AddChat/AddChat.qml" ||
|
||||
window.uiState.page === "Pages/AccountSettings/AccountSettings.qml"
|
||||
|
||||
readonly property var activeAccountIndex:
|
||||
hasActiveAccount ?
|
||||
model.findIndex(window.uiState.pageProperties.userId) : null
|
||||
|
||||
|
||||
|
||||
function previous() {
|
||||
centerToHighlight = true
|
||||
detachedCurrentIndex = true
|
||||
|
||||
if (! mainPane.filter) {
|
||||
_previous()
|
||||
return
|
||||
}
|
||||
|
||||
let reachedStart = false
|
||||
do {
|
||||
if (currentIndex === count - 1 && reachedStart) break
|
||||
_previous()
|
||||
if (currentIndex === 0) reachedStart = true
|
||||
} while (! currentItem.roomList.currentItem)
|
||||
}
|
||||
|
||||
function _previous() {
|
||||
const currentAccount = currentItem
|
||||
|
||||
// Nothing is selected
|
||||
if (! currentAccount) {
|
||||
decrementCurrentIndex()
|
||||
}
|
||||
|
||||
const roomList = currentAccount.roomList
|
||||
|
||||
// An account is selected
|
||||
if (! roomList.currentItem) {
|
||||
decrementCurrentIndex()
|
||||
// Select the last room of the previous account that's now selected
|
||||
currentItem.roomList.decrementCurrentIndex()
|
||||
return
|
||||
}
|
||||
|
||||
// A room is selected
|
||||
const selectedIsFirst = roomList.currentIndex === 0
|
||||
const noRooms = roomList.count === 0
|
||||
|
||||
if (currentAccount.collapsed || selectedIsFirst || noRooms) {
|
||||
// Have the account itself be selected
|
||||
roomList.currentIndex = -1 // XXX
|
||||
} else {
|
||||
roomList.decrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
function next() {
|
||||
centerToHighlight = true
|
||||
detachedCurrentIndex = true
|
||||
|
||||
if (! mainPane.filter) {
|
||||
_next()
|
||||
return
|
||||
}
|
||||
|
||||
let reachedEnd = false
|
||||
do {
|
||||
if (currentIndex === 0 && reachedEnd) break
|
||||
_next()
|
||||
if (currentIndex === count - 1) reachedEnd = true
|
||||
} while (! currentItem.roomList.currentItem)
|
||||
}
|
||||
|
||||
function _next() {
|
||||
const currentAccount = currentItem
|
||||
|
||||
// Nothing is selected
|
||||
if (! currentAccount) {
|
||||
incrementCurrentIndex()
|
||||
return
|
||||
}
|
||||
|
||||
const roomList = currentAccount.roomList
|
||||
|
||||
// An account is selected
|
||||
if (! roomList.currentItem) {
|
||||
if (currentAccount.collapsed || roomList.count === 0) {
|
||||
incrementCurrentIndex()
|
||||
} else {
|
||||
roomList.incrementCurrentIndex()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// A room is selected
|
||||
const selectedIsLast = roomList.currentIndex >= roomList.count - 1
|
||||
const noRooms = roomList.count === 0
|
||||
|
||||
if (currentAccount.collapsed || selectedIsLast || noRooms) {
|
||||
roomList.currentIndex = -1 // XXX
|
||||
mainPaneList.incrementCurrentIndex()
|
||||
} else {
|
||||
roomList.incrementCurrentIndex()
|
||||
}
|
||||
}
|
||||
|
||||
function goToRoom(index) {
|
||||
if (! currentItem) next()
|
||||
if (! currentItem) return
|
||||
|
||||
const room = currentItem.roomList.contentItem.children[index]
|
||||
print(index, room, room.item)
|
||||
if (room && room.item && room.item.activated) room.item.activated()
|
||||
}
|
||||
|
||||
function requestActivate() {
|
||||
activateLimiter.restart()
|
||||
}
|
||||
|
||||
function activate() {
|
||||
if (! currentItem) next()
|
||||
if (! currentItem) return
|
||||
|
||||
selectedRoom ?
|
||||
currentItem.roomList.currentItem.item.activated() :
|
||||
currentItem.account.activated()
|
||||
|
||||
detachedCurrentIndex = false
|
||||
}
|
||||
|
||||
function accountSettings() {
|
||||
if (! currentItem) next()
|
||||
if (! currentItem) return
|
||||
currentItem.account.activated()
|
||||
|
||||
detachedCurrentIndex = false
|
||||
}
|
||||
|
||||
function addNewChat() {
|
||||
if (! currentItem) next()
|
||||
if (! currentItem) return
|
||||
currentItem.account.addChat.clicked()
|
||||
|
||||
detachedCurrentIndex = false
|
||||
}
|
||||
|
||||
function setCollapseAccount(collapse) {
|
||||
if (! currentItem) return
|
||||
currentItem.account.setCollapse(collapse)
|
||||
}
|
||||
|
||||
function toggleCollapseAccount() {
|
||||
if (mainPane.filter) return
|
||||
if (! currentItem) next()
|
||||
|
||||
currentItem.account.toggleCollapse()
|
||||
}
|
||||
|
||||
|
||||
Binding on currentIndex {
|
||||
value:
|
||||
hasActiveAccount ?
|
||||
(activeAccountIndex === null ? -1 : activeAccountIndex) : -1
|
||||
|
||||
when: ! detachedCurrentIndex
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.addNewChat
|
||||
onActivated: addNewChat()
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.accountSettings
|
||||
onActivated: accountSettings()
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.toggleCollapseAccount
|
||||
onActivated: toggleCollapseAccount()
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.goToPreviousRoom
|
||||
onActivated: { previous(); requestActivate() }
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.goToNextRoom
|
||||
onActivated: { next(); requestActivate() }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Object.keys(window.settings.keys.focusRoomAtIndex)
|
||||
|
||||
Item {
|
||||
HShortcut {
|
||||
sequence: window.settings.keys.focusRoomAtIndex[modelData]
|
||||
onActivated: goToRoom(parseInt(modelData - 1, 10))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: activateLimiter
|
||||
interval: 200
|
||||
onTriggered: activate()
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
z: -100
|
||||
color: theme.mainPane.listView.background
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
Rectangle {
|
||||
// Hide filter field overflowing for a sec on size changes
|
||||
clip: true
|
||||
color: theme.mainPane.bottomBar.background
|
||||
|
||||
|
||||
property AccountRoomsList mainPaneList
|
||||
readonly property alias addAccountButton: addAccountButton
|
||||
readonly property alias filterField: filterField
|
||||
property alias roomFilter: filterField.text
|
||||
|
||||
|
||||
HRowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
HButton {
|
||||
id: addAccountButton
|
||||
icon.name: "add-account"
|
||||
toolTip.text: qsTr("Add another account")
|
||||
backgroundColor: theme.mainPane.bottomBar.settingsButtonBackground
|
||||
onClicked: pageLoader.showPage("AddAccount/AddAccount")
|
||||
|
||||
Layout.fillHeight: true
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.addNewAccount
|
||||
onActivated: addAccountButton.clicked()
|
||||
}
|
||||
}
|
||||
|
||||
HTextField {
|
||||
id: filterField
|
||||
saveName: "roomFilterField"
|
||||
|
||||
placeholderText: qsTr("Filter rooms")
|
||||
backgroundColor: theme.mainPane.bottomBar.filterFieldBackground
|
||||
bordered: false
|
||||
opacity: width >= 16 * theme.uiScale ? 1 : 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
Keys.onUpPressed: mainPaneList.previous(false) // do not activate
|
||||
Keys.onDownPressed: mainPaneList.next(false)
|
||||
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
Keys.onReturnPressed: {
|
||||
if (event.modifiers & Qt.ShiftModifier) {
|
||||
mainPaneList.toggleCollapseAccount()
|
||||
return
|
||||
}
|
||||
|
||||
if (window.settings.clearRoomFilterOnEnter) {
|
||||
mainPaneList.setCollapseAccount(false)
|
||||
text = ""
|
||||
}
|
||||
|
||||
mainPaneList.requestActivate()
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
if (window.settings.clearRoomFilterOnEscape) text = ""
|
||||
mainUI.pageLoader.forceActiveFocus()
|
||||
}
|
||||
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
HShortcut {
|
||||
sequences: window.settings.keys.clearRoomFilter
|
||||
onActivated: filterField.text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,37 +8,13 @@ HDrawer {
|
|||
id: mainPane
|
||||
saveName: "mainPane"
|
||||
color: theme.mainPane.background
|
||||
minimumSize: bottomBar.addAccountButton.width
|
||||
// minimumSize: bottomBar.addAccountButton.width
|
||||
|
||||
onHasFocusChanged:
|
||||
if (! hasFocus) mainPaneList.detachedCurrentIndex = false
|
||||
|
||||
|
||||
property alias filter: bottomBar.roomFilter
|
||||
// property alias filter: bottomBar.roomFilter
|
||||
|
||||
readonly property bool small:
|
||||
width < theme.controls.avatar.size + theme.spacing * 2
|
||||
|
||||
readonly property bool hasFocus: bottomBar.filterField.activeFocus
|
||||
readonly property alias mainPaneList: mainPaneList
|
||||
readonly property alias topBar: topBar
|
||||
readonly property alias bottomBar: bottomBar
|
||||
|
||||
|
||||
function toggleFocus() {
|
||||
if (mainPane.activeFocus) {
|
||||
pageLoader.takeFocus()
|
||||
return
|
||||
}
|
||||
|
||||
mainPane.open()
|
||||
bottomBar.filterField.forceActiveFocus()
|
||||
}
|
||||
|
||||
function addccount() {
|
||||
bottomBar.addAccountButton.clicked()
|
||||
}
|
||||
|
||||
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
|
@ -47,38 +23,22 @@ HDrawer {
|
|||
when: ! mainUI.accountsPresent
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
active: mainUI.accountsPresent
|
||||
sequences: window.settings.keys.toggleFocusMainPane
|
||||
onActivated: toggleFocus()
|
||||
}
|
||||
|
||||
HColumnLayout {
|
||||
HRowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
TopBar {
|
||||
id: topBar
|
||||
AccountBar {
|
||||
id: accountBar
|
||||
roomContainer: roomPane
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
Layout.fillWidth: false
|
||||
}
|
||||
|
||||
AccountRoomsList {
|
||||
id: mainPaneList
|
||||
clip: true
|
||||
RoomPane {
|
||||
id: roomPane
|
||||
currentIndex: 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
BottomBar {
|
||||
id: bottomBar
|
||||
mainPaneList: mainPaneList
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ HTileDelegate {
|
|||
// topPadding: theme.spacing / (model.index === 0 ? 1 : 1.5)
|
||||
// bottomPadding:
|
||||
// theme.spacing / (model.index === view.count - 1 ? 1 : 1.5)
|
||||
leftPadding: theme.spacing * 2
|
||||
rightPadding: theme.spacing
|
||||
|
||||
contentItem: ContentRow {
|
||||
tile: room
|
||||
|
@ -207,15 +205,8 @@ HTileDelegate {
|
|||
}
|
||||
}
|
||||
|
||||
onActivated: {
|
||||
pageLoader.showRoom(userId, model.id)
|
||||
mainPaneList.detachedCurrentIndex = false
|
||||
mainPaneList.centerToHighlight = false
|
||||
}
|
||||
|
||||
|
||||
property string userId
|
||||
property QtObject model
|
||||
|
||||
readonly property bool joined: ! invited && ! parted
|
||||
readonly property bool invited: model.inviter_id && ! parted
|
||||
|
|
74
src/gui/MainPane/RoomList.qml
Normal file
74
src/gui/MainPane/RoomList.qml
Normal file
|
@ -0,0 +1,74 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
import "../Base"
|
||||
|
||||
HListView {
|
||||
id: roomList
|
||||
model: ModelStore.get(accountModel.id, "rooms")
|
||||
|
||||
delegate: Room {
|
||||
width: roomList.width
|
||||
userId: accountModel.id
|
||||
onActivated: showRoom(model.index)
|
||||
}
|
||||
|
||||
|
||||
property var accountModel
|
||||
property var roomPane
|
||||
property bool isCurrent: false
|
||||
|
||||
|
||||
function showRoom(index=currentIndex) {
|
||||
pageLoader.showRoom(accountModel.id, model.get(index).id)
|
||||
currentIndex = index
|
||||
}
|
||||
|
||||
|
||||
Timer {
|
||||
id: showRoomLimiter
|
||||
interval: 200
|
||||
onTriggered: showRoom()
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
enabled: isCurrent
|
||||
sequences: window.settings.keys.goToPreviousRoom
|
||||
onActivated: { decrementCurrentIndex(); showRoomLimiter.restart() }
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
enabled: isCurrent
|
||||
sequences: window.settings.keys.goToNextRoom
|
||||
onActivated: { incrementCurrentIndex(); showRoomLimiter.restart() }
|
||||
}
|
||||
|
||||
Repeater {
|
||||
model: Object.keys(window.settings.keys.focusRoomAtIndex)
|
||||
|
||||
Item {
|
||||
HShortcut {
|
||||
enabled: isCurrent
|
||||
sequence: window.settings.keys.focusRoomAtIndex[modelData]
|
||||
onActivated: showRoom(parseInt(modelData - 1, 10))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
onWheel: {
|
||||
const goingDown = wheel.angleDelta.y < 0
|
||||
|
||||
if (! goingDown && roomList.atYBeginning)
|
||||
roomPane.decrementCurrentIndex()
|
||||
else if (goingDown && roomList.atYEnd)
|
||||
roomPane.incrementCurrentIndex()
|
||||
else
|
||||
wheel.accepted = false
|
||||
}
|
||||
}
|
||||
}
|
100
src/gui/MainPane/RoomPane.qml
Normal file
100
src/gui/MainPane/RoomPane.qml
Normal file
|
@ -0,0 +1,100 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import ".."
|
||||
import "../Base"
|
||||
|
||||
HSwipeView {
|
||||
id: swipeView
|
||||
orientation: Qt.Vertical
|
||||
|
||||
Repeater {
|
||||
model: ModelStore.get("accounts")
|
||||
|
||||
HLoader {
|
||||
id: loader
|
||||
active:
|
||||
HSwipeView.isCurrentItem ||
|
||||
HSwipeView.isNextItem ||
|
||||
HSwipeView.isPreviousItem
|
||||
|
||||
readonly property bool isCurrent: HSwipeView.isCurrentItem
|
||||
|
||||
sourceComponent: HColumnLayout {
|
||||
id: column
|
||||
|
||||
readonly property QtObject accountModel: model
|
||||
readonly property alias roomList: roomList
|
||||
|
||||
Account {
|
||||
id: account
|
||||
isCurrent: loader.isCurrent
|
||||
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
RoomList {
|
||||
id: roomList
|
||||
clip: true
|
||||
accountModel: column.accountModel
|
||||
roomPane: swipeView
|
||||
isCurrent: loader.isCurrent
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HTextField {
|
||||
id: filterField
|
||||
saveName: "roomFilterField"
|
||||
|
||||
placeholderText: qsTr("Filter rooms")
|
||||
backgroundColor:
|
||||
theme.mainPane.bottomBar.filterFieldBackground
|
||||
bordered: false
|
||||
opacity: width >= 16 * theme.uiScale ? 1 : 0
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: theme.baseElementsHeight
|
||||
|
||||
Keys.onUpPressed: roomList.decrementCurrentIndex()
|
||||
Keys.onDownPressed: roomList.incrementCurrentIndex()
|
||||
|
||||
Keys.onEnterPressed: Keys.onReturnPressed(event)
|
||||
Keys.onReturnPressed: {
|
||||
if (window.settings.clearRoomFilterOnEnter) text = ""
|
||||
roomList.showRoom()
|
||||
}
|
||||
|
||||
Keys.onEscapePressed: {
|
||||
if (window.settings.clearRoomFilterOnEscape) text = ""
|
||||
mainUI.pageLoader.forceActiveFocus()
|
||||
}
|
||||
|
||||
Behavior on opacity { HNumberAnimation {} }
|
||||
|
||||
HShortcut {
|
||||
enabled: loader.isCurrent
|
||||
sequences: window.settings.keys.clearRoomFilter
|
||||
onActivated: filterField.text = ""
|
||||
}
|
||||
|
||||
HShortcut {
|
||||
enabled: loader.isCurrent
|
||||
sequences: window.settings.keys.toggleFocusMainPane
|
||||
onActivated: {
|
||||
if (filterField.activeFocus) {
|
||||
pageLoader.takeFocus()
|
||||
return
|
||||
}
|
||||
|
||||
mainPane.open()
|
||||
filterField.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import "../Base"
|
||||
|
||||
Rectangle {
|
||||
clip: true
|
||||
color: theme.mainPane.topBar.background
|
||||
|
||||
HRowLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
HButton {
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "settings"
|
||||
toolTip.text: qsTr("Open config folder")
|
||||
|
||||
onClicked: py.callCoro("get_config_dir", [], Qt.openUrlExternally)
|
||||
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
backgroundColor: "transparent"
|
||||
|
||||
text: qsTr("%1 %2")
|
||||
.arg(Qt.application.displayName).arg(Qt.application.version)
|
||||
label.color: theme.mainPane.topBar.nameVersionLabel
|
||||
toolTip.text: qsTr("Open project repository")
|
||||
|
||||
onClicked:
|
||||
Qt.openUrlExternally("https://github.com/mirukana/mirage")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "reload-config-files"
|
||||
toolTip.text: qsTr("Reload config files")
|
||||
|
||||
onClicked: mainUI.reloadSettings()
|
||||
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
|
||||
HButton {
|
||||
visible: Layout.preferredWidth > 0
|
||||
backgroundColor: "transparent"
|
||||
icon.name: "go-back-to-chat-from-main-pane"
|
||||
toolTip.text: qsTr("Go back to room")
|
||||
|
||||
onClicked: mainPane.toggleFocus()
|
||||
|
||||
Layout.preferredWidth: mainPane.collapse ? implicitWidth : 0
|
||||
Layout.fillHeight: true
|
||||
|
||||
Behavior on Layout.preferredWidth { HNumberAnimation {} }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user