mirror of
https://github.com/adoyle0/thaw.git
synced 2025-01-22 22:09:22 -05:00
fix: next_frame leaks (#147)
* fix: next_frame leaks * ci: added workflow path
This commit is contained in:
parent
2be216043e
commit
535594f963
6 changed files with 74 additions and 18 deletions
13
.github/workflows/ci.yml
vendored
13
.github/workflows/ci.yml
vendored
|
@ -2,13 +2,16 @@ name: CI
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths: ["demo/**", "demo_markdown/**", "thaw/**"]
|
paths:
|
||||||
|
[
|
||||||
|
"demo/**",
|
||||||
|
"demo_markdown/**",
|
||||||
|
"thaw/**",
|
||||||
|
"thaw_components/**",
|
||||||
|
"thaw_utils/**",
|
||||||
|
]
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
push:
|
|
||||||
paths: ["demo/**", "demo_markdown/**", "thaw/**"]
|
|
||||||
branches:
|
|
||||||
- thaw/v0.2
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
stable:
|
stable:
|
||||||
|
|
9
.github/workflows/demo.yml
vendored
9
.github/workflows/demo.yml
vendored
|
@ -2,7 +2,14 @@ name: Deploy demo
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
paths: ["demo/**", "demo_markdown/**", "thaw/**"]
|
paths:
|
||||||
|
[
|
||||||
|
"demo/**",
|
||||||
|
"demo_markdown/**",
|
||||||
|
"thaw/**",
|
||||||
|
"thaw_components/**",
|
||||||
|
"thaw_utils/**",
|
||||||
|
]
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use leptos::{html::ElementDescriptor, *};
|
use leptos::{html::ElementDescriptor, *};
|
||||||
use std::{ops::Deref, time::Duration};
|
use std::{ops::Deref, time::Duration};
|
||||||
use thaw_utils::{add_event_listener, EventListenerHandle};
|
use thaw_utils::{add_event_listener, use_next_frame, EventListenerHandle};
|
||||||
|
|
||||||
/// # CSS Transition
|
/// # CSS Transition
|
||||||
///
|
///
|
||||||
|
@ -26,6 +26,7 @@ where
|
||||||
let any_el = node_el.clone().into_any();
|
let any_el = node_el.clone().into_any();
|
||||||
let el = any_el.deref().clone();
|
let el = any_el.deref().clone();
|
||||||
let class_list = el.class_list();
|
let class_list = el.class_list();
|
||||||
|
let next_frame = use_next_frame();
|
||||||
let end_handle = StoredValue::new(None::<EventListenerHandle>);
|
let end_handle = StoredValue::new(None::<EventListenerHandle>);
|
||||||
let end_count = StoredValue::new(None::<usize>);
|
let end_count = StoredValue::new(None::<usize>);
|
||||||
let finish = StoredValue::new(None::<Callback<()>>);
|
let finish = StoredValue::new(None::<Callback<()>>);
|
||||||
|
@ -53,7 +54,7 @@ where
|
||||||
|
|
||||||
set_timeout(
|
set_timeout(
|
||||||
move || {
|
move || {
|
||||||
finish.update_value(|v| {
|
finish.try_update_value(|v| {
|
||||||
v.take().map(|f| f.call(()));
|
v.take().map(|f| f.call(()));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -107,7 +108,7 @@ where
|
||||||
display.set(None);
|
display.set(None);
|
||||||
|
|
||||||
let class_list = class_list.clone();
|
let class_list = class_list.clone();
|
||||||
next_frame(move || {
|
next_frame.run(move || {
|
||||||
let _ = class_list.remove_1(&enter_from);
|
let _ = class_list.remove_1(&enter_from);
|
||||||
let _ = class_list.add_1(&enter_to);
|
let _ = class_list.add_1(&enter_to);
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ where
|
||||||
let _ = class_list.add_2(&leave_from, &leave_active);
|
let _ = class_list.add_2(&leave_from, &leave_active);
|
||||||
|
|
||||||
let class_list = class_list.clone();
|
let class_list = class_list.clone();
|
||||||
next_frame(move || {
|
next_frame.run(move || {
|
||||||
let _ = class_list.remove_1(&leave_from);
|
let _ = class_list.remove_1(&leave_from);
|
||||||
let _ = class_list.add_1(&leave_to);
|
let _ = class_list.add_1(&leave_to);
|
||||||
|
|
||||||
|
@ -170,17 +171,19 @@ where
|
||||||
|
|
||||||
show
|
show
|
||||||
});
|
});
|
||||||
|
|
||||||
|
on_cleanup(move || {
|
||||||
|
end_handle.update_value(|handle| {
|
||||||
|
if let Some(handle) = handle.take() {
|
||||||
|
handle.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
children(display.read_only())
|
children(display.read_only())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_frame(cb: impl FnOnce() + 'static) {
|
|
||||||
request_animation_frame(move || {
|
|
||||||
request_animation_frame(cb);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum AnimationTypes {
|
enum AnimationTypes {
|
||||||
Transition,
|
Transition,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
mod use_click_position;
|
mod use_click_position;
|
||||||
mod use_lock_html_scroll;
|
mod use_lock_html_scroll;
|
||||||
|
mod use_next_frame;
|
||||||
|
|
||||||
pub use use_click_position::use_click_position;
|
pub use use_click_position::use_click_position;
|
||||||
pub use use_lock_html_scroll::use_lock_html_scroll;
|
pub use use_lock_html_scroll::use_lock_html_scroll;
|
||||||
|
pub use use_next_frame::{use_next_frame, NextFrame};
|
||||||
|
|
41
thaw_utils/src/hooks/use_next_frame.rs
Normal file
41
thaw_utils/src/hooks/use_next_frame.rs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
use leptos::{
|
||||||
|
leptos_dom::helpers::AnimationFrameRequestHandle, on_cleanup,
|
||||||
|
request_animation_frame_with_handle, StoredValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn use_next_frame() -> NextFrame {
|
||||||
|
let next_frame = NextFrame::default();
|
||||||
|
|
||||||
|
on_cleanup(move || {
|
||||||
|
next_frame.cancel();
|
||||||
|
});
|
||||||
|
|
||||||
|
next_frame
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct NextFrame(StoredValue<Option<AnimationFrameRequestHandle>>);
|
||||||
|
|
||||||
|
impl Copy for NextFrame {}
|
||||||
|
|
||||||
|
impl NextFrame {
|
||||||
|
pub fn run(&self, cb: impl FnOnce() + 'static) {
|
||||||
|
self.cancel();
|
||||||
|
|
||||||
|
let next_frame_hadnle = self.0.clone();
|
||||||
|
let handle = request_animation_frame_with_handle(move || {
|
||||||
|
let handle = request_animation_frame_with_handle(cb).unwrap();
|
||||||
|
next_frame_hadnle.set_value(Some(handle));
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
self.0.set_value(Some(handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn cancel(&self) {
|
||||||
|
self.0.update_value(|value| {
|
||||||
|
if let Some(value) = value.take() {
|
||||||
|
value.cancel();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,13 +7,13 @@ mod signals;
|
||||||
mod time;
|
mod time;
|
||||||
|
|
||||||
pub use event_listener::{add_event_listener, EventListenerHandle};
|
pub use event_listener::{add_event_listener, EventListenerHandle};
|
||||||
pub use hooks::{use_click_position, use_lock_html_scroll};
|
pub use hooks::{use_click_position, use_lock_html_scroll, use_next_frame, NextFrame};
|
||||||
pub use mount_style::mount_style;
|
pub use mount_style::mount_style;
|
||||||
pub use optional_prop::OptionalProp;
|
pub use optional_prop::OptionalProp;
|
||||||
pub use signals::{
|
pub use signals::{
|
||||||
create_component_ref, ComponentRef, Model, OptionalMaybeSignal, SignalWatch, StoredMaybeSignal,
|
create_component_ref, ComponentRef, Model, OptionalMaybeSignal, SignalWatch, StoredMaybeSignal,
|
||||||
};
|
};
|
||||||
pub use time::*;
|
pub use time::now_date;
|
||||||
|
|
||||||
pub fn with_hydration_off<T>(f: impl FnOnce() -> T) -> T {
|
pub fn with_hydration_off<T>(f: impl FnOnce() -> T) -> T {
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(feature = "hydrate")]
|
||||||
|
|
Loading…
Add table
Reference in a new issue