|
1 | | -use crate::commands::Function; |
| 1 | +use crate::commands::{ClipBoardContentType, ClipboardContent, Function}; |
2 | 2 | use crate::config::Config; |
3 | 3 | use crate::macos::{focus_this_app, transform_process_to_ui_element}; |
4 | 4 | use crate::{macos, utils::get_installed_apps}; |
5 | 5 |
|
| 6 | +use arboard::{Clipboard, ImageData}; |
6 | 7 | use global_hotkey::{GlobalHotKeyEvent, HotKeyState}; |
7 | 8 | use iced::futures::SinkExt; |
8 | 9 | use iced::{ |
@@ -116,6 +117,8 @@ pub enum Message { |
116 | 117 | WindowFocusChanged(Id, bool), |
117 | 118 | ClearSearchQuery, |
118 | 119 | ReloadConfig, |
| 120 | + ClipboardHistory(ClipBoardContentType), |
| 121 | + ShowClipboardHistory, |
119 | 122 | _Nothing, |
120 | 123 | } |
121 | 124 |
|
@@ -148,6 +151,7 @@ pub struct Tile { |
148 | 151 | frontmost: Option<Retained<NSRunningApplication>>, |
149 | 152 | config: Config, |
150 | 153 | open_hotkey_id: u32, |
| 154 | + clipboard_content: Vec<ClipboardContent>, |
151 | 155 | } |
152 | 156 |
|
153 | 157 | impl Tile { |
@@ -197,6 +201,7 @@ impl Tile { |
197 | 201 | config: config.clone(), |
198 | 202 | theme: config.theme.to_owned().to_iced_theme(), |
199 | 203 | open_hotkey_id: keybind_id, |
| 204 | + clipboard_content: vec![], |
200 | 205 | }, |
201 | 206 | Task::batch([open.map(|_| Message::OpenWindow)]), |
202 | 207 | ) |
@@ -347,6 +352,16 @@ impl Tile { |
347 | 352 | } |
348 | 353 | } |
349 | 354 |
|
| 355 | + Message::ClipboardHistory(clip_content) => { |
| 356 | + self.clipboard_content |
| 357 | + .push(ClipboardContent::from_content_type(clip_content)); |
| 358 | + Task::none() |
| 359 | + } |
| 360 | + |
| 361 | + Message::ShowClipboardHistory => { |
| 362 | + Task::none() |
| 363 | + }, |
| 364 | + |
350 | 365 | Message::_Nothing => Task::none(), |
351 | 366 | } |
352 | 367 | } |
@@ -391,6 +406,7 @@ impl Tile { |
391 | 406 | Subscription::batch([ |
392 | 407 | Subscription::run(handle_hotkeys), |
393 | 408 | Subscription::run(handle_hot_reloading), |
| 409 | + Subscription::run(handle_clipboard_history), |
394 | 410 | window::close_events().map(Message::HideWindow), |
395 | 411 | keyboard::listen().filter_map(|event| { |
396 | 412 | if let keyboard::Event::KeyPressed { key, .. } = event { |
@@ -494,3 +510,31 @@ fn handle_hotkeys() -> impl futures::Stream<Item = Message> { |
494 | 510 | } |
495 | 511 | }) |
496 | 512 | } |
| 513 | + |
| 514 | +fn handle_clipboard_history() -> impl futures::Stream<Item = Message> { |
| 515 | + stream::channel(100, async |mut output| { |
| 516 | + let mut clipboard = Clipboard::new().unwrap(); |
| 517 | + let mut prev_byte_rep: Option<ClipBoardContentType> = None; |
| 518 | + |
| 519 | + loop { |
| 520 | + let byte_rep = if let Ok(a) = clipboard.get_image() { |
| 521 | + Some(ClipBoardContentType::Image(a)) |
| 522 | + } else if let Ok(a) = clipboard.get_text() { |
| 523 | + Some(ClipBoardContentType::Text(a)) |
| 524 | + } else { |
| 525 | + None |
| 526 | + }; |
| 527 | + |
| 528 | + if byte_rep != prev_byte_rep |
| 529 | + && let Some(content) = &byte_rep |
| 530 | + { |
| 531 | + output |
| 532 | + .send(Message::ClipboardHistory(content.to_owned())) |
| 533 | + .await |
| 534 | + .ok(); |
| 535 | + prev_byte_rep = byte_rep; |
| 536 | + } |
| 537 | + tokio::time::sleep(Duration::from_millis(10)).await; |
| 538 | + } |
| 539 | + }) |
| 540 | +} |
0 commit comments