diff --git a/Cargo.lock b/Cargo.lock index 329cce7..f68f5e9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -881,6 +881,8 @@ dependencies = [ "copypasta", "dioxus", "dioxus-lib", + "wasm-bindgen-futures", + "web-sys", ] [[package]] @@ -2285,10 +2287,11 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -2360,9 +2363,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" @@ -4076,9 +4079,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.41.1" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", @@ -4094,9 +4097,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -4417,24 +4420,24 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.89", @@ -4443,21 +4446,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4465,9 +4469,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -4478,9 +4482,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-streams" @@ -4593,9 +4600,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/Cargo.toml b/Cargo.toml index 8a6e9cf..5fc2214 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,16 @@ repository = "https://github.com/dioxus-community/dioxus-clipboard" keywords = ["dioxus"] categories = ["gui"] + + [dependencies] dioxus-lib = { version = "0.6.0", default-features = false, features = ["macro", "hooks", "signals"] } copypasta = "0.10" +web-sys = { version = "0.3.77", default-features = false, features = ["Clipboard", "Window", "Navigator", "Permissions"] } +wasm-bindgen-futures = { version = "0.4.50" } + [dev-dependencies] -dioxus = { version = "0.6.0", features = ["desktop"]} \ No newline at end of file +dioxus = { version = "0.6.0", features = ["desktop"]} + + diff --git a/src/hooks/mod.rs b/src/hooks/mod.rs index f51ee17..2901b5c 100644 --- a/src/hooks/mod.rs +++ b/src/hooks/mod.rs @@ -1,3 +1,7 @@ -mod use_clipboard; +mod use_clipboard_desktop; +mod use_clipboard_wasm; +mod use_clipboard_kind; -pub use use_clipboard::*; + + +pub use use_clipboard_desktop::*; diff --git a/src/hooks/use_clipboard.rs b/src/hooks/use_clipboard_desktop.rs similarity index 70% rename from src/hooks/use_clipboard.rs rename to src/hooks/use_clipboard_desktop.rs index 0ac4d0f..8a4f8e4 100644 --- a/src/hooks/use_clipboard.rs +++ b/src/hooks/use_clipboard_desktop.rs @@ -3,6 +3,10 @@ use copypasta::{ClipboardContext, ClipboardProvider}; use dioxus_lib::prelude::*; +#[cfg(target_arch = "wasm32")] +use super::use_clipboard_wasm::UseClipboardWasm; +use super::use_clipboard_kind::UseClipboard; + #[derive(Debug, PartialEq, Clone)] pub enum ClipboardError { FailedToRead, @@ -14,11 +18,16 @@ pub enum ClipboardError { /// /// Use it through [use_clipboard]. #[derive(Clone, Copy, PartialEq)] -pub struct UseClipboard { - clipboard: Signal>, +pub struct UseClipboardDesktop { + pub(crate) clipboard: Signal>, } -impl UseClipboard { +impl UseClipboardDesktop { + pub(crate) fn new() -> Self { + Self { + clipboard: Signal::new_in_scope(ClipboardContext::new().ok(), ScopeId::ROOT), + } + } // Read from the clipboard pub fn get(&mut self) -> Result { self.clipboard @@ -51,22 +60,17 @@ impl UseClipboard { /// let mut clipboard = use_clipboard(); /// /// // Read the clipboard content -/// if let Ok(content) = clipboard.get() { +/// if let Ok(content) = clipboard.get().await { /// println!("{}", content); /// } /// /// // Write to the clipboard -/// clipboard.set("Hello, Dioxus!".to_string());; +/// clipboard.set("Hello, Dioxus!".to_string()).await;; /// /// ``` pub fn use_clipboard() -> UseClipboard { - let clipboard = match try_consume_context() { + match try_consume_context() { Some(rt) => rt, - None => { - let clipboard_signal = - Signal::new_in_scope(ClipboardContext::new().ok(), ScopeId::ROOT); - provide_root_context(clipboard_signal) - } - }; - UseClipboard { clipboard } + None => provide_root_context(UseClipboard::new()), + } } diff --git a/src/hooks/use_clipboard_kind.rs b/src/hooks/use_clipboard_kind.rs new file mode 100644 index 0000000..dcb9066 --- /dev/null +++ b/src/hooks/use_clipboard_kind.rs @@ -0,0 +1,34 @@ +use dioxus_lib::prelude::*; + +use super::{use_clipboard_wasm::UseClipboardWasm, ClipboardError, UseClipboardDesktop}; + +#[derive(Clone, Copy)] +pub enum UseClipboard { + Desktop(UseClipboardDesktop), + Wasm(UseClipboardWasm), +} + +impl UseClipboard { + pub fn new() -> Self { + client! { + #[cfg(target_arch = "wasm32")] + return Self::Wasm(UseClipboardWasm::new()); + } + + #[cfg(not(target_arch = "wasm32"))] + return Self::Desktop(UseClipboardDesktop::new()); + } + pub async fn set(&mut self, value: impl Into) -> Result<(), ClipboardError> { + match self { + UseClipboard::Desktop(clipboard) => clipboard.set(value.into()), + UseClipboard::Wasm(clipboard) => clipboard.set(value.into()).await, + + } + } + pub async fn get(&mut self) -> Result { + match self { + UseClipboard::Desktop(clipboard) => clipboard.get(), + UseClipboard::Wasm(clipboard) => clipboard.get().await, + } + } +} diff --git a/src/hooks/use_clipboard_wasm.rs b/src/hooks/use_clipboard_wasm.rs new file mode 100644 index 0000000..d74b09e --- /dev/null +++ b/src/hooks/use_clipboard_wasm.rs @@ -0,0 +1,54 @@ +//! Provides a clipboard abstraction to access the target system's clipboard. + +use dioxus_lib::prelude::*; + +use super::ClipboardError; + +/// Handle to access the ClipboardContext. +/// +/// Use it through [use_clipboard]. +#[derive(Clone, PartialEq, Copy)] +pub struct UseClipboardWasm { + pub clipboard: Signal>, +} + +impl UseClipboardWasm { + pub(crate) fn new() -> Self { + Self { + clipboard: Signal::new_in_scope( + ::web_sys::window().map(|w| w.navigator().clipboard()), + ScopeId::ROOT, + ), + } + } + // Read from the clipboard + pub async fn get(&self) -> Result { + wasm_bindgen_futures::JsFuture::from( + self.clipboard + .read() + .as_ref() + .ok_or(ClipboardError::NotAvailable)? + .read_text(), + ) + .await + .as_mut() + .map_err(|_| ClipboardError::FailedToRead)? + .as_string() + .ok_or(ClipboardError::FailedToRead) + } + // Write to the clipboard + pub async fn set(&mut self, contents: impl Into) -> Result<(), ClipboardError> { + wasm_bindgen_futures::JsFuture::from( + self.clipboard + .write() + .as_mut() + .ok_or(ClipboardError::NotAvailable)? + .write_text(&contents.into()), + ) + .await + .as_mut() + .map_err(|_| ClipboardError::FailedToSet)?; + + Ok(()) + } +}