feat(ui): epoch-based debounce cancels stale search results

This commit is contained in:
2026-03-15 20:00:17 +01:00
parent 1e305dc5bf
commit c68f07d522

View File

@@ -27,6 +27,7 @@ pub struct KLauncherApp {
selected: usize,
cfg: AppearanceCfg,
error: Option<String>,
search_epoch: u64,
}
impl KLauncherApp {
@@ -43,6 +44,7 @@ impl KLauncherApp {
selected: 0,
cfg,
error: None,
search_epoch: 0,
}
}
}
@@ -50,7 +52,7 @@ impl KLauncherApp {
#[derive(Debug, Clone)]
pub enum Message {
QueryChanged(String),
ResultsReady(Arc<Vec<SearchResult>>),
ResultsReady(u64, Arc<Vec<SearchResult>>),
KeyPressed(KeyEvent),
}
@@ -60,14 +62,21 @@ fn update(state: &mut KLauncherApp, message: Message) -> Task<Message> {
state.error = None;
state.query = q.clone();
state.selected = 0;
state.search_epoch += 1;
let epoch = state.search_epoch;
let engine = state.engine.clone();
Task::perform(
async move { engine.search(&q).await },
|results| Message::ResultsReady(Arc::new(results)),
async move {
tokio::time::sleep(std::time::Duration::from_millis(50)).await;
(epoch, engine.search(&q).await)
},
|(epoch, results)| Message::ResultsReady(epoch, Arc::new(results)),
)
}
Message::ResultsReady(results) => {
Message::ResultsReady(epoch, results) => {
if epoch == state.search_epoch {
state.results = results;
}
Task::none()
}
Message::KeyPressed(event) => {