parent
d9269335a1
commit
5e68d600b9
|
@ -122,7 +122,9 @@ macro_rules! make {
|
|||
$threads.thread_nodes.entry($c).and_modify(|e| {
|
||||
e.parent = Some($p);
|
||||
});
|
||||
let old_group = $threads.groups[&old_group_hash].clone();
|
||||
let old_group = std::mem::replace($threads.groups.entry(old_group_hash).or_default(), ThreadGroup::Node {
|
||||
parent: RefCell::new(parent_group_hash),
|
||||
});
|
||||
$threads.thread_nodes.entry($c).and_modify(|e| {
|
||||
e.group = parent_group_hash;
|
||||
});
|
||||
|
@ -130,21 +132,21 @@ macro_rules! make {
|
|||
e.group = parent_group_hash;
|
||||
});
|
||||
{
|
||||
let parent_group = $threads.groups.entry(parent_group_hash).or_default();
|
||||
let parent_group = $threads.thread_ref_mut(parent_group_hash);
|
||||
match (parent_group, old_group) {
|
||||
(ThreadGroup::Group {
|
||||
(Thread {
|
||||
ref mut date,
|
||||
ref mut len,
|
||||
ref mut unseen,
|
||||
ref mut snoozed,
|
||||
..
|
||||
}, ThreadGroup::Group {
|
||||
}, ThreadGroup::Root(Thread {
|
||||
date: old_date,
|
||||
len: old_len,
|
||||
unseen: old_unseen,
|
||||
snoozed: old_snoozed,
|
||||
..
|
||||
}) => {
|
||||
})) => {
|
||||
*date = std::cmp::max(old_date, *date);
|
||||
*len += old_len;
|
||||
*unseen |= old_unseen;
|
||||
|
@ -153,14 +155,10 @@ macro_rules! make {
|
|||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
{
|
||||
let old_group = $threads.groups.entry(old_group_hash).or_default();
|
||||
*old_group = ThreadGroup::Node {
|
||||
parent: RefCell::new(parent_group_hash),
|
||||
};
|
||||
}
|
||||
prev_parent
|
||||
} else { None }
|
||||
prev_parent
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
|
@ -269,69 +267,62 @@ impl FromStr for SortOrder {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Thread {
|
||||
root: ThreadNodeHash,
|
||||
date: UnixTimestamp,
|
||||
len: usize,
|
||||
unseen: usize,
|
||||
|
||||
snoozed: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub enum ThreadGroup {
|
||||
Group {
|
||||
root: ThreadNodeHash,
|
||||
date: UnixTimestamp,
|
||||
len: usize,
|
||||
unseen: usize,
|
||||
|
||||
snoozed: bool,
|
||||
},
|
||||
Node {
|
||||
parent: RefCell<ThreadHash>,
|
||||
},
|
||||
Root(Thread),
|
||||
Node { parent: RefCell<ThreadHash> },
|
||||
}
|
||||
|
||||
impl Default for ThreadGroup {
|
||||
fn default() -> Self {
|
||||
ThreadGroup::Group {
|
||||
root: ThreadNodeHash::null(),
|
||||
date: 0,
|
||||
len: 0,
|
||||
unseen: 0,
|
||||
snoozed: false,
|
||||
ThreadGroup::Root(Thread::default())
|
||||
}
|
||||
}
|
||||
|
||||
impl ThreadGroup {
|
||||
fn root(&self) -> Option<&Thread> {
|
||||
if let ThreadGroup::Root(ref root) = self {
|
||||
Some(root)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn root_mut(&mut self) -> Option<&mut Thread> {
|
||||
if let ThreadGroup::Root(ref mut root) = self {
|
||||
Some(root)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! property {
|
||||
($name:ident: $t:ty, $e:expr) => {
|
||||
($name:ident: $t:ty) => {
|
||||
pub fn $name(&self) -> $t {
|
||||
match self {
|
||||
ThreadGroup::Group { $name, .. } => (*$name).into(),
|
||||
_ => {
|
||||
debug!(
|
||||
"ThreadGroup::{}() called on a ThreadGroup::Node: {:?}",
|
||||
stringify!($name),
|
||||
self
|
||||
);
|
||||
$e
|
||||
}
|
||||
}
|
||||
(self.$name).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
impl ThreadGroup {
|
||||
property!(root: Option<ThreadNodeHash>, None);
|
||||
property!(len: usize, 0);
|
||||
property!(unseen: usize, 0);
|
||||
property!(snoozed: bool, false);
|
||||
property!(date: UnixTimestamp, 0);
|
||||
|
||||
impl Thread {
|
||||
property!(root: ThreadNodeHash);
|
||||
property!(len: usize);
|
||||
property!(unseen: usize);
|
||||
property!(snoozed: bool);
|
||||
property!(date: UnixTimestamp);
|
||||
|
||||
pub fn set_snoozed(&mut self, val: bool) {
|
||||
match self {
|
||||
ThreadGroup::Group {
|
||||
ref mut snoozed, ..
|
||||
} => *snoozed = val,
|
||||
_ => {
|
||||
debug!(
|
||||
"ThreadGroup::set_snoozed() called on a ThreadGroup::Node: {:?}",
|
||||
self
|
||||
);
|
||||
}
|
||||
}
|
||||
self.snoozed = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -504,13 +495,26 @@ impl PartialEq for ThreadNode {
|
|||
|
||||
impl Threads {
|
||||
pub fn is_snoozed(&self, h: ThreadNodeHash) -> bool {
|
||||
let root = &self.find_group(self.thread_nodes[&h].group);
|
||||
self.groups[&root].snoozed()
|
||||
self.thread_ref(self.thread_nodes[&h].group).snoozed()
|
||||
}
|
||||
|
||||
pub fn thread_ref(&self, h: ThreadHash) -> &Thread {
|
||||
match self.groups[&self.find_group(h)] {
|
||||
ThreadGroup::Root(ref root) => root,
|
||||
ThreadGroup::Node { .. } => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn thread_ref_mut(&mut self, h: ThreadHash) -> &mut Thread {
|
||||
match self.groups.get_mut(&self.find_group(h)) {
|
||||
Some(ThreadGroup::Root(ref mut root)) => root,
|
||||
Some(ThreadGroup::Node { .. }) | None => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn find_group(&self, h: ThreadHash) -> ThreadHash {
|
||||
let p = match self.groups[&h] {
|
||||
ThreadGroup::Group { .. } => return h,
|
||||
ThreadGroup::Root(_) => return h,
|
||||
ThreadGroup::Node { ref parent } => *parent.borrow(),
|
||||
};
|
||||
|
||||
|
@ -579,7 +583,7 @@ impl Threads {
|
|||
|
||||
pub fn thread_group_iter(&self, index: ThreadHash) -> ThreadGroupIterator {
|
||||
ThreadGroupIterator {
|
||||
group: self.groups[&index].root().unwrap(),
|
||||
group: self.thread_ref(index).root(),
|
||||
pos: 0,
|
||||
stack: SmallVec::new(),
|
||||
thread_nodes: &self.thread_nodes,
|
||||
|
@ -610,16 +614,15 @@ impl Threads {
|
|||
let was_unseen = self.thread_nodes[&thread_hash].unseen;
|
||||
let is_unseen = !envelopes.read().unwrap()[&new_hash].is_seen();
|
||||
if was_unseen != is_unseen {
|
||||
let thread = self.find_group(self.thread_nodes[&thread_hash].group);
|
||||
self.groups.entry(thread).and_modify(|e| {
|
||||
if let ThreadGroup::Group { ref mut unseen, .. } = e {
|
||||
if was_unseen {
|
||||
*unseen -= 1;
|
||||
} else {
|
||||
*unseen += 1;
|
||||
}
|
||||
if let Thread { ref mut unseen, .. } =
|
||||
self.thread_ref_mut(self.thread_nodes[&thread_hash].group)
|
||||
{
|
||||
if was_unseen {
|
||||
*unseen -= 1;
|
||||
} else {
|
||||
*unseen += 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
self.thread_nodes.get_mut(&thread_hash).unwrap().unseen = is_unseen;
|
||||
self.hash_set.remove(&old_hash);
|
||||
|
@ -753,7 +756,7 @@ impl Threads {
|
|||
|
||||
self.groups.insert(
|
||||
self.thread_nodes[&new_id].group,
|
||||
ThreadGroup::Group {
|
||||
ThreadGroup::Root(Thread {
|
||||
root: new_id,
|
||||
date: envelopes_lck[&env_hash].date(),
|
||||
len: 1,
|
||||
|
@ -763,7 +766,7 @@ impl Threads {
|
|||
0
|
||||
},
|
||||
snoozed: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
self.message_ids
|
||||
.insert(envelopes_lck[&env_hash].message_id().raw().to_vec(), new_id);
|
||||
|
@ -795,13 +798,13 @@ impl Threads {
|
|||
|
||||
self.groups.insert(
|
||||
self.thread_nodes[&reply_to_id].group,
|
||||
ThreadGroup::Group {
|
||||
ThreadGroup::Root(Thread {
|
||||
root: reply_to_id,
|
||||
date: envelopes_lck[&env_hash].date(),
|
||||
len: 0,
|
||||
unseen: 0,
|
||||
snoozed: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
make!((reply_to_id) parent of (new_id), self);
|
||||
self.missing_message_ids.insert(r.to_vec());
|
||||
|
@ -838,13 +841,13 @@ impl Threads {
|
|||
);
|
||||
self.groups.insert(
|
||||
self.thread_nodes[&id].group,
|
||||
ThreadGroup::Group {
|
||||
ThreadGroup::Root(Thread {
|
||||
root: id,
|
||||
date: envelopes_lck[&env_hash].date(),
|
||||
len: 0,
|
||||
unseen: 0,
|
||||
snoozed: false,
|
||||
},
|
||||
}),
|
||||
);
|
||||
make!((id) parent of (current_descendant_id), self);
|
||||
self.missing_message_ids.insert(reference.raw().to_vec());
|
||||
|
@ -960,18 +963,18 @@ impl Threads {
|
|||
let envelopes = envelopes.read().unwrap();
|
||||
vec.sort_by(|a, b| match sort {
|
||||
(SortField::Date, SortOrder::Desc) => {
|
||||
let a = self.groups[&a].date();
|
||||
let b = self.groups[&b].date();
|
||||
let a = self.thread_ref(*a).date();
|
||||
let b = self.thread_ref(*b).date();
|
||||
b.cmp(&a)
|
||||
}
|
||||
(SortField::Date, SortOrder::Asc) => {
|
||||
let a = self.groups[&a].date();
|
||||
let b = self.groups[&b].date();
|
||||
let a = self.thread_ref(*a).date();
|
||||
let b = self.thread_ref(*b).date();
|
||||
a.cmp(&b)
|
||||
}
|
||||
(SortField::Subject, SortOrder::Desc) => {
|
||||
let a = &self.thread_nodes[&self.groups[&a].root().unwrap()].message();
|
||||
let b = &self.thread_nodes[&self.groups[&b].root().unwrap()].message();
|
||||
let a = &self.thread_nodes[&self.thread_ref(*a).root()].message();
|
||||
let b = &self.thread_nodes[&self.thread_ref(*b).root()].message();
|
||||
|
||||
match (a, b) {
|
||||
(Some(_), Some(_)) => {}
|
||||
|
@ -999,8 +1002,8 @@ impl Threads {
|
|||
}
|
||||
}
|
||||
(SortField::Subject, SortOrder::Asc) => {
|
||||
let a = &self.thread_nodes[&self.groups[&a].root().unwrap()].message();
|
||||
let b = &self.thread_nodes[&self.groups[&b].root().unwrap()].message();
|
||||
let a = &self.thread_nodes[&self.thread_ref(*a).root()].message();
|
||||
let b = &self.thread_nodes[&self.thread_ref(*b).root()].message();
|
||||
|
||||
match (a, b) {
|
||||
(Some(_), Some(_)) => {}
|
||||
|
@ -1040,17 +1043,13 @@ impl Threads {
|
|||
let envelopes = envelopes.read().unwrap();
|
||||
vec.sort_by(|a, b| match sort {
|
||||
(SortField::Date, SortOrder::Desc) => {
|
||||
let a_group = self.find_group(self.thread_nodes[&a].group);
|
||||
let b_group = self.find_group(self.thread_nodes[&b].group);
|
||||
let a = self.groups[&a_group].date();
|
||||
let b = self.groups[&b_group].date();
|
||||
let a = self.thread_ref(self.thread_nodes[&a].group).date();
|
||||
let b = self.thread_ref(self.thread_nodes[&b].group).date();
|
||||
b.cmp(&a)
|
||||
}
|
||||
(SortField::Date, SortOrder::Asc) => {
|
||||
let a_group = self.find_group(self.thread_nodes[&a].group);
|
||||
let b_group = self.find_group(self.thread_nodes[&b].group);
|
||||
let a = self.groups[&a_group].date();
|
||||
let b = self.groups[&b_group].date();
|
||||
let a = self.thread_ref(self.thread_nodes[&a].group).date();
|
||||
let b = self.thread_ref(self.thread_nodes[&b].group).date();
|
||||
a.cmp(&b)
|
||||
}
|
||||
(SortField::Subject, SortOrder::Desc) => {
|
||||
|
@ -1120,17 +1119,13 @@ impl Threads {
|
|||
let envelopes = envelopes.read().unwrap();
|
||||
tree.sort_by(|a, b| match sort {
|
||||
(SortField::Date, SortOrder::Desc) => {
|
||||
let a_group = self.find_group(self.thread_nodes[&a].group);
|
||||
let b_group = self.find_group(self.thread_nodes[&b].group);
|
||||
let a = self.groups[&a_group].date();
|
||||
let b = self.groups[&b_group].date();
|
||||
let a = self.thread_ref(self.thread_nodes[&a].group).date();
|
||||
let b = self.thread_ref(self.thread_nodes[&b].group).date();
|
||||
b.cmp(&a)
|
||||
}
|
||||
(SortField::Date, SortOrder::Asc) => {
|
||||
let a_group = self.find_group(self.thread_nodes[&a].group);
|
||||
let b_group = self.find_group(self.thread_nodes[&b].group);
|
||||
let a = self.groups[&a_group].date();
|
||||
let b = self.groups[&b_group].date();
|
||||
let a = self.thread_ref(self.thread_nodes[&a].group).date();
|
||||
let b = self.thread_ref(self.thread_nodes[&b].group).date();
|
||||
a.cmp(&b)
|
||||
}
|
||||
(SortField::Subject, SortOrder::Desc) => {
|
||||
|
|
|
@ -118,13 +118,14 @@ impl ListingTrait for CompactListing {
|
|||
if self.length == 0 {
|
||||
return;
|
||||
}
|
||||
let thread = self.get_thread_under_cursor(idx, context);
|
||||
let thread_hash = self.get_thread_under_cursor(idx, context);
|
||||
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = &account.collection.threads[&folder_hash];
|
||||
let thread = threads.thread_ref(thread_hash);
|
||||
|
||||
let fg_color = if threads.groups[&thread].unseen() > 0 {
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
} else {
|
||||
Color::Default
|
||||
|
@ -132,9 +133,9 @@ impl ListingTrait for CompactListing {
|
|||
let bg_color = if context.settings.terminal.theme == "light" {
|
||||
if self.cursor_pos.2 == idx {
|
||||
Color::Byte(244)
|
||||
} else if self.selection[&thread] {
|
||||
} else if self.selection[&thread_hash] {
|
||||
Color::Byte(210)
|
||||
} else if threads.groups[&thread].unseen() > 0 {
|
||||
} else if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else if idx % 2 == 0 {
|
||||
Color::Byte(252)
|
||||
|
@ -144,9 +145,9 @@ impl ListingTrait for CompactListing {
|
|||
} else {
|
||||
if self.cursor_pos.2 == idx {
|
||||
Color::Byte(246)
|
||||
} else if self.selection[&thread] {
|
||||
} else if self.selection[&thread_hash] {
|
||||
Color::Byte(210)
|
||||
} else if threads.groups[&thread].unseen() > 0 {
|
||||
} else if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else if idx % 2 == 0 {
|
||||
Color::Byte(236)
|
||||
|
@ -549,7 +550,7 @@ impl CompactListing {
|
|||
threads: &Threads,
|
||||
hash: ThreadHash,
|
||||
) -> EntryStrings {
|
||||
let thread = &threads.groups[&hash];
|
||||
let thread = threads.thread_ref(hash);
|
||||
let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
|
||||
.unwrap()
|
||||
.folder
|
||||
|
@ -714,7 +715,7 @@ impl CompactListing {
|
|||
for (idx, thread) in items.enumerate() {
|
||||
debug!(thread);
|
||||
self.length += 1;
|
||||
let thread_node = &threads.thread_nodes()[&threads.groups[&thread].root().unwrap()];
|
||||
let thread_node = &threads.thread_nodes()[&threads.thread_ref(thread).root()];
|
||||
let root_env_hash = thread_node.message().unwrap_or_else(|| {
|
||||
let mut iter_ptr = thread_node.children()[0];
|
||||
while threads.thread_nodes()[&iter_ptr].message().is_none() {
|
||||
|
@ -811,13 +812,14 @@ impl CompactListing {
|
|||
|
||||
panic!();
|
||||
}
|
||||
let fg_color = if threads.groups[&thread].unseen() > 0 {
|
||||
let thread = threads.thread_ref(thread);
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
} else {
|
||||
Color::Default
|
||||
};
|
||||
let bg_color = if context.settings.terminal.theme == "light" {
|
||||
if threads.groups[&thread].unseen() > 0 {
|
||||
if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else if idx % 2 == 0 {
|
||||
Color::Byte(252)
|
||||
|
@ -825,7 +827,7 @@ impl CompactListing {
|
|||
Color::Default
|
||||
}
|
||||
} else {
|
||||
if threads.groups[&thread].unseen() > 0 {
|
||||
if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else if idx % 2 == 0 {
|
||||
Color::Byte(236)
|
||||
|
@ -921,7 +923,7 @@ impl CompactListing {
|
|||
self.data_columns.columns[4][(x, idx)].set_bg(bg_color);
|
||||
}
|
||||
match (
|
||||
threads.groups[&thread].snoozed(),
|
||||
thread.snoozed(),
|
||||
context.accounts[self.cursor_pos.0]
|
||||
.collection
|
||||
.get_env(root_env_hash)
|
||||
|
@ -983,9 +985,9 @@ impl CompactListing {
|
|||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = &account.collection.threads[&folder_hash];
|
||||
if let Some(env_hash) =
|
||||
threads.thread_nodes()[&threads.groups[&thread_hash].root().unwrap()].message()
|
||||
{
|
||||
let thread = threads.thread_ref(thread_hash);
|
||||
// FIXME: Thread root doesn't nessessarily have message set
|
||||
if let Some(env_hash) = threads.thread_nodes()[&thread.root()].message() {
|
||||
if !account.contains_key(env_hash) {
|
||||
/* The envelope has been renamed or removed, so wait for the appropriate event to
|
||||
* arrive */
|
||||
|
@ -993,14 +995,14 @@ impl CompactListing {
|
|||
}
|
||||
let envelope: EnvelopeRef = account.collection.get_env(env_hash);
|
||||
let has_attachments = envelope.has_attachments();
|
||||
let fg_color = if threads.groups[&thread_hash].unseen() > 0 {
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
} else {
|
||||
Color::Default
|
||||
};
|
||||
let idx = self.order[&thread_hash];
|
||||
let bg_color = if context.settings.terminal.theme == "light" {
|
||||
if threads.groups[&thread_hash].unseen() > 0 {
|
||||
if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else if idx % 2 == 0 {
|
||||
Color::Byte(252)
|
||||
|
@ -1008,7 +1010,7 @@ impl CompactListing {
|
|||
Color::Default
|
||||
}
|
||||
} else {
|
||||
if threads.groups[&thread_hash].unseen() > 0 {
|
||||
if thread.unseen() > 0 {
|
||||
Color::Byte(253)
|
||||
} else if idx % 2 == 0 {
|
||||
Color::Byte(236)
|
||||
|
@ -1117,7 +1119,7 @@ impl CompactListing {
|
|||
columns[4][c].set_ch(' ');
|
||||
columns[4][c].set_bg(bg_color);
|
||||
}
|
||||
match (threads.groups[&thread_hash].snoozed(), has_attachments) {
|
||||
match (thread.snoozed(), has_attachments) {
|
||||
(true, true) => {
|
||||
columns[3][(0, idx)].set_fg(Color::Byte(103));
|
||||
columns[3][(2, idx)].set_fg(Color::Red);
|
||||
|
@ -1246,41 +1248,45 @@ impl Component for CompactListing {
|
|||
let thread_hash = self.get_thread_under_cursor(self.cursor_pos.2, context);
|
||||
self.selection.entry(thread_hash).and_modify(|e| *e = !*e);
|
||||
}
|
||||
UIEvent::Action(ref action) => match action {
|
||||
Action::Sort(field, order) if !self.unfocused => {
|
||||
debug!("Sort {:?} , {:?}", field, order);
|
||||
self.sort = (*field, *order);
|
||||
if !self.filtered_selection.is_empty() {
|
||||
// FIXME: perform sort
|
||||
self.dirty = true;
|
||||
} else {
|
||||
self.refresh_mailbox(context);
|
||||
UIEvent::Action(ref action) => {
|
||||
match action {
|
||||
Action::Sort(field, order) if !self.unfocused => {
|
||||
debug!("Sort {:?} , {:?}", field, order);
|
||||
self.sort = (*field, *order);
|
||||
if !self.filtered_selection.is_empty() {
|
||||
// FIXME: perform sort
|
||||
self.dirty = true;
|
||||
} else {
|
||||
self.refresh_mailbox(context);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Action::SubSort(field, order) if !self.unfocused => {
|
||||
debug!("SubSort {:?} , {:?}", field, order);
|
||||
self.subsort = (*field, *order);
|
||||
// FIXME: perform subsort.
|
||||
return true;
|
||||
}
|
||||
Action::ToggleThreadSnooze if !self.unfocused => {
|
||||
let thread = self.get_thread_under_cursor(self.cursor_pos.2, context);
|
||||
let account = &mut context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
account
|
||||
.collection
|
||||
.threads
|
||||
.entry(folder_hash)
|
||||
.and_modify(|threads| {
|
||||
let is_snoozed = threads.thread_ref(thread).snoozed();
|
||||
threads.thread_ref_mut(thread).set_snoozed(!is_snoozed);
|
||||
});
|
||||
self.row_updates.push(thread);
|
||||
self.refresh_mailbox(context);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
Action::SubSort(field, order) if !self.unfocused => {
|
||||
debug!("SubSort {:?} , {:?}", field, order);
|
||||
self.subsort = (*field, *order);
|
||||
// FIXME: perform subsort.
|
||||
return true;
|
||||
}
|
||||
Action::ToggleThreadSnooze if !self.unfocused => {
|
||||
let thread = self.get_thread_under_cursor(self.cursor_pos.2, context);
|
||||
let account = &mut context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = account.collection.threads.entry(folder_hash).or_default();
|
||||
let is_snoozed = threads.groups[&thread].snoozed();
|
||||
threads
|
||||
.groups
|
||||
.entry(thread)
|
||||
.and_modify(|entry| entry.set_snoozed(!is_snoozed));
|
||||
self.row_updates.push(thread);
|
||||
self.refresh_mailbox(context);
|
||||
return true;
|
||||
}
|
||||
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,22 +149,23 @@ impl ListingTrait for ConversationsListing {
|
|||
if self.length == 0 {
|
||||
return;
|
||||
}
|
||||
let thread = self.get_thread_under_cursor(idx, context);
|
||||
let thread_hash = self.get_thread_under_cursor(idx, context);
|
||||
|
||||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = &account.collection.threads[&folder_hash];
|
||||
let thread = threads.thread_ref(thread_hash);
|
||||
|
||||
let fg_color = if threads.groups[&thread].unseen() > 0 {
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
} else {
|
||||
Color::Default
|
||||
};
|
||||
let bg_color = if self.cursor_pos.2 == idx {
|
||||
Color::Byte(246)
|
||||
} else if self.selection[&thread] {
|
||||
} else if self.selection[&thread_hash] {
|
||||
Color::Byte(210)
|
||||
} else if threads.groups[&thread].unseen() > 0 {
|
||||
} else if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else {
|
||||
Color::Default
|
||||
|
@ -186,7 +187,7 @@ impl ListingTrait for ConversationsListing {
|
|||
let (upper_left, bottom_right) = area;
|
||||
let width = self.content.size().0;
|
||||
let (x, y) = upper_left;
|
||||
if self.cursor_pos.2 == idx || self.selection[&thread] {
|
||||
if self.cursor_pos.2 == idx || self.selection[&thread_hash] {
|
||||
for x in x..=get_x(bottom_right) {
|
||||
grid[(x, y)].set_fg(fg_color);
|
||||
grid[(x, y)].set_bg(bg_color);
|
||||
|
@ -522,7 +523,7 @@ impl ConversationsListing {
|
|||
threads: &Threads,
|
||||
hash: ThreadHash,
|
||||
) -> EntryStrings {
|
||||
let thread = &threads.groups[&hash];
|
||||
let thread = threads.thread_ref(hash);
|
||||
let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
|
||||
.unwrap()
|
||||
.folder
|
||||
|
@ -676,7 +677,7 @@ impl ConversationsListing {
|
|||
std::collections::HashSet::new();
|
||||
for (idx, thread) in items.enumerate() {
|
||||
self.length += 1;
|
||||
let thread_node = &threads.thread_nodes()[&threads.groups[&thread].root().unwrap()];
|
||||
let thread_node = &threads.thread_nodes()[&threads.thread_ref(thread).root()];
|
||||
let root_env_hash = thread_node.message().unwrap_or_else(|| {
|
||||
let mut iter_ptr = thread_node.children()[0];
|
||||
while threads.thread_nodes()[&iter_ptr].message().is_none() {
|
||||
|
@ -750,12 +751,13 @@ impl ConversationsListing {
|
|||
if !context.accounts[self.cursor_pos.0].contains_key(root_env_hash) {
|
||||
panic!();
|
||||
}
|
||||
let fg_color = if threads.groups[&thread].unseen() > 0 {
|
||||
let thread = threads.thread_ref(thread);
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
} else {
|
||||
Color::Default
|
||||
};
|
||||
let bg_color = if threads.groups[&thread].unseen() > 0 {
|
||||
let bg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else {
|
||||
Color::Default
|
||||
|
@ -919,19 +921,18 @@ impl ConversationsListing {
|
|||
let account = &context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = &account.collection.threads[&folder_hash];
|
||||
let thread = threads.thread_ref(thread_hash);
|
||||
let idx: usize = self.order[&thread_hash];
|
||||
let width = self.content.size().0;
|
||||
|
||||
let env_hash = threads.thread_nodes()[&threads.groups[&thread_hash].root().unwrap()]
|
||||
.message()
|
||||
.unwrap();
|
||||
let env_hash = threads.thread_nodes()[&thread.root()].message().unwrap();
|
||||
|
||||
let fg_color = if threads.groups[&thread_hash].unseen() > 0 {
|
||||
let fg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(0)
|
||||
} else {
|
||||
Color::Default
|
||||
};
|
||||
let bg_color = if threads.groups[&thread_hash].unseen() > 0 {
|
||||
let bg_color = if thread.unseen() > 0 {
|
||||
Color::Byte(251)
|
||||
} else {
|
||||
Color::Default
|
||||
|
@ -1262,12 +1263,14 @@ impl Component for ConversationsListing {
|
|||
let thread = self.get_thread_under_cursor(self.cursor_pos.2, context);
|
||||
let account = &mut context.accounts[self.cursor_pos.0];
|
||||
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
|
||||
let threads = account.collection.threads.entry(folder_hash).or_default();
|
||||
let is_snoozed = threads.groups[&thread].snoozed();
|
||||
threads
|
||||
.groups
|
||||
.entry(thread)
|
||||
.and_modify(|entry| entry.set_snoozed(!is_snoozed));
|
||||
account
|
||||
.collection
|
||||
.threads
|
||||
.entry(folder_hash)
|
||||
.and_modify(|threads| {
|
||||
let is_snoozed = threads.thread_ref(thread).snoozed();
|
||||
threads.thread_ref_mut(thread).set_snoozed(!is_snoozed);
|
||||
});
|
||||
self.row_updates.push(thread);
|
||||
self.refresh_mailbox(context);
|
||||
return true;
|
||||
|
|
|
@ -599,7 +599,10 @@ impl Account {
|
|||
self.collection.threads[&folder_hash]
|
||||
.find_group(self.collection.threads[&folder_hash][&thread_hash].group)
|
||||
};
|
||||
if self.collection.threads[&folder_hash].groups[&thread].snoozed() {
|
||||
if self.collection.threads[&folder_hash]
|
||||
.thread_ref(thread)
|
||||
.snoozed()
|
||||
{
|
||||
return Some(UIEvent::MailboxUpdate((self.index, folder_hash)));
|
||||
}
|
||||
if is_seen || is_draft {
|
||||
|
|
Loading…
Reference in New Issue