dioxus-helmet icon indicating copy to clipboard operation
dioxus-helmet copied to clipboard

Upgrade dioxus to 0.5

Open painedpineapple opened this issue 1 year ago • 2 comments

Closes https://github.com/dioxus-community/dioxus-helmet/issues/3

painedpineapple avatar May 13 '24 18:05 painedpineapple

@marc2332 My apologies here. I had only intended to use this internally and quickly scraped something that was working for my intended purposes. I should have cleaned it up a bit before opening this PR. I am a bit of a rust noob and am running into an error that I cannot figure out how to resolve when attempting to use the custom HelmetProps with the Drop trait. Maybe this will seem obvious to you?

cannot move out of type `HelmetProps`, which implements the `Drop` trait
move occurs because `new_clone.children` has type `std::option::Option<dioxus::prelude::VNode>`, which does not implement the 

code:

#[derive(Props, Clone, PartialEq)]
pub struct HelmetProps {
    children: Element,
}

pub fn Helmet(props: HelmetProps) -> Element {
    if let Some(window) = web_sys::window() {
        if let Some(document) = window.document() {
            if let Some(head) = document.head() {
                if let Some(element_maps) = extract_element_maps(&props.children) {
                    if let Ok(mut init_cache) = INIT_CACHE.try_lock() {
                        element_maps.iter().for_each(|element_map| {
                            let mut hasher = FxHasher::default();
                            element_map.hash(&mut hasher);
                            let hash = hasher.finish();

                            if !init_cache.contains(&hash) {
                                init_cache.push(hash);

                                if let Some(new_element) =
                                    element_map.try_into_element(&document, &hash)
                                {
                                    let _ = head.append_child(&new_element);
                                }
                            }
                        });
                    }
                }
            }
        }
    }

    None
}

impl Drop for HelmetProps {
    fn drop(&mut self) {
        if let Some(window) = web_sys::window() {
            if let Some(document) = window.document() {
                if let Some(element_maps) = extract_element_maps(&self.children) {
                    if let Ok(mut init_cache) = INIT_CACHE.try_lock() {
                        element_maps.iter().for_each(|element_map| {
                            let mut hasher = FxHasher::default();
                            element_map.hash(&mut hasher);
                            let hash = hasher.finish();

                            if let Some(index) = init_cache.iter().position(|&c| c == hash) {
                                init_cache.remove(index);
                            }

                            if let Ok(children) =
                                document.query_selector_all(&format!("[data-helmet-id='{hash}']"))
                            {
                                if let Ok(Some(children_iter)) = js_sys::try_iter(&children) {
                                    children_iter.for_each(|child| {
                                        if let Ok(child) = child {
                                            let el = web_sys::Element::from(child);
                                            el.remove();
                                        };
                                    });
                                }
                            }
                        });
                    }
                }
            }
        }
    }
}

painedpineapple avatar May 13 '24 21:05 painedpineapple

Hmmm, I see, it actually doesn't make sense to implement Drop in the Props anyway. I will try to update it according the new dioxus 0.5 apis asap 👍🏻 No worries

marc2332 avatar May 13 '24 21:05 marc2332