From 82b1cc4e5f5a13793b3347c69292be22292aa82c Mon Sep 17 00:00:00 2001
From: Guillaume Girol <symphorien+git@xlumurb.eu>
Date: Sat, 11 Sep 2021 12:00:00 +0000
Subject: [PATCH] add Alt+A keybinding to switch to next room with unread
 messages

---
 resources/qml/Root.qml         |  5 ++++
 src/timeline/RoomlistModel.cpp | 46 ++++++++++++++++++++++++++++++++++
 src/timeline/RoomlistModel.h   |  1 +
 3 files changed, 52 insertions(+)

diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml
index cc7d32ea4..4207f35b6 100644
--- a/resources/qml/Root.qml
+++ b/resources/qml/Root.qml
@@ -120,6 +120,11 @@ Page {
         }
     }
 
+    Shortcut {
+        sequence: "Alt+A"
+        onActivated: Rooms.nextRoomWithActivity()
+    }
+
     Shortcut {
         sequence: "Ctrl+Down"
         onActivated: Rooms.nextRoom()
diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index 942a4b05c..0f44ec6c8 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -899,6 +899,52 @@ FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on)
         }
 }
 
+void
+FilteredRoomlistModel::nextRoomWithActivity()
+{
+        int roomWithMention       = -1;
+        int roomWithNotification  = -1;
+        int roomWithUnreadMessage = -1;
+        auto r                    = currentRoom();
+        int currentRoomIdx        = r ? roomidToIndex(r->roomId()) : -1;
+        // first look for mentions
+        for (int i = 0; i < (int)roomlistmodel->roomids.size(); i++) {
+                if (i == currentRoomIdx)
+                        continue;
+                if (this->data(index(i, 0), RoomlistModel::HasLoudNotification).toBool()) {
+                        roomWithMention = i;
+                        break;
+                }
+                if (roomWithNotification == -1 &&
+                    this->data(index(i, 0), RoomlistModel::NotificationCount).toInt() > 0) {
+                        roomWithNotification = i;
+                        // don't break, we must continue looking for rooms with mentions
+                }
+                if (roomWithNotification == -1 && roomWithUnreadMessage == -1 &&
+                    this->data(index(i, 0), RoomlistModel::HasUnreadMessages).toBool()) {
+                        roomWithUnreadMessage = i;
+                        // don't break, we must continue looking for rooms with mentions
+                }
+        }
+        QString targetRoomId = nullptr;
+        if (roomWithMention != -1) {
+                targetRoomId =
+                  this->data(index(roomWithMention, 0), RoomlistModel::RoomId).toString();
+                nhlog::ui()->debug("choosing {} for mentions", targetRoomId.toStdString());
+        } else if (roomWithNotification != -1) {
+                targetRoomId =
+                  this->data(index(roomWithNotification, 0), RoomlistModel::RoomId).toString();
+                nhlog::ui()->debug("choosing {} for notifications", targetRoomId.toStdString());
+        } else if (roomWithUnreadMessage != -1) {
+                targetRoomId =
+                  this->data(index(roomWithUnreadMessage, 0), RoomlistModel::RoomId).toString();
+                nhlog::ui()->debug("choosing {} for unread messages", targetRoomId.toStdString());
+        }
+        if (targetRoomId != nullptr) {
+                setCurrentRoom(targetRoomId);
+        }
+}
+
 void
 FilteredRoomlistModel::nextRoom()
 {
diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h
index 6ac6da186..dbdd06c2b 100644
--- a/src/timeline/RoomlistModel.h
+++ b/src/timeline/RoomlistModel.h
@@ -170,6 +170,7 @@ public slots:
         void setCurrentRoom(QString roomid) { roomlistmodel->setCurrentRoom(std::move(roomid)); }
         void resetCurrentRoom() { roomlistmodel->resetCurrentRoom(); }
 
+        void nextRoomWithActivity();
         void nextRoom();
         void previousRoom();
 
-- 
GitLab