From 2a0b6c74f303530eebd1f7307b80fcfb8663430c Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Fri, 27 Nov 2020 23:43:11 +0100 Subject: [PATCH] Switch between room list items with standard tab switching keyboard shortcuts Ctrl+PgUp/PgDn and Ctrl+Tab/Ctrl+Shift+Tab Fix #66 --- imports/NeoChat/Page/RoomListPage.qml | 14 +++++ imports/NeoChat/Page/RoomPage.qml | 77 +++++++++++++++++---------- qml/main.qml | 23 ++++++-- 3 files changed, 84 insertions(+), 30 deletions(-) diff --git a/imports/NeoChat/Page/RoomListPage.qml b/imports/NeoChat/Page/RoomListPage.qml index 3131c1f11..08a5b671c 100644 --- a/imports/NeoChat/Page/RoomListPage.qml +++ b/imports/NeoChat/Page/RoomListPage.qml @@ -25,6 +25,20 @@ Kirigami.ScrollablePage { signal enterRoom(var room) signal leaveRoom(var room) + function goToNextRoom() { + do { + listView.incrementCurrentIndex(); + } while (!listView.currentItem.visible && listView.currentIndex === listView.count) + listView.currentItem.action.trigger(); + } + + function goToPreviousRoom() { + do { + listView.decrementCurrentIndex(); + } while (!listView.currentItem.visible && listView.currentIndex !== 0) + listView.currentItem.action.trigger(); + } + title: i18n("Rooms") titleDelegate: Kirigami.SearchField { diff --git a/imports/NeoChat/Page/RoomPage.qml b/imports/NeoChat/Page/RoomPage.qml index 8cc6d9f4a..0e7ada836 100644 --- a/imports/NeoChat/Page/RoomPage.qml +++ b/imports/NeoChat/Page/RoomPage.qml @@ -26,9 +26,59 @@ Kirigami.ScrollablePage { property var currentRoom + signal switchRoomUp() + signal switchRoomDown() + title: currentRoom.name + focus: true + + Keys.onTabPressed: { + if (event.modifiers & Qt.ControlModifier) { + switchRoomDown(); + } + } + + Keys.onBacktabPressed: { + if (event.modifiers & Qt.ControlModifier) { + switchRoomUp(); + } + } + + Keys.onPressed: { + if (event.key === Qt.Key_PageDown) { + switchRoomDown(); + } else if (event.key === Qt.Key_PageUp) { + switchRoomUp(); + } + } ListView { + id: messageListView + + readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1 + readonly property bool noNeedMoreContent: !currentRoom || currentRoom.eventsHistoryJob || currentRoom.allHistoryLoaded + readonly property bool isLoaded: page.width * page.height > 10 + + spacing: Kirigami.Units.smallSpacing + clip: true + + verticalLayoutDirection: ListView.BottomToTop + highlightMoveDuration: 500 + + model: !isLoaded ? undefined : sortedMessageEventModel + + onContentYChanged: { + if(!noNeedMoreContent && contentY - 5000 < originY) + currentRoom.getPreviousContent(20); + const index = eventToIndex(currentRoom.readMarkerEventId) + if(index === -1) + return + if(firstVisibleIndex() === -1 || lastVisibleIndex() === -1) + return + if(index < firstVisibleIndex() && index > lastVisibleIndex()) { + currentRoom.readMarkerEventId = sortedMessageEventModel.data(sortedMessageEventModel.index(lastVisibleIndex(), 0), MessageEventModel.EventIdRole) + } + } MessageEventModel { id: messageEventModel @@ -102,33 +152,6 @@ Kirigami.ScrollablePage { return messageEventModel.data(messageEventModel.index(row, 0), MessageEventModel.MessageRole) !== 0x10 && messageEventModel.data(messageEventModel.index(row, 0), MessageEventModel.EventTypeRole) !== "other" } } - readonly property int largestVisibleIndex: count > 0 ? indexAt(contentX + (width / 2), contentY + height - 1) : -1 - readonly property bool noNeedMoreContent: !currentRoom || currentRoom.eventsHistoryJob || currentRoom.allHistoryLoaded - - readonly property bool isLoaded: page.width * page.height > 10 - - id: messageListView - - spacing: Kirigami.Units.smallSpacing - clip: true - - verticalLayoutDirection: ListView.BottomToTop - highlightMoveDuration: 500 - - model: !isLoaded ? undefined : sortedMessageEventModel - - onContentYChanged: { - if(!noNeedMoreContent && contentY - 5000 < originY) - currentRoom.getPreviousContent(20); - const index = eventToIndex(currentRoom.readMarkerEventId) - if(index === -1) - return - if(firstVisibleIndex() === -1 || lastVisibleIndex() === -1) - return - if(index < firstVisibleIndex() && index > lastVisibleIndex()) { - currentRoom.readMarkerEventId = sortedMessageEventModel.data(sortedMessageEventModel.index(lastVisibleIndex(), 0), MessageEventModel.EventIdRole) - } - } // populate: Transition { // NumberAnimation { diff --git a/qml/main.qml b/qml/main.qml index f5443e491..34638e8c0 100644 --- a/qml/main.qml +++ b/qml/main.qml @@ -29,6 +29,7 @@ Kirigami.ApplicationWindow { property var currentRoom: null property alias pageStack: root.pageStack property bool invitationOpen: false + property var roomList: null readonly property bool hasOpenRoom: currentRoom !== null @@ -39,7 +40,8 @@ Kirigami.ApplicationWindow { if (Config.openRoom) { const room = Controller.activeConnection.room(Config.openRoom); currentRoom = room; - pageStack.push(roomPage, { 'currentRoom': room, }); + let item = pageStack.push(roomPage, { 'currentRoom': room, }); + connectRoomToSignal(item); } else { // TODO create welcome page } @@ -56,6 +58,7 @@ Kirigami.ApplicationWindow { currentRoom = room; Config.openRoom = room.id; Config.save(); + connectRoomToSignal(item); return item; } @@ -71,6 +74,20 @@ Kirigami.ApplicationWindow { function getBack() { pageStack.replace(roomPage, { 'currentRoom': currentRoom, }); } + + function connectRoomToSignal(item) { + console.log("connect") + if (!roomList) { + console.log("Should not happen: no room list page but room page"); + } + item.switchRoomUp.connect(function() { + roomList.goToNextRoom(); + }); + + item.switchRoomDown.connect(function() { + roomList.goToPreviousRoom(); + }); + } } function pushReplaceLayer(page, args) { @@ -167,14 +184,14 @@ Kirigami.ApplicationWindow { if (Controller.accountCount === 0) { pageStack.replace("qrc:/imports/NeoChat/Page/LoginPage.qml", {}); } else { - pageStack.replace(roomListComponent, {'activeConnection': Controller.activeConnection}); + roomManager.roomList = pageStack.replace(roomListComponent, {'activeConnection': Controller.activeConnection}); roomManager.loadInitialRoom(); } } onConnectionAdded: { if (Controller.accountCount === 1) { - pageStack.replace(roomListComponent); + roomManager.roomList = pageStack.replace(roomListComponent); } }