From 4ae8cbadbf4c5d619b32799eab5e87c2de9782cb Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Mon, 29 Apr 2019 10:54:40 +0300 Subject: [PATCH] ui: reassign listing shortcuts after `312011c ui: move account menu functions to Listing`, shortcuts like prev_folder etc should be generic over all listing types. --- ui/src/components/mail/listing.rs | 135 +++++++++++++++------- ui/src/components/mail/listing/compact.rs | 68 +---------- ui/src/components/mail/listing/plain.rs | 58 ---------- ui/src/components/mail/listing/thread.rs | 58 ---------- ui/src/conf/shortcuts.rs | 41 ++++--- ui/src/terminal/keys.rs | 6 + 6 files changed, 130 insertions(+), 236 deletions(-) diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index ad15c619..5fbfb85e 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -20,7 +20,6 @@ */ use super::*; -use std::ops::{Deref, DerefMut}; mod compact; pub use self::compact::*; @@ -74,7 +73,7 @@ pub struct Listing { accounts: Vec, dirty: bool, visible: bool, - cursor: (usize, usize), + cursor_pos: (usize, usize), id: ComponentId, show_divider: bool, @@ -152,26 +151,34 @@ impl Component for Listing { return true; } + let shortcuts = self.get_shortcuts(context); match *event { - UIEvent::Input(Key::Char(k @ 'J')) | UIEvent::Input(Key::Char(k @ 'K')) => { - let folder_length = context.accounts[self.cursor.0].len(); + UIEvent::Input(ref k) + if k == shortcuts["next_folder"] || k == shortcuts["prev_folder"] => + { + let folder_length = context.accounts[self.cursor_pos.0].len(); match k { - 'J' if folder_length > 0 => { - if self.cursor.1 < folder_length - 1 { - self.cursor.1 += 1; - self.component - .set_coordinates((self.cursor.0, self.cursor.1, None)); + k if k == shortcuts["next_folder"] && folder_length > 0 => { + if self.cursor_pos.1 < folder_length - 1 { + self.cursor_pos.1 += 1; + self.component.set_coordinates(( + self.cursor_pos.0, + self.cursor_pos.1, + None, + )); self.set_dirty(); } else { return true; } } - 'K' => { - if self.cursor.1 > 0 { - self.cursor.1 -= 1; - let coors = self.component.coordinates(); - self.component - .set_coordinates((self.cursor.0, self.cursor.1, None)); + k if k == shortcuts["prev_folder"] => { + if self.cursor_pos.1 > 0 { + self.cursor_pos.1 -= 1; + self.component.set_coordinates(( + self.cursor_pos.0, + self.cursor_pos.1, + None, + )); self.set_dirty(); } else { return true; @@ -179,28 +186,31 @@ impl Component for Listing { } _ => return false, } - let folder_hash = context.accounts[self.cursor.0].folders_order[self.cursor.1]; + let folder_hash = + context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1]; // Inform State that we changed the current folder view. context .replies - .push_back(UIEvent::RefreshMailbox((self.cursor.0, folder_hash))); + .push_back(UIEvent::RefreshMailbox((self.cursor_pos.0, folder_hash))); return true; } - UIEvent::Input(Key::Char(k @ 'h')) | UIEvent::Input(Key::Char(k @ 'l')) => { + UIEvent::Input(ref k) + if k == shortcuts["next_account"] || k == shortcuts["prev_account"] => + { match k { - 'h' => { - if self.cursor.0 < self.accounts.len() - 1 { - self.cursor = (self.cursor.0 + 1, 0); - self.component.set_coordinates((self.cursor.0, 0, None)); + k if k == shortcuts["next_account"] => { + if self.cursor_pos.0 < self.accounts.len() - 1 { + self.cursor_pos = (self.cursor_pos.0 + 1, 0); + self.component.set_coordinates((self.cursor_pos.0, 0, None)); self.set_dirty(); } else { return true; } } - 'l' => { - if self.cursor.0 > 0 { - self.cursor = (self.cursor.0 - 1, 0); - self.component.set_coordinates((self.cursor.0, 0, None)); + k if k == shortcuts["prev_account"] => { + if self.cursor_pos.0 > 0 { + self.cursor_pos = (self.cursor_pos.0 - 1, 0); + self.component.set_coordinates((self.cursor_pos.0, 0, None)); self.set_dirty(); } else { return true; @@ -208,12 +218,12 @@ impl Component for Listing { } _ => return false, } - let folder_hash = context.accounts[self.cursor.0].folders_order[self.cursor.1]; + let folder_hash = + context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1]; // Inform State that we changed the current folder view. - context.replies.push_back(UIEvent::RefreshMailbox(( - self.cursor.0, - std::dbg!(folder_hash), - ))); + context + .replies + .push_back(UIEvent::RefreshMailbox((self.cursor_pos.0, folder_hash))); return true; } UIEvent::Action(ref action) => match action { @@ -277,7 +287,7 @@ impl Component for Listing { _ => {} }, UIEvent::RefreshMailbox((idxa, folder_hash)) => { - self.cursor = ( + self.cursor_pos = ( idxa, context.accounts[idxa] .folders_order @@ -293,10 +303,16 @@ impl Component for Listing { UIEvent::Resize => { self.dirty = true; } - UIEvent::Input(Key::Char('`')) => { + UIEvent::Input(ref k) if k == shortcuts["toggle-menu-visibility"] => { self.menu_visibility = !self.menu_visibility; self.set_dirty(); } + UIEvent::Input(ref k) if k == shortcuts["new_mail"] => { + context + .replies + .push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0)))); + return true; + } UIEvent::StartupCheck(_) => { self.dirty = true; } @@ -330,9 +346,48 @@ impl Component for Listing { Plain(ref l) => l.get_shortcuts(context), Threaded(ref l) => l.get_shortcuts(context), }; - map.insert("Toggle account menu visibility", Key::Char('`')); - map.insert("prev_account", Key::Char('h')); - map.insert("next_account", Key::Char('l')); + let config_map = context.settings.shortcuts.listing.key_values(); + map.insert( + "new_mail", + if let Some(key) = config_map.get("new_mail") { + (*key).clone() + } else { + Key::Char('m') + }, + ); + map.insert( + "prev_folder", + if let Some(key) = config_map.get("prev_folder") { + (*key).clone() + } else { + Key::Char('J') + }, + ); + map.insert( + "next_folder", + if let Some(key) = config_map.get("next_folder") { + (*key).clone() + } else { + Key::Char('K') + }, + ); + map.insert( + "prev_account", + if let Some(key) = config_map.get("prev_account") { + (*key).clone() + } else { + Key::Char('h') + }, + ); + map.insert( + "next_account", + if let Some(key) = config_map.get("next_account") { + (*key).clone() + } else { + Key::Char('l') + }, + ); + map.insert("toggle-menu-visibility", Key::Char('`')); map } @@ -378,7 +433,7 @@ impl Listing { accounts, visible: true, dirty: true, - cursor: (0, 0), + cursor_pos: (0, 0), id: ComponentId::new_v4(), show_divider: false, menu_visibility: true, @@ -435,7 +490,7 @@ impl Listing { let upper_left = upper_left!(area); let bottom_right = bottom_right!(area); - let highlight = self.cursor.0 == a.index; + let highlight = self.cursor_pos.0 == a.index; let mut inc = 0; let mut depth = String::from(""); @@ -530,7 +585,7 @@ impl Listing { } let s = lines[idx].to_string(); let (color_fg, color_bg) = if highlight { - if self.cursor.1 + 1 == idx { + if self.cursor_pos.1 + 1 == idx { (Color::Byte(233), Color::Byte(15)) } else { (Color::Byte(15), Color::Byte(233)) @@ -570,7 +625,7 @@ impl Listing { } } - if highlight && idx > 1 && self.cursor.1 == idx - 1 { + if highlight && idx > 1 && self.cursor_pos.1 == idx - 1 { change_colors(grid, ((x, y), (get_x(bottom_right), y)), color_fg, color_bg); } else { change_colors(grid, ((x, y), set_y(bottom_right, y)), color_fg, color_bg); diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 8c50c334..af8d162b 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -481,12 +481,6 @@ impl Component for MailboxView { } _ => {} }, - UIEvent::Input(Key::Char('m')) if !self.unfocused => { - context - .replies - .push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0)))); - return true; - } _ => {} } false @@ -546,46 +540,6 @@ impl Component for MailboxView { Key::Char('i') }, ); - map.insert( - "prev_folder", - if let Some(key) = config_map.get("prev_folder") { - (*key).clone() - } else { - Key::Char('J') - }, - ); - map.insert( - "next_folder", - if let Some(key) = config_map.get("next_folder") { - (*key).clone() - } else { - Key::Char('K') - }, - ); - map.insert( - "prev_account", - if let Some(key) = config_map.get("prev_account") { - (*key).clone() - } else { - Key::Char('h') - }, - ); - map.insert( - "next_account", - if let Some(key) = config_map.get("next_account") { - (*key).clone() - } else { - Key::Char('l') - }, - ); - map.insert( - "new_mail", - if let Some(key) = config_map.get("new_mail") { - (*key).clone() - } else { - Key::Char('m') - }, - ); map } @@ -703,27 +657,7 @@ impl Component for CompactListing { if self.views.is_empty() { return Default::default(); } - let mut map = self.views[self.cursor].get_shortcuts(context); - - let config_map = context.settings.shortcuts.compact_listing.key_values(); - map.insert( - "prev_account", - if let Some(key) = config_map.get("prev_account") { - (*key).clone() - } else { - Key::Char('h') - }, - ); - map.insert( - "next_account", - if let Some(key) = config_map.get("next_account") { - (*key).clone() - } else { - Key::Char('l') - }, - ); - - map + self.views[self.cursor].get_shortcuts(context) } fn id(&self) -> ComponentId { diff --git a/ui/src/components/mail/listing/plain.rs b/ui/src/components/mail/listing/plain.rs index b022b91e..93c6764a 100644 --- a/ui/src/components/mail/listing/plain.rs +++ b/ui/src/components/mail/listing/plain.rs @@ -434,70 +434,12 @@ impl Component for PlainListing { self.dirty = true; return true; } - UIEvent::Input(Key::Char('m')) if !self.unfocused => { - context - .replies - .push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0)))); - return true; - } UIEvent::Input(Key::Char('i')) if self.unfocused => { self.unfocused = false; self.dirty = true; self.view = None; return true; } - UIEvent::Input(Key::Char(k @ 'J')) | UIEvent::Input(Key::Char(k @ 'K')) => { - let folder_length = context.accounts[self.cursor_pos.0].len(); - let accounts_length = context.accounts.len(); - match k { - 'J' if folder_length > 0 => { - if self.new_cursor_pos.1 < folder_length - 1 { - self.new_cursor_pos.1 = self.cursor_pos.1 + 1; - self.dirty = true; - self.refresh_mailbox(context); - } else if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 - { - self.new_cursor_pos.0 = self.cursor_pos.0 + 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - } - 'K' => { - if self.cursor_pos.1 > 0 { - self.new_cursor_pos.1 = self.cursor_pos.1 - 1; - self.dirty = true; - self.refresh_mailbox(context); - } else if self.cursor_pos.0 > 0 { - self.new_cursor_pos.0 = self.cursor_pos.0 - 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - } - _ => {} - } - return true; - } - UIEvent::Input(Key::Char(k @ 'h')) | UIEvent::Input(Key::Char(k @ 'l')) => { - let accounts_length = context.accounts.len(); - match k { - 'h' if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 => { - self.new_cursor_pos.0 = self.cursor_pos.0 + 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - 'l' if self.cursor_pos.0 > 0 => { - self.new_cursor_pos.0 = self.cursor_pos.0 - 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - _ => {} - } - return true; - } UIEvent::RefreshMailbox(_) => { self.dirty = true; self.view = None; diff --git a/ui/src/components/mail/listing/thread.rs b/ui/src/components/mail/listing/thread.rs index 182b6f8f..1f2e8efc 100644 --- a/ui/src/components/mail/listing/thread.rs +++ b/ui/src/components/mail/listing/thread.rs @@ -599,70 +599,12 @@ impl Component for ThreadListing { self.dirty = true; return true; } - UIEvent::Input(Key::Char('m')) if !self.unfocused => { - context - .replies - .push_back(UIEvent::Action(Tab(NewDraft(self.cursor_pos.0)))); - return true; - } UIEvent::Input(Key::Char('i')) if self.unfocused => { self.unfocused = false; self.dirty = true; self.view = None; return true; } - UIEvent::Input(Key::Char(k @ 'J')) | UIEvent::Input(Key::Char(k @ 'K')) => { - let folder_length = context.accounts[self.cursor_pos.0].len(); - let accounts_length = context.accounts.len(); - match k { - 'J' if folder_length > 0 => { - if self.new_cursor_pos.1 < folder_length - 1 { - self.new_cursor_pos.1 = self.cursor_pos.1 + 1; - self.dirty = true; - self.refresh_mailbox(context); - } else if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 - { - self.new_cursor_pos.0 = self.cursor_pos.0 + 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - } - 'K' => { - if self.cursor_pos.1 > 0 { - self.new_cursor_pos.1 = self.cursor_pos.1 - 1; - self.dirty = true; - self.refresh_mailbox(context); - } else if self.cursor_pos.0 > 0 { - self.new_cursor_pos.0 = self.cursor_pos.0 - 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - } - _ => {} - } - return true; - } - UIEvent::Input(Key::Char(k @ 'h')) | UIEvent::Input(Key::Char(k @ 'l')) => { - let accounts_length = context.accounts.len(); - match k { - 'h' if accounts_length > 0 && self.new_cursor_pos.0 < accounts_length - 1 => { - self.new_cursor_pos.0 = self.cursor_pos.0 + 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - 'l' if self.cursor_pos.0 > 0 => { - self.new_cursor_pos.0 = self.cursor_pos.0 - 1; - self.new_cursor_pos.1 = 0; - self.dirty = true; - self.refresh_mailbox(context); - } - _ => {} - } - return true; - } UIEvent::RefreshMailbox(_) => { self.dirty = true; self.view = None; diff --git a/ui/src/conf/shortcuts.rs b/ui/src/conf/shortcuts.rs index 84ea8eba..a3814ab6 100644 --- a/ui/src/conf/shortcuts.rs +++ b/ui/src/conf/shortcuts.rs @@ -4,6 +4,8 @@ use fnv::FnvHashMap; #[derive(Debug, Clone, Default, Deserialize)] pub struct Shortcuts { + #[serde(flatten)] + pub listing: ListingShortcuts, #[serde(flatten)] pub compact_listing: CompactListingShortcuts, #[serde(flatten)] @@ -45,19 +47,12 @@ macro_rules! shortcut_key_values { } } -shortcut_key_values! { "compact-listing", -/// Shortcut listing for a mail listing in compact mode. -pub struct CompactListingShortcuts { - open_thread: Key |> "Open thread.", - exit_thread: Key |> "Exit thread view.", - prev_page: Key |> "Go to previous page.", - next_page: Key |> "Go to next page.", - prev_folder: Key |> "Go to previous folder.", - next_folder: Key |> "Go to next folder.", - prev_account: Key |> "Go to previous account.", - next_account: Key |> "Go to next account.", - new_mail: Key |> "Start new mail draft in new tab." -} +shortcut_key_values! { "compact_listing", + /// Shortcut listing for a mail listing in compact mode. + pub struct CompactListingShortcuts { + open_thread: Key |> "Open thread.", + exit_thread: Key |> "Exit thread view." + } } impl Default for CompactListingShortcuts { @@ -65,6 +60,26 @@ impl Default for CompactListingShortcuts { CompactListingShortcuts { open_thread: Key::Char('\n'), exit_thread: Key::Char('i'), + } + } +} + +shortcut_key_values! { "listing", + /// Shortcut listing for a mail listing. + pub struct ListingShortcuts { + prev_page: Key |> "Go to previous page.", + next_page: Key |> "Go to next page.", + prev_folder: Key |> "Go to previous folder.", + next_folder: Key |> "Go to next folder.", + prev_account: Key |> "Go to previous account.", + next_account: Key |> "Go to next account.", + new_mail: Key |> "Start new mail draft in new tab." + } +} + +impl Default for ListingShortcuts { + fn default() -> Self { + ListingShortcuts { prev_page: Key::PageUp, next_page: Key::PageDown, prev_folder: Key::Char('J'), diff --git a/ui/src/terminal/keys.rs b/ui/src/terminal/keys.rs index dd6b51d6..a85855dd 100644 --- a/ui/src/terminal/keys.rs +++ b/ui/src/terminal/keys.rs @@ -129,6 +129,12 @@ impl From for Key { } } +impl PartialEq for &Key { + fn eq(&self, other: &Key) -> bool { + **self == *other + } +} + #[derive(PartialEq)] enum InputMode { Normal,