feat: add combobox filter
This commit is contained in:
@@ -5,7 +5,8 @@ use std::time::Duration;
|
||||
|
||||
use gpui::prelude::FluentBuilder as _;
|
||||
use gpui::{
|
||||
AnyView, App, ClipboardItem, ElementId, Entity, IntoElement, RenderOnce, SharedString, Window,
|
||||
AnyView, App, ClipboardItem, ElementId, Entity, IntoElement, RenderOnce, SharedString, Task,
|
||||
Window,
|
||||
};
|
||||
use gpui_native_icons::IconRole;
|
||||
use gpui_native_theme::Size;
|
||||
@@ -92,11 +93,22 @@ impl Sizable for ClipboardButton {
|
||||
}
|
||||
}
|
||||
|
||||
/// The transient copied marker keyed per button.
|
||||
struct CopiedState {
|
||||
generation: u64,
|
||||
tasks: Vec<Task<()>>,
|
||||
}
|
||||
|
||||
impl RenderOnce for ClipboardButton {
|
||||
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||
let copied: Entity<Option<u64>> =
|
||||
window.use_keyed_state((self.id.clone(), "clipboard-copied"), cx, |_, _| None);
|
||||
let is_copied = copied.read(cx).is_some();
|
||||
let copied: Entity<CopiedState> =
|
||||
window.use_keyed_state((self.id.clone(), "clipboard-copied"), cx, |_, _| {
|
||||
CopiedState {
|
||||
generation: 0,
|
||||
tasks: Vec::new(),
|
||||
}
|
||||
});
|
||||
let is_copied = copied.read(cx).generation != 0;
|
||||
|
||||
let selector = if is_copied {
|
||||
"clipboard-copied"
|
||||
@@ -126,30 +138,29 @@ impl RenderOnce for ClipboardButton {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(value.to_string()));
|
||||
|
||||
let generation = copied.update(cx, |state, cx| {
|
||||
let generation = state.map_or(1, |generation| generation.wrapping_add(1));
|
||||
*state = Some(generation);
|
||||
state.generation += 1;
|
||||
cx.notify();
|
||||
generation
|
||||
state.generation
|
||||
});
|
||||
|
||||
// Clear the copied state after the duration expires
|
||||
window
|
||||
.spawn(cx, {
|
||||
let copied = copied.clone();
|
||||
async move |cx| {
|
||||
cx.background_executor().timer(COPIED_DURATION).await;
|
||||
cx.update(|_, cx| {
|
||||
copied.update(cx, |state, cx| {
|
||||
if *state == Some(generation) {
|
||||
*state = None;
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
let weak = copied.downgrade();
|
||||
let task = window.spawn(cx, async move |cx| {
|
||||
cx.background_executor().timer(COPIED_DURATION).await;
|
||||
cx.update(|_, cx| {
|
||||
weak.update(cx, |state, cx| {
|
||||
if state.generation == generation {
|
||||
state.generation = 0;
|
||||
cx.notify();
|
||||
}
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
.ok();
|
||||
});
|
||||
|
||||
copied.update(cx, |state, _| {
|
||||
state.tasks.push(task);
|
||||
});
|
||||
|
||||
// Invoke the callback after copying
|
||||
if let Some(on_copied) = &on_copied {
|
||||
|
||||
Reference in New Issue
Block a user