|
|
|
@ -895,6 +895,12 @@ enum ListingFocus {
|
|
|
|
|
Mailbox,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
|
|
|
|
struct CursorPos {
|
|
|
|
|
account: usize,
|
|
|
|
|
menu: MenuEntryCursor,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
|
|
|
|
|
enum MenuEntryCursor {
|
|
|
|
|
Status,
|
|
|
|
@ -926,8 +932,8 @@ pub struct Listing {
|
|
|
|
|
accounts: Vec<AccountMenuEntry>,
|
|
|
|
|
status: Option<AccountStatus>,
|
|
|
|
|
dirty: bool,
|
|
|
|
|
cursor_pos: (usize, MenuEntryCursor),
|
|
|
|
|
menu_cursor_pos: (usize, MenuEntryCursor),
|
|
|
|
|
cursor_pos: CursorPos,
|
|
|
|
|
menu_cursor_pos: CursorPos,
|
|
|
|
|
menu_content: CellBuffer,
|
|
|
|
|
menu_scrollbar_show_timer: crate::jobs::Timer,
|
|
|
|
|
show_menu_scrollbar: ShowMenuScrollbar,
|
|
|
|
@ -1009,7 +1015,7 @@ impl Component for Listing {
|
|
|
|
|
.push_back(((mid, get_y(upper_left)), (mid, get_y(bottom_right))));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let account_hash = self.accounts[self.cursor_pos.0].hash;
|
|
|
|
|
let account_hash = self.accounts[self.cursor_pos.account].hash;
|
|
|
|
|
if right_component_width == total_cols {
|
|
|
|
|
if context.is_online(account_hash).is_err()
|
|
|
|
|
&& !matches!(self.component, ListingComponent::Offline(_))
|
|
|
|
@ -1063,7 +1069,7 @@ impl Component for Listing {
|
|
|
|
|
match event {
|
|
|
|
|
UIEvent::ConfigReload { old_settings: _ } => {
|
|
|
|
|
self.theme_default = crate::conf::value(context, "theme_default");
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.account].hash();
|
|
|
|
|
self.sidebar_divider =
|
|
|
|
|
*account_settings!(context[account_hash].listing.sidebar_divider);
|
|
|
|
|
self.sidebar_divider_theme = conf::value(context, "mail.sidebar_divider");
|
|
|
|
@ -1097,7 +1103,7 @@ impl Component for Listing {
|
|
|
|
|
.accounts
|
|
|
|
|
.get_index_of(account_hash)
|
|
|
|
|
.expect("Invalid account_hash in UIEventMailbox{Delete,Create}");
|
|
|
|
|
if self.cursor_pos.0 == account_index {
|
|
|
|
|
if self.cursor_pos.account == account_index {
|
|
|
|
|
self.change_account(context);
|
|
|
|
|
} else {
|
|
|
|
|
let previous_collapsed_mailboxes: BTreeSet<MailboxHash> = self.accounts
|
|
|
|
@ -1179,9 +1185,9 @@ impl Component for Listing {
|
|
|
|
|
})
|
|
|
|
|
.collect::<_>();
|
|
|
|
|
let mut fallback = 0;
|
|
|
|
|
if let MenuEntryCursor::Mailbox(ref mut cur) = self.cursor_pos.1 {
|
|
|
|
|
if let MenuEntryCursor::Mailbox(ref mut cur) = self.cursor_pos.menu {
|
|
|
|
|
*cur = std::cmp::min(
|
|
|
|
|
self.accounts[self.cursor_pos.0]
|
|
|
|
|
self.accounts[self.cursor_pos.account]
|
|
|
|
|
.entries
|
|
|
|
|
.len()
|
|
|
|
|
.saturating_sub(1),
|
|
|
|
@ -1193,8 +1199,8 @@ impl Component for Listing {
|
|
|
|
|
self.component
|
|
|
|
|
.process_event(&mut UIEvent::VisibilityChange(false), context);
|
|
|
|
|
self.component.set_coordinates((
|
|
|
|
|
self.accounts[self.cursor_pos.0].hash,
|
|
|
|
|
self.accounts[self.cursor_pos.0].entries[fallback].mailbox_hash,
|
|
|
|
|
self.accounts[self.cursor_pos.account].hash,
|
|
|
|
|
self.accounts[self.cursor_pos.account].entries[fallback].mailbox_hash,
|
|
|
|
|
));
|
|
|
|
|
self.component.refresh_mailbox(context, true);
|
|
|
|
|
}
|
|
|
|
@ -1214,10 +1220,10 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Action(Action::ViewMailbox(ref idx)) => {
|
|
|
|
|
if let Some(MailboxMenuEntry { mailbox_hash, .. }) =
|
|
|
|
|
self.accounts[self.cursor_pos.0].entries.get(*idx)
|
|
|
|
|
self.accounts[self.cursor_pos.account].entries.get(*idx)
|
|
|
|
|
{
|
|
|
|
|
let account_hash = self.accounts[self.cursor_pos.0].hash;
|
|
|
|
|
self.cursor_pos.1 = MenuEntryCursor::Mailbox(*idx);
|
|
|
|
|
let account_hash = self.accounts[self.cursor_pos.account].hash;
|
|
|
|
|
self.cursor_pos.menu = MenuEntryCursor::Mailbox(*idx);
|
|
|
|
|
self.status = None;
|
|
|
|
|
self.component
|
|
|
|
|
.process_event(&mut UIEvent::VisibilityChange(false), context);
|
|
|
|
@ -1389,13 +1395,13 @@ impl Component for Listing {
|
|
|
|
|
};
|
|
|
|
|
let target = match k {
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["next_mailbox"]) => {
|
|
|
|
|
match self.cursor_pos.1 {
|
|
|
|
|
match self.cursor_pos.menu {
|
|
|
|
|
MenuEntryCursor::Status => amount.saturating_sub(1),
|
|
|
|
|
MenuEntryCursor::Mailbox(idx) => idx + amount,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["prev_mailbox"]) => {
|
|
|
|
|
match self.cursor_pos.1 {
|
|
|
|
|
match self.cursor_pos.menu {
|
|
|
|
|
MenuEntryCursor::Status => {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -1410,12 +1416,12 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
_ => return true,
|
|
|
|
|
};
|
|
|
|
|
if self.accounts[self.cursor_pos.0]
|
|
|
|
|
if self.accounts[self.cursor_pos.account]
|
|
|
|
|
.entries
|
|
|
|
|
.get(target)
|
|
|
|
|
.is_some()
|
|
|
|
|
{
|
|
|
|
|
self.cursor_pos.1 = MenuEntryCursor::Mailbox(target)
|
|
|
|
|
self.cursor_pos.menu = MenuEntryCursor::Mailbox(target)
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -1445,17 +1451,17 @@ impl Component for Listing {
|
|
|
|
|
};
|
|
|
|
|
match k {
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["next_account"]) => {
|
|
|
|
|
if self.cursor_pos.0 + amount < self.accounts.len() {
|
|
|
|
|
self.cursor_pos =
|
|
|
|
|
(self.cursor_pos.0 + amount, MenuEntryCursor::Mailbox(0));
|
|
|
|
|
if self.cursor_pos.account + amount < self.accounts.len() {
|
|
|
|
|
self.cursor_pos.account += amount;
|
|
|
|
|
self.cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["prev_account"]) => {
|
|
|
|
|
if self.cursor_pos.0 >= amount {
|
|
|
|
|
self.cursor_pos =
|
|
|
|
|
(self.cursor_pos.0 - amount, MenuEntryCursor::Mailbox(0));
|
|
|
|
|
if self.cursor_pos.account >= amount {
|
|
|
|
|
self.cursor_pos.account -= amount;
|
|
|
|
|
self.cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -1513,7 +1519,7 @@ impl Component for Listing {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
Action::Listing(ListingAction::Import(file_path, mailbox_path)) => {
|
|
|
|
|
let account = &mut context.accounts[self.cursor_pos.0];
|
|
|
|
|
let account = &mut context.accounts[self.cursor_pos.account];
|
|
|
|
|
if let Err(err) = account
|
|
|
|
|
.mailbox_by_path(mailbox_path)
|
|
|
|
|
.and_then(|mailbox_hash| {
|
|
|
|
@ -1678,8 +1684,8 @@ impl Component for Listing {
|
|
|
|
|
UIEvent::Input(ref key)
|
|
|
|
|
if shortcut!(key == shortcuts[Shortcuts::LISTING]["refresh"]) =>
|
|
|
|
|
{
|
|
|
|
|
let account = &mut context.accounts[self.cursor_pos.0];
|
|
|
|
|
if let MenuEntryCursor::Mailbox(idx) = self.cursor_pos.1 {
|
|
|
|
|
let account = &mut context.accounts[self.cursor_pos.account];
|
|
|
|
|
if let MenuEntryCursor::Mailbox(idx) = self.cursor_pos.menu {
|
|
|
|
|
if let Some(&mailbox_hash) = account.mailboxes_order.get(idx) {
|
|
|
|
|
if let Err(err) = account.refresh(mailbox_hash) {
|
|
|
|
|
context.replies.push_back(UIEvent::Notification(
|
|
|
|
@ -1753,10 +1759,10 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Input(ref k)
|
|
|
|
|
if shortcut!(k == shortcuts[Shortcuts::LISTING]["open_mailbox"])
|
|
|
|
|
&& self.menu_cursor_pos.1 == MenuEntryCursor::Status =>
|
|
|
|
|
&& self.menu_cursor_pos.menu == MenuEntryCursor::Status =>
|
|
|
|
|
{
|
|
|
|
|
self.cursor_pos = self.menu_cursor_pos;
|
|
|
|
|
self.open_status(self.menu_cursor_pos.0, context);
|
|
|
|
|
self.open_status(self.menu_cursor_pos.account, context);
|
|
|
|
|
self.set_dirty(true);
|
|
|
|
|
self.focus = ListingFocus::Mailbox;
|
|
|
|
|
self.ratio = self.prev_ratio;
|
|
|
|
@ -1769,15 +1775,15 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Input(ref k)
|
|
|
|
|
if shortcut!(k == shortcuts[Shortcuts::LISTING]["toggle_mailbox_collapse"])
|
|
|
|
|
&& matches!(self.menu_cursor_pos.1, MenuEntryCursor::Mailbox(_)) =>
|
|
|
|
|
&& matches!(self.menu_cursor_pos.menu, MenuEntryCursor::Mailbox(_)) =>
|
|
|
|
|
{
|
|
|
|
|
let target_mailbox_idx =
|
|
|
|
|
if let MenuEntryCursor::Mailbox(idx) = self.menu_cursor_pos.1 {
|
|
|
|
|
if let MenuEntryCursor::Mailbox(idx) = self.menu_cursor_pos.menu {
|
|
|
|
|
idx
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
if let Some(target) = self.accounts[self.menu_cursor_pos.0]
|
|
|
|
|
if let Some(target) = self.accounts[self.menu_cursor_pos.account]
|
|
|
|
|
.entries
|
|
|
|
|
.get_mut(target_mailbox_idx)
|
|
|
|
|
{
|
|
|
|
@ -1837,35 +1843,30 @@ impl Component for Listing {
|
|
|
|
|
if shortcut!(k == shortcuts[Shortcuts::LISTING]["scroll_up"]) {
|
|
|
|
|
while amount > 0 {
|
|
|
|
|
match self.menu_cursor_pos {
|
|
|
|
|
(
|
|
|
|
|
ref mut account_cursor,
|
|
|
|
|
ref mut entry_cursor @ MenuEntryCursor::Status,
|
|
|
|
|
) => {
|
|
|
|
|
if *account_cursor > 0 {
|
|
|
|
|
*account_cursor -= 1;
|
|
|
|
|
*entry_cursor = MenuEntryCursor::Mailbox(
|
|
|
|
|
self.accounts[*account_cursor]
|
|
|
|
|
.entries
|
|
|
|
|
.len()
|
|
|
|
|
.saturating_sub(1),
|
|
|
|
|
CursorPos {
|
|
|
|
|
ref mut account,
|
|
|
|
|
menu: MenuEntryCursor::Status,
|
|
|
|
|
} => {
|
|
|
|
|
if *account > 0 {
|
|
|
|
|
*account -= 1;
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(
|
|
|
|
|
self.accounts[*account].entries.len().saturating_sub(1),
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
(
|
|
|
|
|
ref account_cursor,
|
|
|
|
|
MenuEntryCursor::Mailbox(ref mut mailbox_idx),
|
|
|
|
|
) => loop {
|
|
|
|
|
CursorPos {
|
|
|
|
|
ref account,
|
|
|
|
|
menu: MenuEntryCursor::Mailbox(ref mut mailbox_idx),
|
|
|
|
|
} => loop {
|
|
|
|
|
if *mailbox_idx > 0 {
|
|
|
|
|
*mailbox_idx -= 1;
|
|
|
|
|
if self.accounts[*account_cursor].entries[*mailbox_idx]
|
|
|
|
|
.visible
|
|
|
|
|
{
|
|
|
|
|
if self.accounts[*account].entries[*mailbox_idx].visible {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
self.menu_cursor_pos.1 = MenuEntryCursor::Status;
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Status;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
@ -1877,41 +1878,44 @@ impl Component for Listing {
|
|
|
|
|
while amount > 0 {
|
|
|
|
|
match self.menu_cursor_pos {
|
|
|
|
|
/* If current account has mailboxes, go to first mailbox */
|
|
|
|
|
(
|
|
|
|
|
ref account_cursor,
|
|
|
|
|
ref mut entry_cursor @ MenuEntryCursor::Status,
|
|
|
|
|
) if !self.accounts[*account_cursor].entries.is_empty() => {
|
|
|
|
|
*entry_cursor = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
CursorPos {
|
|
|
|
|
ref account,
|
|
|
|
|
ref mut menu,
|
|
|
|
|
} if !self.accounts[*account].entries.is_empty()
|
|
|
|
|
&& *menu == MenuEntryCursor::Status =>
|
|
|
|
|
{
|
|
|
|
|
*menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
}
|
|
|
|
|
/* If current account has no mailboxes, go to next account */
|
|
|
|
|
(
|
|
|
|
|
ref mut account_cursor,
|
|
|
|
|
ref mut entry_cursor @ MenuEntryCursor::Status,
|
|
|
|
|
) if *account_cursor + 1 < self.accounts.len() => {
|
|
|
|
|
*account_cursor += 1;
|
|
|
|
|
*entry_cursor = MenuEntryCursor::Status;
|
|
|
|
|
CursorPos {
|
|
|
|
|
ref mut account,
|
|
|
|
|
ref mut menu,
|
|
|
|
|
} if *account + 1 < self.accounts.len()
|
|
|
|
|
&& *menu == MenuEntryCursor::Status =>
|
|
|
|
|
{
|
|
|
|
|
*account += 1;
|
|
|
|
|
*menu = MenuEntryCursor::Status;
|
|
|
|
|
}
|
|
|
|
|
/* If current account has no mailboxes and there is no next
|
|
|
|
|
* account, return true */
|
|
|
|
|
(_, MenuEntryCursor::Status) => {
|
|
|
|
|
CursorPos {
|
|
|
|
|
menu: MenuEntryCursor::Status,
|
|
|
|
|
..
|
|
|
|
|
} => {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
(
|
|
|
|
|
ref mut account_cursor,
|
|
|
|
|
MenuEntryCursor::Mailbox(ref mut mailbox_idx),
|
|
|
|
|
) => loop {
|
|
|
|
|
if (*mailbox_idx + 1)
|
|
|
|
|
< self.accounts[*account_cursor].entries.len()
|
|
|
|
|
{
|
|
|
|
|
CursorPos {
|
|
|
|
|
ref mut account,
|
|
|
|
|
menu: MenuEntryCursor::Mailbox(ref mut mailbox_idx),
|
|
|
|
|
} => loop {
|
|
|
|
|
if (*mailbox_idx + 1) < self.accounts[*account].entries.len() {
|
|
|
|
|
*mailbox_idx += 1;
|
|
|
|
|
if self.accounts[*account_cursor].entries[*mailbox_idx]
|
|
|
|
|
.visible
|
|
|
|
|
{
|
|
|
|
|
if self.accounts[*account].entries[*mailbox_idx].visible {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else if *account_cursor + 1 < self.accounts.len() {
|
|
|
|
|
*account_cursor += 1;
|
|
|
|
|
self.menu_cursor_pos.1 = MenuEntryCursor::Status;
|
|
|
|
|
} else if *account + 1 < self.accounts.len() {
|
|
|
|
|
*account += 1;
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Status;
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
@ -1953,13 +1957,13 @@ impl Component for Listing {
|
|
|
|
|
};
|
|
|
|
|
let target = match k {
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["next_mailbox"]) => {
|
|
|
|
|
match self.menu_cursor_pos.1 {
|
|
|
|
|
match self.menu_cursor_pos.menu {
|
|
|
|
|
MenuEntryCursor::Status => amount.saturating_sub(1),
|
|
|
|
|
MenuEntryCursor::Mailbox(idx) => idx + amount,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["prev_mailbox"]) => {
|
|
|
|
|
match self.menu_cursor_pos.1 {
|
|
|
|
|
match self.menu_cursor_pos.menu {
|
|
|
|
|
MenuEntryCursor::Status => {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -1974,12 +1978,12 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
_ => return true,
|
|
|
|
|
};
|
|
|
|
|
if self.accounts[self.menu_cursor_pos.0]
|
|
|
|
|
if self.accounts[self.menu_cursor_pos.account]
|
|
|
|
|
.entries
|
|
|
|
|
.get(target)
|
|
|
|
|
.is_some()
|
|
|
|
|
{
|
|
|
|
|
self.menu_cursor_pos.1 = MenuEntryCursor::Mailbox(target)
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(target)
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -2017,9 +2021,9 @@ impl Component for Listing {
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["next_account"])
|
|
|
|
|
|| shortcut!(k == shortcuts[Shortcuts::LISTING]["next_page"]) =>
|
|
|
|
|
{
|
|
|
|
|
if self.menu_cursor_pos.0 + amount < self.accounts.len() {
|
|
|
|
|
self.menu_cursor_pos =
|
|
|
|
|
(self.menu_cursor_pos.0 + amount, MenuEntryCursor::Mailbox(0));
|
|
|
|
|
if self.menu_cursor_pos.account + amount < self.accounts.len() {
|
|
|
|
|
self.menu_cursor_pos.account += amount;
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -2027,9 +2031,9 @@ impl Component for Listing {
|
|
|
|
|
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["prev_account"])
|
|
|
|
|
|| shortcut!(k == shortcuts[Shortcuts::LISTING]["prev_page"]) =>
|
|
|
|
|
{
|
|
|
|
|
if self.menu_cursor_pos.0 >= amount {
|
|
|
|
|
self.menu_cursor_pos =
|
|
|
|
|
(self.menu_cursor_pos.0 - amount, MenuEntryCursor::Mailbox(0));
|
|
|
|
|
if self.menu_cursor_pos.account >= amount {
|
|
|
|
|
self.menu_cursor_pos.account -= amount;
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -2045,12 +2049,75 @@ impl Component for Listing {
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Input(ref key) if *key == Key::Home => {
|
|
|
|
|
if matches!(
|
|
|
|
|
self.menu_cursor_pos,
|
|
|
|
|
CursorPos {
|
|
|
|
|
account: 0,
|
|
|
|
|
menu: MenuEntryCursor::Mailbox(0)
|
|
|
|
|
}
|
|
|
|
|
) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if self.menu_cursor_pos.menu == MenuEntryCursor::Mailbox(0) {
|
|
|
|
|
self.menu_cursor_pos.account = 0;
|
|
|
|
|
} else {
|
|
|
|
|
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
}
|
|
|
|
|
if self.show_menu_scrollbar != ShowMenuScrollbar::Never {
|
|
|
|
|
self.menu_scrollbar_show_timer.rearm();
|
|
|
|
|
self.show_menu_scrollbar = ShowMenuScrollbar::True;
|
|
|
|
|
}
|
|
|
|
|
self.menu_content.empty();
|
|
|
|
|
self.set_dirty(true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Input(ref key) if *key == Key::End => {
|
|
|
|
|
let CursorPos {
|
|
|
|
|
ref mut account,
|
|
|
|
|
ref mut menu,
|
|
|
|
|
} = self.menu_cursor_pos;
|
|
|
|
|
if matches!(
|
|
|
|
|
(*account, *menu),
|
|
|
|
|
(a, MenuEntryCursor::Mailbox(
|
|
|
|
|
i
|
|
|
|
|
)) if a == self.accounts.len().saturating_sub(1) && i ==
|
|
|
|
|
self.accounts[*account].entries.len().saturating_sub(1)
|
|
|
|
|
) {
|
|
|
|
|
// Do nothing, this is the End.
|
|
|
|
|
// "Father?"
|
|
|
|
|
// "Yes, son?"
|
|
|
|
|
// "I want to kill you"
|
|
|
|
|
// "Come on, baby"
|
|
|
|
|
return true;
|
|
|
|
|
} else if matches!(
|
|
|
|
|
*menu,
|
|
|
|
|
MenuEntryCursor::Mailbox(
|
|
|
|
|
i
|
|
|
|
|
) if i ==
|
|
|
|
|
self.accounts[*account].entries.len().saturating_sub(1)
|
|
|
|
|
) {
|
|
|
|
|
*account = self.accounts.len().saturating_sub(1);
|
|
|
|
|
*menu = MenuEntryCursor::Mailbox(0);
|
|
|
|
|
} else {
|
|
|
|
|
*menu = MenuEntryCursor::Mailbox(
|
|
|
|
|
self.accounts[*account].entries.len().saturating_sub(1),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if self.show_menu_scrollbar != ShowMenuScrollbar::Never {
|
|
|
|
|
self.menu_scrollbar_show_timer.rearm();
|
|
|
|
|
self.show_menu_scrollbar = ShowMenuScrollbar::True;
|
|
|
|
|
}
|
|
|
|
|
self.menu_content.empty();
|
|
|
|
|
self.set_dirty(true);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
match *event {
|
|
|
|
|
UIEvent::Input(ref k) if shortcut!(k == shortcuts[Shortcuts::LISTING]["new_mail"]) => {
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.account].hash();
|
|
|
|
|
let composer = Composer::with_account(account_hash, context);
|
|
|
|
|
context
|
|
|
|
|
.replies
|
|
|
|
@ -2058,7 +2125,7 @@ impl Component for Listing {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Action(Action::Tab(ManageMailboxes)) => {
|
|
|
|
|
let account_pos = self.cursor_pos.0;
|
|
|
|
|
let account_pos = self.cursor_pos.account;
|
|
|
|
|
let mgr = MailboxManager::new(context, account_pos);
|
|
|
|
|
context
|
|
|
|
|
.replies
|
|
|
|
@ -2073,7 +2140,7 @@ impl Component for Listing {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
UIEvent::Action(Action::Compose(ComposeAction::Mailto(ref mailto))) => {
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.account].hash();
|
|
|
|
|
let mut composer = Composer::with_account(account_hash, context);
|
|
|
|
|
composer.set_draft(mailto.into(), context);
|
|
|
|
|
context
|
|
|
|
@ -2177,10 +2244,10 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn status(&self, context: &Context) -> String {
|
|
|
|
|
let mailbox_hash = match self.cursor_pos.1 {
|
|
|
|
|
let mailbox_hash = match self.cursor_pos.menu {
|
|
|
|
|
MenuEntryCursor::Mailbox(idx) => {
|
|
|
|
|
if let Some(MailboxMenuEntry { mailbox_hash, .. }) =
|
|
|
|
|
self.accounts[self.cursor_pos.0].entries.get(idx)
|
|
|
|
|
self.accounts[self.cursor_pos.account].entries.get(idx)
|
|
|
|
|
{
|
|
|
|
|
*mailbox_hash
|
|
|
|
|
} else {
|
|
|
|
@ -2188,11 +2255,11 @@ impl Component for Listing {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
MenuEntryCursor::Status => {
|
|
|
|
|
return format!("{} status", &self.accounts[self.cursor_pos.0].name)
|
|
|
|
|
return format!("{} status", &self.accounts[self.cursor_pos.account].name)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let account = &context.accounts[self.cursor_pos.0];
|
|
|
|
|
let account = &context.accounts[self.cursor_pos.account];
|
|
|
|
|
use crate::conf::accounts::MailboxStatus;
|
|
|
|
|
match account[&mailbox_hash].status {
|
|
|
|
|
MailboxStatus::Available | MailboxStatus::Parsing(_, _) => {
|
|
|
|
@ -2289,8 +2356,14 @@ impl Listing {
|
|
|
|
|
accounts: account_entries,
|
|
|
|
|
status: None,
|
|
|
|
|
dirty: true,
|
|
|
|
|
cursor_pos: (0, MenuEntryCursor::Mailbox(0)),
|
|
|
|
|
menu_cursor_pos: (0, MenuEntryCursor::Mailbox(0)),
|
|
|
|
|
cursor_pos: CursorPos {
|
|
|
|
|
account: 0,
|
|
|
|
|
menu: MenuEntryCursor::Mailbox(0),
|
|
|
|
|
},
|
|
|
|
|
menu_cursor_pos: CursorPos {
|
|
|
|
|
account: 0,
|
|
|
|
|
menu: MenuEntryCursor::Mailbox(0),
|
|
|
|
|
},
|
|
|
|
|
menu_content: CellBuffer::new_with_context(0, 0, None, context),
|
|
|
|
|
menu_scrollbar_show_timer: context.main_loop_handler.job_executor.clone().create_timer(
|
|
|
|
|
std::time::Duration::from_secs(0),
|
|
|
|
@ -2350,14 +2423,14 @@ impl Listing {
|
|
|
|
|
let rows = height!(area);
|
|
|
|
|
let (width, height) = self.menu_content.size();
|
|
|
|
|
const SCROLLING_CONTEXT: usize = 3;
|
|
|
|
|
let y_offset = (cursor.0)
|
|
|
|
|
let y_offset = (cursor.account)
|
|
|
|
|
+ self
|
|
|
|
|
.accounts
|
|
|
|
|
.iter()
|
|
|
|
|
.take(cursor.0)
|
|
|
|
|
.take(cursor.account)
|
|
|
|
|
.map(|entry| entry.entries.len() + 1)
|
|
|
|
|
.sum::<usize>()
|
|
|
|
|
+ match cursor.1 {
|
|
|
|
|
+ match cursor.menu {
|
|
|
|
|
MenuEntryCursor::Status => 0,
|
|
|
|
|
MenuEntryCursor::Mailbox(idx) => idx + 1,
|
|
|
|
|
}
|
|
|
|
@ -2452,7 +2525,7 @@ impl Listing {
|
|
|
|
|
ListingFocus::Menu => self.menu_cursor_pos,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let must_highlight_account: bool = cursor.0 == self.accounts[aidx].index;
|
|
|
|
|
let must_highlight_account: bool = cursor.account == self.accounts[aidx].index;
|
|
|
|
|
|
|
|
|
|
let mut lines: Vec<Line> = Vec::new();
|
|
|
|
|
|
|
|
|
@ -2499,7 +2572,7 @@ impl Listing {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let account_attrs = if must_highlight_account {
|
|
|
|
|
if cursor.1 == MenuEntryCursor::Status {
|
|
|
|
|
if cursor.menu == MenuEntryCursor::Status {
|
|
|
|
|
let mut v = crate::conf::value(context, "mail.sidebar_highlighted");
|
|
|
|
|
if !context.settings.terminal.use_color() {
|
|
|
|
|
v.attrs |= Attr::REVERSE;
|
|
|
|
@ -2579,7 +2652,7 @@ impl Listing {
|
|
|
|
|
l.collapsed_count = Some(counter);
|
|
|
|
|
}
|
|
|
|
|
let (att, index_att, unread_count_att) = if must_highlight_account {
|
|
|
|
|
if match cursor.1 {
|
|
|
|
|
if match cursor.menu {
|
|
|
|
|
MenuEntryCursor::Mailbox(c) => c == idx,
|
|
|
|
|
_ => false,
|
|
|
|
|
} {
|
|
|
|
@ -2675,7 +2748,7 @@ impl Listing {
|
|
|
|
|
{
|
|
|
|
|
format!(
|
|
|
|
|
"{:>width$}",
|
|
|
|
|
(l.inc - cursor.1).abs(),
|
|
|
|
|
(l.inc - cursor.menu).abs(),
|
|
|
|
|
width = total_mailbox_no_digits
|
|
|
|
|
)
|
|
|
|
|
} else {
|
|
|
|
@ -2777,8 +2850,9 @@ impl Listing {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn change_account(&mut self, context: &mut Context) {
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
|
|
|
|
let previous_collapsed_mailboxes: BTreeSet<MailboxHash> = self.accounts[self.cursor_pos.0]
|
|
|
|
|
let account_hash = context.accounts[self.cursor_pos.account].hash();
|
|
|
|
|
let previous_collapsed_mailboxes: BTreeSet<MailboxHash> = self.accounts
|
|
|
|
|
[self.cursor_pos.account]
|
|
|
|
|
.entries
|
|
|
|
|
.iter()
|
|
|
|
|
.filter_map(|e| {
|
|
|
|
@ -2789,11 +2863,11 @@ impl Listing {
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
.collect::<_>();
|
|
|
|
|
self.accounts[self.cursor_pos.0].entries = context.accounts[self.cursor_pos.0]
|
|
|
|
|
self.accounts[self.cursor_pos.account].entries = context.accounts[self.cursor_pos.account]
|
|
|
|
|
.list_mailboxes()
|
|
|
|
|
.into_iter()
|
|
|
|
|
.filter(|mailbox_node| {
|
|
|
|
|
context.accounts[self.cursor_pos.0][&mailbox_node.hash]
|
|
|
|
|
context.accounts[self.cursor_pos.account][&mailbox_node.hash]
|
|
|
|
|
.ref_mailbox
|
|
|
|
|
.is_subscribed()
|
|
|
|
|
})
|
|
|
|
@ -2804,17 +2878,19 @@ impl Listing {
|
|
|
|
|
mailbox_hash: f.hash,
|
|
|
|
|
visible: true,
|
|
|
|
|
collapsed: if previous_collapsed_mailboxes.is_empty() {
|
|
|
|
|
context.accounts[self.cursor_pos.0][&f.hash].conf.collapsed
|
|
|
|
|
context.accounts[self.cursor_pos.account][&f.hash]
|
|
|
|
|
.conf
|
|
|
|
|
.collapsed
|
|
|
|
|
} else {
|
|
|
|
|
previous_collapsed_mailboxes.contains(&f.hash)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
.collect::<_>();
|
|
|
|
|
match self.cursor_pos.1 {
|
|
|
|
|
match self.cursor_pos.menu {
|
|
|
|
|
MenuEntryCursor::Mailbox(idx) => {
|
|
|
|
|
/* Account might have no mailboxes yet if it's offline */
|
|
|
|
|
if let Some(MailboxMenuEntry { mailbox_hash, .. }) =
|
|
|
|
|
self.accounts[self.cursor_pos.0].entries.get(idx)
|
|
|
|
|
self.accounts[self.cursor_pos.account].entries.get(idx)
|
|
|
|
|
{
|
|
|
|
|
self.component
|
|
|
|
|
.process_event(&mut UIEvent::VisibilityChange(false), context);
|
|
|
|
@ -2840,7 +2916,7 @@ impl Listing {
|
|
|
|
|
)));
|
|
|
|
|
}
|
|
|
|
|
MenuEntryCursor::Status => {
|
|
|
|
|
self.open_status(self.cursor_pos.0, context);
|
|
|
|
|
self.open_status(self.cursor_pos.account, context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
self.sidebar_divider = *account_settings!(context[account_hash].listing.sidebar_divider);
|
|
|
|
|