mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-27 23:59:52 +03:00
Add checkbox to only show installed extensions (#8208)
This PR adds a checkbox to the extensions view to allow filtering to just extensions that are installed: <img width="1408" alt="Screenshot 2024-02-22 at 12 05 40 PM" src="https://github.com/zed-industries/zed/assets/1486634/b5e82941-53be-432e-bfe5-fec7fd0959c5"> Release Notes: - Added a checkbox to the extensions view to only show installed extensions.
This commit is contained in:
parent
5c4f3c0cea
commit
af06063d31
@ -34,7 +34,7 @@ pub struct ExtensionsApiResponse {
|
||||
pub data: Vec<Extension>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Clone, Deserialize)]
|
||||
pub struct Extension {
|
||||
pub id: Arc<str>,
|
||||
pub version: Arc<str>,
|
||||
|
@ -11,7 +11,7 @@ use settings::Settings;
|
||||
use std::time::Duration;
|
||||
use std::{ops::Range, sync::Arc};
|
||||
use theme::ThemeSettings;
|
||||
use ui::{prelude::*, Tooltip};
|
||||
use ui::{prelude::*, CheckboxWithLabel, Tooltip};
|
||||
|
||||
use workspace::{
|
||||
item::{Item, ItemEvent},
|
||||
@ -34,7 +34,8 @@ pub struct ExtensionsPage {
|
||||
list: UniformListScrollHandle,
|
||||
telemetry: Arc<Telemetry>,
|
||||
is_fetching_extensions: bool,
|
||||
extensions_entries: Vec<Extension>,
|
||||
is_only_showing_installed_extensions: bool,
|
||||
extension_entries: Vec<Extension>,
|
||||
query_editor: View<Editor>,
|
||||
query_contains_error: bool,
|
||||
_subscription: gpui::Subscription,
|
||||
@ -54,7 +55,8 @@ impl ExtensionsPage {
|
||||
list: UniformListScrollHandle::new(),
|
||||
telemetry: workspace.client().telemetry().clone(),
|
||||
is_fetching_extensions: false,
|
||||
extensions_entries: Vec::new(),
|
||||
is_only_showing_installed_extensions: false,
|
||||
extension_entries: Vec::new(),
|
||||
query_contains_error: false,
|
||||
extension_fetch_task: None,
|
||||
_subscription: subscription,
|
||||
@ -65,6 +67,24 @@ impl ExtensionsPage {
|
||||
})
|
||||
}
|
||||
|
||||
fn filtered_extension_entries(&self, cx: &mut ViewContext<Self>) -> Vec<Extension> {
|
||||
let extension_store = ExtensionStore::global(cx).read(cx);
|
||||
|
||||
self.extension_entries
|
||||
.iter()
|
||||
.filter(|extension| {
|
||||
if self.is_only_showing_installed_extensions {
|
||||
let status = extension_store.extension_status(&extension.id);
|
||||
|
||||
matches!(status, ExtensionStatus::Installed(_))
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
fn install_extension(
|
||||
&self,
|
||||
extension_id: Arc<str>,
|
||||
@ -94,7 +114,7 @@ impl ExtensionsPage {
|
||||
let fetch_result = extensions.await;
|
||||
match fetch_result {
|
||||
Ok(extensions) => this.update(&mut cx, |this, cx| {
|
||||
this.extensions_entries = extensions;
|
||||
this.extension_entries = extensions;
|
||||
this.is_fetching_extensions = false;
|
||||
cx.notify();
|
||||
}),
|
||||
@ -113,7 +133,7 @@ impl ExtensionsPage {
|
||||
}
|
||||
|
||||
fn render_extensions(&mut self, range: Range<usize>, cx: &mut ViewContext<Self>) -> Vec<Div> {
|
||||
self.extensions_entries[range]
|
||||
self.filtered_extension_entries(cx)[range]
|
||||
.iter()
|
||||
.map(|extension| self.render_entry(extension, cx))
|
||||
.collect()
|
||||
@ -381,10 +401,32 @@ impl ExtensionsPage {
|
||||
Some(search)
|
||||
}
|
||||
}
|
||||
|
||||
fn render_empty_state(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
let has_search = self.search_query(cx).is_some();
|
||||
|
||||
let message = if self.is_fetching_extensions {
|
||||
"Loading extensions..."
|
||||
} else if self.is_only_showing_installed_extensions {
|
||||
if has_search {
|
||||
"No installed extensions that match your search."
|
||||
} else {
|
||||
"No installed extensions."
|
||||
}
|
||||
} else {
|
||||
if has_search {
|
||||
"No extensions that match your search."
|
||||
} else {
|
||||
"No extensions."
|
||||
}
|
||||
};
|
||||
|
||||
Label::new(message)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ExtensionsPage {
|
||||
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> impl IntoElement {
|
||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
v_flex()
|
||||
.size_full()
|
||||
.p_4()
|
||||
@ -395,25 +437,39 @@ impl Render for ExtensionsPage {
|
||||
.w_full()
|
||||
.child(Headline::new("Extensions").size(HeadlineSize::XLarge)),
|
||||
)
|
||||
.child(h_flex().w_56().child(self.render_search(cx)))
|
||||
.child(
|
||||
h_flex()
|
||||
.w_full()
|
||||
.gap_2()
|
||||
.child(h_flex().child(self.render_search(cx)))
|
||||
.child(CheckboxWithLabel::new(
|
||||
"installed",
|
||||
Label::new("Only show installed"),
|
||||
if self.is_only_showing_installed_extensions {
|
||||
Selection::Selected
|
||||
} else {
|
||||
Selection::Unselected
|
||||
},
|
||||
cx.listener(|this, selection, _cx| {
|
||||
this.is_only_showing_installed_extensions = match selection {
|
||||
Selection::Selected => true,
|
||||
Selection::Unselected => false,
|
||||
Selection::Indeterminate => return,
|
||||
}
|
||||
}),
|
||||
)),
|
||||
)
|
||||
.child(v_flex().size_full().overflow_y_hidden().map(|this| {
|
||||
if self.extensions_entries.is_empty() {
|
||||
let message = if self.is_fetching_extensions {
|
||||
"Loading extensions..."
|
||||
} else if self.search_query(cx).is_some() {
|
||||
"No extensions that match your search."
|
||||
} else {
|
||||
"No extensions."
|
||||
};
|
||||
|
||||
return this.child(Label::new(message));
|
||||
let entries = self.filtered_extension_entries(cx);
|
||||
if entries.is_empty() {
|
||||
return this.child(self.render_empty_state(cx));
|
||||
}
|
||||
|
||||
this.child(
|
||||
canvas({
|
||||
let view = cx.view().clone();
|
||||
let scroll_handle = self.list.clone();
|
||||
let item_count = self.extensions_entries.len();
|
||||
let item_count = entries.len();
|
||||
move |bounds, cx| {
|
||||
uniform_list::<_, Div, _>(
|
||||
view,
|
||||
|
Loading…
Reference in New Issue
Block a user