Skip to content

Commit 535594f

Browse files
authored
fix: next_frame leaks (#147)
* fix: next_frame leaks * ci: added workflow path
1 parent 2be2160 commit 535594f

File tree

6 files changed

+74
-18
lines changed

6 files changed

+74
-18
lines changed

.github/workflows/ci.yml

+8-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ name: CI
22
on:
33
workflow_dispatch:
44
pull_request:
5-
paths: ["demo/**", "demo_markdown/**", "thaw/**"]
5+
paths:
6+
[
7+
"demo/**",
8+
"demo_markdown/**",
9+
"thaw/**",
10+
"thaw_components/**",
11+
"thaw_utils/**",
12+
]
613
branches:
714
- main
8-
push:
9-
paths: ["demo/**", "demo_markdown/**", "thaw/**"]
10-
branches:
11-
- thaw/v0.2
1215

1316
jobs:
1417
stable:

.github/workflows/demo.yml

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ name: Deploy demo
22
on:
33
workflow_dispatch:
44
push:
5-
paths: ["demo/**", "demo_markdown/**", "thaw/**"]
5+
paths:
6+
[
7+
"demo/**",
8+
"demo_markdown/**",
9+
"thaw/**",
10+
"thaw_components/**",
11+
"thaw_utils/**",
12+
]
613
branches:
714
- main
815

thaw_components/src/css_transition/mod.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use leptos::{html::ElementDescriptor, *};
22
use std::{ops::Deref, time::Duration};
3-
use thaw_utils::{add_event_listener, EventListenerHandle};
3+
use thaw_utils::{add_event_listener, use_next_frame, EventListenerHandle};
44

55
/// # CSS Transition
66
///
@@ -26,6 +26,7 @@ where
2626
let any_el = node_el.clone().into_any();
2727
let el = any_el.deref().clone();
2828
let class_list = el.class_list();
29+
let next_frame = use_next_frame();
2930
let end_handle = StoredValue::new(None::<EventListenerHandle>);
3031
let end_count = StoredValue::new(None::<usize>);
3132
let finish = StoredValue::new(None::<Callback<()>>);
@@ -53,7 +54,7 @@ where
5354

5455
set_timeout(
5556
move || {
56-
finish.update_value(|v| {
57+
finish.try_update_value(|v| {
5758
v.take().map(|f| f.call(()));
5859
});
5960
},
@@ -107,7 +108,7 @@ where
107108
display.set(None);
108109

109110
let class_list = class_list.clone();
110-
next_frame(move || {
111+
next_frame.run(move || {
111112
let _ = class_list.remove_1(&enter_from);
112113
let _ = class_list.add_1(&enter_to);
113114

@@ -136,7 +137,7 @@ where
136137
let _ = class_list.add_2(&leave_from, &leave_active);
137138

138139
let class_list = class_list.clone();
139-
next_frame(move || {
140+
next_frame.run(move || {
140141
let _ = class_list.remove_1(&leave_from);
141142
let _ = class_list.add_1(&leave_to);
142143

@@ -170,17 +171,19 @@ where
170171

171172
show
172173
});
174+
175+
on_cleanup(move || {
176+
end_handle.update_value(|handle| {
177+
if let Some(handle) = handle.take() {
178+
handle.remove();
179+
}
180+
});
181+
})
173182
});
174183

175184
children(display.read_only())
176185
}
177186

178-
fn next_frame(cb: impl FnOnce() + 'static) {
179-
request_animation_frame(move || {
180-
request_animation_frame(cb);
181-
});
182-
}
183-
184187
#[derive(PartialEq)]
185188
enum AnimationTypes {
186189
Transition,

thaw_utils/src/hooks/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
mod use_click_position;
22
mod use_lock_html_scroll;
3+
mod use_next_frame;
34

45
pub use use_click_position::use_click_position;
56
pub use use_lock_html_scroll::use_lock_html_scroll;
7+
pub use use_next_frame::{use_next_frame, NextFrame};
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use leptos::{
2+
leptos_dom::helpers::AnimationFrameRequestHandle, on_cleanup,
3+
request_animation_frame_with_handle, StoredValue,
4+
};
5+
6+
pub fn use_next_frame() -> NextFrame {
7+
let next_frame = NextFrame::default();
8+
9+
on_cleanup(move || {
10+
next_frame.cancel();
11+
});
12+
13+
next_frame
14+
}
15+
16+
#[derive(Default, Clone)]
17+
pub struct NextFrame(StoredValue<Option<AnimationFrameRequestHandle>>);
18+
19+
impl Copy for NextFrame {}
20+
21+
impl NextFrame {
22+
pub fn run(&self, cb: impl FnOnce() + 'static) {
23+
self.cancel();
24+
25+
let next_frame_hadnle = self.0.clone();
26+
let handle = request_animation_frame_with_handle(move || {
27+
let handle = request_animation_frame_with_handle(cb).unwrap();
28+
next_frame_hadnle.set_value(Some(handle));
29+
})
30+
.unwrap();
31+
self.0.set_value(Some(handle));
32+
}
33+
34+
pub fn cancel(&self) {
35+
self.0.update_value(|value| {
36+
if let Some(value) = value.take() {
37+
value.cancel();
38+
}
39+
});
40+
}
41+
}

thaw_utils/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ mod signals;
77
mod time;
88

99
pub use event_listener::{add_event_listener, EventListenerHandle};
10-
pub use hooks::{use_click_position, use_lock_html_scroll};
10+
pub use hooks::{use_click_position, use_lock_html_scroll, use_next_frame, NextFrame};
1111
pub use mount_style::mount_style;
1212
pub use optional_prop::OptionalProp;
1313
pub use signals::{
1414
create_component_ref, ComponentRef, Model, OptionalMaybeSignal, SignalWatch, StoredMaybeSignal,
1515
};
16-
pub use time::*;
16+
pub use time::now_date;
1717

1818
pub fn with_hydration_off<T>(f: impl FnOnce() -> T) -> T {
1919
#[cfg(feature = "hydrate")]

0 commit comments

Comments
 (0)