use crate::config::ARGS;
use crate::config::CONFIG_PATH;
use crate::config::RUNS_ON_CONSOLE;
use crate::VERSION;
use lazy_static::lazy_static;
use msgbox::IconType;
use std::env;
use std::path::PathBuf;
use std::sync::mpsc::sync_channel;
use std::sync::mpsc::Receiver;
use std::sync::mpsc::RecvTimeoutError;
use std::sync::mpsc::SyncSender;
use std::sync::Mutex;
use std::thread;
use std::thread::sleep;
use std::time::Duration;
pub const QUEUE_LEN: usize = 30;
const DIALOG_TITLE: &str = "Tp-Note";
lazy_static! {
pub static ref MESSAGE_CHANNEL: (SyncSender<String>, Mutex<Receiver<String>>) = {
let (tx, rx) = sync_channel(QUEUE_LEN);
(tx, Mutex::new(rx))
};
}
lazy_static! {
static ref DIALOG_TITLE_LINE: String = format!(
"{} (v{})",
&DIALOG_TITLE,
VERSION.unwrap_or("unknown")
);
}
lazy_static! {
static ref BUSY_LOCK: Mutex<()> = Mutex::new(());
}
#[cfg(feature = "message-box")]
const KEEP_ALIVE: u64 = 1000;
const FLUSH_TIMEOUT: u64 = 10;
pub struct AlertService {}
#[cfg(feature = "message-box")]
impl AlertService {
pub fn init() {
#[cfg(feature = "message-box")]
if !*RUNS_ON_CONSOLE && !ARGS.batch {
lazy_static::initialize(&MESSAGE_CHANNEL);
thread::spawn(move || {
AlertService::run();
});
};
}
fn run() {
let (_, rx) = &*MESSAGE_CHANNEL;
let rx = rx.lock().unwrap();
let mut opt_guard = None;
loop {
let msg = if opt_guard.is_none() {
Some(rx.recv().unwrap())
} else {
match rx.recv_timeout(Duration::from_millis(KEEP_ALIVE)) {
Ok(s) => Some(s),
Err(RecvTimeoutError::Timeout) => None,
Err(RecvTimeoutError::Disconnected) => panic!(),
}
};
match msg {
Some(s) => {
if opt_guard.is_none() {
opt_guard = BUSY_LOCK.try_lock().ok();
}
Self::print_error(&s);
}
None => {
opt_guard = None;
}
}
}
}
pub fn flush() {
sleep(Duration::from_millis(FLUSH_TIMEOUT));
let _res = BUSY_LOCK.lock();
}
fn print_error(msg: &str) {
let _ = msgbox::create(&*DIALOG_TITLE_LINE, &msg, IconType::Info);
}
pub fn format_error(msg: &str) -> String {
let mut args_str = String::new();
for argument in env::args() {
args_str.push_str(argument.as_str());
args_str.push(' ');
}
format!(
"{}\n\
__________\n\
Additional technical details:\n\
* Command line parameters:\n\
{}\n\
* Configuration file:\n\
{}",
msg,
args_str,
&*CONFIG_PATH
.as_ref()
.unwrap_or(&PathBuf::from("no path found"))
.to_str()
.unwrap_or_default()
)
}
}