listing/offline.rs: add in-progress messages while connecting in IMAP
parent
9cbbf71e0f
commit
388d4e35d6
|
@ -57,18 +57,17 @@ use self::maildir::MaildirType;
|
||||||
#[cfg(feature = "mbox_backend")]
|
#[cfg(feature = "mbox_backend")]
|
||||||
use self::mbox::MboxType;
|
use self::mbox::MboxType;
|
||||||
use super::email::{Envelope, EnvelopeHash, Flag};
|
use super::email::{Envelope, EnvelopeHash, Flag};
|
||||||
|
use futures::stream::Stream;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::Deref;
|
|
||||||
use std::sync::{Arc, RwLock};
|
|
||||||
|
|
||||||
use futures::stream::Stream;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::sync::{Arc, RwLock};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! get_path_hash {
|
macro_rules! get_path_hash {
|
||||||
|
@ -265,6 +264,9 @@ pub enum BackendEvent {
|
||||||
level: crate::LoggingLevel,
|
level: crate::LoggingLevel,
|
||||||
},
|
},
|
||||||
Refresh(RefreshEvent),
|
Refresh(RefreshEvent),
|
||||||
|
AccountStateChange {
|
||||||
|
message: Cow<'static, str>,
|
||||||
|
},
|
||||||
//Job(Box<Future<Output = Result<()>> + Send + 'static>)
|
//Job(Box<Future<Output = Result<()>> + Send + 'static>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,12 +115,19 @@ pub struct ImapConnection {
|
||||||
impl ImapStream {
|
impl ImapStream {
|
||||||
pub async fn new_connection(
|
pub async fn new_connection(
|
||||||
server_conf: &ImapServerConf,
|
server_conf: &ImapServerConf,
|
||||||
|
uid_store: &UIDStore,
|
||||||
) -> Result<(Capabilities, ImapStream)> {
|
) -> Result<(Capabilities, ImapStream)> {
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
let path = &server_conf.server_hostname;
|
let path = &server_conf.server_hostname;
|
||||||
|
|
||||||
let cmd_id = 1;
|
let cmd_id = 1;
|
||||||
let stream = if server_conf.use_tls {
|
let stream = if server_conf.use_tls {
|
||||||
|
(uid_store.event_consumer)(
|
||||||
|
uid_store.account_hash,
|
||||||
|
crate::backends::BackendEvent::AccountStateChange {
|
||||||
|
message: "Establishing TLS connection.".into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
let mut connector = TlsConnector::builder();
|
let mut connector = TlsConnector::builder();
|
||||||
if server_conf.danger_accept_invalid_certs {
|
if server_conf.danger_accept_invalid_certs {
|
||||||
connector.danger_accept_invalid_certs(true);
|
connector.danger_accept_invalid_certs(true);
|
||||||
|
@ -312,6 +319,12 @@ impl ImapStream {
|
||||||
return Ok((Default::default(), ret));
|
return Ok((Default::default(), ret));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(uid_store.event_consumer)(
|
||||||
|
uid_store.account_hash,
|
||||||
|
crate::backends::BackendEvent::AccountStateChange {
|
||||||
|
message: "Negotiating server capabilities.".into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
ret.send_command(b"CAPABILITY").await?;
|
ret.send_command(b"CAPABILITY").await?;
|
||||||
ret.read_response(&mut res).await?;
|
ret.read_response(&mut res).await?;
|
||||||
let capabilities: std::result::Result<Vec<&[u8]>, _> = res
|
let capabilities: std::result::Result<Vec<&[u8]>, _> = res
|
||||||
|
@ -353,6 +366,12 @@ impl ImapStream {
|
||||||
.set_err_kind(crate::error::ErrorKind::Authentication));
|
.set_err_kind(crate::error::ErrorKind::Authentication));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(uid_store.event_consumer)(
|
||||||
|
uid_store.account_hash,
|
||||||
|
crate::backends::BackendEvent::AccountStateChange {
|
||||||
|
message: "Attempting authentication.".into(),
|
||||||
|
},
|
||||||
|
);
|
||||||
match server_conf.protocol {
|
match server_conf.protocol {
|
||||||
ImapProtocol::IMAP {
|
ImapProtocol::IMAP {
|
||||||
extension_use: ImapExtensionUse { oauth2, .. },
|
extension_use: ImapExtensionUse { oauth2, .. },
|
||||||
|
@ -601,7 +620,11 @@ impl ImapConnection {
|
||||||
if SystemTime::now().duration_since(time).unwrap_or_default()
|
if SystemTime::now().duration_since(time).unwrap_or_default()
|
||||||
>= IMAP_PROTOCOL_TIMEOUT
|
>= IMAP_PROTOCOL_TIMEOUT
|
||||||
{
|
{
|
||||||
let err = MeliError::new("Connection timed out").set_kind(ErrorKind::Timeout);
|
let err = MeliError::new(format!(
|
||||||
|
"Connection timed out after {} seconds",
|
||||||
|
IMAP_PROTOCOL_TIMEOUT.as_secs()
|
||||||
|
))
|
||||||
|
.set_kind(ErrorKind::Timeout);
|
||||||
*status = Err(err.clone());
|
*status = Err(err.clone());
|
||||||
self.stream = Err(err);
|
self.stream = Err(err);
|
||||||
}
|
}
|
||||||
|
@ -624,7 +647,7 @@ impl ImapConnection {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let new_stream = ImapStream::new_connection(&self.server_conf).await;
|
let new_stream = ImapStream::new_connection(&self.server_conf, &self.uid_store).await;
|
||||||
if let Err(err) = new_stream.as_ref() {
|
if let Err(err) = new_stream.as_ref() {
|
||||||
self.uid_store.is_online.lock().unwrap().1 = Err(err.clone());
|
self.uid_store.is_online.lock().unwrap().1 = Err(err.clone());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -206,7 +206,7 @@ impl MeliError {
|
||||||
|
|
||||||
impl fmt::Display for MeliError {
|
impl fmt::Display for MeliError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
writeln!(f, "Summary: {}", self.summary)?;
|
writeln!(f, "{}", self.summary)?;
|
||||||
if let Some(details) = self.details.as_ref() {
|
if let Some(details) = self.details.as_ref() {
|
||||||
write!(f, "{}", details)?;
|
write!(f, "{}", details)?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -703,13 +703,10 @@ impl Component for Listing {
|
||||||
|
|
||||||
let account_hash = self.accounts[self.cursor_pos.0].hash;
|
let account_hash = self.accounts[self.cursor_pos.0].hash;
|
||||||
if right_component_width == total_cols {
|
if right_component_width == total_cols {
|
||||||
if context.is_online(account_hash).is_err() {
|
if context.is_online(account_hash).is_err()
|
||||||
match self.component {
|
&& !matches!(self.component, ListingComponent::Offline(_))
|
||||||
ListingComponent::Offline(_) => {}
|
{
|
||||||
_ => {
|
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
||||||
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(s) = self.status.as_mut() {
|
if let Some(s) = self.status.as_mut() {
|
||||||
|
@ -725,13 +722,10 @@ impl Component for Listing {
|
||||||
(upper_left, (mid.saturating_sub(1), get_y(bottom_right))),
|
(upper_left, (mid.saturating_sub(1), get_y(bottom_right))),
|
||||||
context,
|
context,
|
||||||
);
|
);
|
||||||
if context.is_online(account_hash).is_err() {
|
if context.is_online(account_hash).is_err()
|
||||||
match self.component {
|
&& !matches!(self.component, ListingComponent::Offline(_))
|
||||||
ListingComponent::Offline(_) => {}
|
{
|
||||||
_ => {
|
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
||||||
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if let Some(s) = self.status.as_mut() {
|
if let Some(s) = self.status.as_mut() {
|
||||||
s.draw(grid, (set_x(upper_left, mid + 1), bottom_right), context);
|
s.draw(grid, (set_x(upper_left, mid + 1), bottom_right), context);
|
||||||
|
@ -776,7 +770,7 @@ impl Component for Listing {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UIEvent::AccountStatusChange(account_hash) => {
|
UIEvent::AccountStatusChange(account_hash, msg) => {
|
||||||
let account_index: usize = context
|
let account_index: usize = context
|
||||||
.accounts
|
.accounts
|
||||||
.get_index_of(account_hash)
|
.get_index_of(account_hash)
|
||||||
|
@ -821,11 +815,11 @@ impl Component for Listing {
|
||||||
self.menu_content.empty();
|
self.menu_content.empty();
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::UpdateStatus(
|
.push_back(UIEvent::StatusEvent(StatusEvent::UpdateStatus(match msg {
|
||||||
self.get_status(context),
|
Some(msg) => format!("{} {}", self.get_status(context), msg),
|
||||||
)));
|
None => self.get_status(context),
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
UIEvent::MailboxDelete((account_hash, mailbox_hash))
|
UIEvent::MailboxDelete((account_hash, mailbox_hash))
|
||||||
| UIEvent::MailboxCreate((account_hash, mailbox_hash)) => {
|
| UIEvent::MailboxCreate((account_hash, mailbox_hash)) => {
|
||||||
|
@ -2348,8 +2342,7 @@ impl Listing {
|
||||||
let index_style =
|
let index_style =
|
||||||
mailbox_settings!(context[account_hash][mailbox_hash].listing.index_style);
|
mailbox_settings!(context[account_hash][mailbox_hash].listing.index_style);
|
||||||
self.component.set_style(*index_style);
|
self.component.set_style(*index_style);
|
||||||
} else {
|
} else if !matches!(self.component, ListingComponent::Offline(_)) {
|
||||||
/* Set to dummy */
|
|
||||||
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
self.component = Offline(OfflineListing::new((account_hash, 0)));
|
||||||
}
|
}
|
||||||
self.status = None;
|
self.status = None;
|
||||||
|
|
|
@ -21,12 +21,14 @@
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::components::PageMovement;
|
use crate::components::PageMovement;
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OfflineListing {
|
pub struct OfflineListing {
|
||||||
cursor_pos: (AccountHash, MailboxHash),
|
cursor_pos: (AccountHash, MailboxHash),
|
||||||
_row_updates: SmallVec<[ThreadHash; 8]>,
|
_row_updates: SmallVec<[ThreadHash; 8]>,
|
||||||
_selection: HashMap<ThreadHash, bool>,
|
_selection: HashMap<ThreadHash, bool>,
|
||||||
|
messages: Vec<Cow<'static, str>>,
|
||||||
dirty: bool,
|
dirty: bool,
|
||||||
id: ComponentId,
|
id: ComponentId,
|
||||||
}
|
}
|
||||||
|
@ -104,6 +106,7 @@ impl OfflineListing {
|
||||||
cursor_pos,
|
cursor_pos,
|
||||||
_row_updates: SmallVec::new(),
|
_row_updates: SmallVec::new(),
|
||||||
_selection: HashMap::default(),
|
_selection: HashMap::default(),
|
||||||
|
messages: vec![],
|
||||||
dirty: true,
|
dirty: true,
|
||||||
id: ComponentId::new_v4(),
|
id: ComponentId::new_v4(),
|
||||||
})
|
})
|
||||||
|
@ -117,26 +120,50 @@ impl Component for OfflineListing {
|
||||||
}
|
}
|
||||||
self.dirty = false;
|
self.dirty = false;
|
||||||
let theme_default = conf::value(context, "theme_default");
|
let theme_default = conf::value(context, "theme_default");
|
||||||
|
let text_unfocused = conf::value(context, "text.unfocused");
|
||||||
|
let error_message = conf::value(context, "error_message");
|
||||||
clear_area(grid, area, theme_default);
|
clear_area(grid, area, theme_default);
|
||||||
if let Err(err) = context.is_online(self.cursor_pos.0) {
|
if let Err(err) = context.is_online(self.cursor_pos.0) {
|
||||||
let (x, _) = write_string_to_grid(
|
let (x, _) = write_string_to_grid(
|
||||||
"offline: ",
|
"offline: ",
|
||||||
grid,
|
grid,
|
||||||
conf::value(context, "error_message").fg,
|
error_message.fg,
|
||||||
conf::value(context, "error_message").bg,
|
error_message.bg,
|
||||||
conf::value(context, "error_message").attrs,
|
error_message.attrs,
|
||||||
area,
|
area,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
write_string_to_grid(
|
write_string_to_grid(
|
||||||
&err.to_string(),
|
&err.to_string(),
|
||||||
grid,
|
grid,
|
||||||
Color::Red,
|
error_message.fg,
|
||||||
theme_default.bg,
|
error_message.bg,
|
||||||
theme_default.attrs,
|
error_message.attrs,
|
||||||
(set_x(upper_left!(area), x + 1), bottom_right!(area)),
|
(set_x(upper_left!(area), x + 1), bottom_right!(area)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
if let Some(msg) = self.messages.last() {
|
||||||
|
write_string_to_grid(
|
||||||
|
msg,
|
||||||
|
grid,
|
||||||
|
text_unfocused.fg,
|
||||||
|
text_unfocused.bg,
|
||||||
|
Attr::BOLD,
|
||||||
|
(pos_inc((0, 1), upper_left!(area)), bottom_right!(area)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (i, msg) in self.messages.iter().rev().skip(1).enumerate() {
|
||||||
|
write_string_to_grid(
|
||||||
|
msg,
|
||||||
|
grid,
|
||||||
|
text_unfocused.fg,
|
||||||
|
text_unfocused.bg,
|
||||||
|
text_unfocused.attrs,
|
||||||
|
(pos_inc((0, 2 + i), upper_left!(area)), bottom_right!(area)),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let (_, mut y) = write_string_to_grid(
|
let (_, mut y) = write_string_to_grid(
|
||||||
"loading...",
|
"loading...",
|
||||||
|
@ -156,9 +183,9 @@ impl Component for OfflineListing {
|
||||||
write_string_to_grid(
|
write_string_to_grid(
|
||||||
&format!("{}: {:?}", job_id, j),
|
&format!("{}: {:?}", job_id, j),
|
||||||
grid,
|
grid,
|
||||||
theme_default.fg,
|
text_unfocused.fg,
|
||||||
theme_default.bg,
|
text_unfocused.bg,
|
||||||
theme_default.attrs,
|
text_unfocused.attrs,
|
||||||
(set_y(upper_left!(area), y + 1), bottom_right!(area)),
|
(set_y(upper_left!(area), y + 1), bottom_right!(area)),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
@ -167,19 +194,26 @@ impl Component for OfflineListing {
|
||||||
|
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::AccountStatusChange(self.cursor_pos.0));
|
.push_back(UIEvent::AccountStatusChange(self.cursor_pos.0, None));
|
||||||
}
|
}
|
||||||
context.dirty_areas.push_back(area);
|
context.dirty_areas.push_back(area);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, _context: &mut Context) -> bool {
|
||||||
match event {
|
match event {
|
||||||
UIEvent::AccountStatusChange(account_hash) if *account_hash == self.cursor_pos.0 => {
|
UIEvent::AccountStatusChange(account_hash, msg)
|
||||||
|
if *account_hash == self.cursor_pos.0 =>
|
||||||
|
{
|
||||||
|
if let Some(msg) = msg.clone() {
|
||||||
|
self.messages.push(msg);
|
||||||
|
}
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_dirty(&self) -> bool {
|
fn is_dirty(&self) -> bool {
|
||||||
self.dirty
|
self.dirty
|
||||||
}
|
}
|
||||||
|
@ -191,6 +225,7 @@ impl Component for OfflineListing {
|
||||||
fn id(&self) -> ComponentId {
|
fn id(&self) -> ComponentId {
|
||||||
self.id
|
self.id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_id(&mut self, id: ComponentId) {
|
fn set_id(&mut self, id: ComponentId) {
|
||||||
self.id = id;
|
self.id = id;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1612,6 +1612,7 @@ impl Account {
|
||||||
self.sender
|
self.sender
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
||||||
self.hash,
|
self.hash,
|
||||||
|
Some("Loaded mailboxes.".into()),
|
||||||
)))
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if let Err(err) = mailboxes.and_then(|mailboxes| self.init(mailboxes)) {
|
if let Err(err) = mailboxes.and_then(|mailboxes| self.init(mailboxes)) {
|
||||||
|
@ -1730,7 +1731,7 @@ impl Account {
|
||||||
if let Ok(Some(is_online)) = handle.chan.try_recv() {
|
if let Ok(Some(is_online)) = handle.chan.try_recv() {
|
||||||
self.sender
|
self.sender
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
||||||
self.hash,
|
self.hash, None,
|
||||||
)))
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if is_online.is_ok() {
|
if is_online.is_ok() {
|
||||||
|
@ -1785,7 +1786,7 @@ impl Account {
|
||||||
self.is_online = Ok(());
|
self.is_online = Ok(());
|
||||||
self.sender
|
self.sender
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
||||||
self.hash,
|
self.hash, None,
|
||||||
)))
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -1805,7 +1806,7 @@ impl Account {
|
||||||
self.is_online = Err(err);
|
self.is_online = Err(err);
|
||||||
self.sender
|
self.sender
|
||||||
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
||||||
self.hash,
|
self.hash, None,
|
||||||
)))
|
)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,10 @@ fn unlink_attrs<'k, 't: 'k>(theme: &'t Theme, mut key: &'k str) -> Attr {
|
||||||
|
|
||||||
const DEFAULT_KEYS: &[&str] = &[
|
const DEFAULT_KEYS: &[&str] = &[
|
||||||
"theme_default",
|
"theme_default",
|
||||||
|
"text.normal",
|
||||||
|
"text.unfocused",
|
||||||
|
"text.error",
|
||||||
|
"text.highlight",
|
||||||
"error_message",
|
"error_message",
|
||||||
"email_header",
|
"email_header",
|
||||||
"highlight",
|
"highlight",
|
||||||
|
@ -1295,11 +1299,22 @@ impl Default for Themes {
|
||||||
light.insert($key.into(), ThemeAttributeInner::default());
|
light.insert($key.into(), ThemeAttributeInner::default());
|
||||||
dark.insert($key.into(), ThemeAttributeInner::default());
|
dark.insert($key.into(), ThemeAttributeInner::default());
|
||||||
};
|
};
|
||||||
|
($key:literal, $copy_from:literal) => {
|
||||||
|
light.insert($key.into(), light[$copy_from].clone());
|
||||||
|
dark.insert($key.into(), dark[$copy_from].clone());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
add!("theme_default", dark = { fg: Color::Default, bg: Color::Default, attrs: Attr::DEFAULT }, light = { fg: Color::Default, bg: Color::Default, attrs: Attr::DEFAULT });
|
add!("theme_default", dark = { fg: Color::Default, bg: Color::Default, attrs: Attr::DEFAULT }, light = { fg: Color::Default, bg: Color::Default, attrs: Attr::DEFAULT });
|
||||||
|
|
||||||
add!("error_message", dark = { fg: Color::Byte(243), bg: Color::Default, attrs: Attr::DEFAULT }, light = { fg: Color::Byte(243), bg: Color::Default, attrs: Attr::DEFAULT });
|
add!("error_message", dark = { fg: Color::Red, bg: "theme_default", attrs: "theme_default" }, light = { fg: Color::Red, bg: "theme_default", attrs: "theme_default" });
|
||||||
|
|
||||||
|
/* text palettes */
|
||||||
|
add!("text.normal", "theme_default");
|
||||||
|
add!("text.unfocused", dark = { fg: Color::GREY, bg: "theme_default", attrs: Attr::DIM }, light = { fg: Color::GREY, bg: "theme_default", attrs: Attr::DIM });
|
||||||
|
add!("text.error", "error_message");
|
||||||
|
add!("text.highlight", dark = { fg: Color::Blue, bg: "theme_default", attrs: Attr::REVERSE }, light = { fg: Color::Blue, bg: "theme_default", attrs: Attr::REVERSE });
|
||||||
|
|
||||||
|
/* rest */
|
||||||
add!("email_header", dark = { fg: Color::Byte(33), bg: Color::Default, attrs: Attr::DEFAULT }, light = { fg: Color::Byte(33), bg: Color::Default, attrs: Attr::DEFAULT });
|
add!("email_header", dark = { fg: Color::Byte(33), bg: Color::Default, attrs: Attr::DEFAULT }, light = { fg: Color::Byte(33), bg: Color::Default, attrs: Attr::DEFAULT });
|
||||||
|
|
||||||
add!("highlight", dark = { fg: Color::Byte(240), bg: Color::Byte(237), attrs: Attr::BOLD }, light = { fg: Color::Byte(240), bg: Color::Byte(237), attrs: Attr::BOLD });
|
add!("highlight", dark = { fg: Color::Byte(240), bg: Color::Byte(237), attrs: Attr::BOLD }, light = { fg: Color::Byte(240), bg: Color::Byte(237), attrs: Attr::BOLD });
|
||||||
|
|
14
src/state.rs
14
src/state.rs
|
@ -145,10 +145,16 @@ impl Context {
|
||||||
}
|
}
|
||||||
accounts[account_pos].watch();
|
accounts[account_pos].watch();
|
||||||
|
|
||||||
replies.push_back(UIEvent::AccountStatusChange(accounts[account_pos].hash()));
|
replies.push_back(UIEvent::AccountStatusChange(
|
||||||
|
accounts[account_pos].hash(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
if ret.is_ok() != was_online {
|
if ret.is_ok() != was_online {
|
||||||
replies.push_back(UIEvent::AccountStatusChange(accounts[account_pos].hash()));
|
replies.push_back(UIEvent::AccountStatusChange(
|
||||||
|
accounts[account_pos].hash(),
|
||||||
|
None,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
@ -1015,6 +1021,10 @@ impl State {
|
||||||
)));
|
)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
UIEvent::BackendEvent(account_hash, BackendEvent::AccountStateChange { message }) => {
|
||||||
|
self.rcv_event(UIEvent::AccountStatusChange(account_hash, Some(message)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
UIEvent::BackendEvent(_, BackendEvent::Refresh(refresh_event)) => {
|
UIEvent::BackendEvent(_, BackendEvent::Refresh(refresh_event)) => {
|
||||||
self.refresh_event(refresh_event);
|
self.refresh_event(refresh_event);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -754,3 +754,267 @@ impl Serialize for Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub use aliases::*;
|
||||||
|
pub mod aliases {
|
||||||
|
use super::Color;
|
||||||
|
|
||||||
|
impl Color {
|
||||||
|
pub const BLACK: Color = Color::Black;
|
||||||
|
pub const MAROON: Color = Color::Byte(1);
|
||||||
|
pub const GREEN: Color = Color::Green;
|
||||||
|
pub const OLIVE: Color = Color::Byte(3);
|
||||||
|
pub const NAVY: Color = Color::Byte(4);
|
||||||
|
pub const PURPLE: Color = Color::Magenta;
|
||||||
|
pub const TEAL: Color = Color::Cyan;
|
||||||
|
pub const SILVER: Color = Color::Byte(7);
|
||||||
|
pub const GREY: Color = Color::Byte(8);
|
||||||
|
pub const RED: Color = Color::Byte(9);
|
||||||
|
pub const LIME: Color = Color::Byte(10);
|
||||||
|
pub const YELLOW: Color = Color::Byte(11);
|
||||||
|
pub const BLUE: Color = Color::Byte(12);
|
||||||
|
pub const FUCHSIA: Color = Color::Byte(13);
|
||||||
|
pub const AQUA: Color = Color::Byte(14);
|
||||||
|
pub const WHITE: Color = Color::Byte(15);
|
||||||
|
pub const GREY0: Color = Color::Byte(16);
|
||||||
|
pub const NAVYBLUE: Color = Color::Byte(17);
|
||||||
|
pub const DARKBLUE: Color = Color::Byte(18);
|
||||||
|
pub const BLUE3: Color = Color::Byte(19);
|
||||||
|
pub const BLUE3_: Color = Color::Byte(20);
|
||||||
|
pub const BLUE1: Color = Color::Byte(21);
|
||||||
|
pub const DARKGREEN: Color = Color::Byte(22);
|
||||||
|
pub const DEEPSKYBLUE4: Color = Color::Byte(23);
|
||||||
|
pub const DEEPSKYBLUE4_: Color = Color::Byte(24);
|
||||||
|
pub const DEEPSKYBLUE4__: Color = Color::Byte(25);
|
||||||
|
pub const DODGERBLUE3: Color = Color::Byte(26);
|
||||||
|
pub const DODGERBLUE2: Color = Color::Byte(27);
|
||||||
|
pub const GREEN4: Color = Color::Byte(28);
|
||||||
|
pub const SPRINGGREEN4: Color = Color::Byte(29);
|
||||||
|
pub const TURQUOISE4: Color = Color::Byte(30);
|
||||||
|
pub const DEEPSKYBLUE3: Color = Color::Byte(31);
|
||||||
|
pub const DEEPSKYBLUE3_: Color = Color::Byte(32);
|
||||||
|
pub const DODGERBLUE1: Color = Color::Byte(33);
|
||||||
|
pub const GREEN3: Color = Color::Byte(34);
|
||||||
|
pub const SPRINGGREEN3: Color = Color::Byte(35);
|
||||||
|
pub const DARKCYAN: Color = Color::Byte(36);
|
||||||
|
pub const LIGHTSEAGREEN: Color = Color::Byte(37);
|
||||||
|
pub const DEEPSKYBLUE2: Color = Color::Byte(38);
|
||||||
|
pub const DEEPSKYBLUE1: Color = Color::Byte(39);
|
||||||
|
pub const GREEN3_: Color = Color::Byte(40);
|
||||||
|
pub const SPRINGGREEN3_: Color = Color::Byte(41);
|
||||||
|
pub const SPRINGGREEN2: Color = Color::Byte(42);
|
||||||
|
pub const CYAN3: Color = Color::Byte(43);
|
||||||
|
pub const DARKTURQUOISE: Color = Color::Byte(44);
|
||||||
|
pub const TURQUOISE2: Color = Color::Byte(45);
|
||||||
|
pub const GREEN1: Color = Color::Byte(46);
|
||||||
|
pub const SPRINGGREEN2_: Color = Color::Byte(47);
|
||||||
|
pub const SPRINGGREEN1: Color = Color::Byte(48);
|
||||||
|
pub const MEDIUMSPRINGGREEN: Color = Color::Byte(49);
|
||||||
|
pub const CYAN2: Color = Color::Byte(50);
|
||||||
|
pub const CYAN1: Color = Color::Byte(51);
|
||||||
|
pub const DARKRED: Color = Color::Byte(52);
|
||||||
|
pub const DEEPPINK4: Color = Color::Byte(53);
|
||||||
|
pub const PURPLE4: Color = Color::Byte(54);
|
||||||
|
pub const PURPLE4_: Color = Color::Byte(55);
|
||||||
|
pub const PURPLE3: Color = Color::Byte(56);
|
||||||
|
pub const BLUEVIOLET: Color = Color::Byte(57);
|
||||||
|
pub const ORANGE4: Color = Color::Byte(58);
|
||||||
|
pub const GREY37: Color = Color::Byte(59);
|
||||||
|
pub const MEDIUMPURPLE4: Color = Color::Byte(60);
|
||||||
|
pub const SLATEBLUE3: Color = Color::Byte(61);
|
||||||
|
pub const SLATEBLUE3_: Color = Color::Byte(62);
|
||||||
|
pub const ROYALBLUE1: Color = Color::Byte(63);
|
||||||
|
pub const CHARTREUSE4: Color = Color::Byte(64);
|
||||||
|
pub const DARKSEAGREEN4: Color = Color::Byte(65);
|
||||||
|
pub const PALETURQUOISE4: Color = Color::Byte(66);
|
||||||
|
pub const STEELBLUE: Color = Color::Byte(67);
|
||||||
|
pub const STEELBLUE3: Color = Color::Byte(68);
|
||||||
|
pub const CORNFLOWERBLUE: Color = Color::Byte(69);
|
||||||
|
pub const CHARTREUSE3: Color = Color::Byte(70);
|
||||||
|
pub const DARKSEAGREEN4_: Color = Color::Byte(71);
|
||||||
|
pub const CADETBLUE: Color = Color::Byte(72);
|
||||||
|
pub const CADETBLUE_: Color = Color::Byte(73);
|
||||||
|
pub const SKYBLUE3: Color = Color::Byte(74);
|
||||||
|
pub const STEELBLUE1: Color = Color::Byte(75);
|
||||||
|
pub const CHARTREUSE3_: Color = Color::Byte(76);
|
||||||
|
pub const PALEGREEN3: Color = Color::Byte(77);
|
||||||
|
pub const SEAGREEN3: Color = Color::Byte(78);
|
||||||
|
pub const AQUAMARINE3: Color = Color::Byte(79);
|
||||||
|
pub const MEDIUMTURQUOISE: Color = Color::Byte(80);
|
||||||
|
pub const STEELBLUE1_: Color = Color::Byte(81);
|
||||||
|
pub const CHARTREUSE2: Color = Color::Byte(82);
|
||||||
|
pub const SEAGREEN2: Color = Color::Byte(83);
|
||||||
|
pub const SEAGREEN1: Color = Color::Byte(84);
|
||||||
|
pub const SEAGREEN1_: Color = Color::Byte(85);
|
||||||
|
pub const AQUAMARINE1: Color = Color::Byte(86);
|
||||||
|
pub const DARKSLATEGRAY2: Color = Color::Byte(87);
|
||||||
|
pub const DARKRED_: Color = Color::Byte(88);
|
||||||
|
pub const DEEPPINK4_: Color = Color::Byte(89);
|
||||||
|
pub const DARKMAGENTA: Color = Color::Byte(90);
|
||||||
|
pub const DARKMAGENTA_: Color = Color::Byte(91);
|
||||||
|
pub const DARKVIOLET: Color = Color::Byte(92);
|
||||||
|
pub const PURPLE_: Color = Color::Byte(93);
|
||||||
|
pub const ORANGE4_: Color = Color::Byte(94);
|
||||||
|
pub const LIGHTPINK4: Color = Color::Byte(95);
|
||||||
|
pub const PLUM4: Color = Color::Byte(96);
|
||||||
|
pub const MEDIUMPURPLE3: Color = Color::Byte(97);
|
||||||
|
pub const MEDIUMPURPLE3_: Color = Color::Byte(98);
|
||||||
|
pub const SLATEBLUE1: Color = Color::Byte(99);
|
||||||
|
pub const YELLOW4: Color = Color::Byte(100);
|
||||||
|
pub const WHEAT4: Color = Color::Byte(101);
|
||||||
|
pub const GREY53: Color = Color::Byte(102);
|
||||||
|
pub const LIGHTSLATEGREY: Color = Color::Byte(103);
|
||||||
|
pub const MEDIUMPURPLE: Color = Color::Byte(104);
|
||||||
|
pub const LIGHTSLATEBLUE: Color = Color::Byte(105);
|
||||||
|
pub const YELLOW4_: Color = Color::Byte(106);
|
||||||
|
pub const DARKOLIVEGREEN3: Color = Color::Byte(107);
|
||||||
|
pub const DARKSEAGREEN: Color = Color::Byte(108);
|
||||||
|
pub const LIGHTSKYBLUE3: Color = Color::Byte(109);
|
||||||
|
pub const LIGHTSKYBLUE3_: Color = Color::Byte(110);
|
||||||
|
pub const SKYBLUE2: Color = Color::Byte(111);
|
||||||
|
pub const CHARTREUSE2_: Color = Color::Byte(112);
|
||||||
|
pub const DARKOLIVEGREEN3_: Color = Color::Byte(113);
|
||||||
|
pub const PALEGREEN3_: Color = Color::Byte(114);
|
||||||
|
pub const DARKSEAGREEN3: Color = Color::Byte(115);
|
||||||
|
pub const DARKSLATEGRAY3: Color = Color::Byte(116);
|
||||||
|
pub const SKYBLUE1: Color = Color::Byte(117);
|
||||||
|
pub const CHARTREUSE1: Color = Color::Byte(118);
|
||||||
|
pub const LIGHTGREEN: Color = Color::Byte(119);
|
||||||
|
pub const LIGHTGREEN_: Color = Color::Byte(120);
|
||||||
|
pub const PALEGREEN1: Color = Color::Byte(121);
|
||||||
|
pub const AQUAMARINE1_: Color = Color::Byte(122);
|
||||||
|
pub const DARKSLATEGRAY1: Color = Color::Byte(123);
|
||||||
|
pub const RED3: Color = Color::Byte(124);
|
||||||
|
pub const DEEPPINK4__: Color = Color::Byte(125);
|
||||||
|
pub const MEDIUMVIOLETRED: Color = Color::Byte(126);
|
||||||
|
pub const MAGENTA3: Color = Color::Byte(127);
|
||||||
|
pub const DARKVIOLET_: Color = Color::Byte(128);
|
||||||
|
pub const PURPLE__: Color = Color::Byte(129);
|
||||||
|
pub const DARKORANGE3: Color = Color::Byte(130);
|
||||||
|
pub const INDIANRED: Color = Color::Byte(131);
|
||||||
|
pub const HOTPINK3: Color = Color::Byte(132);
|
||||||
|
pub const MEDIUMORCHID3: Color = Color::Byte(133);
|
||||||
|
pub const MEDIUMORCHID: Color = Color::Byte(134);
|
||||||
|
pub const MEDIUMPURPLE2: Color = Color::Byte(135);
|
||||||
|
pub const DARKGOLDENROD: Color = Color::Byte(136);
|
||||||
|
pub const LIGHTSALMON3: Color = Color::Byte(137);
|
||||||
|
pub const ROSYBROWN: Color = Color::Byte(138);
|
||||||
|
pub const GREY63: Color = Color::Byte(139);
|
||||||
|
pub const MEDIUMPURPLE2_: Color = Color::Byte(140);
|
||||||
|
pub const MEDIUMPURPLE1: Color = Color::Byte(141);
|
||||||
|
pub const GOLD3: Color = Color::Byte(142);
|
||||||
|
pub const DARKKHAKI: Color = Color::Byte(143);
|
||||||
|
pub const NAVAJOWHITE3: Color = Color::Byte(144);
|
||||||
|
pub const GREY69: Color = Color::Byte(145);
|
||||||
|
pub const LIGHTSTEELBLUE3: Color = Color::Byte(146);
|
||||||
|
pub const LIGHTSTEELBLUE: Color = Color::Byte(147);
|
||||||
|
pub const YELLOW3: Color = Color::Byte(148);
|
||||||
|
pub const DARKOLIVEGREEN3__: Color = Color::Byte(149);
|
||||||
|
pub const DARKSEAGREEN3_: Color = Color::Byte(150);
|
||||||
|
pub const DARKSEAGREEN2: Color = Color::Byte(151);
|
||||||
|
pub const LIGHTCYAN3: Color = Color::Byte(152);
|
||||||
|
pub const LIGHTSKYBLUE1: Color = Color::Byte(153);
|
||||||
|
pub const GREENYELLOW: Color = Color::Byte(154);
|
||||||
|
pub const DARKOLIVEGREEN2: Color = Color::Byte(155);
|
||||||
|
pub const PALEGREEN1_: Color = Color::Byte(156);
|
||||||
|
pub const DARKSEAGREEN2_: Color = Color::Byte(157);
|
||||||
|
pub const DARKSEAGREEN1: Color = Color::Byte(158);
|
||||||
|
pub const PALETURQUOISE1: Color = Color::Byte(159);
|
||||||
|
pub const RED3_: Color = Color::Byte(160);
|
||||||
|
pub const DEEPPINK3: Color = Color::Byte(161);
|
||||||
|
pub const DEEPPINK3_: Color = Color::Byte(162);
|
||||||
|
pub const MAGENTA3_: Color = Color::Byte(163);
|
||||||
|
pub const MAGENTA3__: Color = Color::Byte(164);
|
||||||
|
pub const MAGENTA2: Color = Color::Byte(165);
|
||||||
|
pub const DARKORANGE3_: Color = Color::Byte(166);
|
||||||
|
pub const INDIANRED_: Color = Color::Byte(167);
|
||||||
|
pub const HOTPINK3_: Color = Color::Byte(168);
|
||||||
|
pub const HOTPINK2: Color = Color::Byte(169);
|
||||||
|
pub const ORCHID: Color = Color::Byte(170);
|
||||||
|
pub const MEDIUMORCHID1: Color = Color::Byte(171);
|
||||||
|
pub const ORANGE3: Color = Color::Byte(172);
|
||||||
|
pub const LIGHTSALMON3_: Color = Color::Byte(173);
|
||||||
|
pub const LIGHTPINK3: Color = Color::Byte(174);
|
||||||
|
pub const PINK3: Color = Color::Byte(175);
|
||||||
|
pub const PLUM3: Color = Color::Byte(176);
|
||||||
|
pub const VIOLET: Color = Color::Byte(177);
|
||||||
|
pub const GOLD3_: Color = Color::Byte(178);
|
||||||
|
pub const LIGHTGOLDENROD3: Color = Color::Byte(179);
|
||||||
|
pub const TAN: Color = Color::Byte(180);
|
||||||
|
pub const MISTYROSE3: Color = Color::Byte(181);
|
||||||
|
pub const THISTLE3: Color = Color::Byte(182);
|
||||||
|
pub const PLUM2: Color = Color::Byte(183);
|
||||||
|
pub const YELLOW3_: Color = Color::Byte(184);
|
||||||
|
pub const KHAKI3: Color = Color::Byte(185);
|
||||||
|
pub const LIGHTGOLDENROD2: Color = Color::Byte(186);
|
||||||
|
pub const LIGHTYELLOW3: Color = Color::Byte(187);
|
||||||
|
pub const GREY84: Color = Color::Byte(188);
|
||||||
|
pub const LIGHTSTEELBLUE1: Color = Color::Byte(189);
|
||||||
|
pub const YELLOW2: Color = Color::Byte(190);
|
||||||
|
pub const DARKOLIVEGREEN1: Color = Color::Byte(191);
|
||||||
|
pub const DARKOLIVEGREEN1_: Color = Color::Byte(192);
|
||||||
|
pub const DARKSEAGREEN1_: Color = Color::Byte(193);
|
||||||
|
pub const HONEYDEW2: Color = Color::Byte(194);
|
||||||
|
pub const LIGHTCYAN1: Color = Color::Byte(195);
|
||||||
|
pub const RED1: Color = Color::Byte(196);
|
||||||
|
pub const DEEPPINK2: Color = Color::Byte(197);
|
||||||
|
pub const DEEPPINK1: Color = Color::Byte(198);
|
||||||
|
pub const DEEPPINK1_: Color = Color::Byte(199);
|
||||||
|
pub const MAGENTA2_: Color = Color::Byte(200);
|
||||||
|
pub const MAGENTA1: Color = Color::Byte(201);
|
||||||
|
pub const ORANGERED1: Color = Color::Byte(202);
|
||||||
|
pub const INDIANRED1: Color = Color::Byte(203);
|
||||||
|
pub const INDIANRED1_: Color = Color::Byte(204);
|
||||||
|
pub const HOTPINK: Color = Color::Byte(205);
|
||||||
|
pub const HOTPINK_: Color = Color::Byte(206);
|
||||||
|
pub const MEDIUMORCHID1_: Color = Color::Byte(207);
|
||||||
|
pub const DARKORANGE: Color = Color::Byte(208);
|
||||||
|
pub const SALMON1: Color = Color::Byte(209);
|
||||||
|
pub const LIGHTCORAL: Color = Color::Byte(210);
|
||||||
|
pub const PALEVIOLETRED1: Color = Color::Byte(211);
|
||||||
|
pub const ORCHID2: Color = Color::Byte(212);
|
||||||
|
pub const ORCHID1: Color = Color::Byte(213);
|
||||||
|
pub const ORANGE1: Color = Color::Byte(214);
|
||||||
|
pub const SANDYBROWN: Color = Color::Byte(215);
|
||||||
|
pub const LIGHTSALMON1: Color = Color::Byte(216);
|
||||||
|
pub const LIGHTPINK1: Color = Color::Byte(217);
|
||||||
|
pub const PINK1: Color = Color::Byte(218);
|
||||||
|
pub const PLUM1: Color = Color::Byte(219);
|
||||||
|
pub const GOLD1: Color = Color::Byte(220);
|
||||||
|
pub const LIGHTGOLDENROD2_: Color = Color::Byte(221);
|
||||||
|
pub const LIGHTGOLDENROD2__: Color = Color::Byte(222);
|
||||||
|
pub const NAVAJOWHITE1: Color = Color::Byte(223);
|
||||||
|
pub const MISTYROSE1: Color = Color::Byte(224);
|
||||||
|
pub const THISTLE1: Color = Color::Byte(225);
|
||||||
|
pub const YELLOW1: Color = Color::Byte(226);
|
||||||
|
pub const LIGHTGOLDENROD1: Color = Color::Byte(227);
|
||||||
|
pub const KHAKI1: Color = Color::Byte(228);
|
||||||
|
pub const WHEAT1: Color = Color::Byte(229);
|
||||||
|
pub const CORNSILK1: Color = Color::Byte(230);
|
||||||
|
pub const GREY100: Color = Color::Byte(231);
|
||||||
|
pub const GREY3: Color = Color::Byte(232);
|
||||||
|
pub const GREY7: Color = Color::Byte(233);
|
||||||
|
pub const GREY11: Color = Color::Byte(234);
|
||||||
|
pub const GREY15: Color = Color::Byte(235);
|
||||||
|
pub const GREY19: Color = Color::Byte(236);
|
||||||
|
pub const GREY23: Color = Color::Byte(237);
|
||||||
|
pub const GREY27: Color = Color::Byte(238);
|
||||||
|
pub const GREY30: Color = Color::Byte(239);
|
||||||
|
pub const GREY35: Color = Color::Byte(240);
|
||||||
|
pub const GREY39: Color = Color::Byte(241);
|
||||||
|
pub const GREY42: Color = Color::Byte(242);
|
||||||
|
pub const GREY46: Color = Color::Byte(243);
|
||||||
|
pub const GREY50: Color = Color::Byte(244);
|
||||||
|
pub const GREY54: Color = Color::Byte(245);
|
||||||
|
pub const GREY58: Color = Color::Byte(246);
|
||||||
|
pub const GREY62: Color = Color::Byte(247);
|
||||||
|
pub const GREY66: Color = Color::Byte(248);
|
||||||
|
pub const GREY70: Color = Color::Byte(249);
|
||||||
|
pub const GREY74: Color = Color::Byte(250);
|
||||||
|
pub const GREY78: Color = Color::Byte(251);
|
||||||
|
pub const GREY82: Color = Color::Byte(252);
|
||||||
|
pub const GREY85: Color = Color::Byte(253);
|
||||||
|
pub const GREY89: Color = Color::Byte(254);
|
||||||
|
pub const GREY93: Color = Color::Byte(255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ use super::command::Action;
|
||||||
use super::jobs::{JobExecutor, JobId};
|
use super::jobs::{JobExecutor, JobId};
|
||||||
use super::terminal::*;
|
use super::terminal::*;
|
||||||
use crate::components::{Component, ComponentId, ScrollUpdate};
|
use crate::components::{Component, ComponentId, ScrollUpdate};
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use melib::backends::{AccountHash, BackendEvent, MailboxHash};
|
use melib::backends::{AccountHash, BackendEvent, MailboxHash};
|
||||||
|
@ -134,7 +135,7 @@ pub enum UIEvent {
|
||||||
MailboxUpdate((AccountHash, MailboxHash)), // (account_idx, mailbox_idx)
|
MailboxUpdate((AccountHash, MailboxHash)), // (account_idx, mailbox_idx)
|
||||||
MailboxDelete((AccountHash, MailboxHash)),
|
MailboxDelete((AccountHash, MailboxHash)),
|
||||||
MailboxCreate((AccountHash, MailboxHash)),
|
MailboxCreate((AccountHash, MailboxHash)),
|
||||||
AccountStatusChange(AccountHash),
|
AccountStatusChange(AccountHash, Option<Cow<'static, str>>),
|
||||||
ComponentKill(Uuid),
|
ComponentKill(Uuid),
|
||||||
BackendEvent(AccountHash, BackendEvent),
|
BackendEvent(AccountHash, BackendEvent),
|
||||||
StartupCheck(MailboxHash),
|
StartupCheck(MailboxHash),
|
||||||
|
|
Loading…
Reference in New Issue