mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-05-12 21:19:44 +00:00
chore: fmt and clippy
This commit is contained in:
parent
3ada077429
commit
d48d24a471
@ -109,12 +109,11 @@ impl ChatApp {
|
|||||||
|
|
||||||
/// Load state from file.
|
/// Load state from file.
|
||||||
fn load_state(path: &PathBuf) -> AppState {
|
fn load_state(path: &PathBuf) -> AppState {
|
||||||
if path.exists() {
|
if path.exists()
|
||||||
if let Ok(contents) = fs::read_to_string(path) {
|
&& let Ok(contents) = fs::read_to_string(path)
|
||||||
if let Ok(state) = serde_json::from_str(&contents) {
|
&& let Ok(state) = serde_json::from_str(&contents)
|
||||||
return state;
|
{
|
||||||
}
|
return state;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AppState::default()
|
AppState::default()
|
||||||
}
|
}
|
||||||
@ -307,14 +306,14 @@ impl ChatApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let message = String::from_utf8_lossy(&content.data).to_string();
|
let message = String::from_utf8_lossy(&content.data).to_string();
|
||||||
if !message.is_empty() {
|
if !message.is_empty()
|
||||||
if let Some(session) = self.state.sessions.get_mut(from_user) {
|
&& let Some(session) = self.state.sessions.get_mut(from_user)
|
||||||
session.messages.push(DisplayMessage {
|
{
|
||||||
from_self: false,
|
session.messages.push(DisplayMessage {
|
||||||
content: message,
|
from_self: false,
|
||||||
timestamp: envelope.timestamp,
|
content: message,
|
||||||
});
|
timestamp: envelope.timestamp,
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
self.save_state()?;
|
self.save_state()?;
|
||||||
@ -334,11 +333,11 @@ impl ChatApp {
|
|||||||
timestamp: now(),
|
timestamp: now(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(active) = &self.state.active_chat.clone() {
|
if let Some(active) = &self.state.active_chat.clone()
|
||||||
if let Some(session) = self.state.sessions.get_mut(active) {
|
&& let Some(session) = self.state.sessions.get_mut(active)
|
||||||
session.messages.push(msg);
|
{
|
||||||
return;
|
session.messages.push(msg);
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
// No active chat - add to global messages
|
// No active chat - add to global messages
|
||||||
self.global_messages.push(msg);
|
self.global_messages.push(msg);
|
||||||
@ -443,11 +442,11 @@ impl ChatApp {
|
|||||||
Ok(Some(status))
|
Ok(Some(status))
|
||||||
}
|
}
|
||||||
"/clear" => {
|
"/clear" => {
|
||||||
if let Some(active) = &self.state.active_chat {
|
if let Some(active) = &self.state.active_chat.clone()
|
||||||
if let Some(session) = self.state.sessions.get_mut(active) {
|
&& let Some(session) = self.state.sessions.get_mut(active)
|
||||||
session.messages.clear();
|
{
|
||||||
self.save_state()?;
|
session.messages.clear();
|
||||||
}
|
self.save_state()?;
|
||||||
}
|
}
|
||||||
Ok(Some("Messages cleared".to_string()))
|
Ok(Some("Messages cleared".to_string()))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -31,13 +31,12 @@ pub struct FileTransport {
|
|||||||
|
|
||||||
impl FileTransport {
|
impl FileTransport {
|
||||||
/// Create a new file transport.
|
/// Create a new file transport.
|
||||||
pub fn new(user_name: &str, data_dir: &PathBuf) -> Result<Self> {
|
pub fn new(user_name: &str, data_dir: &Path) -> Result<Self> {
|
||||||
let base_dir = data_dir.join("transport");
|
let base_dir = data_dir.join("transport");
|
||||||
let inbox_dir = base_dir.join(user_name);
|
let inbox_dir = base_dir.join(user_name);
|
||||||
|
|
||||||
// Create our inbox directory
|
// Create our inbox directory
|
||||||
fs::create_dir_all(&inbox_dir)
|
fs::create_dir_all(&inbox_dir).context("Failed to create inbox directory")?;
|
||||||
.context("Failed to create inbox directory")?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
user_name: user_name.to_string(),
|
user_name: user_name.to_string(),
|
||||||
@ -50,10 +49,9 @@ impl FileTransport {
|
|||||||
/// Send a message to a specific user.
|
/// Send a message to a specific user.
|
||||||
pub fn send(&self, to_user: &str, data: Vec<u8>) -> Result<()> {
|
pub fn send(&self, to_user: &str, data: Vec<u8>) -> Result<()> {
|
||||||
let target_dir = self.base_dir.join(to_user);
|
let target_dir = self.base_dir.join(to_user);
|
||||||
|
|
||||||
// Create target inbox if it doesn't exist
|
// Create target inbox if it doesn't exist
|
||||||
fs::create_dir_all(&target_dir)
|
fs::create_dir_all(&target_dir).context("Failed to create target inbox")?;
|
||||||
.context("Failed to create target inbox")?;
|
|
||||||
|
|
||||||
let envelope = MessageEnvelope {
|
let envelope = MessageEnvelope {
|
||||||
from: self.user_name.clone(),
|
from: self.user_name.clone(),
|
||||||
@ -64,10 +62,9 @@ impl FileTransport {
|
|||||||
// Write message to a unique file
|
// Write message to a unique file
|
||||||
let filename = format!("{}_{}.json", self.user_name, now());
|
let filename = format!("{}_{}.json", self.user_name, now());
|
||||||
let filepath = target_dir.join(&filename);
|
let filepath = target_dir.join(&filename);
|
||||||
|
|
||||||
let json = serde_json::to_string_pretty(&envelope)?;
|
let json = serde_json::to_string_pretty(&envelope)?;
|
||||||
fs::write(&filepath, json)
|
fs::write(&filepath, json).context("Failed to write message file")?;
|
||||||
.context("Failed to write message file")?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -82,13 +79,14 @@ impl FileTransport {
|
|||||||
|
|
||||||
for entry in entries.flatten() {
|
for entry in entries.flatten() {
|
||||||
let path = entry.path();
|
let path = entry.path();
|
||||||
|
|
||||||
// Skip non-json files
|
// Skip non-json files
|
||||||
if path.extension().map(|e| e != "json").unwrap_or(true) {
|
if path.extension().map(|e| e != "json").unwrap_or(true) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let filename = path.file_name()
|
let filename = path
|
||||||
|
.file_name()
|
||||||
.and_then(|n| n.to_str())
|
.and_then(|n| n.to_str())
|
||||||
.unwrap_or("")
|
.unwrap_or("")
|
||||||
.to_string();
|
.to_string();
|
||||||
@ -99,13 +97,13 @@ impl FileTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to read and parse the message
|
// Try to read and parse the message
|
||||||
if let Ok(contents) = fs::read_to_string(&path) {
|
if let Ok(contents) = fs::read_to_string(&path)
|
||||||
if let Ok(envelope) = serde_json::from_str::<MessageEnvelope>(&contents) {
|
&& let Ok(envelope) = serde_json::from_str::<MessageEnvelope>(&contents)
|
||||||
// Mark as processed and delete
|
{
|
||||||
self.processed.insert(filename);
|
// Mark as processed and delete
|
||||||
let _ = fs::remove_file(&path);
|
self.processed.insert(filename);
|
||||||
return Some(envelope);
|
let _ = fs::remove_file(&path);
|
||||||
}
|
return Some(envelope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,19 +113,18 @@ impl FileTransport {
|
|||||||
/// List available peers (users with inbox directories).
|
/// List available peers (users with inbox directories).
|
||||||
pub fn list_peers(&self) -> Vec<String> {
|
pub fn list_peers(&self) -> Vec<String> {
|
||||||
let mut peers = Vec::new();
|
let mut peers = Vec::new();
|
||||||
|
|
||||||
if let Ok(entries) = fs::read_dir(&self.base_dir) {
|
if let Ok(entries) = fs::read_dir(&self.base_dir) {
|
||||||
for entry in entries.flatten() {
|
for entry in entries.flatten() {
|
||||||
if entry.path().is_dir() {
|
if entry.path().is_dir()
|
||||||
if let Some(name) = entry.file_name().to_str() {
|
&& let Some(name) = entry.file_name().to_str()
|
||||||
if name != self.user_name {
|
&& name != self.user_name
|
||||||
peers.push(name.to_string());
|
{
|
||||||
}
|
peers.push(name.to_string());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
peers
|
peers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -98,9 +98,10 @@ fn draw_messages(frame: &mut Frame, app: &ChatApp, area: Rect) {
|
|||||||
// Split content into lines that fit within inner_width.
|
// Split content into lines that fit within inner_width.
|
||||||
let content = &msg.content;
|
let content = &msg.content;
|
||||||
if content.is_empty() {
|
if content.is_empty() {
|
||||||
return vec![ListItem::new(Line::from(vec![
|
return vec![ListItem::new(Line::from(vec![Span::styled(
|
||||||
Span::styled(prefix_str, style.add_modifier(Modifier::BOLD)),
|
prefix_str,
|
||||||
]))];
|
style.add_modifier(Modifier::BOLD),
|
||||||
|
)]))];
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
@ -191,52 +192,52 @@ fn draw_status(frame: &mut Frame, app: &ChatApp, area: Rect) {
|
|||||||
/// Handle keyboard events.
|
/// Handle keyboard events.
|
||||||
pub fn handle_events(app: &mut ChatApp) -> io::Result<bool> {
|
pub fn handle_events(app: &mut ChatApp) -> io::Result<bool> {
|
||||||
// Poll for events with a short timeout to allow checking incoming messages
|
// Poll for events with a short timeout to allow checking incoming messages
|
||||||
if event::poll(std::time::Duration::from_millis(100))? {
|
if event::poll(std::time::Duration::from_millis(100))?
|
||||||
if let Event::Key(key) = event::read()? {
|
&& let Event::Key(key) = event::read()?
|
||||||
if key.kind != KeyEventKind::Press {
|
{
|
||||||
return Ok(true);
|
if key.kind != KeyEventKind::Press {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
match key.code {
|
||||||
|
KeyCode::Esc => return Ok(false),
|
||||||
|
// Handle Ctrl+C
|
||||||
|
KeyCode::Char('c') if key.modifiers.contains(event::KeyModifiers::CONTROL) => {
|
||||||
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
KeyCode::Enter => {
|
||||||
|
if !app.input.is_empty() {
|
||||||
|
let input = std::mem::take(&mut app.input);
|
||||||
|
|
||||||
match key.code {
|
if input.starts_with('/') {
|
||||||
KeyCode::Esc => return Ok(false),
|
match app.handle_command(&input) {
|
||||||
// Handle Ctrl+C
|
Ok(Some(response)) => {
|
||||||
KeyCode::Char('c') if key.modifiers.contains(event::KeyModifiers::CONTROL) => {
|
app.status = response;
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
KeyCode::Enter => {
|
|
||||||
if !app.input.is_empty() {
|
|
||||||
let input = std::mem::take(&mut app.input);
|
|
||||||
|
|
||||||
if input.starts_with('/') {
|
|
||||||
match app.handle_command(&input) {
|
|
||||||
Ok(Some(response)) => {
|
|
||||||
app.status = response;
|
|
||||||
}
|
|
||||||
Ok(None) => {
|
|
||||||
// Quit signal
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
app.status = format!("Error: {}", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if app.current_session().is_some() {
|
Ok(None) => {
|
||||||
if let Err(e) = app.send_message(&input) {
|
// Quit signal
|
||||||
app.status = format!("Send error: {}", e);
|
return Ok(false);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
app.status = format!("Error: {}", e);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
app.status = "No active chat. Use /connect first.".to_string();
|
|
||||||
}
|
}
|
||||||
|
} else if app.current_session().is_some() {
|
||||||
|
if let Err(e) = app.send_message(&input) {
|
||||||
|
app.status = format!("Send error: {}", e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
app.status = "No active chat. Use /connect first.".to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KeyCode::Char(c) => {
|
|
||||||
app.input.push(c);
|
|
||||||
}
|
|
||||||
KeyCode::Backspace => {
|
|
||||||
app.input.pop();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
KeyCode::Char(c) => {
|
||||||
|
app.input.push(c);
|
||||||
|
}
|
||||||
|
KeyCode::Backspace => {
|
||||||
|
app.input.pop();
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user