From 87bf368da344f5ef177e994aaa2e2e7550fa5c9e Mon Sep 17 00:00:00 2001 From: Maccesch Date: Sat, 29 Jul 2023 15:12:09 +0100 Subject: [PATCH 01/15] fixed use_event_listener removing of listener with non default options --- Cargo.toml | 4 + src/use_event_listener.rs | 7 +- src/use_websocket.rs | 309 +++++++++++++++++++------------------- 3 files changed, 162 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6ba2f57..9b28302 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ cfg-if = "1" [dependencies.web-sys] version = "0.3" features = [ + "AddEventListenerOptions", "BinaryType", "CssStyleDeclaration", "CloseEvent", @@ -37,6 +38,9 @@ features = [ "DataTransfer", "DragEvent", "Element", + "EventListener", + "EventListenerOptions", + "EventTarget", "File", "FileList", "HtmlElement", diff --git a/src/use_event_listener.rs b/src/use_event_listener.rs index f80a645..51f9d5c 100644 --- a/src/use_event_listener.rs +++ b/src/use_event_listener.rs @@ -112,11 +112,13 @@ where let cleanup_fn = { let closure_js = closure_js.clone(); + let options = options.clone(); move |element: &web_sys::EventTarget| { - let _ = element.remove_event_listener_with_callback( + let _ = element.remove_event_listener_with_callback_and_event_listener_options( &event_name, closure_js.as_ref().unchecked_ref(), + options.unchecked_ref(), ); } }; @@ -125,8 +127,7 @@ where let signal = (target).into(); - let prev_element: Rc>> = - Rc::new(RefCell::new(signal.get_untracked().map(|e| e.into()))); + let prev_element = Rc::new(RefCell::new(None::)); let cleanup_prev_element = { let prev_element = prev_element.clone(); diff --git a/src/use_websocket.rs b/src/use_websocket.rs index c75add0..0fbfa3e 100644 --- a/src/use_websocket.rs +++ b/src/use_websocket.rs @@ -24,7 +24,8 @@ use crate::utils::CloneableFnWithArg; /// /// ``` /// # use leptos::*; -/// # use leptos_use::{use_websocket, UseWebsocketReturn}; +/// # use leptos_use::{use_websocket, UseWebsocketReturn}; +/// # use leptos_use::core::ConnectionReadyState; /// # /// # #[component] /// # fn Demo() -> impl IntoView { @@ -37,16 +38,14 @@ use crate::utils::CloneableFnWithArg; /// open, /// close, /// .. -/// } = use_websocket("wss://echo.websocket.events/".to_string()); +/// } = use_websocket("wss://echo.websocket.events/"); /// /// let send_message = move |_| { -/// let m = "Hello, world!".to_string(); -/// send(m.clone()); +/// send("Hello, world!".to_string()); /// }; /// /// let send_byte_message = move |_| { -/// let m = b"Hello, world!\r\n".to_vec(); -/// send_bytes(m.clone()); +/// send_bytes(b"Hello, world!\r\n".to_vec()); /// }; /// /// let status = move || ready_state.get().to_string(); @@ -118,167 +117,167 @@ pub fn use_websocket_with_options( let connect_ref: StoredValue>> = store_value(None); - // cfg_if! { if #[cfg(not(feature = "ssr"))] { - let on_open_ref = store_value(options.on_open); - let on_message_ref = store_value(options.on_message); - let on_message_bytes_ref = store_value(options.on_message_bytes); - let on_error_ref = store_value(options.on_error); - let on_close_ref = store_value(options.on_close); + cfg_if! { if #[cfg(not(feature = "ssr"))] { + let on_open_ref = store_value(options.on_open); + let on_message_ref = store_value(options.on_message); + let on_message_bytes_ref = store_value(options.on_message_bytes); + let on_error_ref = store_value(options.on_error); + let on_close_ref = store_value(options.on_close); - let reconnect_interval = options.reconnect_interval; - let protocols = options.protocols; + let reconnect_interval = options.reconnect_interval; + let protocols = options.protocols; - let reconnect_ref: StoredValue>> = store_value(None); - reconnect_ref.set_value({ - let ws = ws_ref.get_value(); - Some(Rc::new(move || { - if reconnect_times_ref.get_value() < reconnect_limit - && ws - .clone() - .map_or(false, |ws: WebSocket| ws.ready_state() != WebSocket::OPEN) - { - reconnect_timer_ref.set_value( - set_timeout_with_handle( - move || { - if let Some(connect) = connect_ref.get_value() { - connect(); - reconnect_times_ref.update_value(|current| *current += 1); - } - }, - Duration::from_millis(reconnect_interval), - ) - .ok(), - ); - } - })) - }); - - connect_ref.set_value({ - let ws = ws_ref.get_value(); - let url = url; - - Some(Rc::new(move || { - reconnect_timer_ref.set_value(None); - - if let Some(web_socket) = &ws { - let _ = web_socket.close(); - } - - let web_socket = { - protocols.as_ref().map_or_else( - || WebSocket::new(&url).unwrap_throw(), - |protocols| { - let array = protocols - .iter() - .map(|p| JsValue::from(p.clone())) - .collect::(); - WebSocket::new_with_str_sequence(&url, &JsValue::from(&array)) - .unwrap_throw() - }, - ) - }; - web_socket.set_binary_type(BinaryType::Arraybuffer); - set_ready_state.set(ConnectionReadyState::Connecting); - - // onopen handler - { - let onopen_closure = Closure::wrap(Box::new(move |e: Event| { - if unmounted_ref.get_value() { - return; - } - - let callback = on_open_ref.get_value(); - callback(e); - - set_ready_state.set(ConnectionReadyState::Open); - }) as Box); - web_socket.set_onopen(Some(onopen_closure.as_ref().unchecked_ref())); - // Forget the closure to keep it alive - onopen_closure.forget(); - } - - // onmessage handler - { - let onmessage_closure = Closure::wrap(Box::new(move |e: MessageEvent| { - if unmounted_ref.get_value() { - return; - } - - e.data().dyn_into::().map_or_else( - |_| { - e.data().dyn_into::().map_or_else( - |_| { - unreachable!("message event, received Unknown: {:?}", e.data()); - }, - |txt| { - let txt = String::from(&txt); - let callback = on_message_ref.get_value(); - callback(txt.clone()); - - set_message.set(Some(txt)); - }, - ); - }, - |array_buffer| { - let array = js_sys::Uint8Array::new(&array_buffer); - let array = array.to_vec(); - let callback = on_message_bytes_ref.get_value(); - callback(array.clone()); - - set_message_bytes.set(Some(array)); - }, + let reconnect_ref: StoredValue>> = store_value(None); + reconnect_ref.set_value({ + let ws = ws_ref.get_value(); + Some(Rc::new(move || { + if reconnect_times_ref.get_value() < reconnect_limit + && ws + .clone() + .map_or(false, |ws: WebSocket| ws.ready_state() != WebSocket::OPEN) + { + reconnect_timer_ref.set_value( + set_timeout_with_handle( + move || { + if let Some(connect) = connect_ref.get_value() { + connect(); + reconnect_times_ref.update_value(|current| *current += 1); + } + }, + Duration::from_millis(reconnect_interval), + ) + .ok(), ); - }) - as Box); - web_socket.set_onmessage(Some(onmessage_closure.as_ref().unchecked_ref())); - onmessage_closure.forget(); - } + } + })) + }); - // onerror handler - { - let onerror_closure = Closure::wrap(Box::new(move |e: Event| { - if unmounted_ref.get_value() { - return; - } + connect_ref.set_value({ + let ws = ws_ref.get_value(); + let url = url; - if let Some(reconnect) = &reconnect_ref.get_value() { - reconnect(); - } + Some(Rc::new(move || { + reconnect_timer_ref.set_value(None); - let callback = on_error_ref.get_value(); - callback(e); + if let Some(web_socket) = &ws { + let _ = web_socket.close(); + } - set_ready_state.set(ConnectionReadyState::Closed); - }) as Box); - web_socket.set_onerror(Some(onerror_closure.as_ref().unchecked_ref())); - onerror_closure.forget(); - } + let web_socket = { + protocols.as_ref().map_or_else( + || WebSocket::new(&url).unwrap_throw(), + |protocols| { + let array = protocols + .iter() + .map(|p| JsValue::from(p.clone())) + .collect::(); + WebSocket::new_with_str_sequence(&url, &JsValue::from(&array)) + .unwrap_throw() + }, + ) + }; + web_socket.set_binary_type(BinaryType::Arraybuffer); + set_ready_state.set(ConnectionReadyState::Connecting); - // onclose handler - { - let onclose_closure = Closure::wrap(Box::new(move |e: CloseEvent| { - if unmounted_ref.get_value() { - return; - } + // onopen handler + { + let onopen_closure = Closure::wrap(Box::new(move |e: Event| { + if unmounted_ref.get_value() { + return; + } - if let Some(reconnect) = &reconnect_ref.get_value() { - reconnect(); - } + let callback = on_open_ref.get_value(); + callback(e); - let callback = on_close_ref.get_value(); - callback(e); + set_ready_state.set(ConnectionReadyState::Open); + }) as Box); + web_socket.set_onopen(Some(onopen_closure.as_ref().unchecked_ref())); + // Forget the closure to keep it alive + onopen_closure.forget(); + } - set_ready_state.set(ConnectionReadyState::Closed); - }) - as Box); - web_socket.set_onclose(Some(onclose_closure.as_ref().unchecked_ref())); - onclose_closure.forget(); - } + // onmessage handler + { + let onmessage_closure = Closure::wrap(Box::new(move |e: MessageEvent| { + if unmounted_ref.get_value() { + return; + } - ws_ref.set_value(Some(web_socket)); - })) - }); - // }} + e.data().dyn_into::().map_or_else( + |_| { + e.data().dyn_into::().map_or_else( + |_| { + unreachable!("message event, received Unknown: {:?}", e.data()); + }, + |txt| { + let txt = String::from(&txt); + let callback = on_message_ref.get_value(); + callback(txt.clone()); + + set_message.set(Some(txt)); + }, + ); + }, + |array_buffer| { + let array = js_sys::Uint8Array::new(&array_buffer); + let array = array.to_vec(); + let callback = on_message_bytes_ref.get_value(); + callback(array.clone()); + + set_message_bytes.set(Some(array)); + }, + ); + }) + as Box); + web_socket.set_onmessage(Some(onmessage_closure.as_ref().unchecked_ref())); + onmessage_closure.forget(); + } + + // onerror handler + { + let onerror_closure = Closure::wrap(Box::new(move |e: Event| { + if unmounted_ref.get_value() { + return; + } + + if let Some(reconnect) = &reconnect_ref.get_value() { + reconnect(); + } + + let callback = on_error_ref.get_value(); + callback(e); + + set_ready_state.set(ConnectionReadyState::Closed); + }) as Box); + web_socket.set_onerror(Some(onerror_closure.as_ref().unchecked_ref())); + onerror_closure.forget(); + } + + // onclose handler + { + let onclose_closure = Closure::wrap(Box::new(move |e: CloseEvent| { + if unmounted_ref.get_value() { + return; + } + + if let Some(reconnect) = &reconnect_ref.get_value() { + reconnect(); + } + + let callback = on_close_ref.get_value(); + callback(e); + + set_ready_state.set(ConnectionReadyState::Closed); + }) + as Box); + web_socket.set_onclose(Some(onclose_closure.as_ref().unchecked_ref())); + onclose_closure.forget(); + } + + ws_ref.set_value(Some(web_socket)); + })) + }); + }} // Send text (String) let send = { From e993f9a5f31039d5cc23535b053414b806b313d5 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Sat, 29 Jul 2023 16:54:51 +0100 Subject: [PATCH 02/15] fixing book logo hack to not partially cover the search button --- docs/book/theme/header.hbs | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/book/theme/header.hbs b/docs/book/theme/header.hbs index 5c058aa..2e2bf2f 100644 --- a/docs/book/theme/header.hbs +++ b/docs/book/theme/header.hbs @@ -46,6 +46,7 @@ width: calc(100% - var(--open-sidebar-width) - 113px - 65px); height: var(--menu-bar-height); transition: all 0.3s; + pointer-events: none; } #header-logo { From a00fe0c4a51dbdd1233efb425f666164809e0591 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Wed, 2 Aug 2023 01:16:13 +0100 Subject: [PATCH 03/15] fixed get untracked warning in use_storage --- src/storage/use_storage.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/storage/use_storage.rs b/src/storage/use_storage.rs index bb5dbc9..7a8cc4c 100644 --- a/src/storage/use_storage.rs +++ b/src/storage/use_storage.rs @@ -187,7 +187,7 @@ where let (data, set_data) = defaults.into_signal(); - let raw_init = data.get(); + let raw_init = data.get_untracked(); cfg_if! { if #[cfg(feature = "ssr")] { let remove: Box = Box::new(|| {}); @@ -301,7 +301,7 @@ where resume: resume_watch, .. } = watch_pausable_with_options( - move || data.get(), + move || data.get(), move |data, _, _| write.clone()(data), WatchOptions::default().filter(filter), ); From edd8b4981c0474f460babc298a124ed91c2e7bfb Mon Sep 17 00:00:00 2001 From: Maccesch Date: Thu, 3 Aug 2023 13:45:58 +0100 Subject: [PATCH 04/15] added 0.6.1 to CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3127d4..814f243 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The option `manual` has been renamed to `immediate` to make it more consistent with other functions. To port please note that `immediate` is the inverse of `manual` (`immediate` = `!manual`). +## [0.6.1] - 2023-08-03 + +### Fixes 🍕 + +- `use_storage` now uses `.get_untracked()` to avoid warnings. + ## [0.6.0] - 2023-07-17 ### New Functions 🚀 From 3eb610cc6fb412b6364983c7985e54831ceca610 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Thu, 3 Aug 2023 18:37:42 +0100 Subject: [PATCH 05/15] added 0.6.2 to CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 814f243..318a621 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The option `manual` has been renamed to `immediate` to make it more consistent with other functions. To port please note that `immediate` is the inverse of `manual` (`immediate` = `!manual`). +## [0.6.2] - 2023-08-03 + +### Fixes 🍕 + +- `use_event_listener_with_options` removes the handlers now correctly. + ## [0.6.1] - 2023-08-03 ### Fixes 🍕 From 04c880a3fc22a8670decb4480a136b1c57f72cf7 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Fri, 4 Aug 2023 13:18:38 +0100 Subject: [PATCH 06/15] fixed use_websocket example --- examples/use_websocket/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/use_websocket/src/main.rs b/examples/use_websocket/src/main.rs index 91a4008..f05af76 100644 --- a/examples/use_websocket/src/main.rs +++ b/examples/use_websocket/src/main.rs @@ -1,7 +1,7 @@ use leptos::*; use leptos_use::docs::demo_or_body; use leptos_use::{ - use_websocket, use_websocket_with_options, UseWebSocketOptions, ConnectionReadyState, + core::ConnectionReadyState, use_websocket, use_websocket_with_options, UseWebSocketOptions, UseWebsocketReturn, }; @@ -27,7 +27,7 @@ fn Demo() -> impl IntoView { open, close, .. - } = use_websocket("wss://echo.websocket.events/".to_string()); + } = use_websocket("wss://echo.websocket.events/"); let send_message = move |_| { let m = "Hello, world!".to_string(); @@ -107,9 +107,9 @@ fn Demo() -> impl IntoView { message_bytes: message_bytes2, .. } = use_websocket_with_options( - "wss://echo.websocket.events/".to_string(), + "wss://echo.websocket.events/", UseWebSocketOptions::default() - .manual(true) + .immediate(false) .on_open(on_open_callback.clone()) .on_close(on_close_callback.clone()) .on_error(on_error_callback.clone()) From 19c4f00c5bcce12077263335eb4d3207185d0dfe Mon Sep 17 00:00:00 2001 From: Maccesch Date: Fri, 4 Aug 2023 13:19:34 +0100 Subject: [PATCH 07/15] removed use_raf_fn Clone from callback --- CHANGELOG.md | 4 ++++ src/use_raf_fn.rs | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 318a621..f06f064 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The option `manual` has been renamed to `immediate` to make it more consistent with other functions. To port please note that `immediate` is the inverse of `manual` (`immediate` = `!manual`). +### Other Changes 🔥 + +- Callback in `use_raf_fn` doesn't require to be cloneable anymore + ## [0.6.2] - 2023-08-03 ### Fixes 🍕 diff --git a/src/use_raf_fn.rs b/src/use_raf_fn.rs index 237cf00..b5c6755 100644 --- a/src/use_raf_fn.rs +++ b/src/use_raf_fn.rs @@ -35,14 +35,14 @@ use wasm_bindgen::JsCast; /// You can use `use_raf_fn_with_options` and set `immediate` to `false`. In that case /// you have to call `resume()` before the `callback` is executed. pub fn use_raf_fn( - callback: impl Fn(UseRafFnCallbackArgs) + Clone + 'static, + callback: impl Fn(UseRafFnCallbackArgs) + 'static, ) -> Pausable { use_raf_fn_with_options(callback, UseRafFnOptions::default()) } /// Version of [`use_raf_fn`] that takes a `UseRafFnOptions`. See [`use_raf_fn`] for how to use. pub fn use_raf_fn_with_options( - callback: impl Fn(UseRafFnCallbackArgs) + Clone + 'static, + callback: impl Fn(UseRafFnCallbackArgs) + 'static, options: UseRafFnOptions, ) -> Pausable { let UseRafFnOptions { immediate } = options; From 58c54bb3e70b49aa8a006ecd4981053a36354679 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Fri, 4 Aug 2023 15:58:03 +0100 Subject: [PATCH 08/15] migrated away from CloneableFn... traits --- CHANGELOG.md | 5 + Cargo.toml | 2 +- src/storage/shared.rs | 8 +- src/storage/use_storage.rs | 125 ++++++++++--------- src/use_color_mode.rs | 28 ++--- src/use_debounce_fn.rs | 12 +- src/use_draggable.rs | 20 +-- src/use_drop_zone.rs | 38 ++++-- src/use_interval.rs | 9 +- src/use_media_query.rs | 19 ++- src/use_scroll.rs | 14 +-- src/use_throttle_fn.rs | 12 +- src/use_websocket.rs | 70 ++++++----- src/utils/clonable_fn/mod.rs | 43 ------- src/utils/clonable_fn/mut_.rs | 32 ----- src/utils/clonable_fn/mut_with_arg.rs | 36 ------ src/utils/clonable_fn/with_arg.rs | 36 ------ src/utils/clonable_fn/with_arg_and_return.rs | 38 ------ src/utils/clonable_fn/with_return.rs | 37 ------ src/utils/filters/debounce.rs | 5 +- src/utils/filters/mod.rs | 29 +++-- src/utils/filters/throttle.rs | 5 +- src/utils/mod.rs | 2 - 23 files changed, 210 insertions(+), 415 deletions(-) delete mode 100644 src/utils/clonable_fn/mod.rs delete mode 100644 src/utils/clonable_fn/mut_.rs delete mode 100644 src/utils/clonable_fn/mut_with_arg.rs delete mode 100644 src/utils/clonable_fn/with_arg.rs delete mode 100644 src/utils/clonable_fn/with_arg_and_return.rs delete mode 100644 src/utils/clonable_fn/with_return.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index f06f064..3c7597a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,9 +25,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The options `reconnect_limit` and `reconnect_interval` now take a `u64` instead of `Option` to improve DX. - The option `manual` has been renamed to `immediate` to make it more consistent with other functions. To port please note that `immediate` is the inverse of `manual` (`immediate` = `!manual`). +- `use_color_mode`: + - The optional `on_changed` handler parameters have changed slightly. Please refer to the docs for more details. +- Throttled or debounced functions cannot be `FnOnce` anymore. +- All traits `ClonableFn...` have been removed. ### Other Changes 🔥 +- Callbacks in options don't require to be cloneable anymore - Callback in `use_raf_fn` doesn't require to be cloneable anymore ## [0.6.2] - 2023-08-03 diff --git a/Cargo.toml b/Cargo.toml index 9b28302..ad542b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ homepage = "https://leptos-use.rs" leptos = "0.5.0-alpha" wasm-bindgen = "0.2" js-sys = "0.3" -default-struct-builder = "0.4" +default-struct-builder = "0.5" num = { version = "0.4", optional = true } serde = { version = "1", optional = true } serde_json = { version = "1", optional = true } diff --git a/src/storage/shared.rs b/src/storage/shared.rs index 2eb8233..bd9ef93 100644 --- a/src/storage/shared.rs +++ b/src/storage/shared.rs @@ -1,8 +1,9 @@ use crate::filter_builder_methods; use crate::storage::{StorageType, UseStorageError, UseStorageOptions}; -use crate::utils::{CloneableFnWithArg, DebounceOptions, FilterOptions, ThrottleOptions}; +use crate::utils::{DebounceOptions, FilterOptions, ThrottleOptions}; use default_struct_builder::DefaultBuilder; use leptos::*; +use std::rc::Rc; macro_rules! use_specific_storage { ($(#[$outer:meta])* @@ -58,8 +59,7 @@ pub struct UseSpecificStorageOptions { /// Defaults to simply returning the stored value. merge_defaults: fn(&str, &T) -> String, /// Optional callback whenever an error occurs. The callback takes an argument of type [`UseStorageError`]. - #[builder(into)] - on_error: Box>, + on_error: Rc, /// Debounce or throttle the writing to storage whenever the value changes. filter: FilterOptions, @@ -71,7 +71,7 @@ impl Default for UseSpecificStorageOptions { listen_to_storage_changes: true, write_defaults: true, merge_defaults: |stored_value, _default_value| stored_value.to_string(), - on_error: Box::new(|_| ()), + on_error: Rc::new(|_| ()), filter: Default::default(), } } diff --git a/src/storage/use_storage.rs b/src/storage/use_storage.rs index 7a8cc4c..f5c61e1 100644 --- a/src/storage/use_storage.rs +++ b/src/storage/use_storage.rs @@ -1,7 +1,7 @@ #![cfg_attr(feature = "ssr", allow(unused_variables, unused_imports, dead_code))] use crate::core::MaybeRwSignal; -use crate::utils::{CloneableFn, CloneableFnWithArg, FilterOptions}; +use crate::utils::FilterOptions; use crate::{ filter_builder_methods, use_event_listener, watch_pausable_with_options, DebounceOptions, ThrottleOptions, WatchOptions, WatchPausableReturn, @@ -12,6 +12,7 @@ use js_sys::Reflect; use leptos::*; use serde::{Deserialize, Serialize}; use serde_json::Error; +use std::rc::Rc; use std::time::Duration; use wasm_bindgen::{JsCast, JsValue}; @@ -190,18 +191,18 @@ where let raw_init = data.get_untracked(); cfg_if! { if #[cfg(feature = "ssr")] { - let remove: Box = Box::new(|| {}); + let remove: Rc = Rc::new(|| {}); } else { let storage = storage_type.into_storage(); - let remove: Box = match storage { + let remove: Rc = match storage { Ok(Some(storage)) => { let write = { let on_error = on_error.clone(); let storage = storage.clone(); let key = key.to_string(); - move |v: &T| { + Rc::new(move |v: &T| { match serde_json::to_string(&v) { Ok(ref serialized) => match storage.get_item(&key) { Ok(old_value) => { @@ -240,7 +241,7 @@ where on_error.clone()(UseStorageError::SerializationError(e)); } } - } + }) }; let read = { @@ -249,51 +250,53 @@ where let key = key.to_string(); let raw_init = raw_init.clone(); - move |event_detail: Option| -> Option { - let serialized_init = match serde_json::to_string(&raw_init) { - Ok(serialized) => Some(serialized), - Err(e) => { - on_error.clone()(UseStorageError::DefaultSerializationError(e)); - None - } - }; - - let raw_value = if let Some(event_detail) = event_detail { - event_detail.new_value - } else { - match storage.get_item(&key) { - Ok(raw_value) => match raw_value { - Some(raw_value) => Some(merge_defaults(&raw_value, &raw_init)), - None => serialized_init.clone(), - }, + Rc::new( + move |event_detail: Option| -> Option { + let serialized_init = match serde_json::to_string(&raw_init) { + Ok(serialized) => Some(serialized), Err(e) => { - on_error.clone()(UseStorageError::StorageAccessError(e)); + on_error.clone()(UseStorageError::DefaultSerializationError(e)); None } - } - }; + }; - match raw_value { - Some(raw_value) => match serde_json::from_str(&raw_value) { - Ok(v) => Some(v), - Err(e) => { - on_error.clone()(UseStorageError::SerializationError(e)); - None - } - }, - None => { - if let Some(serialized_init) = &serialized_init { - if write_defaults { - if let Err(e) = storage.set_item(&key, serialized_init) { - on_error(UseStorageError::StorageAccessError(e)); - } + let raw_value = if let Some(event_detail) = event_detail { + event_detail.new_value + } else { + match storage.get_item(&key) { + Ok(raw_value) => match raw_value { + Some(raw_value) => Some(merge_defaults(&raw_value, &raw_init)), + None => serialized_init.clone(), + }, + Err(e) => { + on_error.clone()(UseStorageError::StorageAccessError(e)); + None } } + }; - Some(raw_init) + match raw_value { + Some(raw_value) => match serde_json::from_str(&raw_value) { + Ok(v) => Some(v), + Err(e) => { + on_error.clone()(UseStorageError::SerializationError(e)); + None + } + }, + None => { + if let Some(serialized_init) = &serialized_init { + if write_defaults { + if let Err(e) = storage.set_item(&key, serialized_init) { + on_error(UseStorageError::StorageAccessError(e)); + } + } + } + + Some(raw_init.clone()) + } } - } - } + }, + ) }; let WatchPausableReturn { @@ -311,15 +314,15 @@ where let storage = storage.clone(); let raw_init = raw_init.clone(); - move |event_detail: Option| { + Rc::new(move |event_detail: Option| { if let Some(event_detail) = &event_detail { - if event_detail.storage_area != Some(storage) { + if event_detail.storage_area != Some(storage.clone()) { return; } match &event_detail.key { None => { - set_data.set(raw_init); + set_data.set(raw_init.clone()); return; } Some(event_key) => { @@ -343,21 +346,25 @@ where } else { resume_watch(); } - } + }) }; - let upd = update.clone(); - let update_from_custom_event = - move |event: web_sys::CustomEvent| upd.clone()(Some(event.into())); + let update_from_custom_event = { + let update = Rc::clone(&update); - let upd = update.clone(); - let update_from_storage_event = - move |event: web_sys::StorageEvent| upd.clone()(Some(event.into())); + move |event: web_sys::CustomEvent| update(Some(event.into())) + }; + + let update_from_storage_event = { + let update = Rc::clone(&update); + + move |event: web_sys::StorageEvent| update(Some(event.into())) + }; if listen_to_storage_changes { let _ = use_event_listener(window(), ev::storage, update_from_storage_event); let _ = use_event_listener( - window(), + window(), ev::Custom::new(CUSTOM_STORAGE_EVENT_NAME), update_from_custom_event, ); @@ -367,22 +374,22 @@ where let k = key.to_string(); - Box::new(move || { + Rc::new(move || { let _ = storage.remove_item(&k); }) } Err(e) => { on_error(UseStorageError::NoStorage(e)); - Box::new(move || {}) + Rc::new(move || {}) } _ => { // do nothing - Box::new(move || {}) + Rc::new(move || {}) } }; }} - (data, set_data, move || remove.clone()()) + (data, set_data, move || remove()) } #[derive(Clone)] @@ -461,7 +468,7 @@ pub struct UseStorageOptions { /// Defaults to simply returning the stored value. pub(crate) merge_defaults: fn(&str, &T) -> String, /// Optional callback whenever an error occurs. The callback takes an argument of type [`UseStorageError`]. - pub(crate) on_error: Box>, + pub(crate) on_error: Rc, /// Debounce or throttle the writing to storage whenever the value changes. pub(crate) filter: FilterOptions, @@ -474,7 +481,7 @@ impl Default for UseStorageOptions { listen_to_storage_changes: true, write_defaults: true, merge_defaults: |stored_value, _default_value| stored_value.to_string(), - on_error: Box::new(|_| ()), + on_error: Rc::new(|_| ()), filter: Default::default(), } } diff --git a/src/use_color_mode.rs b/src/use_color_mode.rs index a4f1d1c..a022045 100644 --- a/src/use_color_mode.rs +++ b/src/use_color_mode.rs @@ -7,11 +7,11 @@ use std::fmt::{Display, Formatter}; use crate::core::StorageType; use crate::use_preferred_dark; -use crate::utils::CloneableFnWithArg; use cfg_if::cfg_if; use default_struct_builder::DefaultBuilder; use leptos::*; use std::marker::PhantomData; +use std::rc::Rc; use wasm_bindgen::JsCast; /// Reactive color mode (dark / light / customs) with auto data persistence. @@ -217,10 +217,7 @@ where }; let on_changed = move |mode: ColorMode| { - on_changed(UseColorModeOnChangeArgs { - mode, - default_handler: Box::new(default_on_changed.clone()), - }); + on_changed(mode, Rc::new(default_on_changed.clone())); }; create_effect({ @@ -333,16 +330,6 @@ impl From for ColorMode { } } -/// Arguments to [`UseColorModeOptions::on_changed`] -#[derive(Clone)] -pub struct UseColorModeOnChangeArgs { - /// The color mode to change to. - pub mode: ColorMode, - - /// The default handler that would have been called if the `on_changed` handler had not been specified. - pub default_handler: Box>, -} - #[derive(DefaultBuilder)] pub struct UseColorModeOptions where @@ -367,7 +354,10 @@ where /// Custom handler that is called on updates. /// If specified this will override the default behavior. /// To get the default behaviour back you can call the provided `default_handler` function. - on_changed: Box>, + /// It takes two parameters: + /// - `mode: ColorMode`: The color mode to change to. + /// -`default_handler: Rc`: The default handler that would have been called if the `on_changed` handler had not been specified. + on_changed: OnChangedFn, /// When provided, `useStorage` will be skipped. /// Storage requires the *create feature* **`storage`** to be enabled. @@ -411,6 +401,8 @@ where _marker: PhantomData, } +type OnChangedFn = Rc)>; + impl Default for UseColorModeOptions<&'static str, web_sys::Element> { fn default() -> Self { Self { @@ -418,9 +410,7 @@ impl Default for UseColorModeOptions<&'static str, web_sys::Element> { attribute: "class".into(), initial_value: ColorMode::Auto.into(), custom_modes: vec![], - on_changed: Box::new(move |args: UseColorModeOnChangeArgs| { - (args.default_handler)(args.mode) - }), + on_changed: Rc::new(move |mode, default_handler| (default_handler)(mode)), storage_signal: None, storage_key: "leptos-use-color-scheme".into(), storage: StorageType::default(), diff --git a/src/use_debounce_fn.rs b/src/use_debounce_fn.rs index a80e080..d512720 100644 --- a/src/use_debounce_fn.rs +++ b/src/use_debounce_fn.rs @@ -77,7 +77,7 @@ pub fn use_debounce_fn( ms: impl Into> + 'static, ) -> impl Fn() -> Rc>> + Clone where - F: FnOnce() -> R + Clone + 'static, + F: Fn() -> R + Clone + 'static, R: 'static, { use_debounce_fn_with_options(func, ms, DebounceOptions::default()) @@ -90,10 +90,10 @@ pub fn use_debounce_fn_with_options( options: DebounceOptions, ) -> impl Fn() -> Rc>> + Clone where - F: FnOnce() -> R + Clone + 'static, + F: Fn() -> R + Clone + 'static, R: 'static, { - create_filter_wrapper(Box::new(debounce_filter(ms, options)), func) + create_filter_wrapper(Rc::new(debounce_filter(ms, options)), func) } /// Version of [`use_debounce_fn`] with an argument for the debounced function. See the docs for [`use_debounce_fn`] for how to use. @@ -102,7 +102,7 @@ pub fn use_debounce_fn_with_arg( ms: impl Into> + 'static, ) -> impl Fn(Arg) -> Rc>> + Clone where - F: FnOnce(Arg) -> R + Clone + 'static, + F: Fn(Arg) -> R + Clone + 'static, Arg: Clone + 'static, R: 'static, { @@ -116,9 +116,9 @@ pub fn use_debounce_fn_with_arg_and_options( options: DebounceOptions, ) -> impl Fn(Arg) -> Rc>> + Clone where - F: FnOnce(Arg) -> R + Clone + 'static, + F: Fn(Arg) -> R + Clone + 'static, Arg: Clone + 'static, R: 'static, { - create_filter_wrapper_with_arg(Box::new(debounce_filter(ms, options)), func) + create_filter_wrapper_with_arg(Rc::new(debounce_filter(ms, options)), func) } diff --git a/src/use_draggable.rs b/src/use_draggable.rs index 2e1b21c..c882949 100644 --- a/src/use_draggable.rs +++ b/src/use_draggable.rs @@ -1,10 +1,10 @@ use crate::core::{ElementMaybeSignal, MaybeRwSignal, PointerType, Position}; use crate::use_event_listener_with_options; -use crate::utils::{CloneableFnMutWithArg, CloneableFnWithArgAndReturn}; use default_struct_builder::DefaultBuilder; use leptos::ev::{pointerdown, pointermove, pointerup}; use leptos::*; use std::marker::PhantomData; +use std::rc::Rc; use wasm_bindgen::JsCast; use web_sys::PointerEvent; @@ -134,7 +134,7 @@ where x: event.client_x() as f64 - rect.left(), y: event.client_y() as f64 - rect.top(), }; - if !on_start.clone()(UseDraggableCallbackArgs { + if !on_start(UseDraggableCallbackArgs { position, event: event.clone(), }) { @@ -159,7 +159,7 @@ where y: event.client_y() as f64 - start_position.y, }; set_position.set(position); - on_move.clone()(UseDraggableCallbackArgs { + on_move(UseDraggableCallbackArgs { position, event: event.clone(), }); @@ -176,7 +176,7 @@ where return; } set_start_position.set(None); - on_end.clone()(UseDraggableCallbackArgs { + on_end(UseDraggableCallbackArgs { position: position.get_untracked(), event: event.clone(), }); @@ -253,13 +253,13 @@ where initial_value: MaybeRwSignal, /// Callback when the dragging starts. Return `false` to prevent dragging. - on_start: Box>, + on_start: Rc bool>, /// Callback during dragging. - on_move: Box>, + on_move: Rc, /// Callback when dragging end. - on_end: Box>, + on_end: Rc, #[builder(skip)] _marker1: PhantomData, @@ -284,9 +284,9 @@ impl Default handle: None, pointer_types: vec![PointerType::Mouse, PointerType::Touch, PointerType::Pen], initial_value: MaybeRwSignal::default(), - on_start: Box::new(|_| true), - on_move: Box::new(|_| {}), - on_end: Box::new(|_| {}), + on_start: Rc::new(|_| true), + on_move: Rc::new(|_| {}), + on_end: Rc::new(|_| {}), _marker1: PhantomData, _marker2: PhantomData, } diff --git a/src/use_drop_zone.rs b/src/use_drop_zone.rs index 964d4be..164c152 100644 --- a/src/use_drop_zone.rs +++ b/src/use_drop_zone.rs @@ -1,9 +1,10 @@ use crate::core::ElementMaybeSignal; use crate::use_event_listener; -use crate::utils::CloneableFnMutWithArg; use default_struct_builder::DefaultBuilder; use leptos::ev::{dragenter, dragleave, dragover, drop}; use leptos::*; +use std::fmt::{Debug, Formatter}; +use std::rc::Rc; /// Create a zone where files can be dropped. /// @@ -65,10 +66,10 @@ where T: Into + Clone + 'static, { let UseDropZoneOptions { - mut on_drop, - mut on_enter, - mut on_leave, - mut on_over, + on_drop, + on_enter, + on_leave, + on_over, } = options; let (is_over_drop_zone, set_over_drop_zone) = create_signal(false); @@ -147,16 +148,33 @@ where } /// Options for [`use_drop_zone_with_options`]. -#[derive(DefaultBuilder, Default, Clone, Debug)] +#[derive(DefaultBuilder, Clone)] pub struct UseDropZoneOptions { /// Event handler for the [`drop`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event) event - on_drop: Box>, + on_drop: Rc, /// Event handler for the [`dragenter`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragenter_event) event - on_enter: Box>, + on_enter: Rc, /// Event handler for the [`dragleave`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragleave_event) event - on_leave: Box>, + on_leave: Rc, /// Event handler for the [`dragover`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dragover_event) event - on_over: Box>, + on_over: Rc, +} + +impl Default for UseDropZoneOptions { + fn default() -> Self { + Self { + on_drop: Rc::new(|_| {}), + on_enter: Rc::new(|_| {}), + on_leave: Rc::new(|_| {}), + on_over: Rc::new(|_| {}), + } + } +} + +impl Debug for UseDropZoneOptions { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "UseDropZoneOptions") + } } /// Event passed as argument to the event handler functions of `UseDropZoneOptions`. diff --git a/src/use_interval.rs b/src/use_interval.rs index 244a321..eb39926 100644 --- a/src/use_interval.rs +++ b/src/use_interval.rs @@ -1,6 +1,7 @@ -use crate::utils::{CloneableFnWithArg, Pausable}; +use crate::utils::Pausable; use crate::{use_interval_fn_with_options, UseIntervalFnOptions}; use default_struct_builder::DefaultBuilder; +use std::rc::Rc; use leptos::*; @@ -61,7 +62,7 @@ where let cb = move || { update(); - callback.clone()(counter.get()); + callback(counter.get()); }; let Pausable { @@ -93,14 +94,14 @@ pub struct UseIntervalOptions { immediate: bool, /// Callback on every interval. - callback: Box>, + callback: Rc, } impl Default for UseIntervalOptions { fn default() -> Self { Self { immediate: true, - callback: Box::new(|_: u64| {}), + callback: Rc::new(|_: u64| {}), } } } diff --git a/src/use_media_query.rs b/src/use_media_query.rs index 3363276..b9c5be8 100644 --- a/src/use_media_query.rs +++ b/src/use_media_query.rs @@ -1,7 +1,6 @@ #![cfg_attr(feature = "ssr", allow(unused_variables, unused_imports, dead_code))] use crate::use_event_listener; -use crate::utils::CloneableFnMutWithArg; use cfg_if::cfg_if; use leptos::ev::change; use leptos::*; @@ -48,8 +47,7 @@ pub fn use_media_query(query: impl Into>) -> Signal { let media_query: Rc>> = Rc::new(RefCell::new(None)); let remove_listener: RemoveListener = Rc::new(RefCell::new(None)); - let listener: Rc>>> = - Rc::new(RefCell::new(Box::new(|_| {}))); + let listener = Rc::new(RefCell::new(Rc::new(|_| {}) as Rc)); let cleanup = { let remove_listener = Rc::clone(&remove_listener); @@ -65,7 +63,7 @@ pub fn use_media_query(query: impl Into>) -> Signal { let cleanup = cleanup.clone(); let listener = Rc::clone(&listener); - move || { + Rc::new(move || { cleanup(); let mut media_query = media_query.borrow_mut(); @@ -74,21 +72,22 @@ pub fn use_media_query(query: impl Into>) -> Signal { if let Some(media_query) = media_query.as_ref() { set_matches.set(media_query.matches()); + let listener = Rc::clone(&*listener.borrow()); + remove_listener.replace(Some(Box::new(use_event_listener( - media_query.clone(), + media_query.clone(), change, - listener.borrow().clone(), + move |e| listener(e), )))); } else { set_matches.set(false); } - } + }) }; { - let update = update.clone(); - listener - .replace(Box::new(move |_| update()) as Box>); + let update = Rc::clone(&update); + listener.replace(Rc::new(move |_| update()) as Rc); } create_effect(move |_| update()); diff --git a/src/use_scroll.rs b/src/use_scroll.rs index daed2a2..c495051 100644 --- a/src/use_scroll.rs +++ b/src/use_scroll.rs @@ -1,11 +1,11 @@ use crate::core::ElementMaybeSignal; use crate::use_event_listener::use_event_listener_with_options; -use crate::utils::CloneableFnWithArg; use crate::{use_debounce_fn_with_arg, use_throttle_fn_with_arg_and_options, ThrottleOptions}; use default_struct_builder::DefaultBuilder; use leptos::ev::EventDescriptor; use leptos::*; use std::borrow::Cow; +use std::rc::Rc; use wasm_bindgen::JsCast; /// Reactive scroll position and state. @@ -232,7 +232,7 @@ where }); let on_scroll_end = { - let on_stop = options.on_stop.clone(); + let on_stop = Rc::clone(&options.on_stop); move |e| { if !is_scrolling.get_untracked() { @@ -328,7 +328,7 @@ where }; let on_scroll_handler = { - let on_scroll = options.on_scroll.clone(); + let on_scroll = Rc::clone(&options.on_scroll); move |e: web_sys::Event| { let target: web_sys::Element = event_target(&e); @@ -441,10 +441,10 @@ pub struct UseScrollOptions { offset: ScrollOffset, /// Callback when scrolling is happening. - on_scroll: Box>, + on_scroll: Rc, /// Callback when scrolling stops (after `idle` + `throttle` milliseconds have passed). - on_stop: Box>, + on_stop: Rc, /// Options passed to the `addEventListener("scroll", ...)` call event_listener_options: web_sys::AddEventListenerOptions, @@ -461,8 +461,8 @@ impl Default for UseScrollOptions { throttle: 0.0, idle: 200.0, offset: ScrollOffset::default(), - on_scroll: Box::new(|_| {}), - on_stop: Box::new(|_| {}), + on_scroll: Rc::new(|_| {}), + on_stop: Rc::new(|_| {}), event_listener_options: Default::default(), behavior: Default::default(), } diff --git a/src/use_throttle_fn.rs b/src/use_throttle_fn.rs index 985cdb8..6652248 100644 --- a/src/use_throttle_fn.rs +++ b/src/use_throttle_fn.rs @@ -73,7 +73,7 @@ pub fn use_throttle_fn( ms: impl Into> + 'static, ) -> impl Fn() -> Rc>> + Clone where - F: FnOnce() -> R + Clone + 'static, + F: Fn() -> R + Clone + 'static, R: 'static, { use_throttle_fn_with_options(func, ms, Default::default()) @@ -86,10 +86,10 @@ pub fn use_throttle_fn_with_options( options: ThrottleOptions, ) -> impl Fn() -> Rc>> + Clone where - F: FnOnce() -> R + Clone + 'static, + F: Fn() -> R + Clone + 'static, R: 'static, { - create_filter_wrapper(Box::new(throttle_filter(ms, options)), func) + create_filter_wrapper(Rc::new(throttle_filter(ms, options)), func) } /// Version of [`use_throttle_fn`] with an argument for the throttled function. See the docs for [`use_throttle_fn`] for how to use. @@ -98,7 +98,7 @@ pub fn use_throttle_fn_with_arg( ms: impl Into> + 'static, ) -> impl Fn(Arg) -> Rc>> + Clone where - F: FnOnce(Arg) -> R + Clone + 'static, + F: Fn(Arg) -> R + Clone + 'static, Arg: Clone + 'static, R: 'static, { @@ -112,9 +112,9 @@ pub fn use_throttle_fn_with_arg_and_options( options: ThrottleOptions, ) -> impl Fn(Arg) -> Rc>> + Clone where - F: FnOnce(Arg) -> R + Clone + 'static, + F: Fn(Arg) -> R + Clone + 'static, Arg: Clone + 'static, R: 'static, { - create_filter_wrapper_with_arg(Box::new(throttle_filter(ms, options)), func) + create_filter_wrapper_with_arg(Rc::new(throttle_filter(ms, options)), func) } diff --git a/src/use_websocket.rs b/src/use_websocket.rs index 0fbfa3e..098e33c 100644 --- a/src/use_websocket.rs +++ b/src/use_websocket.rs @@ -1,7 +1,6 @@ #![cfg_attr(feature = "ssr", allow(unused_variables, unused_imports, dead_code))] use cfg_if::cfg_if; -use core::fmt; use leptos::{leptos_dom::helpers::TimeoutHandle, *}; use std::rc::Rc; use std::time::Duration; @@ -12,8 +11,6 @@ use js_sys::Array; use wasm_bindgen::{prelude::*, JsCast, JsValue}; use web_sys::{BinaryType, CloseEvent, Event, MessageEvent, WebSocket}; -use crate::utils::CloneableFnWithArg; - /// Creating and managing a [Websocket](https://developer.mozilla.org/en-US/docs/Web/API/WebSocket) connection. /// /// ## Demo @@ -102,15 +99,24 @@ pub fn use_websocket_with_options( > { let url = url.to_string(); + let UseWebSocketOptions { + on_open, + on_message, + on_message_bytes, + on_error, + on_close, + reconnect_limit, + reconnect_interval, + immediate, + protocols, + } = options; + let (ready_state, set_ready_state) = create_signal(ConnectionReadyState::Closed); let (message, set_message) = create_signal(None); let (message_bytes, set_message_bytes) = create_signal(None); let ws_ref: StoredValue> = store_value(None); - let reconnect_limit = options.reconnect_limit; - let reconnect_timer_ref: StoredValue> = store_value(None); - let immediate = options.immediate; let reconnect_times_ref: StoredValue = store_value(0); let unmounted_ref = store_value(false); @@ -118,14 +124,6 @@ pub fn use_websocket_with_options( let connect_ref: StoredValue>> = store_value(None); cfg_if! { if #[cfg(not(feature = "ssr"))] { - let on_open_ref = store_value(options.on_open); - let on_message_ref = store_value(options.on_message); - let on_message_bytes_ref = store_value(options.on_message_bytes); - let on_error_ref = store_value(options.on_error); - let on_close_ref = store_value(options.on_close); - - let reconnect_interval = options.reconnect_interval; - let protocols = options.protocols; let reconnect_ref: StoredValue>> = store_value(None); reconnect_ref.set_value({ @@ -181,13 +179,14 @@ pub fn use_websocket_with_options( // onopen handler { + let on_open = Rc::clone(&on_open); + let onopen_closure = Closure::wrap(Box::new(move |e: Event| { if unmounted_ref.get_value() { return; } - let callback = on_open_ref.get_value(); - callback(e); + on_open(e); set_ready_state.set(ConnectionReadyState::Open); }) as Box); @@ -198,6 +197,9 @@ pub fn use_websocket_with_options( // onmessage handler { + let on_message = Rc::clone(&on_message); + let on_message_bytes = Rc::clone(&on_message_bytes); + let onmessage_closure = Closure::wrap(Box::new(move |e: MessageEvent| { if unmounted_ref.get_value() { return; @@ -211,8 +213,7 @@ pub fn use_websocket_with_options( }, |txt| { let txt = String::from(&txt); - let callback = on_message_ref.get_value(); - callback(txt.clone()); + on_message(txt.clone()); set_message.set(Some(txt)); }, @@ -221,8 +222,7 @@ pub fn use_websocket_with_options( |array_buffer| { let array = js_sys::Uint8Array::new(&array_buffer); let array = array.to_vec(); - let callback = on_message_bytes_ref.get_value(); - callback(array.clone()); + on_message_bytes(array.clone()); set_message_bytes.set(Some(array)); }, @@ -235,6 +235,8 @@ pub fn use_websocket_with_options( // onerror handler { + let on_error = Rc::clone(&on_error); + let onerror_closure = Closure::wrap(Box::new(move |e: Event| { if unmounted_ref.get_value() { return; @@ -244,8 +246,7 @@ pub fn use_websocket_with_options( reconnect(); } - let callback = on_error_ref.get_value(); - callback(e); + on_error(e); set_ready_state.set(ConnectionReadyState::Closed); }) as Box); @@ -255,6 +256,8 @@ pub fn use_websocket_with_options( // onclose handler { + let on_close = Rc::clone(&on_close); + let onclose_closure = Closure::wrap(Box::new(move |e: CloseEvent| { if unmounted_ref.get_value() { return; @@ -264,8 +267,7 @@ pub fn use_websocket_with_options( reconnect(); } - let callback = on_close_ref.get_value(); - callback(e); + on_close(e); set_ready_state.set(ConnectionReadyState::Closed); }) @@ -348,15 +350,15 @@ pub fn use_websocket_with_options( #[derive(DefaultBuilder)] pub struct UseWebSocketOptions { /// `WebSocket` connect callback. - on_open: Box>, + on_open: Rc, /// `WebSocket` message callback for text. - on_message: Box>, + on_message: Rc, /// `WebSocket` message callback for binary. - on_message_bytes: Box>>, + on_message_bytes: Rc)>, /// `WebSocket` error callback. - on_error: Box>, + on_error: Rc, /// `WebSocket` close callback. - on_close: Box>, + on_close: Rc, /// Retry times. Defaults to 3. reconnect_limit: u64, /// Retry interval in ms. Defaults to 3000. @@ -372,11 +374,11 @@ pub struct UseWebSocketOptions { impl Default for UseWebSocketOptions { fn default() -> Self { Self { - on_open: Box::new(|_| {}), - on_message: Box::new(|_| {}), - on_message_bytes: Box::new(|_| {}), - on_error: Box::new(|_| {}), - on_close: Box::new(|_| {}), + on_open: Rc::new(|_| {}), + on_message: Rc::new(|_| {}), + on_message_bytes: Rc::new(|_| {}), + on_error: Rc::new(|_| {}), + on_close: Rc::new(|_| {}), reconnect_limit: 3, reconnect_interval: 3000, immediate: true, diff --git a/src/utils/clonable_fn/mod.rs b/src/utils/clonable_fn/mod.rs deleted file mode 100644 index 7e05e40..0000000 --- a/src/utils/clonable_fn/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -mod mut_; -mod mut_with_arg; -mod with_arg; -mod with_arg_and_return; -mod with_return; - -pub use mut_::*; -pub use mut_with_arg::*; -use std::fmt::Debug; -pub use with_arg::*; -pub use with_arg_and_return::*; -pub use with_return::*; - -pub trait CloneableFn: FnOnce() { - fn clone_box(&self) -> Box; -} - -impl CloneableFn for F -where - F: FnOnce() + Clone + 'static, -{ - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } -} - -impl Clone for Box { - fn clone(&self) -> Self { - (**self).clone_box() - } -} - -impl Default for Box { - fn default() -> Self { - Box::new(|| {}) - } -} - -impl Debug for Box { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Box",) - } -} diff --git a/src/utils/clonable_fn/mut_.rs b/src/utils/clonable_fn/mut_.rs deleted file mode 100644 index f2a16b2..0000000 --- a/src/utils/clonable_fn/mut_.rs +++ /dev/null @@ -1,32 +0,0 @@ -use std::fmt::Debug; - -pub trait CloneableFnMut: FnMut() { - fn clone_box(&self) -> Box; -} - -impl CloneableFnMut for F -where - F: FnMut() + Clone + 'static, -{ - fn clone_box(&self) -> Box { - Box::new(self.clone()) - } -} - -impl Clone for Box { - fn clone(&self) -> Self { - (**self).clone_box() - } -} - -impl Default for Box { - fn default() -> Self { - Box::new(|| {}) - } -} - -impl Debug for Box { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "Box",) - } -} diff --git a/src/utils/clonable_fn/mut_with_arg.rs b/src/utils/clonable_fn/mut_with_arg.rs deleted file mode 100644 index 3d8fb63..0000000 --- a/src/utils/clonable_fn/mut_with_arg.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::fmt::Debug; - -pub trait CloneableFnMutWithArg: FnMut(Arg) { - fn clone_box(&self) -> Box>; -} - -impl CloneableFnMutWithArg for F -where - F: FnMut(Arg) + Clone + 'static, -{ - fn clone_box(&self) -> Box> { - Box::new(self.clone()) - } -} - -impl Clone for Box> { - fn clone(&self) -> Self { - (**self).clone_box() - } -} - -impl Default for Box> { - fn default() -> Self { - Box::new(|_| {}) - } -} - -impl Debug for Box> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Box>", - std::any::type_name::() - ) - } -} diff --git a/src/utils/clonable_fn/with_arg.rs b/src/utils/clonable_fn/with_arg.rs deleted file mode 100644 index fedcf57..0000000 --- a/src/utils/clonable_fn/with_arg.rs +++ /dev/null @@ -1,36 +0,0 @@ -use std::fmt::Debug; - -pub trait CloneableFnWithArg: FnOnce(Arg) { - fn clone_box(&self) -> Box>; -} - -impl CloneableFnWithArg for F -where - F: FnOnce(Arg) + Clone + 'static, -{ - fn clone_box(&self) -> Box> { - Box::new(self.clone()) - } -} - -impl Clone for Box> { - fn clone(&self) -> Self { - (**self).clone_box() - } -} - -impl Default for Box> { - fn default() -> Self { - Box::new(|_| {}) - } -} - -impl Debug for Box> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Box>", - std::any::type_name::() - ) - } -} diff --git a/src/utils/clonable_fn/with_arg_and_return.rs b/src/utils/clonable_fn/with_arg_and_return.rs deleted file mode 100644 index b9a4122..0000000 --- a/src/utils/clonable_fn/with_arg_and_return.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::fmt::Debug; - -pub trait CloneableFnWithArgAndReturn: FnOnce(Arg) -> R { - fn clone_box(&self) -> Box>; -} - -impl CloneableFnWithArgAndReturn for F -where - F: FnMut(Arg) -> R + Clone + 'static, - R: 'static, -{ - fn clone_box(&self) -> Box> { - Box::new(self.clone()) - } -} - -impl Clone for Box> { - fn clone(&self) -> Self { - (**self).clone_box() - } -} - -impl Default for Box> { - fn default() -> Self { - Box::new(|_| Default::default()) - } -} - -impl Debug for Box> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Box>", - std::any::type_name::(), - std::any::type_name::() - ) - } -} diff --git a/src/utils/clonable_fn/with_return.rs b/src/utils/clonable_fn/with_return.rs deleted file mode 100644 index 4deb656..0000000 --- a/src/utils/clonable_fn/with_return.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::fmt::Debug; - -pub trait CloneableFnWithReturn: FnOnce() -> R { - fn clone_box(&self) -> Box>; -} - -impl CloneableFnWithReturn for F -where - F: FnOnce() -> R + Clone + 'static, - R: 'static, -{ - fn clone_box(&self) -> Box> { - Box::new(self.clone()) - } -} - -impl Clone for Box> { - fn clone(&self) -> Self { - (**self).clone_box() - } -} - -impl Default for Box> { - fn default() -> Self { - Box::new(|| Default::default()) - } -} - -impl Debug for Box> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - "Box>", - std::any::type_name::() - ) - } -} diff --git a/src/utils/filters/debounce.rs b/src/utils/filters/debounce.rs index b33901b..6186960 100644 --- a/src/utils/filters/debounce.rs +++ b/src/utils/filters/debounce.rs @@ -1,6 +1,5 @@ #![cfg_attr(feature = "ssr", allow(unused_variables, unused_imports))] -use crate::utils::CloneableFnWithReturn; use cfg_if::cfg_if; use default_struct_builder::DefaultBuilder; use leptos::leptos_dom::helpers::TimeoutHandle; @@ -20,7 +19,7 @@ pub struct DebounceOptions { pub fn debounce_filter( ms: impl Into>, options: DebounceOptions, -) -> impl Fn(Box>) -> Rc>> + Clone +) -> impl Fn(Rc R>) -> Rc>> + Clone where R: 'static, { @@ -38,7 +37,7 @@ where let ms = ms.into(); let max_wait_signal = options.max_wait; - move |_invoke: Box>| { + move |_invoke: Rc R>| { let duration = ms.get_untracked(); let max_duration = max_wait_signal.get_untracked(); diff --git a/src/utils/filters/mod.rs b/src/utils/filters/mod.rs index 5d33059..7607d33 100644 --- a/src/utils/filters/mod.rs +++ b/src/utils/filters/mod.rs @@ -4,40 +4,39 @@ mod throttle; pub use debounce::*; pub use throttle::*; -use crate::utils::{CloneableFnWithArgAndReturn, CloneableFnWithReturn}; use leptos::MaybeSignal; use std::cell::RefCell; use std::rc::Rc; -macro_rules! BoxFilterFn { +macro_rules! RcFilterFn { ($R:ident) => { - Box>, Rc>>>> + Rc $R>) -> Rc>>> } } pub fn create_filter_wrapper( - filter: BoxFilterFn!(R), + filter: RcFilterFn!(R), func: F, ) -> impl Fn() -> Rc>> + Clone where - F: FnOnce() -> R + Clone + 'static, + F: Fn() -> R + Clone + 'static, R: 'static, { - move || filter.clone()(Box::new(func.clone())) + move || Rc::clone(&filter)(Rc::new(func.clone())) } pub fn create_filter_wrapper_with_arg( - filter: BoxFilterFn!(R), + filter: RcFilterFn!(R), func: F, ) -> impl Fn(Arg) -> Rc>> + Clone where - F: FnOnce(Arg) -> R + Clone + 'static, + F: Fn(Arg) -> R + Clone + 'static, R: 'static, Arg: Clone + 'static, { move |arg: Arg| { let func = func.clone(); - filter.clone()(Box::new(move || func(arg))) + Rc::clone(&filter)(Rc::new(move || func(arg.clone()))) } } @@ -57,16 +56,16 @@ pub enum FilterOptions { } impl FilterOptions { - pub fn filter_fn(&self) -> BoxFilterFn!(R) + pub fn filter_fn(&self) -> RcFilterFn!(R) where R: 'static, { match self { - FilterOptions::Debounce { ms, options } => Box::new(debounce_filter(*ms, *options)), - FilterOptions::Throttle { ms, options } => Box::new(throttle_filter(*ms, *options)), - FilterOptions::None => Box::new(|invoke: Box>| { - Rc::new(RefCell::new(Some(invoke()))) - }), + FilterOptions::Debounce { ms, options } => Rc::new(debounce_filter(*ms, *options)), + FilterOptions::Throttle { ms, options } => Rc::new(throttle_filter(*ms, *options)), + FilterOptions::None => { + Rc::new(|invoke: Rc R>| Rc::new(RefCell::new(Some(invoke())))) + } } } } diff --git a/src/utils/filters/throttle.rs b/src/utils/filters/throttle.rs index 48b6fc7..caaa15e 100644 --- a/src/utils/filters/throttle.rs +++ b/src/utils/filters/throttle.rs @@ -1,6 +1,5 @@ #![cfg_attr(feature = "ssr", allow(unused_variables, unused_imports))] -use crate::utils::CloneableFnWithReturn; use cfg_if::cfg_if; use default_struct_builder::DefaultBuilder; use js_sys::Date; @@ -31,7 +30,7 @@ impl Default for ThrottleOptions { pub fn throttle_filter( ms: impl Into>, options: ThrottleOptions, -) -> impl Fn(Box>) -> Rc>> + Clone +) -> impl Fn(Rc R>) -> Rc>> + Clone where R: 'static, { @@ -50,7 +49,7 @@ where let ms = ms.into(); - move |mut _invoke: Box>| { + move |mut _invoke: Rc R>| { let duration = ms.get_untracked(); let elapsed = Date::now() - last_exec.get(); diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 30625a0..404c372 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,3 @@ -mod clonable_fn; mod filters; mod is; mod js_value_from_to_string; @@ -6,7 +5,6 @@ mod pausable; mod signal_filtered; mod use_derive_signal; -pub use clonable_fn::*; pub use filters::*; pub use is::*; pub(crate) use js_value_from_to_string::*; From 075b073d319da4331d14455693afed0bb2460941 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Fri, 4 Aug 2023 16:18:59 +0100 Subject: [PATCH 09/15] migrated to leptos 0.5.0-alpha2 --- Cargo.toml | 2 +- examples/Cargo.toml | 1 + examples/on_click_outside/Cargo.toml | 2 +- examples/signal_debounced/Cargo.toml | 2 +- examples/signal_throttled/Cargo.toml | 2 +- examples/ssr/Cargo.toml | 10 +++++----- examples/use_abs/Cargo.toml | 2 +- examples/use_active_element/Cargo.toml | 2 +- examples/use_breakpoints/Cargo.toml | 2 +- examples/use_ceil/Cargo.toml | 2 +- examples/use_color_mode/Cargo.toml | 2 +- examples/use_css_var/Cargo.toml | 2 +- examples/use_cycle_list/Cargo.toml | 2 +- examples/use_debounce_fn/Cargo.toml | 2 +- examples/use_document_visibility/Cargo.toml | 2 +- examples/use_draggable/Cargo.toml | 2 +- examples/use_draggable/src/main.rs | 5 ++--- examples/use_drop_zone/Cargo.toml | 2 +- examples/use_element_hover/Cargo.toml | 2 +- examples/use_element_size/Cargo.toml | 2 +- examples/use_element_visibility/Cargo.toml | 2 +- examples/use_event_listener/Cargo.toml | 2 +- examples/use_favicon/Cargo.toml | 2 +- examples/use_floor/Cargo.toml | 2 +- examples/use_intersection_observer/Cargo.toml | 2 +- examples/use_interval/Cargo.toml | 2 +- examples/use_interval_fn/Cargo.toml | 2 +- examples/use_intl_number_format/Cargo.toml | 2 +- examples/use_media_query/Cargo.toml | 2 +- examples/use_mouse/Cargo.toml | 2 +- examples/use_mutation_observer/Cargo.toml | 2 +- examples/use_raf_fn/Cargo.toml | 2 +- examples/use_resize_observer/Cargo.toml | 2 +- examples/use_round/Cargo.toml | 2 +- examples/use_scroll/Cargo.toml | 2 +- examples/use_storage/Cargo.toml | 2 +- examples/use_throttle_fn/Cargo.toml | 2 +- examples/use_websocket/Cargo.toml | 2 +- examples/use_window_focus/Cargo.toml | 2 +- examples/use_window_scroll/Cargo.toml | 2 +- examples/watch_debounced/Cargo.toml | 2 +- examples/watch_pausable/Cargo.toml | 2 +- examples/watch_throttled/Cargo.toml | 2 +- .../examples/{{ function_name }}/Cargo.ffizer.hbs.toml | 2 +- 44 files changed, 49 insertions(+), 49 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ad542b7..9ea6d2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/Synphonyte/leptos-use" homepage = "https://leptos-use.rs" [dependencies] -leptos = "0.5.0-alpha" +leptos = "0.5.0-alpha2" wasm-bindgen = "0.2" js-sys = "0.3" default-struct-builder = "0.5" diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 4c3dec2..5f534d2 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "on_click_outside", + "portal", "signal_debounced", "signal_throttled", "use_abs", diff --git a/examples/on_click_outside/Cargo.toml b/examples/on_click_outside/Cargo.toml index a055bb2..5342a89 100644 --- a/examples/on_click_outside/Cargo.toml +++ b/examples/on_click_outside/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/signal_debounced/Cargo.toml b/examples/signal_debounced/Cargo.toml index e185e4f..57eabb7 100644 --- a/examples/signal_debounced/Cargo.toml +++ b/examples/signal_debounced/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/signal_throttled/Cargo.toml b/examples/signal_throttled/Cargo.toml index b948721..36b1676 100644 --- a/examples/signal_throttled/Cargo.toml +++ b/examples/signal_throttled/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/ssr/Cargo.toml b/examples/ssr/Cargo.toml index bf11447..2abd26b 100644 --- a/examples/ssr/Cargo.toml +++ b/examples/ssr/Cargo.toml @@ -11,16 +11,16 @@ axum = { version = "0.6.4", optional = true } console_error_panic_hook = "0.1" console_log = "1" cfg-if = "1" -leptos = { version = "0.5.0-alpha", features = ["nightly"] } -leptos_axum = { version = "0.5.0-alpha", optional = true } -leptos_meta = { version = "0.5.0-alpha", features = ["nightly"] } -leptos_router = { version = "0.5.0-alpha", features = ["nightly"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly"] } +leptos_axum = { version = "0.5.0-alpha2", optional = true } +leptos_meta = { version = "0.5.0-alpha2", features = ["nightly"] } +leptos_router = { version = "0.5.0-alpha2", features = ["nightly"] } leptos-use = { path = "../..", features = ["storage"] } log = "0.4" simple_logger = "4" tokio = { version = "1.25.0", optional = true } tower = { version = "0.4.13", optional = true } -tower-http = { version = "0.5.0-alpha", features = ["fs"], optional = true } +tower-http = { version = "0.5.0-alpha2", features = ["fs"], optional = true } wasm-bindgen = "=0.2.87" thiserror = "1.0.38" tracing = { version = "0.1.37", optional = true } diff --git a/examples/use_abs/Cargo.toml b/examples/use_abs/Cargo.toml index 3c7001a..d758876 100644 --- a/examples/use_abs/Cargo.toml +++ b/examples/use_abs/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_active_element/Cargo.toml b/examples/use_active_element/Cargo.toml index f3dfb7f..a3ccfd1 100644 --- a/examples/use_active_element/Cargo.toml +++ b/examples/use_active_element/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_breakpoints/Cargo.toml b/examples/use_breakpoints/Cargo.toml index 47788ee..9eb3186 100644 --- a/examples/use_breakpoints/Cargo.toml +++ b/examples/use_breakpoints/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_ceil/Cargo.toml b/examples/use_ceil/Cargo.toml index 67a16d5..15189fa 100644 --- a/examples/use_ceil/Cargo.toml +++ b/examples/use_ceil/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_color_mode/Cargo.toml b/examples/use_color_mode/Cargo.toml index 15e9757..ad64682 100644 --- a/examples/use_color_mode/Cargo.toml +++ b/examples/use_color_mode/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_css_var/Cargo.toml b/examples/use_css_var/Cargo.toml index 0daf92f..0360d48 100644 --- a/examples/use_css_var/Cargo.toml +++ b/examples/use_css_var/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_cycle_list/Cargo.toml b/examples/use_cycle_list/Cargo.toml index 3b712b4..554fb87 100644 --- a/examples/use_cycle_list/Cargo.toml +++ b/examples/use_cycle_list/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_debounce_fn/Cargo.toml b/examples/use_debounce_fn/Cargo.toml index 5ee6a0b..f23c40f 100644 --- a/examples/use_debounce_fn/Cargo.toml +++ b/examples/use_debounce_fn/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_document_visibility/Cargo.toml b/examples/use_document_visibility/Cargo.toml index aad19cd..2b68975 100644 --- a/examples/use_document_visibility/Cargo.toml +++ b/examples/use_document_visibility/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_draggable/Cargo.toml b/examples/use_draggable/Cargo.toml index e6e0a11..faac6bf 100644 --- a/examples/use_draggable/Cargo.toml +++ b/examples/use_draggable/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_draggable/src/main.rs b/examples/use_draggable/src/main.rs index 9b9315f..cf92cdb 100644 --- a/examples/use_draggable/src/main.rs +++ b/examples/use_draggable/src/main.rs @@ -31,9 +31,8 @@ fn Demo() -> impl IntoView { > "👋 Drag me!"
- I am - {move || x().round()} - ) + I am + {move || x().round()}, {move || y().round()}
diff --git a/examples/use_drop_zone/Cargo.toml b/examples/use_drop_zone/Cargo.toml index 0e9992e..6ad6ef0 100644 --- a/examples/use_drop_zone/Cargo.toml +++ b/examples/use_drop_zone/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_element_hover/Cargo.toml b/examples/use_element_hover/Cargo.toml index fb518a3..0f1ae6e 100644 --- a/examples/use_element_hover/Cargo.toml +++ b/examples/use_element_hover/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_element_size/Cargo.toml b/examples/use_element_size/Cargo.toml index 62ccdbc..abd70cc 100644 --- a/examples/use_element_size/Cargo.toml +++ b/examples/use_element_size/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_element_visibility/Cargo.toml b/examples/use_element_visibility/Cargo.toml index 9fc10c6..9263fe3 100644 --- a/examples/use_element_visibility/Cargo.toml +++ b/examples/use_element_visibility/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_event_listener/Cargo.toml b/examples/use_event_listener/Cargo.toml index 1790534..e925492 100644 --- a/examples/use_event_listener/Cargo.toml +++ b/examples/use_event_listener/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_favicon/Cargo.toml b/examples/use_favicon/Cargo.toml index 3150aaf..12e7f37 100644 --- a/examples/use_favicon/Cargo.toml +++ b/examples/use_favicon/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_floor/Cargo.toml b/examples/use_floor/Cargo.toml index b206f52..53b3cdb 100644 --- a/examples/use_floor/Cargo.toml +++ b/examples/use_floor/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_intersection_observer/Cargo.toml b/examples/use_intersection_observer/Cargo.toml index b689b81..a2374fd 100644 --- a/examples/use_intersection_observer/Cargo.toml +++ b/examples/use_intersection_observer/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_interval/Cargo.toml b/examples/use_interval/Cargo.toml index 03c0abf..407bd63 100644 --- a/examples/use_interval/Cargo.toml +++ b/examples/use_interval/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_interval_fn/Cargo.toml b/examples/use_interval_fn/Cargo.toml index dcd84d6..4f1f5f1 100644 --- a/examples/use_interval_fn/Cargo.toml +++ b/examples/use_interval_fn/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_intl_number_format/Cargo.toml b/examples/use_intl_number_format/Cargo.toml index 5000bfb..4822b27 100644 --- a/examples/use_intl_number_format/Cargo.toml +++ b/examples/use_intl_number_format/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_media_query/Cargo.toml b/examples/use_media_query/Cargo.toml index 05dbbed..8579241 100644 --- a/examples/use_media_query/Cargo.toml +++ b/examples/use_media_query/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_mouse/Cargo.toml b/examples/use_mouse/Cargo.toml index 57c6542..ef03a36 100644 --- a/examples/use_mouse/Cargo.toml +++ b/examples/use_mouse/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_mutation_observer/Cargo.toml b/examples/use_mutation_observer/Cargo.toml index ae88b67..ba7223e 100644 --- a/examples/use_mutation_observer/Cargo.toml +++ b/examples/use_mutation_observer/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_raf_fn/Cargo.toml b/examples/use_raf_fn/Cargo.toml index d7069f8..3f7ff57 100644 --- a/examples/use_raf_fn/Cargo.toml +++ b/examples/use_raf_fn/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_resize_observer/Cargo.toml b/examples/use_resize_observer/Cargo.toml index 1178cff..c4e04ac 100644 --- a/examples/use_resize_observer/Cargo.toml +++ b/examples/use_resize_observer/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_round/Cargo.toml b/examples/use_round/Cargo.toml index 32ed722..0b467fd 100644 --- a/examples/use_round/Cargo.toml +++ b/examples/use_round/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_scroll/Cargo.toml b/examples/use_scroll/Cargo.toml index 8298f0a..2658228 100644 --- a/examples/use_scroll/Cargo.toml +++ b/examples/use_scroll/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_storage/Cargo.toml b/examples/use_storage/Cargo.toml index b3a5f63..462839e 100644 --- a/examples/use_storage/Cargo.toml +++ b/examples/use_storage/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_throttle_fn/Cargo.toml b/examples/use_throttle_fn/Cargo.toml index 76383c6..9bf0266 100644 --- a/examples/use_throttle_fn/Cargo.toml +++ b/examples/use_throttle_fn/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_websocket/Cargo.toml b/examples/use_websocket/Cargo.toml index 5d882ca..e2cb5e2 100644 --- a/examples/use_websocket/Cargo.toml +++ b/examples/use_websocket/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_window_focus/Cargo.toml b/examples/use_window_focus/Cargo.toml index 02a4269..b6145ec 100644 --- a/examples/use_window_focus/Cargo.toml +++ b/examples/use_window_focus/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/use_window_scroll/Cargo.toml b/examples/use_window_scroll/Cargo.toml index 14d6fe8..4cc6225 100644 --- a/examples/use_window_scroll/Cargo.toml +++ b/examples/use_window_scroll/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/watch_debounced/Cargo.toml b/examples/watch_debounced/Cargo.toml index 84a09c2..61a80d2 100644 --- a/examples/watch_debounced/Cargo.toml +++ b/examples/watch_debounced/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/watch_pausable/Cargo.toml b/examples/watch_pausable/Cargo.toml index f71ef47..e1338e4 100644 --- a/examples/watch_pausable/Cargo.toml +++ b/examples/watch_pausable/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/examples/watch_throttled/Cargo.toml b/examples/watch_throttled/Cargo.toml index cab4ec8..9510b5f 100644 --- a/examples/watch_throttled/Cargo.toml +++ b/examples/watch_throttled/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.5.0-alpha", features = ["nightly", "csr"] } +leptos = { version = "0.5.0-alpha2", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" diff --git a/template/examples/{{ function_name }}/Cargo.ffizer.hbs.toml b/template/examples/{{ function_name }}/Cargo.ffizer.hbs.toml index 5af1f96..646a4b1 100644 --- a/template/examples/{{ function_name }}/Cargo.ffizer.hbs.toml +++ b/template/examples/{{ function_name }}/Cargo.ffizer.hbs.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -leptos = { version = "0.4", features = ["nightly", "csr"] } +leptos = { version = "0.5", features = ["nightly", "csr"] } console_error_panic_hook = "0.1" console_log = "1" log = "0.4" From 60b4ae26095404ad8c20585bb6beb90d8d23e9f2 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Sun, 6 Aug 2023 00:31:48 +0100 Subject: [PATCH 10/15] fixed use_storage. This fixes #19 --- examples/Cargo.toml | 1 - src/storage/use_storage.rs | 9 ++++++--- src/use_color_mode.rs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 5f534d2..4c3dec2 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -3,7 +3,6 @@ resolver = "2" members = [ "on_click_outside", - "portal", "signal_debounced", "signal_throttled", "use_abs", diff --git a/src/storage/use_storage.rs b/src/storage/use_storage.rs index f5c61e1..7122882 100644 --- a/src/storage/use_storage.rs +++ b/src/storage/use_storage.rs @@ -305,7 +305,7 @@ where .. } = watch_pausable_with_options( move || data.get(), - move |data, _, _| write.clone()(data), + move |data, _, _| Rc::clone(&write)(data), WatchOptions::default().filter(filter), ); @@ -340,7 +340,7 @@ where } if event_detail.is_some() { - // use timeout to avoid inifinite loop + // use timeout to avoid infinite loop let resume = resume_watch.clone(); let _ = set_timeout_with_handle(resume, Duration::ZERO); } else { @@ -352,7 +352,10 @@ where let update_from_custom_event = { let update = Rc::clone(&update); - move |event: web_sys::CustomEvent| update(Some(event.into())) + move |event: web_sys::CustomEvent| { + let update = Rc::clone(&update); + queue_microtask(move || update(Some(event.into()))) + } }; let update_from_storage_event = { diff --git a/src/use_color_mode.rs b/src/use_color_mode.rs index a022045..0804293 100644 --- a/src/use_color_mode.rs +++ b/src/use_color_mode.rs @@ -269,7 +269,7 @@ cfg_if! { if #[cfg(feature = "storage")] { (store.into(), set_store) } else if storage_enabled { let (store, set_store, _) = use_storage_with_options( - storage_key, + storage_key, initial_value, UseStorageOptions::default() .listen_to_storage_changes(listen_to_storage_changes) From 4bb899126b1c6eccc323e810688fc43254a3f76a Mon Sep 17 00:00:00 2001 From: Danik Vitek Date: Tue, 8 Aug 2023 12:49:48 +0300 Subject: [PATCH 11/15] Update leptos to v0.5.0-beta. Fix tests. Apply `cargo clippy` --- Cargo.toml | 2 +- src/signal_debounced.rs | 4 ++-- src/signal_throttled.rs | 4 ++-- src/use_color_mode.rs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9ea6d2b..6de42f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ repository = "https://github.com/Synphonyte/leptos-use" homepage = "https://leptos-use.rs" [dependencies] -leptos = "0.5.0-alpha2" +leptos = "0.5.0-beta" wasm-bindgen = "0.2" js-sys = "0.3" default-struct-builder = "0.5" diff --git a/src/signal_debounced.rs b/src/signal_debounced.rs index f602408..71da1d1 100644 --- a/src/signal_debounced.rs +++ b/src/signal_debounced.rs @@ -19,7 +19,7 @@ signal_filtered!( /// # #[component] /// # fn Demo() -> impl IntoView { /// let (input, set_input) = create_signal(""); - /// let debounced = signal_debounced(input, 1000.0); + /// let debounced: Signal<&'static str> = signal_debounced(input, 1000.0); /// # /// # view! { } /// # } @@ -36,7 +36,7 @@ signal_filtered!( /// # #[component] /// # fn Demo() -> impl IntoView { /// let (input, set_input) = create_signal(""); - /// let debounced = signal_debounced_with_options( + /// let debounced: Signal<&'static str> = signal_debounced_with_options( /// input, /// 1000.0, /// DebounceOptions::default().max_wait(Some(500.0)) diff --git a/src/signal_throttled.rs b/src/signal_throttled.rs index 6b550a9..9040d10 100644 --- a/src/signal_throttled.rs +++ b/src/signal_throttled.rs @@ -19,7 +19,7 @@ signal_filtered!( /// # #[component] /// # fn Demo() -> impl IntoView { /// let (input, set_input) = create_signal(""); - /// let throttled = signal_throttled(input, 1000.0); + /// let throttled: Signal<&'static str> = signal_throttled(input, 1000.0); /// # /// # view! { } /// # } @@ -36,7 +36,7 @@ signal_filtered!( /// # #[component] /// # fn Demo() -> impl IntoView { /// let (input, set_input) = create_signal(""); - /// let throttled = signal_throttled_with_options( + /// let throttled: Signal<&'static str> = signal_throttled_with_options( /// input, /// 1000.0, /// ThrottleOptions::default().leading(false).trailing(true) diff --git a/src/use_color_mode.rs b/src/use_color_mode.rs index 0804293..3bffcb5 100644 --- a/src/use_color_mode.rs +++ b/src/use_color_mode.rs @@ -285,7 +285,7 @@ cfg_if! { if #[cfg(feature = "storage")] { fn get_store_signal( initial_value: MaybeRwSignal, storage_signal: Option>, - _storage_key: &String, + _storage_key: &str, _storage_enabled: bool, _storage: StorageType, _listen_to_storage_changes: bool, From 4b2b0956faf4dc19bcd721548b9ae688822d950f Mon Sep 17 00:00:00 2001 From: Maccesch Date: Thu, 10 Aug 2023 21:36:12 +0100 Subject: [PATCH 12/15] fixed intersection observer reporting non-intersection erroneously --- src/use_element_visibility.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/use_element_visibility.rs b/src/use_element_visibility.rs index d71d8d0..26202cb 100644 --- a/src/use_element_visibility.rs +++ b/src/use_element_visibility.rs @@ -40,7 +40,6 @@ use std::marker::PhantomData; /// * [`use_intersection_observer`] pub fn use_element_visibility(target: El) -> Signal where - El: Clone, El: Into>, T: Into + Clone + 'static, { @@ -63,9 +62,20 @@ where let (is_visible, set_visible) = create_signal(false); use_intersection_observer_with_options( - (target).into(), + target.into(), move |entries, _| { - set_visible.set(entries[0].is_intersecting()); + // In some circumstances Chrome passes a first (or only) entry which has a zero bounding client rect + // and returns `is_intersecting` erroneously as `false`. + if let Some(entry) = entries + .into_iter() + .filter(|entry| { + let rect = entry.bounding_client_rect(); + rect.width() > 0.0 || rect.height() > 0.0 + }) + .next() + { + set_visible.set(entry.is_intersecting()); + } }, UseIntersectionObserverOptions::default().root(options.viewport), ); From 2a27141dcc9c3c2432491fa832d8aed4e4a888c0 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Thu, 10 Aug 2023 21:38:32 +0100 Subject: [PATCH 13/15] chore: clippy --- src/use_element_visibility.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/use_element_visibility.rs b/src/use_element_visibility.rs index 26202cb..6be8b51 100644 --- a/src/use_element_visibility.rs +++ b/src/use_element_visibility.rs @@ -66,14 +66,10 @@ where move |entries, _| { // In some circumstances Chrome passes a first (or only) entry which has a zero bounding client rect // and returns `is_intersecting` erroneously as `false`. - if let Some(entry) = entries - .into_iter() - .filter(|entry| { - let rect = entry.bounding_client_rect(); - rect.width() > 0.0 || rect.height() > 0.0 - }) - .next() - { + if let Some(entry) = entries.into_iter().find(|entry| { + let rect = entry.bounding_client_rect(); + rect.width() > 0.0 || rect.height() > 0.0 + }) { set_visible.set(entry.is_intersecting()); } }, From 5499306626c3a3329e5e462c6382c8368b3a5881 Mon Sep 17 00:00:00 2001 From: Maccesch Date: Thu, 10 Aug 2023 22:49:36 +0100 Subject: [PATCH 14/15] udpated changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c7597a..de95e92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Callbacks in options don't require to be cloneable anymore - Callback in `use_raf_fn` doesn't require to be cloneable anymore +### Fixes 🍕 + +- `use_element_visibility` didn't work in some cases on Chrome properly. This has been fixed. + ## [0.6.2] - 2023-08-03 ### Fixes 🍕 From 84fd425f487b6e2e24b5e914a18cb6c7a988eefa Mon Sep 17 00:00:00 2001 From: Maccesch Date: Sat, 12 Aug 2023 22:30:06 +0100 Subject: [PATCH 15/15] fixed websocket unmount panic --- CHANGELOG.md | 6 ++++++ src/use_websocket.rs | 19 +++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de95e92..839143b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `use_element_visibility` didn't work in some cases on Chrome properly. This has been fixed. +## [0.6.3] - 2023-08-12 + +### Fixes 🍕 + +- `use_websocket` panicked after unmount + ## [0.6.2] - 2023-08-03 ### Fixes 🍕 diff --git a/src/use_websocket.rs b/src/use_websocket.rs index 098e33c..f67b767 100644 --- a/src/use_websocket.rs +++ b/src/use_websocket.rs @@ -2,6 +2,7 @@ use cfg_if::cfg_if; use leptos::{leptos_dom::helpers::TimeoutHandle, *}; +use std::cell::Cell; use std::rc::Rc; use std::time::Duration; @@ -119,7 +120,8 @@ pub fn use_websocket_with_options( let reconnect_timer_ref: StoredValue> = store_value(None); let reconnect_times_ref: StoredValue = store_value(0); - let unmounted_ref = store_value(false); + + let unmounted = Rc::new(Cell::new(false)); let connect_ref: StoredValue>> = store_value(None); @@ -153,6 +155,7 @@ pub fn use_websocket_with_options( connect_ref.set_value({ let ws = ws_ref.get_value(); let url = url; + let unmounted = Rc::clone(&unmounted); Some(Rc::new(move || { reconnect_timer_ref.set_value(None); @@ -179,10 +182,11 @@ pub fn use_websocket_with_options( // onopen handler { + let unmounted = Rc::clone(&unmounted); let on_open = Rc::clone(&on_open); let onopen_closure = Closure::wrap(Box::new(move |e: Event| { - if unmounted_ref.get_value() { + if unmounted.get() { return; } @@ -197,11 +201,12 @@ pub fn use_websocket_with_options( // onmessage handler { + let unmounted = Rc::clone(&unmounted); let on_message = Rc::clone(&on_message); let on_message_bytes = Rc::clone(&on_message_bytes); let onmessage_closure = Closure::wrap(Box::new(move |e: MessageEvent| { - if unmounted_ref.get_value() { + if unmounted.get() { return; } @@ -235,10 +240,11 @@ pub fn use_websocket_with_options( // onerror handler { + let unmounted = Rc::clone(&unmounted); let on_error = Rc::clone(&on_error); let onerror_closure = Closure::wrap(Box::new(move |e: Event| { - if unmounted_ref.get_value() { + if unmounted.get() { return; } @@ -256,10 +262,11 @@ pub fn use_websocket_with_options( // onclose handler { + let unmounted = Rc::clone(&unmounted); let on_close = Rc::clone(&on_close); let onclose_closure = Closure::wrap(Box::new(move |e: CloseEvent| { - if unmounted_ref.get_value() { + if unmounted.get() { return; } @@ -330,7 +337,7 @@ pub fn use_websocket_with_options( // clean up (unmount) on_cleanup(move || { - unmounted_ref.set_value(true); + unmounted.set(true); close(); });