From b5fd3f57a7d99b8918ca7bd24f715ccd6bfe448a Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 8 Mar 2024 16:07:05 +0200 Subject: [PATCH] listing.rs: make self.view an Option Prevent accessing a ThreadView if it has not been initialized by making an uninitialized ThreadView impossible. Signed-off-by: Manos Pitsidianakis --- meli/src/mail/listing.rs | 61 +++++++++++++++++++++++++----------- meli/src/mail/view/thread.rs | 8 +++-- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/meli/src/mail/listing.rs b/meli/src/mail/listing.rs index a88d356c..2af95775 100644 --- a/meli/src/mail/listing.rs +++ b/meli/src/mail/listing.rs @@ -1024,7 +1024,7 @@ pub struct Listing { prev_ratio: usize, menu_width: WidgetWidth, focus: ListingFocus, - view: Box, + view: Option>, } impl std::fmt::Display for Listing { @@ -1102,8 +1102,9 @@ impl Component for Listing { } else { self.component.draw(grid, area, context); if self.component.unfocused() { - self.view - .draw(grid, self.component.view_area().unwrap_or(area), context); + if let Some(ref mut view) = self.view { + view.draw(grid, self.component.view_area().unwrap_or(area), context); + } } } } else if right_component_width == 0 { @@ -1126,8 +1127,9 @@ impl Component for Listing { let area = area.skip_cols(mid + 1); self.component.draw(grid, area, context); if self.component.unfocused() { - self.view - .draw(grid, self.component.view_area().unwrap_or(area), context); + if let Some(ref mut view) = self.view { + view.draw(grid, self.component.view_area().unwrap_or(area), context); + } } } } @@ -1329,17 +1331,21 @@ impl Component for Listing { match content.downcast_ref::().copied() { None => {} Some(ListingMessage::FocusUpdate { new_value }) => { - self.view.process_event( - &mut UIEvent::VisibilityChange(!matches!(new_value, Focus::None)), - context, - ); + if let Some(ref mut view) = self.view { + view.process_event( + &mut UIEvent::VisibilityChange(!matches!(new_value, Focus::None)), + context, + ); + } if matches!(new_value, Focus::Entry) { // Need to clear gap between sidebar and listing component, if any. self.dirty = true; } } Some(ListingMessage::UpdateView) => { - self.view.set_dirty(true); + if let Some(ref mut view) = self.view { + view.set_dirty(true); + } } Some(ListingMessage::OpenEntryUnderCursor { env_hash, @@ -1348,8 +1354,10 @@ impl Component for Listing { go_to_first_unread, }) => { let (a, m) = self.component.coordinates(); - self.view.unrealize(context); - self.view = Box::new(ThreadView::new( + if let Some(view) = self.view.take() { + view.unrealize(context); + } + self.view = Some(Box::new(ThreadView::new( (a, m, env_hash), thread_hash, Some(env_hash), @@ -1360,7 +1368,7 @@ impl Component for Listing { Some(ThreadViewFocus::MailView) }, context, - )); + ))); } } return true; @@ -1387,7 +1395,13 @@ impl Component for Listing { _ => {} } - if self.component.unfocused() && self.view.process_event(event, context) { + if self.component.unfocused() + && self + .view + .as_mut() + .map(|v| v.process_event(event, context)) + .unwrap_or(false) + { return true; } @@ -1399,7 +1413,12 @@ impl Component for Listing { } } if (self.focus == ListingFocus::Mailbox && self.status.is_none()) - && ((self.component.unfocused() && self.view.process_event(event, context)) + && ((self.component.unfocused() + && self + .view + .as_mut() + .map(|v| v.process_event(event, context)) + .unwrap_or(false)) || self.component.process_event(event, context)) { return true; @@ -2441,7 +2460,7 @@ impl Component for Listing { .map(Component::is_dirty) .unwrap_or_else(|| self.component.is_dirty()) || if self.component.unfocused() { - self.view.is_dirty() + self.view.as_ref().map(|v| v.is_dirty()).unwrap_or(false) } else { self.component.is_dirty() } @@ -2454,7 +2473,9 @@ impl Component for Listing { } else { self.component.set_dirty(value); if self.component.unfocused() { - self.view.set_dirty(value); + if let Some(ref mut view) = self.view { + view.set_dirty(value); + } } } } @@ -2462,7 +2483,9 @@ impl Component for Listing { fn shortcuts(&self, context: &Context) -> ShortcutMaps { let mut map = ShortcutMaps::default(); if self.focus != ListingFocus::Menu && self.component.unfocused() { - map.extend_shortcuts(self.view.shortcuts(context)); + if let Some(ref view) = self.view { + map.extend_shortcuts(view.shortcuts(context)); + } } map.extend_shortcuts(if let Some(s) = self.status.as_ref() { s.shortcuts(context) @@ -2591,7 +2614,7 @@ impl Listing { first_account_hash, MailboxHash::default(), ))), - view: Box::::default(), + view: None, accounts: account_entries, status: None, dirty: true, diff --git a/meli/src/mail/view/thread.rs b/meli/src/mail/view/thread.rs index 4d3d8bba..61aedd18 100644 --- a/meli/src/mail/view/thread.rs +++ b/meli/src/mail/view/thread.rs @@ -51,7 +51,7 @@ pub enum ThreadViewFocus { MailView, } -#[derive(Debug, Default)] +#[derive(Debug)] pub struct ThreadView { new_cursor_pos: usize, cursor_pos: usize, @@ -106,7 +106,11 @@ impl ThreadView { //], use_color: context.settings.terminal.use_color(), horizontal: None, - ..Default::default() + expanded_pos: 0, + new_expanded_pos: 0, + visible_entries: vec![], + movement: None, + content: Screen::::default(), }; view.initiate(expanded_hash, go_to_first_unread, context); view.new_cursor_pos = view.new_expanded_pos;