Skip to content

Commit ce50bd1

Browse files
committed
Add storing clipboard data logic
1 parent f83c101 commit ce50bd1

File tree

3 files changed

+91
-3
lines changed

3 files changed

+91
-3
lines changed

src/app.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use crate::commands::Function;
1+
use crate::commands::{ClipBoardContentType, ClipboardContent, Function};
22
use crate::config::Config;
33
use crate::macos::{focus_this_app, transform_process_to_ui_element};
44
use crate::{macos, utils::get_installed_apps};
55

6+
use arboard::{Clipboard, ImageData};
67
use global_hotkey::{GlobalHotKeyEvent, HotKeyState};
78
use iced::futures::SinkExt;
89
use iced::{
@@ -116,6 +117,8 @@ pub enum Message {
116117
WindowFocusChanged(Id, bool),
117118
ClearSearchQuery,
118119
ReloadConfig,
120+
ClipboardHistory(ClipBoardContentType),
121+
ShowClipboardHistory,
119122
_Nothing,
120123
}
121124

@@ -148,6 +151,7 @@ pub struct Tile {
148151
frontmost: Option<Retained<NSRunningApplication>>,
149152
config: Config,
150153
open_hotkey_id: u32,
154+
clipboard_content: Vec<ClipboardContent>,
151155
}
152156

153157
impl Tile {
@@ -197,6 +201,7 @@ impl Tile {
197201
config: config.clone(),
198202
theme: config.theme.to_owned().to_iced_theme(),
199203
open_hotkey_id: keybind_id,
204+
clipboard_content: vec![],
200205
},
201206
Task::batch([open.map(|_| Message::OpenWindow)]),
202207
)
@@ -347,6 +352,16 @@ impl Tile {
347352
}
348353
}
349354

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+
350365
Message::_Nothing => Task::none(),
351366
}
352367
}
@@ -391,6 +406,7 @@ impl Tile {
391406
Subscription::batch([
392407
Subscription::run(handle_hotkeys),
393408
Subscription::run(handle_hot_reloading),
409+
Subscription::run(handle_clipboard_history),
394410
window::close_events().map(Message::HideWindow),
395411
keyboard::listen().filter_map(|event| {
396412
if let keyboard::Event::KeyPressed { key, .. } = event {
@@ -494,3 +510,31 @@ fn handle_hotkeys() -> impl futures::Stream<Item = Message> {
494510
}
495511
})
496512
}
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+
}

src/commands.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use std::process::Command;
22

3-
use arboard::Clipboard;
3+
use arboard::{Clipboard, ImageData};
44
use objc2_app_kit::NSWorkspace;
55
use objc2_foundation::NSURL;
66

7-
use crate::config::Config;
7+
use crate::{config::Config, utils::get_time_since_epoch};
88

99
#[derive(Debug, Clone)]
1010
pub enum Function {
@@ -63,3 +63,39 @@ impl Function {
6363
}
6464
}
6565
}
66+
67+
#[derive(Debug, Clone)]
68+
pub struct ClipboardContent {
69+
pub content_type: ClipBoardContentType,
70+
pub copied_since_epoch: i64,
71+
}
72+
73+
#[derive(Debug, Clone)]
74+
pub enum ClipBoardContentType {
75+
Text(String),
76+
Image(ImageData<'static>),
77+
}
78+
79+
impl PartialEq for ClipBoardContentType {
80+
fn eq(&self, other: &Self) -> bool {
81+
if let Self::Text(a) = self
82+
&& let Self::Text(b) = other
83+
{
84+
return a == b;
85+
} else if let Self::Image(image_data) = self
86+
&& let Self::Image(other_image_data) = other
87+
{
88+
return image_data.bytes == other_image_data.bytes;
89+
}
90+
false
91+
}
92+
}
93+
94+
impl ClipboardContent {
95+
pub fn from_content_type(content_type: ClipBoardContentType) -> ClipboardContent {
96+
Self {
97+
content_type,
98+
copied_since_epoch: get_time_since_epoch(),
99+
}
100+
}
101+
}

src/utils.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{
33
io::Write,
44
path::{Path, PathBuf},
55
process::exit,
6+
time::SystemTime,
67
};
78

89
use global_hotkey::hotkey::Code;
@@ -287,3 +288,10 @@ pub fn to_key_code(key_str: &str) -> Option<Code> {
287288
_ => None,
288289
}
289290
}
291+
292+
pub fn get_time_since_epoch() -> i64 {
293+
SystemTime::now()
294+
.duration_since(SystemTime::UNIX_EPOCH)
295+
.unwrap()
296+
.as_millis() as i64
297+
}

0 commit comments

Comments
 (0)