From d76369932438edca8e3c4da0a0df296d7717d521 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 22 Jul 2018 14:05:41 +0300 Subject: [PATCH] Add support for component specific actions for shortcuts --- melib/src/mailbox/accounts.rs | 4 ++- ui/src/components/mail/listing.rs | 46 +++++++++++++++++++++++-------- ui/src/lib.rs | 18 ++++++++++-- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/melib/src/mailbox/accounts.rs b/melib/src/mailbox/accounts.rs index 64aa98f55..c1b134591 100644 --- a/melib/src/mailbox/accounts.rs +++ b/melib/src/mailbox/accounts.rs @@ -32,6 +32,7 @@ pub struct Account { sent_folder: Option, pub settings: AccountSettings, + pub runtime_settings: AccountSettings, pub backend: Box, } @@ -53,7 +54,8 @@ impl Account { sent_folder: sent_folder, - settings: settings, + settings: settings.clone(), + runtime_settings: settings, backend: backend, } } diff --git a/ui/src/components/mail/listing.rs b/ui/src/components/mail/listing.rs index ece35ae5d..ee08184d0 100644 --- a/ui/src/components/mail/listing.rs +++ b/ui/src/components/mail/listing.rs @@ -1,6 +1,11 @@ use super::*; const MAX_COLS: usize = 500; +#[derive(Debug)] +pub enum MailListingAction { + ToggleThreaded, +} + /// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a /// `Pager`. pub struct MailListing { @@ -46,7 +51,7 @@ impl MailListing { self.cursor_pos.1 = self.new_cursor_pos.1; self.cursor_pos.0 = self.new_cursor_pos.0; - let threaded = context.accounts[self.cursor_pos.0].settings.threaded; + let threaded = context.accounts[self.cursor_pos.0].runtime_settings.threaded; // Get mailbox as a reference. let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); // Inform State that we changed the current folder view. @@ -195,7 +200,7 @@ impl MailListing { self.content = content; } fn highlight_line(&self, grid: &mut CellBuffer, area: Area, idx: usize, context: &Context) { - let threaded = context.accounts[self.cursor_pos.0].settings.threaded; + let threaded = context.accounts[self.cursor_pos.0].runtime_settings.threaded; let mailbox = &context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); let envelope: &Envelope = if threaded { let i = mailbox.threaded_mail(idx); @@ -270,17 +275,17 @@ impl MailListing { /// Create a pager for the `Envelope` currently under the cursor. fn draw_mail_view(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { { - let threaded = context.accounts[self.cursor_pos.0].settings.threaded; - let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); - let envelope: &Envelope = if threaded { - let i = mailbox.threaded_mail(self.cursor_pos.2); - &mailbox.collection[i] - } else { - &mailbox.collection[self.cursor_pos.2] + let envelope_idx: usize = { + let threaded = context.accounts[self.cursor_pos.0].runtime_settings.threaded; + let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); + if threaded { + mailbox.threaded_mail(self.cursor_pos.2) + } else { + self.cursor_pos.2 + } }; - let pager_filter = context.settings.pager.filter.clone(); - self.pager = Some(Pager::new(&envelope, pager_filter)); + self.pager = Some(Pager::from_envelope((self.cursor_pos.0, self.cursor_pos.1), envelope_idx, context)); } self.pager.as_mut().map(|p| p.draw(grid, area, context)); } @@ -399,7 +404,7 @@ impl Component for MailListing { /* Draw header */ let y = { - let threaded = context.accounts[self.cursor_pos.0].settings.threaded; + let threaded = context.accounts[self.cursor_pos.0].runtime_settings.threaded; let mailbox = &mut context.accounts[self.cursor_pos.0][self.cursor_pos.1].as_ref().unwrap().as_ref().unwrap(); let envelope: &Envelope = if threaded { let i = mailbox.threaded_mail(self.cursor_pos.2); @@ -605,6 +610,23 @@ impl Component for MailListing { UIEventType::Resize => { self.dirty = true; }, + UIEventType::Action(ref action) => { + eprintln!("got action"); + match action { + Action::MailListing(MailListingAction::ToggleThreaded) => { + eprintln!("toggled"); + context.accounts[self.cursor_pos.0].runtime_settings.threaded = !context.accounts[self.cursor_pos.0].runtime_settings.threaded; + self.refresh_mailbox(context); + self.dirty = true; + + + }, + _ => { unreachable!() }, + + + } + + }, _ => { }, } diff --git a/ui/src/lib.rs b/ui/src/lib.rs index 0eeb3e529..48e61b540 100644 --- a/ui/src/lib.rs +++ b/ui/src/lib.rs @@ -61,6 +61,11 @@ use termion::screen::AlternateScreen; extern crate nom; use chan::Sender; +#[derive(Debug)] +pub enum Action { + MailListing(MailListingAction), +} + /// `ThreadEvent` encapsulates all of the possible values we need to transfer between our threads /// to the main process. #[derive(Debug)] @@ -100,6 +105,7 @@ pub enum UIEventType { Command(String), Notification(String), EditDraft(std::path::PathBuf), + Action(Action), } @@ -139,6 +145,8 @@ pub struct Notification { pub struct Context { pub accounts: Vec, settings: Settings, + + runtime_settings: Settings, /// Areas of the screen that must be redrawn in the next render dirty_areas: VecDeque, @@ -210,7 +218,8 @@ impl State { context: Context { accounts: accounts, backends: backends, - settings: settings, + settings: settings.clone(), + runtime_settings: settings, dirty_areas: VecDeque::with_capacity(5), replies: VecDeque::with_capacity(5), @@ -352,7 +361,12 @@ impl State { eprintln!("{}",String::from_utf8_lossy(&output.stdout)); return; - } + }, + UIEventType::Input(Key::Char('t')) => + for i in 0..self.entities.len() { + self.entities[i].rcv_event(&UIEvent{ id: 0, event_type: UIEventType::Action(Action::MailListing(MailListingAction::ToggleThreaded)) }, &mut self.context); + } + _ => {}, } /* inform each entity */