Skip to content

Commit

Permalink
feat(ux): show loading screen (#1997)
Browse files Browse the repository at this point in the history
* feat(ux): show loading prompt

* style(fmt): rustfmt
  • Loading branch information
imsnif authored Dec 7, 2022
1 parent 81287a2 commit f8a078c
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 3 deletions.
14 changes: 14 additions & 0 deletions zellij-client/src/input_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,20 @@ impl InputHandler {
self.handle_stdin_ansi_instruction(ansi_instruction);
}
},
Ok((InputInstruction::StartedParsing, _error_context)) => {
log::info!("sending done loading");
self.send_client_instructions
.send(ClientInstruction::StartedParsingStdinQuery)
.unwrap();
log::info!("done sent done loading");
},
Ok((InputInstruction::DoneParsing, _error_context)) => {
log::info!("sending done loading");
self.send_client_instructions
.send(ClientInstruction::DoneParsingStdinQuery)
.unwrap();
log::info!("done sent done loading");
},
Err(err) => panic!("Encountered read error: {:?}", err),
}
}
Expand Down
50 changes: 47 additions & 3 deletions zellij-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ pub(crate) enum ClientInstruction {
SwitchToMode(InputMode),
Connected,
ActiveClients(Vec<ClientId>),
StartedParsingStdinQuery,
DoneParsingStdinQuery,
}

impl From<ServerToClientMsg> for ClientInstruction {
Expand Down Expand Up @@ -70,6 +72,8 @@ impl From<&ClientInstruction> for ClientContext {
ClientInstruction::SwitchToMode(_) => ClientContext::SwitchToMode,
ClientInstruction::Connected => ClientContext::Connected,
ClientInstruction::ActiveClients(_) => ClientContext::ActiveClients,
ClientInstruction::StartedParsingStdinQuery => ClientContext::StartedParsingStdinQuery,
ClientInstruction::DoneParsingStdinQuery => ClientContext::DoneParsingStdinQuery,
}
}
}
Expand Down Expand Up @@ -121,6 +125,8 @@ pub(crate) enum InputInstruction {
KeyEvent(InputEvent, Vec<u8>),
SwitchToMode(InputMode),
AnsiStdinInstructions(Vec<AnsiStdinInstruction>),
StartedParsing,
DoneParsing,
}

pub fn start_client(
Expand Down Expand Up @@ -337,13 +343,51 @@ pub fn start_client(
};

let exit_msg: String;
let mut loading = true;
let mut pending_instructions = vec![];

let mut stdout = os_input.get_stdout_writer();
stdout
.write_all("\u{1b}[1mLoading Zellij\u{1b}[m".as_bytes())
.expect("cannot write to stdout");
stdout.flush().expect("could not flush");

loop {
let (client_instruction, mut err_ctx) = receive_client_instructions
.recv()
.expect("failed to receive app instruction on channel");
let (client_instruction, mut err_ctx) = if !loading && !pending_instructions.is_empty() {
// there are buffered instructions, we need to go through them before processing the
// new ones
pending_instructions.remove(0)
} else {
receive_client_instructions
.recv()
.expect("failed to receive app instruction on channel")
};

if loading {
// when the app is still loading, we buffer instructions and show a loading screen
match client_instruction {
ClientInstruction::StartedParsingStdinQuery => {
stdout
.write_all("\n\rQuerying terminal emulator for \u{1b}[32;1mdefault colors\u{1b}[m and \u{1b}[32;1mpixel/cell\u{1b}[m ratio...".as_bytes())
.expect("cannot write to stdout");
stdout.flush().expect("could not flush");
},
ClientInstruction::DoneParsingStdinQuery => {
stdout
.write_all("done".as_bytes())
.expect("cannot write to stdout");
stdout.flush().expect("could not flush");
loading = false;
},
instruction => {
pending_instructions.push((instruction, err_ctx));
},
}
continue;
}

err_ctx.add_call(ContextType::Client((&client_instruction).into()));

match client_instruction {
ClientInstruction::Exit(reason) => {
os_input.send_to_server(ClientToServerMsg::ClientExited);
Expand Down
3 changes: 3 additions & 0 deletions zellij-client/src/stdin_ansi_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ impl StdinAnsiParser {
}
false
}
pub fn startup_query_duration(&self) -> u64 {
STARTUP_PARSE_DEADLINE_MS
}
pub fn parse(&mut self, mut raw_bytes: Vec<u8>) -> Vec<AnsiStdinInstruction> {
for byte in raw_bytes.drain(..) {
self.parse_byte(byte);
Expand Down
19 changes: 19 additions & 0 deletions zellij-client/src/stdin_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ use std::sync::{Arc, Mutex};
use zellij_utils::channels::SenderWithContext;
use zellij_utils::termwiz::input::{InputEvent, InputParser, MouseButtons};

fn send_done_parsing_after_query_timeout(
send_input_instructions: SenderWithContext<InputInstruction>,
query_duration: u64,
) {
std::thread::spawn({
move || {
std::thread::sleep(std::time::Duration::from_millis(query_duration));
send_input_instructions
.send(InputInstruction::DoneParsing)
.unwrap();
}
});
}

pub(crate) fn stdin_loop(
mut os_input: Box<dyn ClientOsApi>,
send_input_instructions: SenderWithContext<InputInstruction>,
Expand All @@ -15,6 +29,9 @@ pub(crate) fn stdin_loop(
let mut current_buffer = vec![];
// on startup we send a query to the terminal emulator for stuff like the pixel size and colors
// we get a response through STDIN, so it makes sense to do this here
send_input_instructions
.send(InputInstruction::StartedParsing)
.unwrap();
let terminal_emulator_query_string = stdin_ansi_parser
.lock()
.unwrap()
Expand All @@ -23,6 +40,8 @@ pub(crate) fn stdin_loop(
.get_stdout_writer()
.write(terminal_emulator_query_string.as_bytes())
.unwrap();
let query_duration = stdin_ansi_parser.lock().unwrap().startup_query_duration();
send_done_parsing_after_query_timeout(send_input_instructions.clone(), query_duration);
loop {
let buf = os_input.read_from_stdin();
{
Expand Down
2 changes: 2 additions & 0 deletions zellij-utils/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,8 @@ pub enum ClientContext {
Connected,
ActiveClients,
OwnClientId,
StartedParsingStdinQuery,
DoneParsingStdinQuery,
}

/// Stack call representations corresponding to the different types of [`ServerInstruction`]s.
Expand Down

0 comments on commit f8a078c

Please sign in to comment.