notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

commit d1f38c3d19c61d0db92d86ab649dcb3998a5d9bc
parent 26b58683b8bb72771fca4397d9657d064ec705ca
Author: William Casarin <jb55@jb55.com>
Date:   Fri, 21 Mar 2025 16:46:31 -0700

Merge right click paste #507

jglad (1):
      #507 add right click paste in search

Diffstat:
MCargo.lock | 2++
MCargo.toml | 2+-
Mcrates/notedeck/Cargo.toml | 1+
Mcrates/notedeck/src/app.rs | 4++++
Mcrates/notedeck/src/context.rs | 2++
Mcrates/notedeck_columns/Cargo.toml | 1+
Mcrates/notedeck_columns/src/nav.rs | 2+-
Mcrates/notedeck_columns/src/ui/search/mod.rs | 31++++++++++++++++++++++++++-----
8 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -2729,6 +2729,7 @@ dependencies = [ "dirs", "eframe", "egui", + "egui-winit", "ehttp", "enostr", "hex", @@ -2786,6 +2787,7 @@ dependencies = [ "dirs", "eframe", "egui", + "egui-winit", "egui_extras", "egui_nav", "egui_tabs", diff --git a/Cargo.toml b/Cargo.toml @@ -19,7 +19,7 @@ dirs = "5.0.1" eframe = { version = "0.31.1", default-features = false, features = [ "wgpu", "wayland", "x11", "android-game-activity" ] } egui = { version = "0.31.1", features = ["serde"] } egui_extras = { version = "0.31.1", features = ["all_loaders"] } -egui-winit = { version = "0.31.1", features = ["android-game-activity"] } +egui-winit = { version = "0.31.1", features = ["android-game-activity", "clipboard"] } egui_nav = { git = "https://github.com/damus-io/egui-nav", rev = "5e816ac95e20f31dbb243a0d76179eab329a8ac0" } egui_tabs = { git = "https://github.com/damus-io/egui-tabs", rev = "881d86bdf8b424563bf0869eaab5ab9a69e012a4" } #egui_virtual_list = "0.6.0" diff --git a/crates/notedeck/Cargo.toml b/crates/notedeck/Cargo.toml @@ -30,6 +30,7 @@ sha2 = { workspace = true } bincode = { workspace = true } ehttp = {workspace = true } mime_guess = { workspace = true } +egui-winit = { workspace = true } [dev-dependencies] tempfile = { workspace = true } diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs @@ -4,6 +4,7 @@ use crate::{ KeyStorageType, NoteCache, RelayDebugView, ThemeHandler, UnknownIds, }; use egui::ThemePreference; +use egui_winit::clipboard::Clipboard; use enostr::RelayPool; use nostrdb::{Config, Ndb, Transaction}; use std::cell::RefCell; @@ -31,6 +32,7 @@ pub struct Notedeck { zoom: ZoomHandler, app_size: AppSizeHandler, unrecognized_args: BTreeSet<String>, + clipboard: Clipboard, } /// Our chrome, which is basically nothing @@ -214,6 +216,7 @@ impl Notedeck { zoom, app_size, unrecognized_args, + clipboard: Clipboard::new(None), } } @@ -233,6 +236,7 @@ impl Notedeck { path: &self.path, args: &self.args, theme: &mut self.theme, + clipboard: &mut self.clipboard, } } diff --git a/crates/notedeck/src/context.rs b/crates/notedeck/src/context.rs @@ -1,4 +1,5 @@ use crate::{Accounts, Args, DataPath, Images, NoteCache, ThemeHandler, UnknownIds}; +use egui_winit::clipboard::Clipboard; use enostr::RelayPool; use nostrdb::Ndb; @@ -15,4 +16,5 @@ pub struct AppContext<'a> { pub path: &'a DataPath, pub args: &'a Args, pub theme: &'a mut ThemeHandler, + pub clipboard: &'a mut Clipboard, } diff --git a/crates/notedeck_columns/Cargo.toml b/crates/notedeck_columns/Cargo.toml @@ -48,6 +48,7 @@ urlencoding = { workspace = true } uuid = { workspace = true } sha2 = { workspace = true } base64 = { workspace = true } +egui-winit = { workspace = true } [target.'cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))'.dependencies] rfd = "0.15" diff --git a/crates/notedeck_columns/src/nav.rs b/crates/notedeck_columns/src/nav.rs @@ -424,7 +424,7 @@ fn render_nav_body( search_buffer, &mut note_context, ) - .show(ui) + .show(ui, ctx.clipboard) .map(RenderNavAction::NoteAction) } diff --git a/crates/notedeck_columns/src/ui/search/mod.rs b/crates/notedeck_columns/src/ui/search/mod.rs @@ -5,6 +5,7 @@ use crate::{ actionbar::NoteAction, ui::{note::NoteOptions, timeline::TimelineTabView}, }; +use egui_winit::clipboard::Clipboard; use nostrdb::{Filter, Transaction}; use notedeck::{MuteFun, NoteRef}; use std::time::{Duration, Instant}; @@ -39,14 +40,18 @@ impl<'a, 'd> SearchView<'a, 'd> { } } - pub fn show(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> { - padding(8.0, ui, |ui| self.show_impl(ui)).inner + pub fn show(&mut self, ui: &mut egui::Ui, clipboard: &mut Clipboard) -> Option<NoteAction> { + padding(8.0, ui, |ui| self.show_impl(ui, clipboard)).inner } - pub fn show_impl(&mut self, ui: &mut egui::Ui) -> Option<NoteAction> { + pub fn show_impl( + &mut self, + ui: &mut egui::Ui, + clipboard: &mut Clipboard, + ) -> Option<NoteAction> { ui.spacing_mut().item_spacing = egui::vec2(0.0, 12.0); - if search_box(self.query, ui) { + if search_box(self.query, ui, clipboard) { self.execute_search(ui.ctx()); } @@ -132,7 +137,7 @@ impl<'a, 'd> SearchView<'a, 'd> { } } -fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui) -> bool { +fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui, clipboard: &mut Clipboard) -> bool { ui.horizontal(|ui| { // Container for search input and icon let search_container = egui::Frame { @@ -168,6 +173,22 @@ fn search_box(query: &mut SearchQueryState, ui: &mut egui::Ui) -> bool { .frame(false), ); + response.context_menu(|ui| { + if ui.button("paste").clicked() { + if let Some(text) = clipboard.get() { + query.string.clear(); + query.string.push_str(&text); + } + } + }); + + if response.middle_clicked() { + if let Some(text) = clipboard.get() { + query.string.clear(); + query.string.push_str(&text); + } + } + if query.focus_state == FocusState::ShouldRequestFocus { response.request_focus(); query.focus_state = FocusState::RequestedFocus;