Created
April 7, 2022 21:02
-
-
Save HurricanKai/9d1b30ac08168728db48e3c950d56d3c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use gloo_timers::callback::Timeout; | |
use std::mem::replace; | |
use std::ops::DerefMut; | |
use yew::{ | |
prelude::*, | |
suspense::{Suspension, SuspensionHandle, SuspensionResult}, | |
}; | |
#[hook] | |
fn use_delay(ms: u32) -> SuspensionResult<bool> { | |
enum TriggerState { | |
Done, | |
// I couldn't find a way to tie the knot here. | |
// This state exists only during the first initialization. | |
Initial, | |
Waiting(SuspensionHandle), | |
} | |
let is_initialized = use_state(|| false); | |
let trigger_state = use_mut_ref(|| TriggerState::Initial); | |
{ | |
let is_initialized = is_initialized.clone(); | |
let trigger_state = trigger_state.clone(); | |
use_effect_with_deps( | |
move |_| { | |
let timeout = Timeout::new(ms, move || { | |
match replace(trigger_state.borrow_mut().deref_mut(), TriggerState::Done) { | |
TriggerState::Done | TriggerState::Initial => unreachable!("Impossible!"), | |
TriggerState::Waiting(handle) => handle.resume(), | |
} | |
}); | |
is_initialized.set(true); | |
|| { | |
timeout.cancel(); | |
} | |
}, | |
(), | |
); | |
}; | |
if !*is_initialized { | |
return Ok(true); | |
} | |
let mut trigger_state = trigger_state.borrow_mut(); | |
if let TriggerState::Done = *trigger_state { | |
Ok(false) | |
} else { | |
let (suspense, handle) = Suspension::new(); | |
*trigger_state = TriggerState::Waiting(handle); | |
Err(suspense) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment