pryty_rustbrowser/
clipboard.rs1use dioxus::prelude::*;
2use wasm_bindgen_futures::JsFuture;
3
4#[derive(Debug, Clone, PartialEq)]
5pub enum ClipboardError {
6 WindowUnavailable,
7 ClipboardUnavailable,
8 ReadFailed(String),
9 WriteFailed(String),
10}
11
12impl core::fmt::Display for ClipboardError {
13 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
14 match self {
15 ClipboardError::WindowUnavailable => write!(f, "window unavailable"),
16 ClipboardError::ClipboardUnavailable => write!(f, "clipboard unavailable"),
17 ClipboardError::ReadFailed(e) => write!(f, "clipboard read failed: {e}"),
18 ClipboardError::WriteFailed(e) => write!(f, "clipboard write failed: {e}"),
19 }
20 }
21}
22
23pub struct Clipboard;
24
25pub fn use_clipboard() -> Clipboard {
26 Clipboard
27}
28
29impl Clipboard {
30 pub fn write(&self, text: &str) -> Callback<()> {
31 let payload = text.to_owned();
32 Callback::new(move |_| {
33 let payload = payload.clone();
34 spawn(async move {
35 let _ = write_clipboard_text(payload).await;
36 });
37 })
38 }
39
40 pub async fn write_async(&self, text: &str) -> Result<(), ClipboardError> {
41 write_clipboard_text(text.to_owned()).await
42 }
43
44 pub async fn read(&self) -> Result<Option<String>, ClipboardError> {
45 let window = web_sys::window().ok_or(ClipboardError::WindowUnavailable)?;
46 let clipboard = window.navigator().clipboard();
47
48 let value = JsFuture::from(clipboard.read_text())
49 .await
50 .map_err(|e| ClipboardError::ReadFailed(format!("{e:?}")))?;
51
52 Ok(value.as_string())
53 }
54}
55
56async fn write_clipboard_text(text: String) -> Result<(), ClipboardError> {
57 let window = web_sys::window().ok_or(ClipboardError::WindowUnavailable)?;
58 let clipboard = window.navigator().clipboard();
59
60 JsFuture::from(clipboard.write_text(&text))
61 .await
62 .map_err(|e| ClipboardError::WriteFailed(format!("{e:?}")))?;
63
64 Ok(())
65}