perspective_viewer/custom_elements/
copy_dropdown.rs1use std::cell::RefCell;
14use std::rc::Rc;
15
16use ::perspective_js::utils::{global, *};
17use wasm_bindgen::prelude::*;
18use wasm_bindgen_futures::spawn_local;
19use web_sys::*;
20use yew::*;
21
22use super::modal::*;
23use super::viewer::PerspectiveViewerElement;
24use crate::components::copy_dropdown::{CopyDropDownMenu, CopyDropDownMenuProps};
25use crate::js::*;
26use crate::model::*;
27use crate::utils::*;
28
29#[wasm_bindgen]
30#[derive(Clone)]
31pub struct CopyDropDownMenuElement {
32 elem: HtmlElement,
33 modal: Rc<RefCell<Option<ModalElement<CopyDropDownMenu>>>>,
34}
35
36impl CustomElementMetadata for CopyDropDownMenuElement {
37 const CUSTOM_ELEMENT_NAME: &'static str = "perspective-copy-menu";
38}
39
40#[wasm_bindgen]
41impl CopyDropDownMenuElement {
42 #[wasm_bindgen(constructor)]
43 pub fn new(elem: HtmlElement) -> Self {
44 Self {
45 elem,
46 modal: Default::default(),
47 }
48 }
49
50 pub fn open(&self, target: HtmlElement) {
51 if let Some(x) = &*self.modal.borrow() {
52 ApiFuture::spawn(x.clone().open(target, None));
53 }
54 }
55
56 pub fn hide(&self) -> ApiResult<()> {
57 let borrowed = self.modal.borrow();
58 borrowed.as_ref().into_apierror()?.hide()
59 }
60
61 #[allow(clippy::not_unsafe_ptr_arg_deref)]
65 pub fn unsafe_set_model(&self, ptr: *const PerspectiveViewerElement) {
66 let model = unsafe { ptr.as_ref().unwrap() };
67 self.set_model(model);
68 }
69
70 pub fn connected_callback(&self) {}
71}
72
73impl CopyDropDownMenuElement {
74 pub fn new_from_model<A: GetViewerConfigModel>(model: &A) -> Self {
75 let dropdown = global::document()
76 .create_element("perspective-copy-menu")
77 .unwrap()
78 .unchecked_into::<HtmlElement>();
79
80 let elem = Self::new(dropdown);
81 elem.set_model(model);
82 elem
83 }
84
85 pub fn set_model<A: GetViewerConfigModel>(&self, model: &A) {
86 let callback = Callback::from({
87 let model = model.cloned();
88 let modal_rc = self.modal.clone();
89 move |x: ExportMethod| {
90 let js_task = model.export_method_to_jsvalue(x);
91 let copy_task = copy_to_clipboard(js_task, x.mimetype());
92 let modal = modal_rc.borrow().clone().unwrap();
93 spawn_local(async move {
94 let result = copy_task.await;
95 crate::js_log_maybe!({
96 result?;
97 modal.hide()?;
98 })
99 })
100 }
101 });
102
103 let renderer = model.renderer().clone();
104 let props = props!(CopyDropDownMenuProps { renderer, callback });
105 let modal = ModalElement::new(self.elem.clone(), props, true, None);
106 *self.modal.borrow_mut() = Some(modal);
107 }
108}