This commit is contained in:
MeexReay 2025-02-12 01:49:53 +03:00
parent 04bfc95df1
commit 7afca71b59

View File

@ -1,7 +1,7 @@
use std::{cmp::{max, min}, error::Error, io::{stdout, Write}, sync::{atomic::{AtomicUsize, Ordering}, Arc, RwLock}, thread, time::{Duration, SystemTime}}; use std::{cmp::{max, min}, error::Error, io::{stdout, Write}, sync::{atomic::{AtomicUsize, Ordering}, Arc, RwLock}, thread, time::{Duration, SystemTime}};
use colored::{Color, Colorize}; use colored::{Color, Colorize};
use crossterm::{cursor::{MoveLeft, MoveRight}, event::{self, Event, KeyCode, KeyModifiers, MouseEventKind}, terminal::{self, disable_raw_mode, enable_raw_mode}}; use crossterm::{cursor::{MoveLeft, MoveRight}, event::{self, Event, KeyCode, KeyModifiers, MouseEventKind}, execute, terminal::{self, disable_raw_mode, enable_raw_mode}};
use rand::random; use rand::random;
use crate::{proto::send_message_auth, util::string_chunks, IP_REGEX}; use crate::{proto::send_message_auth, util::string_chunks, IP_REGEX};
@ -92,27 +92,57 @@ pub fn print_console(ctx: Arc<Context>, messages: Vec<String>, input: &str) -> R
let (width, height) = terminal::size()?; let (width, height) = terminal::size()?;
let (width, height) = (width as usize, height as usize); let (width, height) = (width as usize, height as usize);
let scroll = ctx.scroll.load(Ordering::SeqCst); let messages = messages
let scroll = (1f64 - scroll as f64 / messages.len() as f64) * (height) as f64; .into_iter()
let scroll = scroll as usize; .flat_map(|o| string_chunks(&o, width as usize - 1))
.collect::<Vec<(String, usize)>>();
let scroll = min(ctx.scroll.load(Ordering::SeqCst), messages.len()-height);
let scroll_f = ((1f64 - scroll as f64 / (messages.len()-height+1) as f64) * (height-2) as f64).round() as usize+1;
let messages = if height < messages.len() {
if scroll < messages.len() - height {
messages[
messages.len()-height-scroll..
messages.len()-scroll
].to_vec()
} else {
if scroll < messages.len() {
messages[
0..
messages.len()-scroll
].to_vec()
} else {
vec![]
}
}
} else {
messages
};
let formatted_messages = if ctx.disable_formatting { let formatted_messages = if ctx.disable_formatting {
messages messages
.into_iter()
.map(|(i, _)| i)
.collect::<Vec<String>>()
} else { } else {
messages[messages.len()-height-1..].into_iter() messages
.flat_map(|o| string_chunks(&o, width as usize - 1)) .into_iter()
.enumerate() .enumerate()
.map(|(i, (s, l))| { .map(|(i, (s, l))| {
format!("{}{}{}", format!("{}{}{}",
s, s,
" ".repeat(width - 1 - l), " ".repeat(width - 1 - l),
if i == scroll { if i == scroll_f {
"#" "#"
} else { } else {
"|" "|"
} }
) )
}).collect::<Vec<String>>() })
.collect::<Vec<String>>()
}; };
let text = format!( let text = format!(
@ -306,7 +336,7 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
replace_input_left(cursor, len, &history[history_cursor], cursor); replace_input_left(cursor, len, &history[history_cursor], cursor);
} }
KeyCode::Esc => { KeyCode::Esc => {
disable_raw_mode()?; on_close();
break; break;
} }
KeyCode::Up | KeyCode::Down => { KeyCode::Up | KeyCode::Down => {
@ -321,10 +351,22 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
cursor = history[history_cursor].chars().count(); cursor = history[history_cursor].chars().count();
} }
KeyCode::PageUp => { KeyCode::PageUp => {
let height = terminal::size().unwrap().1 as usize;
ctx.scroll.store(min(ctx.scroll.load(Ordering::SeqCst)+height, ctx.messages.messages().len()), Ordering::SeqCst);
print_console(
ctx.clone(),
messages.messages(),
&input.read().unwrap()
)?;
} }
KeyCode::PageDown => { KeyCode::PageDown => {
let height = terminal::size().unwrap().1 as usize;
ctx.scroll.store(max(ctx.scroll.load(Ordering::SeqCst), height)-height, Ordering::SeqCst);
print_console(
ctx.clone(),
messages.messages(),
&input.read().unwrap()
)?;
} }
KeyCode::Left => { KeyCode::Left => {
if cursor > 0 { if cursor > 0 {
@ -342,7 +384,7 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
} }
KeyCode::Char(c) => { KeyCode::Char(c) => {
if event.modifiers.contains(KeyModifiers::CONTROL) && "zxcZXCячсЯЧС".contains(c) { if event.modifiers.contains(KeyModifiers::CONTROL) && "zxcZXCячсЯЧС".contains(c) {
disable_raw_mode().unwrap(); on_close();
break; break;
} }
history[history_cursor].insert(cursor, c); history[history_cursor].insert(cursor, c);
@ -372,10 +414,20 @@ fn poll_events(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
Event::Mouse(data) => { Event::Mouse(data) => {
match data.kind { match data.kind {
MouseEventKind::ScrollUp => { MouseEventKind::ScrollUp => {
ctx.scroll.store(min(ctx.scroll.load(Ordering::SeqCst)+3, ctx.messages.messages().len()), Ordering::SeqCst);
print_console(
ctx.clone(),
messages.messages(),
&input.read().unwrap()
)?;
}, },
MouseEventKind::ScrollDown => { MouseEventKind::ScrollDown => {
ctx.scroll.store(max(ctx.scroll.load(Ordering::SeqCst), 3)-3, Ordering::SeqCst);
print_console(
ctx.clone(),
messages.messages(),
&input.read().unwrap()
)?;
}, },
_ => {} _ => {}
} }
@ -401,8 +453,14 @@ pub fn recv_tick(ctx: Arc<Context>) -> Result<(), Box<dyn Error>> {
Ok(()) Ok(())
} }
pub fn on_close() {
disable_raw_mode().unwrap();
execute!(stdout(), event::DisableMouseCapture).unwrap();
}
pub fn run_main_loop(ctx: Arc<Context>) { pub fn run_main_loop(ctx: Arc<Context>) {
enable_raw_mode().unwrap(); enable_raw_mode().unwrap();
execute!(stdout(), event::EnableMouseCapture).unwrap();
thread::spawn({ thread::spawn({
let ctx = ctx.clone(); let ctx = ctx.clone();