use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
use crate::app::{Modal, Pane, PeopleFocus, SettingsTab, SidebarFocus, SidebarItem, TuiApp};
#[derive(Debug)]
pub enum Action {
Nothing,
Quit,
OpenQuitConfirm,
CloseModal,
OpenStartRoom,
OpenHelp,
LobbyNavigateUp,
LobbyNavigateDown,
LobbyJoinSelected,
LobbyRefresh,
LobbyFocusToggle,
FocusSidebar,
FocusPane,
LobbyReconnectPeer,
LobbyForgetPeer,
OpenDialPeer,
SidebarSectionPrev,
SidebarToggleExpand,
JumpToPeoplePane,
JumpToSettingsPane,
OpenComposeDm,
ComposeDmTypeChar(char),
ComposeDmBackspace,
ComposeDmConfirm,
ComposeDmCancel,
ToggleMemberMargin,
PeopleFocusNext,
PeoplePersonReconnect,
PeoplePersonBlock,
PeoplePersonUnblock,
PeoplePersonForget,
PeoplePersonStartDm,
PendingRequestUp,
PendingRequestDown,
PendingRequestAccept,
PendingRequestReject,
OpenInvitePicker,
InvitePickerCursorUp,
InvitePickerCursorDown,
InvitePickerToggleSelected,
InvitePickerFilterTypeChar(char),
InvitePickerFilterBackspace,
InvitePickerSend,
InvitePickerCancel,
StartRoomNextField,
StartRoomToggleEncrypted,
StartRoomTypeChar(char),
StartRoomBackspace,
StartRoomConfirm,
JoinRoomTypeChar(char),
JoinRoomBackspace,
JoinRoomConfirm,
DialPeerTypeChar(char),
DialPeerBackspace,
DialPeerConfirm,
TabNext,
TabPrev,
TabSelect(usize),
BackToLobby,
LeaveRoom,
FocusInput,
BlurInput,
ScrollUp,
ScrollDown,
PageUp,
PageDown,
JumpTop,
JumpBottom,
ChatTypeChar(char),
ChatBackspace,
ChatSend,
ChatInsertNewline,
ToggleCardFocus,
CardNext,
CardPrev,
ActivateFocusedCard,
OpenFocusedCard,
CancelFocusedCard,
SaveAgainFocusedCard,
OpenAttachmentPicker,
AttachPickerUp,
AttachPickerDown,
AttachPickerAscend,
AttachPickerDescendOrPick,
OpenRotateRoom,
RotateRoomTypeChar(char),
RotateRoomBackspace,
RotateRoomConfirm,
AcceptRotationTypeChar(char),
AcceptRotationBackspace,
AcceptRotationConfirm,
OpenVerify,
VerifyNext,
VerifyPrev,
VerifyToggle,
ToggleMute,
OpenQrIdentity,
OpenSearch,
SearchTypeChar(char),
SearchBackspace,
SearchSubmit,
SearchNext,
SearchPrev,
InboundDialAccept,
InboundDialReject,
InboundDialTrust,
OpenKickPicker,
OpenGrantPicker,
MemberActionNext,
MemberActionPrev,
MemberActionConfirm,
ShowRoomBans,
ClearBlockedPeers,
VerifyStartSas,
SasMatch,
SasCancel,
SettingsToggleGlobalVerifiedOnly,
ToggleRoomVerifiedOnly,
SettingsTabNext,
SettingsTabPrev,
SettingsTabSelect(SettingsTab),
SettingsToggleMdns,
SettingsToggleNotifications,
ProfileFieldUp,
ProfileFieldDown,
ProfileFieldYank,
OpenEditUsername,
EditUsernameTypeChar(char),
EditUsernameBackspace,
EditUsernameConfirm,
OpenGoDarkModal,
GoDarkTypeChar(char),
GoDarkBackspace,
GoDarkConfirm,
OpenAddFriend,
AddFriendTypeChar(char),
AddFriendBackspace,
AddFriendConfirm,
OpenGenerateJoinCode,
OpenJoinWithCode,
JoinWithCodeTypeChar(char),
JoinWithCodeBackspace,
JoinWithCodeConfirm,
GenerateInvite,
OpenPasteInvite,
PasteInviteTypeChar(char),
PasteInviteBackspace,
PasteInviteConfirm,
ConfirmInviteAccept,
OnboardingNext,
OnboardingPrev,
OnboardingDismiss,
OpenStatusHistory,
StatusHistoryScrollUp,
StatusHistoryScrollDown,
StatusHistoryPageUp,
StatusHistoryPageDown,
ClearStatusHistory,
OpenCommandPalette,
CommandPaletteTypeChar(char),
CommandPaletteBackspace,
CommandPaletteNext,
CommandPalettePrev,
CommandPaletteConfirm,
OpenWhatsNew,
MarkAllRead,
HelpScrollUp,
HelpScrollDown,
HelpPageUp,
HelpPageDown,
UpdateCheckOptInYes,
UpdateCheckOptInNo,
ToggleUpdateCheck,
DismissUpdateBanner,
}
fn is_godark_chord(key: KeyEvent) -> bool {
if matches!(key.code, KeyCode::Char('⁄')) {
return true;
}
if key.modifiers.contains(KeyModifiers::ALT) {
if matches!(key.code, KeyCode::Char('!')) {
return true;
}
if key.modifiers.contains(KeyModifiers::SHIFT)
&& matches!(key.code, KeyCode::Char('1'))
{
return true;
}
}
false
}
pub fn map_key(key: KeyEvent, app: &TuiApp) -> Action {
if key.modifiers.contains(KeyModifiers::CONTROL) && key.code == KeyCode::Char('c') {
return Action::OpenQuitConfirm;
}
if matches!(app.modal, Modal::None) {
if key.modifiers.contains(KeyModifiers::SHIFT) {
match key.code {
KeyCode::Left => return Action::FocusSidebar,
KeyCode::Right => return Action::FocusPane,
_ => {}
}
}
if is_godark_chord(key) {
return Action::OpenGoDarkModal;
}
if key.modifiers.contains(KeyModifiers::CONTROL) {
if matches!(key.code, KeyCode::Char('h') | KeyCode::Char('H')) {
let input_active = app
.active_room()
.map(|r| r.input_active)
.unwrap_or(false);
if !input_active {
return Action::OpenStatusHistory;
}
}
if matches!(key.code, KeyCode::Char('p') | KeyCode::Char('P')) {
let input_active = app
.active_room()
.map(|r| r.input_active)
.unwrap_or(false);
let in_room = matches!(app.pane, Pane::Dm(_) | Pane::Group(_));
if !(in_room && input_active) {
return Action::OpenCommandPalette;
}
}
}
}
match &app.modal {
Modal::QuitConfirm => match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => Action::Quit,
_ => Action::CloseModal,
},
Modal::Error(_) => match key.code {
_ => Action::CloseModal,
},
Modal::Help => match key.code {
KeyCode::Char('j') | KeyCode::Down => Action::HelpScrollDown,
KeyCode::Char('k') | KeyCode::Up => Action::HelpScrollUp,
KeyCode::PageDown => Action::HelpPageDown,
KeyCode::PageUp => Action::HelpPageUp,
_ => Action::CloseModal,
},
Modal::StartRoom(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Tab => Action::StartRoomNextField,
KeyCode::Enter => {
if let Modal::StartRoom(s) = &app.modal {
if matches!(s.focus, crate::app::StartField::Encrypted) {
return Action::StartRoomToggleEncrypted;
}
}
Action::StartRoomConfirm
}
KeyCode::Char(' ') => {
if let Modal::StartRoom(s) = &app.modal {
if matches!(s.focus, crate::app::StartField::Encrypted) {
return Action::StartRoomToggleEncrypted;
}
}
Action::StartRoomTypeChar(' ')
}
KeyCode::Backspace => Action::StartRoomBackspace,
KeyCode::Char(c) => Action::StartRoomTypeChar(c),
_ => Action::Nothing,
},
Modal::JoinRoom(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::JoinRoomConfirm,
KeyCode::Backspace => Action::JoinRoomBackspace,
KeyCode::Char(c) => Action::JoinRoomTypeChar(c),
_ => Action::Nothing,
},
Modal::DialPeer(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::DialPeerConfirm,
KeyCode::Backspace => Action::DialPeerBackspace,
KeyCode::Char(c) => Action::DialPeerTypeChar(c),
_ => Action::Nothing,
},
Modal::AttachPicker(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Char('j') | KeyCode::Down => Action::AttachPickerDown,
KeyCode::Char('k') | KeyCode::Up => Action::AttachPickerUp,
KeyCode::Char('h') | KeyCode::Backspace | KeyCode::Left => Action::AttachPickerAscend,
KeyCode::Enter | KeyCode::Char('l') | KeyCode::Right => Action::AttachPickerDescendOrPick,
_ => Action::Nothing,
},
Modal::RotateRoom(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::RotateRoomConfirm,
KeyCode::Backspace => Action::RotateRoomBackspace,
KeyCode::Char(c) => Action::RotateRoomTypeChar(c),
_ => Action::Nothing,
},
Modal::AcceptRotation(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::AcceptRotationConfirm,
KeyCode::Backspace => Action::AcceptRotationBackspace,
KeyCode::Char(c) => Action::AcceptRotationTypeChar(c),
_ => Action::Nothing,
},
Modal::Verify(_) => match key.code {
KeyCode::Esc | KeyCode::Char('q') => Action::CloseModal,
KeyCode::Char('j') | KeyCode::Down => Action::VerifyNext,
KeyCode::Char('k') | KeyCode::Up => Action::VerifyPrev,
KeyCode::Enter | KeyCode::Char(' ') => Action::VerifyToggle,
KeyCode::Char('s') => Action::VerifyStartSas,
_ => Action::Nothing,
},
Modal::Sas(_) => match key.code {
KeyCode::Esc | KeyCode::Char('c') | KeyCode::Char('q') => Action::SasCancel,
KeyCode::Char('m') | KeyCode::Enter => Action::SasMatch,
_ => Action::Nothing,
},
Modal::EditUsername(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::EditUsernameConfirm,
KeyCode::Backspace => Action::EditUsernameBackspace,
KeyCode::Char(c) => Action::EditUsernameTypeChar(c),
_ => Action::Nothing,
},
Modal::GoDark(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::GoDarkConfirm,
KeyCode::Backspace => Action::GoDarkBackspace,
KeyCode::Char(c) => Action::GoDarkTypeChar(c),
_ => Action::Nothing,
},
Modal::AddFriend(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::AddFriendConfirm,
KeyCode::Backspace => Action::AddFriendBackspace,
KeyCode::Char(c) => Action::AddFriendTypeChar(c),
_ => Action::Nothing,
},
Modal::ShowJoinCode(_) => match key.code {
_ => Action::CloseModal,
},
Modal::JoinWithCode(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::JoinWithCodeConfirm,
KeyCode::Backspace => Action::JoinWithCodeBackspace,
KeyCode::Char(c) => Action::JoinWithCodeTypeChar(c),
_ => Action::Nothing,
},
Modal::ShowInvite(_) => match key.code {
_ => Action::CloseModal,
},
Modal::PasteInvite(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::PasteInviteConfirm,
KeyCode::Backspace => Action::PasteInviteBackspace,
KeyCode::Char(c) => Action::PasteInviteTypeChar(c),
_ => Action::Nothing,
},
Modal::ConfirmInvite(_) => match key.code {
KeyCode::Esc | KeyCode::Char('c') | KeyCode::Char('C') => Action::CloseModal,
KeyCode::Enter | KeyCode::Char('d') | KeyCode::Char('D') => {
Action::ConfirmInviteAccept
}
_ => Action::Nothing,
},
Modal::Onboarding { .. } => match key.code {
KeyCode::Esc | KeyCode::Char('q') => Action::OnboardingDismiss,
KeyCode::Char('h') | KeyCode::Left | KeyCode::Backspace => Action::OnboardingPrev,
KeyCode::Enter
| KeyCode::Char(' ')
| KeyCode::Char('l')
| KeyCode::Right
| KeyCode::Tab => Action::OnboardingNext,
_ => Action::Nothing,
},
Modal::StatusHistory { .. } => match key.code {
KeyCode::Esc | KeyCode::Char('q') => Action::CloseModal,
KeyCode::Char('j') | KeyCode::Down => Action::StatusHistoryScrollDown,
KeyCode::Char('k') | KeyCode::Up => Action::StatusHistoryScrollUp,
KeyCode::PageDown => Action::StatusHistoryPageDown,
KeyCode::PageUp => Action::StatusHistoryPageUp,
KeyCode::Char('c') | KeyCode::Char('C') => Action::ClearStatusHistory,
KeyCode::Char('G') | KeyCode::End => Action::StatusHistoryPageDown,
KeyCode::Char('g') | KeyCode::Home => Action::StatusHistoryPageUp,
_ => Action::Nothing,
},
Modal::CommandPalette(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::CommandPaletteConfirm,
KeyCode::Down => Action::CommandPaletteNext,
KeyCode::Up => Action::CommandPalettePrev,
KeyCode::Backspace => Action::CommandPaletteBackspace,
KeyCode::Char(c) => Action::CommandPaletteTypeChar(c),
_ => Action::Nothing,
},
Modal::UpdateCheckOptIn => match key.code {
KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => {
Action::UpdateCheckOptInYes
}
KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => Action::UpdateCheckOptInNo,
_ => Action::Nothing,
},
Modal::Search(_) => match key.code {
KeyCode::Esc => Action::CloseModal,
KeyCode::Enter => Action::SearchSubmit,
KeyCode::Down => Action::SearchNext,
KeyCode::Up => Action::SearchPrev,
KeyCode::Backspace => Action::SearchBackspace,
KeyCode::Char(c) => Action::SearchTypeChar(c),
_ => Action::Nothing,
},
Modal::Info(_) => match key.code {
_ => Action::CloseModal,
},
Modal::QrIdentity => match key.code {
_ => Action::CloseModal,
},
Modal::InboundDial(_) => match key.code {
KeyCode::Esc | KeyCode::Char('r') | KeyCode::Char('R') => Action::InboundDialReject,
KeyCode::Char('a') | KeyCode::Char('A') | KeyCode::Enter => Action::InboundDialAccept,
KeyCode::Char('t') | KeyCode::Char('T') => Action::InboundDialTrust,
_ => Action::Nothing,
},
Modal::MemberAction(_) => match key.code {
KeyCode::Esc | KeyCode::Char('q') => Action::CloseModal,
KeyCode::Char('j') | KeyCode::Down => Action::MemberActionNext,
KeyCode::Char('k') | KeyCode::Up => Action::MemberActionPrev,
KeyCode::Enter => Action::MemberActionConfirm,
_ => Action::Nothing,
},
Modal::ComposeDm(_) => match key.code {
KeyCode::Esc => Action::ComposeDmCancel,
KeyCode::Enter => Action::ComposeDmConfirm,
KeyCode::Backspace => Action::ComposeDmBackspace,
KeyCode::Char(c) => Action::ComposeDmTypeChar(c),
_ => Action::Nothing,
},
Modal::InvitePicker(_) => match key.code {
KeyCode::Esc => Action::InvitePickerCancel,
KeyCode::Enter => Action::InvitePickerSend,
KeyCode::Up | KeyCode::Char('k') if key.modifiers.contains(KeyModifiers::CONTROL) => {
Action::InvitePickerCursorUp
}
KeyCode::Down | KeyCode::Char('j') if key.modifiers.contains(KeyModifiers::CONTROL) => {
Action::InvitePickerCursorDown
}
KeyCode::Up => Action::InvitePickerCursorUp,
KeyCode::Down => Action::InvitePickerCursorDown,
KeyCode::Char(' ') => Action::InvitePickerToggleSelected,
KeyCode::Backspace => Action::InvitePickerFilterBackspace,
KeyCode::Char(c) => Action::InvitePickerFilterTypeChar(c),
_ => Action::Nothing,
},
Modal::None => map_normal(key, app),
}
}
fn map_normal(key: KeyEvent, app: &TuiApp) -> Action {
let sidebar_has_focus = matches!(app.sidebar.focus, SidebarFocus::Sidebar);
let chat_pane = matches!(app.pane, Pane::Dm(_) | Pane::Group(_));
if !chat_pane || sidebar_has_focus {
map_sidebar(key, app)
} else {
map_in_room(key, app)
}
}
fn map_sidebar(key: KeyEvent, app: &TuiApp) -> Action {
if matches!(app.pane, Pane::Settings) {
match key.code {
KeyCode::Char('V') => return Action::SettingsToggleGlobalVerifiedOnly,
KeyCode::Char('U') => return Action::ToggleUpdateCheck,
KeyCode::Char('E') => return Action::OpenEditUsername,
KeyCode::Char('W') => return Action::OpenWhatsNew,
KeyCode::Char('M') => return Action::SettingsToggleMdns,
KeyCode::Char('N') => return Action::SettingsToggleNotifications,
KeyCode::Char('c') if matches!(app.settings_tab, SettingsTab::Privacy) => {
return Action::ClearBlockedPeers;
}
KeyCode::Char('1') => return Action::SettingsTabSelect(SettingsTab::Account),
KeyCode::Char('2') => return Action::SettingsTabSelect(SettingsTab::Network),
KeyCode::Char('3') => return Action::SettingsTabSelect(SettingsTab::Appearance),
KeyCode::Char('4') => return Action::SettingsTabSelect(SettingsTab::Privacy),
KeyCode::Tab if matches!(app.sidebar.focus, SidebarFocus::Pane) => {
return Action::SettingsTabNext;
}
KeyCode::BackTab if matches!(app.sidebar.focus, SidebarFocus::Pane) => {
return Action::SettingsTabPrev;
}
_ => {}
}
}
if matches!(app.pane, Pane::Profile) {
match key.code {
KeyCode::Char('j') | KeyCode::Down => return Action::ProfileFieldDown,
KeyCode::Char('k') | KeyCode::Up => return Action::ProfileFieldUp,
KeyCode::Char('y') => return Action::ProfileFieldYank,
KeyCode::Char('E') => return Action::OpenEditUsername,
KeyCode::Char('Q') => return Action::OpenQrIdentity,
_ => {}
}
}
if matches!(app.pane, Pane::People) && app.people_focus == PeopleFocus::Known {
match key.code {
KeyCode::Char('m') => return Action::PeoplePersonStartDm,
KeyCode::Char('r') => return Action::PeoplePersonReconnect,
KeyCode::Char('b') => return Action::PeoplePersonBlock,
KeyCode::Char('x') => return Action::PeoplePersonForget,
_ => {}
}
}
if matches!(app.pane, Pane::People) && app.people_focus == PeopleFocus::Blocked {
if let KeyCode::Char('u') = key.code {
return Action::PeoplePersonUnblock;
}
}
if matches!(app.pane, Pane::People) && app.people_focus == PeopleFocus::Pending {
match key.code {
KeyCode::Char('a') | KeyCode::Enter => return Action::PendingRequestAccept,
KeyCode::Char('r') => return Action::PendingRequestReject,
KeyCode::Char('j') | KeyCode::Down => return Action::PendingRequestDown,
KeyCode::Char('k') | KeyCode::Up => return Action::PendingRequestUp,
_ => {}
}
}
if matches!(app.pane, Pane::People) && key.code == KeyCode::Tab {
return Action::PeopleFocusNext;
}
match key.code {
KeyCode::Char('q') => return Action::OpenQuitConfirm,
KeyCode::Char('s') | KeyCode::Char('g') => return Action::OpenStartRoom,
KeyCode::Char('m') => return Action::OpenComposeDm,
KeyCode::Char('?') => return Action::OpenHelp,
KeyCode::Char(':') => return Action::OpenCommandPalette,
KeyCode::Char('a') => return Action::OpenAddFriend,
KeyCode::Char('d') => return Action::OpenDialPeer,
KeyCode::Char('i') => return Action::OpenQrIdentity,
KeyCode::Char(',') => return Action::JumpToSettingsPane,
KeyCode::Char('p') => return Action::JumpToPeoplePane,
KeyCode::Char('c') => return Action::OpenJoinWithCode,
KeyCode::Char('I') => return Action::GenerateInvite,
KeyCode::Char('v') => return Action::OpenPasteInvite,
KeyCode::Char('R') => return Action::MarkAllRead,
_ => {}
}
match key.code {
KeyCode::Tab => Action::LobbyFocusToggle,
KeyCode::BackTab => Action::SidebarSectionPrev,
KeyCode::Char('j') | KeyCode::Down => Action::LobbyNavigateDown,
KeyCode::Char('k') | KeyCode::Up => Action::LobbyNavigateUp,
KeyCode::Char(' ') | KeyCode::Right | KeyCode::Left => Action::SidebarToggleExpand,
KeyCode::Char('r') => {
match &app.sidebar.selection {
SidebarItem::Person(_) => Action::LobbyReconnectPeer,
_ => Action::LobbyRefresh,
}
}
KeyCode::Char('x') => match &app.sidebar.selection {
SidebarItem::Person(_) => Action::LobbyForgetPeer,
_ => Action::Nothing,
},
KeyCode::Enter => Action::LobbyJoinSelected,
KeyCode::Esc => Action::Nothing,
_ => Action::Nothing,
}
}
fn map_in_room(key: KeyEvent, app: &TuiApp) -> Action {
let input_active = app.active_room().map(|r| r.input_active).unwrap_or(false);
let card_focus = app.active_room().map(|r| r.card_focus).unwrap_or(false);
if key.modifiers.contains(KeyModifiers::CONTROL) {
return match key.code {
KeyCode::Char('j') if input_active => Action::ChatInsertNewline,
KeyCode::Char('l') => Action::LeaveRoom,
KeyCode::Char('b') => Action::BackToLobby,
KeyCode::Char('n') => Action::TabNext,
KeyCode::Char('p') => Action::TabPrev,
KeyCode::Char('a') if !input_active => Action::OpenAttachmentPicker,
KeyCode::Char('r') if !input_active => Action::OpenRotateRoom,
KeyCode::Char('v') if !input_active => Action::OpenVerify,
KeyCode::Char('f') if !input_active => Action::OpenSearch,
KeyCode::Char('m') if !input_active => Action::ToggleMute,
KeyCode::Char('k') if !input_active => Action::OpenKickPicker,
KeyCode::Char('g') if !input_active => Action::OpenGrantPicker,
KeyCode::Char('o') if !input_active => Action::ToggleRoomVerifiedOnly,
KeyCode::Char('j') if !input_active => Action::OpenGenerateJoinCode,
KeyCode::Char('I') if !input_active => Action::GenerateInvite,
KeyCode::Char('i') if !input_active => Action::OpenInvitePicker,
_ => Action::Nothing,
};
}
if key.code == KeyCode::Tab {
return Action::TabNext;
}
if !input_active {
if let KeyCode::Char(c @ '1'..='9') = key.code {
let n = (c as u8 - b'1') as usize;
return Action::TabSelect(n);
}
}
if input_active {
if matches!(key.code, KeyCode::Enter)
&& (key.modifiers.contains(KeyModifiers::ALT)
|| key.modifiers.contains(KeyModifiers::SHIFT))
{
return Action::ChatInsertNewline;
}
match key.code {
KeyCode::Enter => Action::ChatSend,
KeyCode::Char('\n') => Action::ChatInsertNewline,
KeyCode::Esc => Action::BlurInput,
KeyCode::Backspace => Action::ChatBackspace,
KeyCode::PageUp => Action::PageUp,
KeyCode::PageDown => Action::PageDown,
KeyCode::Char(c) => Action::ChatTypeChar(c),
_ => Action::Nothing,
}
} else if card_focus {
match key.code {
KeyCode::Esc | KeyCode::Char('f') => Action::ToggleCardFocus,
KeyCode::Char('j') | KeyCode::Down => Action::CardNext,
KeyCode::Char('k') | KeyCode::Up => Action::CardPrev,
KeyCode::Enter => Action::ActivateFocusedCard,
KeyCode::Char('o') => Action::OpenFocusedCard,
KeyCode::Char('c') => Action::CancelFocusedCard,
KeyCode::Char('s') => Action::SaveAgainFocusedCard,
KeyCode::Char('r') => Action::ActivateFocusedCard,
_ => Action::Nothing,
}
} else {
match key.code {
KeyCode::Char('q') => Action::OpenQuitConfirm,
KeyCode::Char('/') => Action::FocusInput,
KeyCode::Char('?') => Action::OpenHelp,
KeyCode::Char(':') => Action::OpenCommandPalette,
KeyCode::Char('f') => Action::ToggleCardFocus,
KeyCode::Char('j') | KeyCode::Down => Action::ScrollDown,
KeyCode::Char('k') | KeyCode::Up => Action::ScrollUp,
KeyCode::PageDown => Action::PageDown,
KeyCode::PageUp => Action::PageUp,
KeyCode::Home | KeyCode::Char('g') => Action::JumpTop,
KeyCode::End | KeyCode::Char('G') => Action::JumpBottom,
KeyCode::Char('B') => Action::ShowRoomBans,
KeyCode::Esc => Action::BackToLobby,
_ => Action::Nothing,
}
}
}