-
-
Save sigmaSd/393b475e3ed3ebec48fedcaabd150e19 to your computer and use it in GitHub Desktop.
channel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use super::Event; | |
use super::{stringify_sendall_errors, Application, NetMessage}; | |
use crate::state::{ApplicationState, TermchatMessageType}; | |
use crate::ui; | |
use crate::util::{termchat_message, Result}; | |
use crossterm::event::{Event as TermEvent, KeyCode, KeyEvent, KeyModifiers}; | |
impl Application { | |
pub fn parse_input(&mut self, input: &str, state: &mut ApplicationState) -> Result<()> { | |
const SEND_COMMAND: &str = "?send"; | |
if input.starts_with(SEND_COMMAND) { | |
let events = self.handle_send_command(input, state)?; | |
let tmp_sender = self.event_queue.sender(); | |
for ev in events.into_iter().rev() { | |
tmp_sender.send(ev); | |
} | |
} | |
Ok(()) | |
} | |
fn handle_send_command( | |
&mut self, | |
input: &str, | |
state: &mut ApplicationState, | |
) -> Result<Vec<Event>> { | |
use std::io::Read; | |
const READ_FILENAME_ERROR: &str = "Unable to read file name"; | |
let path = | |
std::path::Path::new(input.split_whitespace().nth(1).ok_or("No file specified")?); | |
let file_name = path | |
.file_name() | |
.ok_or(READ_FILENAME_ERROR)? | |
.to_str() | |
.ok_or(READ_FILENAME_ERROR)? | |
.to_string(); | |
use std::convert::TryInto; | |
let file_size = std::fs::metadata(path)?.len().try_into()?; | |
state.progress.start(file_size); | |
let mut file = std::fs::File::open(path)?; | |
const BLOCK: usize = 65536; | |
let mut data = [0; BLOCK]; | |
let (local_tx, local_rx) = std::sync::mpsc::channel(); | |
let event_queue = self.event_queue.clone(); | |
std::thread::spawn(move || loop { | |
let mut v = vec![]; | |
let ev = event_queue.receive(); | |
if let Some(Event::Terminal(TermEvent::Key(KeyEvent { | |
code: KeyCode::Char('c'), | |
modifiers: KeyModifiers::CONTROL, | |
}))) = ev | |
{ | |
local_tx.send(v); | |
break; | |
} else { | |
v.push(ev); | |
} | |
}); | |
let mut leftover = vec![]; | |
loop { | |
match file.read(&mut data) { | |
Ok(bytes_read) => { | |
state.progress.advance(bytes_read); | |
let data_to_send = data[..bytes_read].to_vec(); | |
self.network | |
.send_all( | |
state.all_user_endpoints(), | |
NetMessage::UserData( | |
file_name.clone(), | |
Some((data_to_send, bytes_read)), | |
None, | |
), | |
) | |
.map_err(stringify_sendall_errors)?; | |
// done | |
if bytes_read == 0 { | |
let msg = format!("Successfully sent file {} !", file_name); | |
let msg = termchat_message(msg, TermchatMessageType::Notification); | |
state.add_message(msg); | |
break; | |
} | |
} | |
Err(e) => { | |
state.progress.done(); | |
self.network | |
.send_all( | |
state.all_user_endpoints(), | |
NetMessage::UserData(file_name, None, Some(e.to_string())), | |
) | |
.map_err(stringify_sendall_errors)?; | |
return Err(e.into()); | |
} | |
} | |
ui::draw(&mut self.terminal, &state)?; | |
// check for ctrl_c | |
if let Ok(Some(events)) = local_rx.try_recv() { | |
leftover = events; | |
let message = | |
termchat_message("File not sent.".into(), TermchatMessageType::Notification); | |
state.add_message(message); | |
self.network | |
.send_all( | |
state.all_user_endpoints(), | |
NetMessage::UserData(file_name, None, Some("User aborted.".into())), | |
) | |
.map_err(stringify_sendall_errors)?; | |
break; | |
} | |
} | |
state.progress.done(); | |
ui::draw(&mut self.terminal, &state)?; | |
Ok(leftover) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment