use anyhow::Result; use std::io::{self, Write}; use tokio::sync::mpsc; use crate::client::AtProtoClient; use crate::jetstream; use crate::tui; pub async fn run_interactive_mode(client: &AtProtoClient, use_tui: bool) -> Result<()> { if use_tui { run_tui_mode(client).await } else { run_simple_repl(client).await } } async fn run_tui_mode(client: &AtProtoClient) -> Result<()> { // Create channel for messages from jetstream to TUI let (message_tx, message_rx) = mpsc::unbounded_channel(); // Get user's DID to filter out our own messages let own_did = client.get_user_did(); // Start jetstream listener in background let jetstream_tx = message_tx.clone(); tokio::spawn(async move { if let Err(e) = jetstream::start_jetstream_listener(jetstream_tx, own_did).await { eprintln!("Jetstream listener error: {}", e); } }); // Run the TUI tui::run_tui(client, message_rx).await } async fn run_simple_repl(client: &AtProtoClient) -> Result<()> { println!("Entering interactive mode. Type /help for commands."); println!("Enter your thoughts line by line, or use commands starting with '/'"); println!(); loop { print!("> "); io::stdout().flush()?; let mut input = String::new(); io::stdin().read_line(&mut input)?; let input = input.trim(); // Skip empty lines if input.is_empty() { continue; } // Handle commands if input.starts_with('/') { match input { "/exit" | "/quit" => { println!("Goodbye!"); break; } "/help" => { show_help(); continue; } _ => { println!("Unknown command: {}. Type /help for available commands.", input); continue; } } } // Publish the blip match client.publish_blip(input).await { Ok(uri) => { println!("✅ Published: {}", uri); } Err(e) => { println!("❌ Failed to publish: {}", e); } } } Ok(()) } fn show_help() { println!("Interactive mode commands:"); println!(" /help - Show this help message"); println!(" /exit, /quit - Exit interactive mode"); println!(); println!("Just type your message and press Enter to publish a blip."); }