mirror of
https://github.com/Noratrieb/clippyboard.git
synced 2026-01-14 18:05:04 +01:00
split into crates
This commit is contained in:
parent
06b5244638
commit
14e5170f4f
13 changed files with 112 additions and 67 deletions
12
clippyboard-select/Cargo.toml
Normal file
12
clippyboard-select/Cargo.toml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "clippyboard-select"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clippyboard-shared = { path = "../clippyboard-shared" }
|
||||
ciborium.workspace = true
|
||||
eframe = "0.32.2"
|
||||
egui_extras = { version = "0.32.2", features = ["image"] }
|
||||
eyre.workspace = true
|
||||
serde.workspace = true
|
||||
164
clippyboard-select/src/main.rs
Normal file
164
clippyboard-select/src/main.rs
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
use clippyboard_shared::HistoryItem;
|
||||
use clippyboard_shared::MESSAGE_COPY;
|
||||
use clippyboard_shared::MESSAGE_READ;
|
||||
use eframe::egui;
|
||||
use eyre::Context;
|
||||
use std::{
|
||||
io::{BufReader, Write},
|
||||
os::unix::net::UnixStream,
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
pub(crate) struct App {
|
||||
pub(crate) items: Vec<HistoryItem>,
|
||||
pub(crate) selected_idx: usize,
|
||||
pub(crate) socket: UnixStream,
|
||||
}
|
||||
|
||||
impl eframe::App for App {
|
||||
fn update(&mut self, ctx: &egui::Context, _: &mut eframe::Frame) {
|
||||
egui::CentralPanel::default().show(ctx, |ui| {
|
||||
ui.input(|i| {
|
||||
if i.key_down(egui::Key::Escape) {
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
if i.key_pressed(egui::Key::J) || i.key_pressed(egui::Key::ArrowDown) {
|
||||
if self.selected_idx + 1 != self.items.len() {
|
||||
self.selected_idx += 1;
|
||||
}
|
||||
}
|
||||
if i.key_pressed(egui::Key::K) || i.key_pressed(egui::Key::ArrowUp) {
|
||||
self.selected_idx = self.selected_idx.saturating_sub(1);
|
||||
}
|
||||
|
||||
if i.key_pressed(egui::Key::Enter)
|
||||
&& let Some(item) = self.items.get(self.selected_idx)
|
||||
{
|
||||
let _ = self.socket.write_all(&[MESSAGE_COPY]);
|
||||
let _ = self.socket.write_all(&item.id.to_le_bytes());
|
||||
std::process::exit(0);
|
||||
}
|
||||
});
|
||||
|
||||
ui.heading("clippyboard");
|
||||
|
||||
egui::SidePanel::left("selection_panel")
|
||||
.default_width(400.0)
|
||||
.show_inside(ui, |ui| {
|
||||
ui.heading("History");
|
||||
|
||||
ui.add_space(10.0);
|
||||
|
||||
for (idx, item) in self.items.iter().enumerate() {
|
||||
let mut frame = egui::Frame::new().inner_margin(3.0);
|
||||
if self.selected_idx == idx {
|
||||
frame = frame.stroke(egui::Stroke::new(1.0, egui::Color32::PURPLE));
|
||||
}
|
||||
frame.show(ui, |ui| match item.mime.as_str() {
|
||||
"text/plain" => {
|
||||
let mut full =
|
||||
str::from_utf8(&item.data).unwrap_or("<invalid UTF-8>");
|
||||
if full.len() > 1000 {
|
||||
full = &full[..1000];
|
||||
}
|
||||
ui.label(full);
|
||||
}
|
||||
"image/png" => {
|
||||
ui.label("<image>");
|
||||
}
|
||||
_ => {
|
||||
ui.label("<unsupported mime type>");
|
||||
}
|
||||
});
|
||||
|
||||
ui.separator();
|
||||
}
|
||||
});
|
||||
|
||||
egui::CentralPanel::default().show_inside(ui, |ui| {
|
||||
ui.heading("Detail");
|
||||
let Some(item) = &self.items.get(self.selected_idx) else {
|
||||
return;
|
||||
};
|
||||
|
||||
ui.add_space(10.0);
|
||||
|
||||
ui.label(format!("MIME type: {}", item.mime));
|
||||
|
||||
ui.add_space(10.0);
|
||||
|
||||
match item.mime.as_str() {
|
||||
"text/plain" => {
|
||||
ui.label(str::from_utf8(&item.data).unwrap_or("<invalid UTF-8>"));
|
||||
}
|
||||
"image/png" => {
|
||||
ui.image(egui::ImageSource::Bytes {
|
||||
uri: format!("bytes://{}", item.id).into(),
|
||||
bytes: item.data.clone().into(),
|
||||
});
|
||||
}
|
||||
_ => {
|
||||
ui.label("<unsupported mime type>");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() -> eyre::Result<()> {
|
||||
let socket_path = clippyboard_shared::socket_path()?;
|
||||
|
||||
let mut socket = UnixStream::connect(&socket_path).wrap_err_with(|| {
|
||||
format!(
|
||||
"connecting to socket at {}. is the daemon running?",
|
||||
socket_path.display()
|
||||
)
|
||||
})?;
|
||||
socket
|
||||
.write_all(&[MESSAGE_READ])
|
||||
.wrap_err("writing request type")?;
|
||||
|
||||
println!("INFO: Reading clipboard history from socket");
|
||||
let start = Instant::now();
|
||||
let mut items: Vec<HistoryItem> =
|
||||
ciborium::from_reader(BufReader::new(socket)).wrap_err("reading items from socket")?;
|
||||
println!(
|
||||
"INFO: Read clipboard history from socket in {:?}",
|
||||
start.elapsed()
|
||||
);
|
||||
|
||||
items.reverse();
|
||||
|
||||
// heh. good design.
|
||||
let socket = UnixStream::connect(&socket_path).wrap_err_with(|| {
|
||||
format!(
|
||||
"connecting to socket at {}. is the daemon running?",
|
||||
socket_path.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
let options = eframe::NativeOptions {
|
||||
viewport: egui::ViewportBuilder::default()
|
||||
.with_inner_size([500.0, 500.0])
|
||||
.with_app_id("clippyboard"),
|
||||
..Default::default()
|
||||
};
|
||||
eframe::run_native(
|
||||
"clippyboard",
|
||||
options,
|
||||
Box::new(|cc| {
|
||||
egui_extras::install_image_loaders(&cc.egui_ctx);
|
||||
Ok(Box::new(App {
|
||||
items,
|
||||
selected_idx: 0,
|
||||
socket,
|
||||
}))
|
||||
}),
|
||||
)
|
||||
.map_err(|err| eyre::eyre!(err.to_string()))
|
||||
.wrap_err("running GUI")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue