1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
use yew::prelude::*; use crate::button::*; use crate::form::*; use crate::icon::*; use crate::*; use std::time::Duration; use stdweb::js; use yew::services::{Task, TimeoutService}; #[derive(Clone, PartialEq, Properties)] pub struct Props { #[prop_or_default] pub value: String, #[prop_or_default] pub readonly: bool, } pub enum Msg { Copy, Copied, Reset, } const DEFAULT_MESSAGE: &'static str = "Copy to clipboard"; pub struct Clipboard { props: Props, link: ComponentLink<Self>, message: &'static str, task: Option<Box<dyn Task>>, } impl Component for Clipboard { type Message = Msg; type Properties = Props; fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self { Self { props, link, message: DEFAULT_MESSAGE, task: None, } } fn update(&mut self, msg: Self::Message) -> ShouldRender { match msg { Msg::Copy => self.do_copy(), Msg::Copied => { log::info!("Copied"); self.message = "Copied!"; self.task = Some(Box::new(TimeoutService::spawn( Duration::from_secs(2), self.link.callback(|_| Msg::Reset), ))); } Msg::Reset => { self.message = DEFAULT_MESSAGE; self.task.take(); } } true } fn change(&mut self, props: Self::Properties) -> ShouldRender { if self.props != props { self.props = props; true } else { false } } fn view(&self) -> Html { html! { <div class="pf-c-clipboard-copy"> <div class="pf-c-clipboard-copy__group"> <TextInput value=&self.props.value/> <Tooltip text=self.message> <Button variant=Variant::Control icon=Icon::Copy onclick=self.link.callback(|_|Msg::Copy)/> </Tooltip> </div> </div> } } } impl Clipboard { fn do_copy(&self) { let s = self.props.value.clone(); let cb: Callback<()> = self.link.callback(|_| Msg::Copied); let on_copied = move || cb.emit(()); js! { @(no_return) var on_copied = @{on_copied}; window.navigator.clipboard.writeText(@{s}).then(function(){ try { on_copied(); } finally { on_copied.drop(); } }); }; } }