feat(client): prompt for a handle on join when none is given
Make the connect `user` arg optional. When omitted, the client prompts "choose your handle" as the first thing on join (before the TUI opens) and re-prompts if the server rejects the name (e.g. already taken, 409). Passing a name on the CLI still works unchanged, so the demo script is unaffected. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
b4c5f9a9fa
commit
ee9d0f7ff9
|
|
@ -33,7 +33,8 @@ enum Cmd {
|
||||||
Connect {
|
Connect {
|
||||||
ip: String,
|
ip: String,
|
||||||
port: u16,
|
port: u16,
|
||||||
user: String,
|
/// Display name (handle) to join as. Omit to be prompted on join.
|
||||||
|
user: Option<String>,
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
password: String,
|
password: String,
|
||||||
#[arg(long, default_value_t = false)]
|
#[arg(long, default_value_t = false)]
|
||||||
|
|
@ -86,11 +87,28 @@ fn main() -> Result<()> {
|
||||||
insecure,
|
insecure,
|
||||||
theme,
|
theme,
|
||||||
} => {
|
} => {
|
||||||
let session = net::authenticate(&ip, port, &user, &password, no_tls, insecure)?;
|
// Pick a handle and authenticate. If no name was given on the CLI,
|
||||||
|
// prompt for one as the first thing on join — and re-prompt if the
|
||||||
|
// server rejects it (e.g. the name is already taken in the room).
|
||||||
|
let interactive = user.is_none();
|
||||||
|
let mut name = match user {
|
||||||
|
Some(u) => u,
|
||||||
|
None => prompt_handle()?,
|
||||||
|
};
|
||||||
|
let session = loop {
|
||||||
|
match net::authenticate(&ip, port, &name, &password, no_tls, insecure) {
|
||||||
|
Ok(s) => break s,
|
||||||
|
Err(e) if interactive => {
|
||||||
|
eprintln!("✖ {e:#}\n that handle didn't work (taken or full?) — pick another.");
|
||||||
|
name = prompt_handle()?;
|
||||||
|
}
|
||||||
|
Err(e) => return Err(e),
|
||||||
|
}
|
||||||
|
};
|
||||||
let params = net::ConnParams {
|
let params = net::ConnParams {
|
||||||
ip,
|
ip,
|
||||||
port,
|
port,
|
||||||
user,
|
user: name,
|
||||||
password,
|
password,
|
||||||
no_tls,
|
no_tls,
|
||||||
insecure,
|
insecure,
|
||||||
|
|
@ -145,6 +163,25 @@ fn main() -> Result<()> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Prompt for a display name on stdin before the TUI starts. Loops until a
|
||||||
|
/// non-empty handle is entered; errors only if stdin closes (EOF).
|
||||||
|
fn prompt_handle() -> Result<String> {
|
||||||
|
use std::io::Write;
|
||||||
|
loop {
|
||||||
|
print!("⛧ choose your handle: ");
|
||||||
|
std::io::stdout().flush()?;
|
||||||
|
let mut s = String::new();
|
||||||
|
if std::io::stdin().read_line(&mut s)? == 0 {
|
||||||
|
anyhow::bail!("no handle entered (stdin closed)");
|
||||||
|
}
|
||||||
|
let name = s.trim();
|
||||||
|
if !name.is_empty() {
|
||||||
|
return Ok(name.to_string());
|
||||||
|
}
|
||||||
|
eprintln!("a handle can't be empty.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn selftest() -> Result<()> {
|
fn selftest() -> Result<()> {
|
||||||
// Re-derive the golden vectors at runtime as a smoke check.
|
// Re-derive the golden vectors at runtime as a smoke check.
|
||||||
let c = crypto::SrpClient::with_a(b"chat", b"labtest", &{
|
let c = crypto::SrpClient::with_a(b"chat", b"labtest", &{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user