When clicking on an account in the top account bar or using the Keys.Account.(previous/next) keybinds, go to the corresponding account settings instead of trying to focus the first room of that account if there is one: user might not want to clear the read marker of any random room that is out of view and happens to be the first in the list.
300 lines
8.6 KiB
QML
300 lines
8.6 KiB
QML
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
import QtQuick 2.12
|
|
import QtQuick.Layouts 1.12
|
|
import Qt.labs.qmlmodels 1.0
|
|
import ".."
|
|
import "../Base"
|
|
|
|
HListView {
|
|
id: roomList
|
|
|
|
property string filter: ""
|
|
|
|
property bool keepListCentered: true
|
|
|
|
readonly property bool currentShouldBeAccount:
|
|
window.uiState.page === "Pages/AccountSettings/AccountSettings.qml" ||
|
|
window.uiState.page === "Pages/AddChat/AddChat.qml"
|
|
|
|
readonly property bool currentShouldBeRoom:
|
|
window.uiState.page === "Pages/Chat/Chat.qml"
|
|
|
|
readonly property string wantedUserId: (
|
|
window.uiState.pageProperties.userRoomId ||
|
|
[window.uiState.pageProperties.userId, ""]
|
|
)[0] || ""
|
|
|
|
readonly property string wantedRoomId: (
|
|
window.uiState.pageProperties.userRoomId ||
|
|
["", window.uiState.pageProperties.roomId]
|
|
)[1] || ""
|
|
|
|
readonly property var accountIndice: {
|
|
const accounts = {}
|
|
|
|
for (let i = 0; i < model.count; i++) {
|
|
if (model.get(i).type === "Account")
|
|
accounts[model.get(i).id] = i
|
|
}
|
|
|
|
return accounts
|
|
}
|
|
|
|
function goToAccount(userId) {
|
|
currentIndex = accountIndice[userId]
|
|
showItemLimiter.restart()
|
|
}
|
|
|
|
function goToAccountNumber(num) {
|
|
const index = Object.entries(accountIndice)[num][1]
|
|
|
|
model.get(index + 1).type === "Room" ?
|
|
currentIndex = index + 1 :
|
|
currentIndex = index
|
|
|
|
showItemLimiter.restart()
|
|
}
|
|
|
|
function showItemAtIndex(index=currentIndex, fromClick=false) {
|
|
if (index === -1) index = 0
|
|
index = Math.min(index, model.count - 1)
|
|
|
|
const item = model.get(index)
|
|
|
|
item.type === "Account" ?
|
|
pageLoader.show(
|
|
"Pages/AccountSettings/AccountSettings.qml", { "userId": item.id },
|
|
) :
|
|
pageLoader.showRoom(item.for_account, item.id)
|
|
|
|
if (fromClick && ! window.settings.RoomList.click_centers)
|
|
keepListCentered = false
|
|
|
|
currentIndex = index
|
|
|
|
if (fromClick && ! window.settings.RoomList.click_centers)
|
|
keepListCentered = true
|
|
}
|
|
|
|
function showAccountRoomAtIndex(index) {
|
|
const item = model.get(currentIndex === -1 ? 0 : currentIndex)
|
|
|
|
const currentUserId =
|
|
item.type === "Account" ? item.id : item.for_account
|
|
|
|
showItemAtIndex(accountIndice[currentUserId] + 1 + index)
|
|
}
|
|
|
|
function cycleUnreadRooms(forward=true, highlights=false) {
|
|
const prop = highlights ? "highlights" : "unreads"
|
|
const local_prop = highlights ? "highlights" : "local_unreads"
|
|
const start = currentIndex === -1 ? 0 : currentIndex
|
|
let index = start
|
|
|
|
while (true) {
|
|
index += forward ? 1 : -1
|
|
|
|
if (index < 0) index = model.count - 1
|
|
if (index > model.count - 1) index = 0
|
|
|
|
if (index === start && highlights)
|
|
return cycleUnreadRooms(forward, false)
|
|
else if (index === start)
|
|
return false
|
|
|
|
const item = model.get(index)
|
|
|
|
if (item.type === "Room" && (item[prop] || item[local_prop])) {
|
|
currentIndex = index
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
function startCorrectItemSearch() {
|
|
correctTimer.start()
|
|
}
|
|
|
|
function setCorrectCurrentItem() {
|
|
if (! currentShouldBeRoom && ! currentShouldBeAccount) {
|
|
currentIndex = -1
|
|
return null
|
|
}
|
|
|
|
for (let i = 0; i < model.count; i++) {
|
|
const item = model.get(i)
|
|
|
|
if ((
|
|
currentShouldBeRoom &&
|
|
item.type === "Room" &&
|
|
item.id === wantedRoomId &&
|
|
item.for_account === wantedUserId
|
|
) || (
|
|
currentShouldBeAccount &&
|
|
item.type === "Account" &&
|
|
item.id === wantedUserId
|
|
)) {
|
|
currentIndex = i
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
highlightRangeMode:
|
|
keepListCentered ? ListView.ApplyRange : ListView.NoHighlightRange
|
|
|
|
model: ModelStore.get("all_rooms")
|
|
|
|
delegate: DelegateChooser {
|
|
role: "type"
|
|
|
|
DelegateChoice {
|
|
roleValue: "Account"
|
|
AccountDelegate {
|
|
width: roomList.width
|
|
leftPadding: theme.spacing
|
|
rightPadding: 0 // the right buttons have padding
|
|
|
|
filterActive: Boolean(filter)
|
|
enableKeybinds: Boolean(
|
|
roomList.model.get(currentIndex) && (
|
|
roomList.model.get(currentIndex).for_account ||
|
|
roomList.model.get(currentIndex).id
|
|
) === model.id
|
|
)
|
|
|
|
totalMessageIndicator.visible: false
|
|
|
|
onLeftClicked: showItemAtIndex(model.index, true)
|
|
onCollapsedChanged:
|
|
if (wantedUserId === model.id) startCorrectItemSearch()
|
|
|
|
onWentToAccountPage: roomList.currentIndex = model.index
|
|
}
|
|
}
|
|
|
|
DelegateChoice {
|
|
roleValue: "Room"
|
|
RoomDelegate {
|
|
width: roomList.width
|
|
onLeftClicked: showItemAtIndex(model.index, true)
|
|
}
|
|
}
|
|
}
|
|
|
|
onFilterChanged: {
|
|
py.callCoro("set_string_filter", ["all_rooms", filter], () => {
|
|
if (filter) {
|
|
currentIndex = 1 // highlight the first matching room
|
|
return
|
|
}
|
|
|
|
const item = model.get(currentIndex)
|
|
|
|
if (
|
|
! filter &&
|
|
item && (
|
|
currentIndex === 1 || // required, related to the if above
|
|
(
|
|
currentShouldBeAccount &&
|
|
wantedUserId !== item.id
|
|
) || (
|
|
currentShouldBeRoom && (
|
|
wantedUserId !== item.for_account ||
|
|
wantedRoomId !== item.id
|
|
)
|
|
)
|
|
)
|
|
)
|
|
startCorrectItemSearch()
|
|
})
|
|
}
|
|
|
|
Connections {
|
|
target: pageLoader
|
|
onPreviousShown: (componentUrl, properties) => {
|
|
if (setCorrectCurrentItem() === false) startCorrectItemSearch()
|
|
}
|
|
}
|
|
|
|
Timer {
|
|
// On startup, the account/room takes an unknown amount of time to
|
|
// arrive in the model, try to find it until then.
|
|
id: correctTimer
|
|
interval: 200
|
|
running: currentIndex === -1
|
|
repeat: true
|
|
triggeredOnStart: true
|
|
onTriggered: setCorrectCurrentItem()
|
|
onRunningChanged: if (running && currentIndex !== -1) currentIndex = -1
|
|
}
|
|
|
|
Timer {
|
|
id: showItemLimiter
|
|
interval: 100
|
|
onTriggered: showItemAtIndex()
|
|
}
|
|
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.previous
|
|
onActivated: { decrementCurrentIndex(); showItemLimiter.restart() }
|
|
}
|
|
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.next
|
|
onActivated: { incrementCurrentIndex(); showItemLimiter.restart() }
|
|
}
|
|
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.previous_unread
|
|
onActivated: { cycleUnreadRooms(false) && showItemLimiter.restart() }
|
|
}
|
|
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.next_unread
|
|
onActivated: { cycleUnreadRooms(true) && showItemLimiter.restart() }
|
|
}
|
|
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.previous_highlight
|
|
onActivated: cycleUnreadRooms(false, true) && showItemLimiter.restart()
|
|
}
|
|
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.next_highlight
|
|
onActivated: cycleUnreadRooms(true, true) && showItemLimiter.restart()
|
|
}
|
|
|
|
Repeater {
|
|
model: Object.keys(window.settings.Keys.Accounts.AtIndex)
|
|
|
|
Item {
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Accounts.AtIndex[modelData]
|
|
onActivated: goToAccountNumber(parseInt(modelData, 10) - 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
Repeater {
|
|
model: Object.keys(window.settings.Keys.Rooms.AtIndex)
|
|
|
|
Item {
|
|
HShortcut {
|
|
sequences: window.settings.Keys.Rooms.AtIndex[modelData]
|
|
onActivated: showAccountRoomAtIndex(parseInt(modelData,10) - 1)
|
|
}
|
|
}
|
|
}
|
|
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
z: -100
|
|
color: theme.mainPane.listView.background
|
|
}
|
|
}
|