mirror of
https://github.com/MeexReay/bRAC.git
synced 2025-06-24 19:02:58 +03:00
make out-of-focus update time setting
This commit is contained in:
parent
01b3643c14
commit
97948aa420
@ -8,7 +8,8 @@ const MESSAGE_FORMAT: &str = "\u{B9AC}\u{3E70}<{name}> {text}";
|
|||||||
|
|
||||||
fn default_true() -> bool { true }
|
fn default_true() -> bool { true }
|
||||||
pub fn default_max_messages() -> usize { 200 }
|
pub fn default_max_messages() -> usize { 200 }
|
||||||
pub fn default_update_time() -> usize { 50 }
|
pub fn default_update_time() -> usize { 100 }
|
||||||
|
pub fn default_oof_update_time() -> usize { 10000 }
|
||||||
pub fn default_host() -> String { "meex.lol:11234".to_string() }
|
pub fn default_host() -> String { "meex.lol:11234".to_string() }
|
||||||
pub fn default_message_format() -> String { MESSAGE_FORMAT.to_string() }
|
pub fn default_message_format() -> String { MESSAGE_FORMAT.to_string() }
|
||||||
|
|
||||||
@ -18,6 +19,7 @@ pub struct Config {
|
|||||||
#[serde(default)] pub name: Option<String>,
|
#[serde(default)] pub name: Option<String>,
|
||||||
#[serde(default = "default_message_format")] pub message_format: String,
|
#[serde(default = "default_message_format")] pub message_format: String,
|
||||||
#[serde(default = "default_update_time")] pub update_time: usize,
|
#[serde(default = "default_update_time")] pub update_time: usize,
|
||||||
|
#[serde(default = "default_oof_update_time")] pub oof_update_time: usize,
|
||||||
#[serde(default = "default_max_messages")] pub max_messages: usize,
|
#[serde(default = "default_max_messages")] pub max_messages: usize,
|
||||||
#[serde(default = "default_true")] pub hide_my_ip: bool,
|
#[serde(default = "default_true")] pub hide_my_ip: bool,
|
||||||
#[serde(default)] pub show_other_ip: bool,
|
#[serde(default)] pub show_other_ip: bool,
|
||||||
@ -110,6 +112,7 @@ pub struct Args {
|
|||||||
#[arg(short='n', long)] pub name: Option<String>,
|
#[arg(short='n', long)] pub name: Option<String>,
|
||||||
#[arg(long)] pub message_format: Option<String>,
|
#[arg(long)] pub message_format: Option<String>,
|
||||||
#[arg(long)] pub update_time: Option<usize>,
|
#[arg(long)] pub update_time: Option<usize>,
|
||||||
|
#[arg(long)] pub oof_update_time: Option<usize>,
|
||||||
#[arg(long)] pub max_messages: Option<usize>,
|
#[arg(long)] pub max_messages: Option<usize>,
|
||||||
#[arg(long)] pub hide_my_ip: Option<bool>,
|
#[arg(long)] pub hide_my_ip: Option<bool>,
|
||||||
#[arg(long)] pub show_other_ip: Option<bool>,
|
#[arg(long)] pub show_other_ip: Option<bool>,
|
||||||
@ -131,6 +134,7 @@ impl Args {
|
|||||||
if let Some(v) = self.proxy.clone() { config.proxy = Some(v) }
|
if let Some(v) = self.proxy.clone() { config.proxy = Some(v) }
|
||||||
if let Some(v) = self.message_format.clone() { config.message_format = v }
|
if let Some(v) = self.message_format.clone() { config.message_format = v }
|
||||||
if let Some(v) = self.update_time { config.update_time = v }
|
if let Some(v) = self.update_time { config.update_time = v }
|
||||||
|
if let Some(v) = self.oof_update_time { config.oof_update_time = v }
|
||||||
if let Some(v) = self.max_messages { config.max_messages = v }
|
if let Some(v) = self.max_messages { config.max_messages = v }
|
||||||
if let Some(v) = self.hide_my_ip { config.hide_my_ip = v }
|
if let Some(v) = self.hide_my_ip { config.hide_my_ip = v }
|
||||||
if let Some(v) = self.show_other_ip { config.show_other_ip = v }
|
if let Some(v) = self.show_other_ip { config.show_other_ip = v }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::sync::{atomic::{AtomicUsize, Ordering}, mpsc::Sender, Arc, RwLock};
|
use std::sync::{atomic::{AtomicBool, AtomicUsize, Ordering}, mpsc::Sender, Arc, RwLock};
|
||||||
|
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
|
||||||
@ -10,7 +10,8 @@ pub struct Context {
|
|||||||
pub sender: RwLock<Option<Arc<Sender<(String, bool)>>>>,
|
pub sender: RwLock<Option<Arc<Sender<(String, bool)>>>>,
|
||||||
pub messages: RwLock<Vec<String>>,
|
pub messages: RwLock<Vec<String>>,
|
||||||
pub packet_size: AtomicUsize,
|
pub packet_size: AtomicUsize,
|
||||||
pub name: RwLock<String>
|
pub name: RwLock<String>,
|
||||||
|
pub is_focused: AtomicBool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
@ -22,6 +23,7 @@ impl Context {
|
|||||||
messages: RwLock::new(Vec::new()),
|
messages: RwLock::new(Vec::new()),
|
||||||
packet_size: AtomicUsize::default(),
|
packet_size: AtomicUsize::default(),
|
||||||
name: RwLock::new(config.name.clone().unwrap_or_else(|| format!("Anon#{:X}", random::<u16>()))),
|
name: RwLock::new(config.name.clone().unwrap_or_else(|| format!("Anon#{:X}", random::<u16>()))),
|
||||||
|
is_focused: AtomicBool::new(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
102
src/chat/gui.rs
102
src/chat/gui.rs
@ -1,4 +1,4 @@
|
|||||||
use std::sync::{mpsc::{channel, Receiver}, Arc, RwLock};
|
use std::sync::{atomic::Ordering, mpsc::{channel, Receiver}, Arc, RwLock};
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::time::{Duration, SystemTime};
|
use std::time::{Duration, SystemTime};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@ -27,7 +27,7 @@ use gtk::{
|
|||||||
Justification, Label, ListBox, Orientation, Overlay, Picture, ScrolledWindow, Settings, Window
|
Justification, Label, ListBox, Orientation, Overlay, Picture, ScrolledWindow, Settings, Window
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::proto::parse_rac_url;
|
use crate::{chat::config::default_oof_update_time, proto::parse_rac_url};
|
||||||
|
|
||||||
use super::{config::{default_max_messages, default_update_time, get_config_path, save_config, Config},
|
use super::{config::{default_max_messages, default_update_time, get_config_path, save_config, Config},
|
||||||
ctx::Context, on_send_message, parse_message, print_message, recv_tick, sanitize_message, SERVER_LIST};
|
ctx::Context, on_send_message, parse_message, print_message, recv_tick, sanitize_message, SERVER_LIST};
|
||||||
@ -164,6 +164,7 @@ fn open_settings(ctx: Arc<Context>, app: &Application) {
|
|||||||
let message_format_entry = gui_entry_setting!("Message Format", message_format, ctx, vbox);
|
let message_format_entry = gui_entry_setting!("Message Format", message_format, ctx, vbox);
|
||||||
let proxy_entry = gui_option_entry_setting!("Socks5 proxy", proxy, ctx, vbox);
|
let proxy_entry = gui_option_entry_setting!("Socks5 proxy", proxy, ctx, vbox);
|
||||||
let update_time_entry = gui_usize_entry_setting!("Update Time", update_time, ctx, vbox);
|
let update_time_entry = gui_usize_entry_setting!("Update Time", update_time, ctx, vbox);
|
||||||
|
let oof_update_time_entry = gui_usize_entry_setting!("Out-of-focus Update Time", oof_update_time, ctx, vbox);
|
||||||
let max_messages_entry = gui_usize_entry_setting!("Max Messages", max_messages, ctx, vbox);
|
let max_messages_entry = gui_usize_entry_setting!("Max Messages", max_messages, ctx, vbox);
|
||||||
let hide_my_ip_entry = gui_checkbox_setting!("Hide My IP", hide_my_ip, ctx, vbox);
|
let hide_my_ip_entry = gui_checkbox_setting!("Hide My IP", hide_my_ip, ctx, vbox);
|
||||||
let show_other_ip_entry = gui_checkbox_setting!("Show Other IP", show_other_ip, ctx, vbox);
|
let show_other_ip_entry = gui_checkbox_setting!("Show Other IP", show_other_ip, ctx, vbox);
|
||||||
@ -200,6 +201,7 @@ fn open_settings(ctx: Arc<Context>, app: &Application) {
|
|||||||
#[weak] wrac_enabled_entry,
|
#[weak] wrac_enabled_entry,
|
||||||
#[weak] proxy_entry,
|
#[weak] proxy_entry,
|
||||||
#[weak] debug_logs_entry,
|
#[weak] debug_logs_entry,
|
||||||
|
#[weak] oof_update_time_entry,
|
||||||
move |_| {
|
move |_| {
|
||||||
let config = Config {
|
let config = Config {
|
||||||
host: host_entry.text().to_string(),
|
host: host_entry.text().to_string(),
|
||||||
@ -224,6 +226,17 @@ fn open_settings(ctx: Arc<Context>, app: &Application) {
|
|||||||
update_time
|
update_time
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
oof_update_time: {
|
||||||
|
let oof_update_time = oof_update_time_entry.text();
|
||||||
|
|
||||||
|
if let Ok(oof_update_time) = oof_update_time.parse::<usize>() {
|
||||||
|
oof_update_time
|
||||||
|
} else {
|
||||||
|
let oof_update_time = default_oof_update_time();
|
||||||
|
oof_update_time_entry.set_text(&oof_update_time.to_string());
|
||||||
|
oof_update_time
|
||||||
|
}
|
||||||
|
},
|
||||||
max_messages: {
|
max_messages: {
|
||||||
let max_messages = max_messages_entry.text();
|
let max_messages = max_messages_entry.text();
|
||||||
|
|
||||||
@ -481,11 +494,13 @@ fn build_ui(ctx: Arc<Context>, app: &Application) -> UiModel {
|
|||||||
timeout_add_local(Duration::from_millis(30), {
|
timeout_add_local(Duration::from_millis(30), {
|
||||||
let logo = logo.clone();
|
let logo = logo.clone();
|
||||||
let logo_anim = logo_anim.clone();
|
let logo_anim = logo_anim.clone();
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
|
||||||
move || {
|
move || {
|
||||||
logo.set_pixbuf(Some(&logo_anim.pixbuf()));
|
if ctx.is_focused.load(Ordering::SeqCst) {
|
||||||
logo_anim.advance(SystemTime::now());
|
logo.set_pixbuf(Some(&logo_anim.pixbuf()));
|
||||||
|
logo_anim.advance(SystemTime::now());
|
||||||
|
}
|
||||||
ControlFlow::Continue
|
ControlFlow::Continue
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -659,29 +674,30 @@ fn setup(_: &Application, ctx: Arc<Context>, ui: UiModel) {
|
|||||||
|
|
||||||
let (tx, rx) = channel();
|
let (tx, rx) = channel();
|
||||||
|
|
||||||
#[cfg(feature = "libnotify")]
|
ui.window.connect_notify(Some("is-active"), {
|
||||||
ui.window.connect_notify(Some("is-active"), move |a, _| {
|
let ctx = ctx.clone();
|
||||||
if a.is_active() {
|
|
||||||
GLOBAL.with(|global| {
|
|
||||||
if let Some((ui, _)) = &*global.borrow() {
|
|
||||||
for i in ui.notifications.read().unwrap().clone() {
|
|
||||||
i.close().expect("libnotify close error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(not(feature = "libnotify"))]
|
move |a, _| {
|
||||||
ui.window.connect_notify(Some("is-active"), move |a, _| {
|
let is_focused = a.is_active();
|
||||||
if a.is_active() {
|
|
||||||
GLOBAL.with(|global| {
|
ctx.is_focused.store(is_focused, Ordering::SeqCst);
|
||||||
if let Some((ui, _)) = &*global.borrow() {
|
|
||||||
for i in ui.notifications.read().unwrap().clone() {
|
if is_focused {
|
||||||
ui.app.withdraw_notification(&i);
|
make_recv_tick(ctx.clone());
|
||||||
|
|
||||||
|
GLOBAL.with(|global| {
|
||||||
|
if let Some((ui, _)) = &*global.borrow() {
|
||||||
|
#[cfg(feature = "libnotify")]
|
||||||
|
for i in ui.notifications.read().unwrap().clone() {
|
||||||
|
i.close().expect("libnotify close error");
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "libnotify"))]
|
||||||
|
for i in ui.notifications.read().unwrap().clone() {
|
||||||
|
ui.app.withdraw_notification(&i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -704,7 +720,7 @@ fn setup(_: &Application, ctx: Arc<Context>, ui: UiModel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let message: String = rx.recv().unwrap();
|
let message: String = rx.recv().unwrap();
|
||||||
on_add_message(ctx.clone(), &ui, message);
|
on_add_message(ctx.clone(), &ui, message, !clear);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -766,14 +782,14 @@ fn send_notification(_: Arc<Context>, ui: &UiModel, title: &str, message: &str)
|
|||||||
ui.notifications.write().unwrap().push(id);
|
ui.notifications.write().unwrap().push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
|
fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String, notify: bool) {
|
||||||
let Some(message) = sanitize_message(message) else { return; };
|
let Some(message) = sanitize_message(message) else { return; };
|
||||||
|
|
||||||
if message.is_empty() {
|
if message.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: caching these colors maybe??
|
// TODO: cache these colors maybe??
|
||||||
|
|
||||||
let (ip_color, date_color, text_color) = if ui.is_dark_theme {
|
let (ip_color, date_color, text_color) = if ui.is_dark_theme {
|
||||||
(
|
(
|
||||||
@ -803,13 +819,13 @@ fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
|
|||||||
if let Some((name, color)) = nick {
|
if let Some((name, color)) = nick {
|
||||||
label.push_str(&format!("<span font_weight=\"bold\" color=\"{}\"><{}></span> ", color.to_uppercase(), glib::markup_escape_text(&name)));
|
label.push_str(&format!("<span font_weight=\"bold\" color=\"{}\"><{}></span> ", color.to_uppercase(), glib::markup_escape_text(&name)));
|
||||||
|
|
||||||
if !ui.window.is_active() {
|
if notify && !ui.window.is_active() {
|
||||||
if ctx.config(|o| o.chunked_enabled) {
|
if ctx.config(|o| o.chunked_enabled) {
|
||||||
send_notification(ctx.clone(), ui, &format!("{}'s Message", &name), &glib::markup_escape_text(&content));
|
send_notification(ctx.clone(), ui, &format!("{}'s Message", &name), &glib::markup_escape_text(&content));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !ui.window.is_active() {
|
if notify && !ui.window.is_active() {
|
||||||
if ctx.config(|o| o.chunked_enabled) {
|
if ctx.config(|o| o.chunked_enabled) {
|
||||||
send_notification(ctx.clone(), ui, "System Message", &content);
|
send_notification(ctx.clone(), ui, "System Message", &content);
|
||||||
}
|
}
|
||||||
@ -820,7 +836,7 @@ fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
|
|||||||
} else {
|
} else {
|
||||||
label.push_str(&format!("<span color=\"{text_color}\">{}</span>", glib::markup_escape_text(&message)));
|
label.push_str(&format!("<span color=\"{text_color}\">{}</span>", glib::markup_escape_text(&message)));
|
||||||
|
|
||||||
if !ui.window.is_active() {
|
if notify && !ui.window.is_active() {
|
||||||
if ctx.config(|o| o.chunked_enabled) {
|
if ctx.config(|o| o.chunked_enabled) {
|
||||||
send_notification(ctx.clone(), ui, "Chat Message", &message);
|
send_notification(ctx.clone(), ui, "Chat Message", &message);
|
||||||
}
|
}
|
||||||
@ -853,15 +869,27 @@ fn on_add_message(ctx: Arc<Context>, ui: &UiModel, message: String) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_recv_tick(ctx: Arc<Context>) {
|
||||||
|
if let Err(e) = recv_tick(ctx.clone()) {
|
||||||
|
if ctx.config(|o| o.debug_logs) {
|
||||||
|
let _ = print_message(ctx.clone(), format!("Print messages error: {}", e.to_string()).to_string());
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_secs(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn run_recv_loop(ctx: Arc<Context>) {
|
fn run_recv_loop(ctx: Arc<Context>) {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
if let Err(e) = recv_tick(ctx.clone()) {
|
make_recv_tick(ctx.clone());
|
||||||
if ctx.config(|o| o.debug_logs) {
|
|
||||||
let _ = print_message(ctx.clone(), format!("Print messages error: {}", e.to_string()).to_string());
|
thread::sleep(Duration::from_millis(
|
||||||
|
if ctx.is_focused.load(Ordering::SeqCst) {
|
||||||
|
ctx.config(|o| o.update_time) as u64
|
||||||
|
} else {
|
||||||
|
ctx.config(|o| o.oof_update_time) as u64
|
||||||
}
|
}
|
||||||
thread::sleep(Duration::from_secs(1));
|
));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
thread::sleep(Duration::from_millis(ctx.config(|o| o.update_time) as u64));
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user