diff --git a/rklipd/src/database.rs b/rklipd/src/database.rs index 3b79d75..421bab5 100644 --- a/rklipd/src/database.rs +++ b/rklipd/src/database.rs @@ -112,4 +112,10 @@ impl Database { Ok(entries) } + + pub fn delete_entry_by_content(&self, content: &str) -> Result<(), Box> { + self.conn + .execute("DELETE FROM history WHERE content = ?1", [content])?; + Ok(()) + } } diff --git a/rklipd/src/ipc.rs b/rklipd/src/ipc.rs index d0dc095..5a3c9e9 100644 --- a/rklipd/src/ipc.rs +++ b/rklipd/src/ipc.rs @@ -11,6 +11,7 @@ use std::sync::{Arc, Mutex}; pub enum IpcRequest { GetHistory { limit: usize }, SetClipboard { content: String }, + DeleteEntry { content: String }, } #[derive(Serialize, Deserialize, Debug)] @@ -90,6 +91,29 @@ pub fn start_server(db: Arc>, socket_path: &Path) { } } } + + IpcRequest::DeleteEntry { content } => { + { + let db_lock = db_clone.lock().unwrap(); + let _ = db_lock.delete_entry_by_content(&content); + } + + if content.ends_with(".jpg") || content.ends_with(".png") { + if let Some(proj_dirs) = + directories::ProjectDirs::from("com", "zefad", "rklipd") + { + let img_path = + proj_dirs.data_dir().join("images").join(&content); + if img_path.exists() { + if let Err(e) = std::fs::remove_file(&img_path) { + eprintln!("Error while deleting image: {}", e); + } else { + println!("Image deleted : {}", content); + } + } + } + } + } } } } diff --git a/src/app.rs b/src/app.rs index 274b13a..33385e7 100644 --- a/src/app.rs +++ b/src/app.rs @@ -8,6 +8,7 @@ pub enum Mode { Normal, Command, Search, + ConfirmDelete, } pub struct App { diff --git a/src/ipc.rs b/src/ipc.rs index be0d8f5..2372f56 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -6,6 +6,7 @@ use std::os::unix::net::UnixStream; pub enum IpcRequest { GetHistory { limit: usize }, SetClipboard { content: String }, + DeleteEntry { content: String }, } #[derive(Serialize, Deserialize, Debug)] @@ -49,3 +50,16 @@ pub fn set_clipboard(content: String) { } } } + +pub fn delete_entry(content: String) { + if let Some(base_dir) = directories::ProjectDirs::from("com", "zefad", "rklipd") { + let socket_path = base_dir.data_dir().join("rklip.sock"); + if let Ok(mut stream) = UnixStream::connect(&socket_path) { + let req = IpcRequest::DeleteEntry { content }; + if let Ok(req_json) = serde_json::to_string(&req) { + let _ = stream.write_all(req_json.as_bytes()); + let _ = stream.shutdown(std::net::Shutdown::Write); + } + } + } +} diff --git a/src/main.rs b/src/main.rs index 0f3e517..5641af7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -60,7 +60,7 @@ fn run_app(terminal: &mut Terminal>, app: &mut App) } KeyCode::Char('d') => { if last_key_was_d { - app.delete_selected(); + app.mode = Mode::ConfirmDelete; last_key_was_d = false; } else { last_key_was_d = true; @@ -150,6 +150,19 @@ fn run_app(terminal: &mut Terminal>, app: &mut App) } _ => {} }, + Mode::ConfirmDelete => match key.code { + KeyCode::Char('y') | KeyCode::Char('Y') | KeyCode::Enter => { + if let Some(selected) = app.get_selected_item() { + crate::ipc::delete_entry(selected.clone()); + app.delete_selected(); + } + app.mode = Mode::Normal; + } + KeyCode::Char('n') | KeyCode::Char('N') | KeyCode::Esc => { + app.mode = Mode::Normal; + } + _ => {} + }, } } } else { diff --git a/src/ui.rs b/src/ui.rs index ece3a40..d2c7c97 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -21,7 +21,7 @@ pub fn render(f: &mut Frame, app: &mut App) { let content_chunks = Layout::default() .direction(Direction::Horizontal) - .constraints([Constraint::Percentage(50), Constraint::Percentage(50)]) + .constraints([Constraint::Length(50), Constraint::Min(0)]) .split(main_chunks[0]); let items: Vec = app @@ -72,6 +72,10 @@ pub fn render(f: &mut Frame, app: &mut App) { Span::styled("/", Style::default().fg(Color::Cyan)), Span::raw(&app.input_buffer), ]), + Mode::ConfirmDelete => Line::from(vec![Span::styled( + "Delete ? (y/n)", + Style::default().fg(Color::Red).add_modifier(Modifier::BOLD), + )]), }; let bottom_bar = Paragraph::new(bottom_text).block(Block::default().borders(Borders::ALL));