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 <manos@pitsidianak.is>
pull/362/head
Manos Pitsidianakis 2 months ago
parent 1fcb1d59b8
commit b5fd3f57a7
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -1024,7 +1024,7 @@ pub struct Listing {
prev_ratio: usize, prev_ratio: usize,
menu_width: WidgetWidth, menu_width: WidgetWidth,
focus: ListingFocus, focus: ListingFocus,
view: Box<ThreadView>, view: Option<Box<ThreadView>>,
} }
impl std::fmt::Display for Listing { impl std::fmt::Display for Listing {
@ -1102,8 +1102,9 @@ impl Component for Listing {
} else { } else {
self.component.draw(grid, area, context); self.component.draw(grid, area, context);
if self.component.unfocused() { if self.component.unfocused() {
self.view if let Some(ref mut view) = self.view {
.draw(grid, self.component.view_area().unwrap_or(area), context); view.draw(grid, self.component.view_area().unwrap_or(area), context);
}
} }
} }
} else if right_component_width == 0 { } else if right_component_width == 0 {
@ -1126,8 +1127,9 @@ impl Component for Listing {
let area = area.skip_cols(mid + 1); let area = area.skip_cols(mid + 1);
self.component.draw(grid, area, context); self.component.draw(grid, area, context);
if self.component.unfocused() { if self.component.unfocused() {
self.view if let Some(ref mut view) = self.view {
.draw(grid, self.component.view_area().unwrap_or(area), context); view.draw(grid, self.component.view_area().unwrap_or(area), context);
}
} }
} }
} }
@ -1329,17 +1331,21 @@ impl Component for Listing {
match content.downcast_ref::<ListingMessage>().copied() { match content.downcast_ref::<ListingMessage>().copied() {
None => {} None => {}
Some(ListingMessage::FocusUpdate { new_value }) => { Some(ListingMessage::FocusUpdate { new_value }) => {
self.view.process_event( if let Some(ref mut view) = self.view {
&mut UIEvent::VisibilityChange(!matches!(new_value, Focus::None)), view.process_event(
context, &mut UIEvent::VisibilityChange(!matches!(new_value, Focus::None)),
); context,
);
}
if matches!(new_value, Focus::Entry) { if matches!(new_value, Focus::Entry) {
// Need to clear gap between sidebar and listing component, if any. // Need to clear gap between sidebar and listing component, if any.
self.dirty = true; self.dirty = true;
} }
} }
Some(ListingMessage::UpdateView) => { Some(ListingMessage::UpdateView) => {
self.view.set_dirty(true); if let Some(ref mut view) = self.view {
view.set_dirty(true);
}
} }
Some(ListingMessage::OpenEntryUnderCursor { Some(ListingMessage::OpenEntryUnderCursor {
env_hash, env_hash,
@ -1348,8 +1354,10 @@ impl Component for Listing {
go_to_first_unread, go_to_first_unread,
}) => { }) => {
let (a, m) = self.component.coordinates(); let (a, m) = self.component.coordinates();
self.view.unrealize(context); if let Some(view) = self.view.take() {
self.view = Box::new(ThreadView::new( view.unrealize(context);
}
self.view = Some(Box::new(ThreadView::new(
(a, m, env_hash), (a, m, env_hash),
thread_hash, thread_hash,
Some(env_hash), Some(env_hash),
@ -1360,7 +1368,7 @@ impl Component for Listing {
Some(ThreadViewFocus::MailView) Some(ThreadViewFocus::MailView)
}, },
context, context,
)); )));
} }
} }
return true; 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; return true;
} }
@ -1399,7 +1413,12 @@ impl Component for Listing {
} }
} }
if (self.focus == ListingFocus::Mailbox && self.status.is_none()) 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)) || self.component.process_event(event, context))
{ {
return true; return true;
@ -2441,7 +2460,7 @@ impl Component for Listing {
.map(Component::is_dirty) .map(Component::is_dirty)
.unwrap_or_else(|| self.component.is_dirty()) .unwrap_or_else(|| self.component.is_dirty())
|| if self.component.unfocused() { || if self.component.unfocused() {
self.view.is_dirty() self.view.as_ref().map(|v| v.is_dirty()).unwrap_or(false)
} else { } else {
self.component.is_dirty() self.component.is_dirty()
} }
@ -2454,7 +2473,9 @@ impl Component for Listing {
} else { } else {
self.component.set_dirty(value); self.component.set_dirty(value);
if self.component.unfocused() { 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 { fn shortcuts(&self, context: &Context) -> ShortcutMaps {
let mut map = ShortcutMaps::default(); let mut map = ShortcutMaps::default();
if self.focus != ListingFocus::Menu && self.component.unfocused() { 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() { map.extend_shortcuts(if let Some(s) = self.status.as_ref() {
s.shortcuts(context) s.shortcuts(context)
@ -2591,7 +2614,7 @@ impl Listing {
first_account_hash, first_account_hash,
MailboxHash::default(), MailboxHash::default(),
))), ))),
view: Box::<ThreadView>::default(), view: None,
accounts: account_entries, accounts: account_entries,
status: None, status: None,
dirty: true, dirty: true,

@ -51,7 +51,7 @@ pub enum ThreadViewFocus {
MailView, MailView,
} }
#[derive(Debug, Default)] #[derive(Debug)]
pub struct ThreadView { pub struct ThreadView {
new_cursor_pos: usize, new_cursor_pos: usize,
cursor_pos: usize, cursor_pos: usize,
@ -106,7 +106,11 @@ impl ThreadView {
//], //],
use_color: context.settings.terminal.use_color(), use_color: context.settings.terminal.use_color(),
horizontal: None, horizontal: None,
..Default::default() expanded_pos: 0,
new_expanded_pos: 0,
visible_entries: vec![],
movement: None,
content: Screen::<Virtual>::default(),
}; };
view.initiate(expanded_hash, go_to_first_unread, context); view.initiate(expanded_hash, go_to_first_unread, context);
view.new_cursor_pos = view.new_expanded_pos; view.new_cursor_pos = view.new_expanded_pos;

Loading…
Cancel
Save