diff --git a/README.md b/README.md index b4041871..955c9416 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Features - View and save media (documents, photos, videos) - Show message read and edited indicators - Show user status (online, away, typing) -- Jump to next unread chat +- Jump to next or previous unread chat - Archive, pin and delete chats - Search messages within a chat - List dialogs for chats, contacts, emojis, files @@ -60,7 +60,6 @@ Interactive Commands: PageUp history previous page Tab next chat Sh-Tab previous chat - Ctrl-f jump to unread chat Ctrl-g toggle show help bar Ctrl-l toggle show contact list Ctrl-n goto chat @@ -77,8 +76,10 @@ Interactive Commands: Alt-e external editor compose Alt-i auto-compose reply Alt-n search contacts + Alt-o jump to previous unread chat Alt-p pin/unpin current chat Alt-t external telephone call + Alt-y jump to next unread chat Alt-/ find in chat Alt-? find next in chat Alt-$ external spell check @@ -891,6 +892,7 @@ This configuration file holds user interface key bindings. Default content: linebreak=KEY_RETURN next_chat=KEY_TAB next_page=KEY_NPAGE + next_unread_chat=\33\171 ok=KEY_RETURN open=KEY_CTRLV open_link=KEY_CTRLW @@ -900,6 +902,7 @@ This configuration file holds user interface key bindings. Default content: pin=\33\160 prev_chat=KEY_BTAB prev_page=KEY_PPAGE + prev_unread_chat=\33\157 quit=KEY_CTRLQ react=\33\163 right=KEY_RIGHT @@ -918,7 +921,6 @@ This configuration file holds user interface key bindings. Default content: toggle_list=KEY_CTRLL toggle_top=KEY_NONE transfer=KEY_CTRLT - unread_chat=KEY_CTRLF up=KEY_UP The key bindings may be specified in the following formats: diff --git a/src/uikeyconfig.cpp b/src/uikeyconfig.cpp index e4d93564..cf3038e0 100644 --- a/src/uikeyconfig.cpp +++ b/src/uikeyconfig.cpp @@ -235,7 +235,8 @@ void UiKeyConfig::Init(bool p_MapKeys) { "toggle_top", "KEY_NONE" }, { "next_chat", "KEY_TAB" }, { "prev_chat", "KEY_BTAB" }, - { "unread_chat", "KEY_CTRLF" }, + { "next_unread_chat", "\\33\\171" }, // alt/opt-y + { "prev_unread_chat", "\\33\\157" }, // alt/opt-o { "send_msg", "KEY_CTRLX" }, { "delete_msg", "KEY_CTRLD" }, { "delete_chat", "\\33\\144" }, // alt/opt-d diff --git a/src/uimodel.cpp b/src/uimodel.cpp index fd7dc409..ebbbab2e 100644 --- a/src/uimodel.cpp +++ b/src/uimodel.cpp @@ -582,7 +582,7 @@ void UiModel::Impl::OnKeyPrevChat() SetSelectMessageActive(false); } -void UiModel::Impl::OnKeyUnreadChat() +void UiModel::Impl::OnKeyNextUnreadChat() { AnyUserKeyInput(); @@ -635,6 +635,60 @@ void UiModel::Impl::OnKeyUnreadChat() } } +void UiModel::Impl::OnKeyPrevUnreadChat() +{ + AnyUserKeyInput(); + + if (GetEditMessageActive()) return; + + if (m_ChatVec.empty()) return; + + std::vector unreadVec; + bool unreadIsSelected = false; + + // Populating from oldest to newest + for (ssize_t i = (ssize_t)m_ChatVec.size() - 1; i >= 0; --i) + { + const std::pair& chat = m_ChatVec.at(i); + const bool isUnread = GetChatIsUnread(chat.first, chat.second); + if (isUnread) + { + unreadVec.push_back(i); + if (m_CurrentChatIndex == (int)i) + { + unreadIsSelected = true; + } + } + } + + if (!unreadVec.empty()) + { + if (!unreadIsSelected) + { + m_CurrentChatIndex = unreadVec.at(0); + } + else if (unreadVec.size() > 1) + { + auto it = std::find(unreadVec.begin(), unreadVec.end(), m_CurrentChatIndex); + if (it != unreadVec.end()) + { + size_t idx = std::distance(unreadVec.begin(), it); + ++idx; + if (idx >= unreadVec.size()) + { + idx = 0; + } + + m_CurrentChatIndex = unreadVec.at(idx); + } + } + + m_CurrentChat = m_ChatVec.at(m_CurrentChatIndex); + OnCurrentChatChanged(); + SetSelectMessageActive(false); + } +} + void UiModel::Impl::OnKeyPrevPage() { AnyUserKeyInput(); @@ -4438,7 +4492,8 @@ void UiModel::KeyHandler(wint_t p_Key) static wint_t keySendMsg = UiKeyConfig::GetKey("send_msg"); static wint_t keyNextChat = UiKeyConfig::GetKey("next_chat"); static wint_t keyPrevChat = UiKeyConfig::GetKey("prev_chat"); - static wint_t keyUnreadChat = UiKeyConfig::GetKey("unread_chat"); + static wint_t keyNextUnreadChat = UiKeyConfig::GetKey("next_unread_chat"); + static wint_t keyPrevUnreadChat = UiKeyConfig::GetKey("prev_unread_chat"); static wint_t keyQuit = UiKeyConfig::GetKey("quit"); static wint_t keySelectEmoji = UiKeyConfig::GetKey("select_emoji"); @@ -4535,10 +4590,15 @@ void UiModel::KeyHandler(wint_t p_Key) std::unique_lock lock(m_ModelMutex); GetImpl().OnKeyPrevChat(); } - else if (p_Key == keyUnreadChat) + else if (p_Key == keyNextUnreadChat) + { + std::unique_lock lock(m_ModelMutex); + GetImpl().OnKeyNextUnreadChat(); + } + else if (p_Key == keyPrevUnreadChat) { std::unique_lock lock(m_ModelMutex); - GetImpl().OnKeyUnreadChat(); + GetImpl().OnKeyPrevUnreadChat(); } else if (p_Key == keyPrevPage) { diff --git a/src/uimodel.h b/src/uimodel.h index d245d4aa..bd819d7b 100644 --- a/src/uimodel.h +++ b/src/uimodel.h @@ -48,7 +48,8 @@ class UiModel void OnKeyNextChat(); void OnKeyPrevChat(); - void OnKeyUnreadChat(); + void OnKeyNextUnreadChat(); + void OnKeyPrevUnreadChat(); void OnKeyPrevPage(); void OnKeyNextPage(); bool OnKeyHomeFetchCache();