feat(cli): add 'message' subcommand to send private messages
`soulseek-rs message <username> <text>` connects, logs in, sends a private message and exits. Smoke-tested against a local soulfind server.
This commit is contained in:
@@ -89,6 +89,15 @@ pub enum Commands {
|
|||||||
)]
|
)]
|
||||||
max_concurrent_downloads: usize,
|
max_concurrent_downloads: usize,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Send a private message to another user
|
||||||
|
Message {
|
||||||
|
/// Username of the recipient
|
||||||
|
username: String,
|
||||||
|
|
||||||
|
/// Message text to send
|
||||||
|
message: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_server_address(server: &str) -> color_eyre::Result<(String, u16)> {
|
pub fn parse_server_address(server: &str) -> color_eyre::Result<(String, u16)> {
|
||||||
|
|||||||
@@ -89,6 +89,21 @@ fn main() -> Result<()> {
|
|||||||
};
|
};
|
||||||
search_and_download(config)
|
search_and_download(config)
|
||||||
}
|
}
|
||||||
|
Some(Commands::Message {
|
||||||
|
username: recipient,
|
||||||
|
message,
|
||||||
|
}) => send_private_message(
|
||||||
|
&ClientSettings {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
server_address: PeerAddress::new(server_host, server_port),
|
||||||
|
enable_listen: !cli.disable_listener,
|
||||||
|
listen_port: cli.listener_port,
|
||||||
|
shared_directory,
|
||||||
|
},
|
||||||
|
&recipient,
|
||||||
|
&message,
|
||||||
|
),
|
||||||
None => {
|
None => {
|
||||||
use ratatui::crossterm::{
|
use ratatui::crossterm::{
|
||||||
event::EnableMouseCapture,
|
event::EnableMouseCapture,
|
||||||
@@ -139,6 +154,34 @@ fn main() -> Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_private_message(
|
||||||
|
settings: &ClientSettings,
|
||||||
|
recipient: &str,
|
||||||
|
message: &str,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut client = Client::with_settings(settings.clone());
|
||||||
|
client
|
||||||
|
.connect()
|
||||||
|
.map_err(|e| color_eyre::eyre::eyre!("Failed to connect: {}", e))?;
|
||||||
|
if !client
|
||||||
|
.login()
|
||||||
|
.map_err(|e| color_eyre::eyre::eyre!("Failed to login: {}", e))?
|
||||||
|
{
|
||||||
|
return Err(color_eyre::eyre::eyre!("Login rejected by server"));
|
||||||
|
}
|
||||||
|
|
||||||
|
client
|
||||||
|
.send_private_message(recipient, message)
|
||||||
|
.map_err(|e| color_eyre::eyre::eyre!("Failed to send message: {}", e))?;
|
||||||
|
|
||||||
|
// The send is dispatched asynchronously; give the server actor a moment to
|
||||||
|
// flush it to the socket before we drop the client and exit.
|
||||||
|
std::thread::sleep(Duration::from_millis(500));
|
||||||
|
|
||||||
|
println!("✉️ Message sent to {recipient}");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn search_and_download(config: SearchConfig) -> Result<()> {
|
fn search_and_download(config: SearchConfig) -> Result<()> {
|
||||||
if config.verbose > 0 {
|
if config.verbose > 0 {
|
||||||
println!(
|
println!(
|
||||||
|
|||||||
Reference in New Issue
Block a user