Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 31 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]}
dioxus = { version = "0.6.0", features = ["desktop"]}


8 changes: 6 additions & 2 deletions src/hooks/mod.rs
Original file line number Diff line number Diff line change
@@ -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::*;
30 changes: 17 additions & 13 deletions src/hooks/use_clipboard.rs → src/hooks/use_clipboard_desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -14,11 +18,16 @@ pub enum ClipboardError {
///
/// Use it through [use_clipboard].
#[derive(Clone, Copy, PartialEq)]
pub struct UseClipboard {
clipboard: Signal<Option<ClipboardContext>>,
pub struct UseClipboardDesktop {
pub(crate) clipboard: Signal<Option<ClipboardContext>>,
}

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<String, ClipboardError> {
self.clipboard
Expand Down Expand Up @@ -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()),
}
}
34 changes: 34 additions & 0 deletions src/hooks/use_clipboard_kind.rs
Original file line number Diff line number Diff line change
@@ -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<String>) -> 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<String, ClipboardError> {
match self {
UseClipboard::Desktop(clipboard) => clipboard.get(),
UseClipboard::Wasm(clipboard) => clipboard.get().await,
}
}
}
54 changes: 54 additions & 0 deletions src/hooks/use_clipboard_wasm.rs
Original file line number Diff line number Diff line change
@@ -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<Option<web_sys::Clipboard>>,
}

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<String, ClipboardError> {
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<String>) -> 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(())
}
}