Use correct provider icons for extension repository links (#58108)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments (N/A) - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable I was unable to find an issue or PR which mentions this. Extensions with non-GitHub repository links always use the GitHub icon, which is inconsistent with the changes merged in #44738 and #57500. This change makes `extension_ui.rs` use the Git hosting provider registry to determine these icons. Below is a preview of the change: <div align="center"> <img width="450" alt="Preview" src="https://github.com/user-attachments/assets/e35f0eed-de54-48f9-824d-8a5b9bfc596f" /> </div> Release Notes: - Improved extension repository links to show provider-specific icons.
This commit is contained in:
1 parent
20c1f82d13
commit
8f0161b3c2
9 files changed
+51
-20
No files matched your search
Generated
+1
@@ -6439,6 +6439,7 @@ dependencies = [
|
||||
"extension_host",
|
||||
"fs",
|
||||
"fuzzy",
|
||||
"git",
|
||||
"gpui",
|
||||
"language",
|
||||
"log",
|
||||
|
||||
@@ -23,6 +23,7 @@ extension.workspace = true
|
||||
extension_host.workspace = true
|
||||
fs.workspace = true
|
||||
fuzzy.workspace = true
|
||||
git.workspace = true
|
||||
gpui.workspace = true
|
||||
language.workspace = true
|
||||
log.workspace = true
|
||||
|
||||
@@ -68,6 +68,7 @@ struct ExtensionCardDetails {
|
||||
description: Option<SharedString>,
|
||||
authors: SharedString,
|
||||
repository_url: Option<SharedString>,
|
||||
repository_icon: IconName,
|
||||
provided_features: Vec<&'static str>,
|
||||
source: ExtensionCardSource,
|
||||
}
|
||||
@@ -145,6 +146,7 @@ impl ExtensionCard {
|
||||
description: extension.description.clone().map(Into::into),
|
||||
authors: extension.authors.join(", ").into(),
|
||||
repository_url: extension.repository.clone().map(Into::into),
|
||||
repository_icon: IconName::Link,
|
||||
provided_features: provided_feature_labels(extension.provides()),
|
||||
source: ExtensionCardSource::Dev,
|
||||
};
|
||||
@@ -169,6 +171,7 @@ impl ExtensionCard {
|
||||
description: extension.manifest.description.clone().map(Into::into),
|
||||
authors: extension.manifest.authors.join(", ").into(),
|
||||
repository_url: Some(extension.manifest.repository.clone().into()),
|
||||
repository_icon: IconName::Link,
|
||||
provided_features: provided_feature_labels(extension.manifest.provides.iter().copied()),
|
||||
source: ExtensionCardSource::Remote {
|
||||
status,
|
||||
@@ -393,6 +396,11 @@ impl ExtensionCard {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn repository_icon(mut self, icon: IconName) -> Self {
|
||||
self.details.repository_icon = icon;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn context_menu(
|
||||
mut self,
|
||||
builder: impl Fn(Arc<str>, SharedString, &mut Window, &mut App) -> Option<Entity<ContextMenu>>
|
||||
@@ -601,6 +609,7 @@ impl RenderOnce for ExtensionCard {
|
||||
description,
|
||||
authors,
|
||||
repository_url,
|
||||
repository_icon,
|
||||
provided_features,
|
||||
source,
|
||||
} = details;
|
||||
@@ -701,7 +710,7 @@ impl RenderOnce for ExtensionCard {
|
||||
.when_some(repository_url, |this, repository_url| {
|
||||
let repository_url_for_tooltip = repository_url.clone();
|
||||
this.child(
|
||||
IconButton::new(repository_button_id, IconName::Github)
|
||||
IconButton::new(repository_button_id, repository_icon)
|
||||
.icon_size(IconSize::Small)
|
||||
.tooltip(move |_, cx| {
|
||||
Tooltip::with_meta(
|
||||
|
||||
@@ -13,6 +13,7 @@ use command_palette_hooks::CommandPaletteFilter;
|
||||
use editor::{Editor, EditorElement, EditorStyle};
|
||||
use extension_host::{ExtensionManifest, ExtensionStore};
|
||||
use fuzzy::{StringMatch, StringMatchCandidate, match_strings};
|
||||
use git::{GitHostingProviderRegistry, parse_git_remote_url};
|
||||
use gpui::{
|
||||
Action, App, ClipboardItem, Context, DismissEvent, Entity, EventEmitter, Focusable,
|
||||
InteractiveElement, KeyContext, ParentElement, Render, Styled, Task, TaskExt, TextStyle,
|
||||
@@ -378,6 +379,7 @@ fn keywords_by_feature() -> &'static BTreeMap<Feature, Vec<&'static str>> {
|
||||
|
||||
pub struct ExtensionsPage {
|
||||
workspace: WeakEntity<Workspace>,
|
||||
provider_registry: Arc<GitHostingProviderRegistry>,
|
||||
list: UniformListScrollHandle,
|
||||
is_fetching_extensions: bool,
|
||||
fetch_failed: bool,
|
||||
@@ -437,9 +439,11 @@ impl ExtensionsPage {
|
||||
cx.subscribe(&query_editor, Self::on_query_change).detach();
|
||||
|
||||
let scroll_handle = UniformListScrollHandle::new();
|
||||
let provider_registry = GitHostingProviderRegistry::default_global(cx);
|
||||
|
||||
let mut this = Self {
|
||||
workspace: workspace.weak_handle(),
|
||||
provider_registry,
|
||||
list: scroll_handle,
|
||||
is_fetching_extensions: false,
|
||||
fetch_failed: false,
|
||||
@@ -465,6 +469,12 @@ impl ExtensionsPage {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_repository_icon(&self, repository_url: &str) -> IconName {
|
||||
parse_git_remote_url(Arc::clone(&self.provider_registry), repository_url)
|
||||
.map(|(provider, _)| ui::git_hosting_provider_icon(provider.name().as_str()))
|
||||
.unwrap_or(IconName::Link)
|
||||
}
|
||||
|
||||
fn on_extension_installed(
|
||||
&mut self,
|
||||
workspace: WeakEntity<Workspace>,
|
||||
@@ -665,7 +675,16 @@ impl ExtensionsPage {
|
||||
if ix < dev_extension_entries_len {
|
||||
let dev_ix = self.filtered_dev_extension_indices[ix];
|
||||
let extension = &self.dev_extension_entries[dev_ix];
|
||||
ExtensionCard::for_dev(extension.clone(), cx)
|
||||
let repository_icon = extension
|
||||
.repository
|
||||
.as_deref()
|
||||
.map(|url| self.get_repository_icon(url));
|
||||
let card = ExtensionCard::for_dev(extension.clone(), cx);
|
||||
if let Some(icon) = repository_icon {
|
||||
card.repository_icon(icon)
|
||||
} else {
|
||||
card
|
||||
}
|
||||
} else {
|
||||
let extension_ix =
|
||||
self.filtered_remote_extension_indices[ix - dev_extension_entries_len];
|
||||
@@ -681,7 +700,8 @@ impl ExtensionsPage {
|
||||
extension: &ExtensionMetadata,
|
||||
cx: &mut Context<Self>,
|
||||
) -> ExtensionCard {
|
||||
let card = ExtensionCard::for_remote(extension, cx);
|
||||
let repository_icon = self.get_repository_icon(&extension.manifest.repository);
|
||||
let card = ExtensionCard::for_remote(extension, cx).repository_icon(repository_icon);
|
||||
let this = cx.weak_entity();
|
||||
|
||||
card.context_menu(move |extension_id, authors, window, cx| {
|
||||
|
||||
@@ -1226,7 +1226,7 @@ fn remote_provider_icons(
|
||||
let (provider, _) = parse_git_remote_url(provider_registry.clone(), remote_url)?;
|
||||
Some((
|
||||
remote_name.clone(),
|
||||
crate::get_provider_icon(&provider.name()),
|
||||
ui::git_hosting_provider_icon(provider.name().as_str()),
|
||||
))
|
||||
})
|
||||
.collect()
|
||||
|
||||
@@ -1344,7 +1344,7 @@ impl Render for CommitViewToolbar {
|
||||
}),
|
||||
)
|
||||
.children(remote_info.map(|(provider_name, url)| {
|
||||
let icon = crate::get_provider_icon(provider_name.as_str());
|
||||
let icon = ui::git_hosting_provider_icon(provider_name.as_str());
|
||||
|
||||
IconButton::new("view_on_provider", icon)
|
||||
.icon_size(IconSize::Small)
|
||||
|
||||
@@ -2982,7 +2982,7 @@ impl GitGraph {
|
||||
})
|
||||
.when_some(remote.clone(), |this, remote| {
|
||||
let provider_name = remote.host.name();
|
||||
let icon = crate::get_provider_icon(provider_name.as_str());
|
||||
let icon = ui::git_hosting_provider_icon(provider_name.as_str());
|
||||
let parsed_remote = ParsedGitRemote {
|
||||
owner: remote.owner.as_ref().into(),
|
||||
repo: remote.repo.as_ref().into(),
|
||||
|
||||
@@ -60,20 +60,6 @@ pub mod unstaged_diff;
|
||||
pub use blame_ui::GitBlameStatus;
|
||||
pub use conflict_view::MergeConflictIndicator;
|
||||
|
||||
pub fn get_provider_icon(name: &str) -> IconName {
|
||||
match name {
|
||||
"Bitbucket" => IconName::Bitbucket,
|
||||
"Chromium" => IconName::Gerrit,
|
||||
"Codeberg" => IconName::Codeberg,
|
||||
"Forgejo Self-Hosted" => IconName::Forgejo,
|
||||
"GitHub" => IconName::Github,
|
||||
"GitLab" => IconName::Gitlab,
|
||||
"Gitea" => IconName::Gitea,
|
||||
"SourceHut" => IconName::Sourcehut,
|
||||
_ => IconName::Link,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init(cx: &mut App) {
|
||||
editor::set_blame_renderer(blame_ui::GitBlameRenderer, cx);
|
||||
commit_view::init(cx);
|
||||
|
||||
@@ -112,6 +112,20 @@ impl From<IconName> for Icon {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn git_hosting_provider_icon(provider_name: &str) -> IconName {
|
||||
match provider_name {
|
||||
"Bitbucket" => IconName::Bitbucket,
|
||||
"Chromium" => IconName::Gerrit,
|
||||
"Codeberg" => IconName::Codeberg,
|
||||
"Forgejo Self-Hosted" => IconName::Forgejo,
|
||||
"GitHub" => IconName::Github,
|
||||
"GitLab" => IconName::Gitlab,
|
||||
"Gitea" => IconName::Gitea,
|
||||
"SourceHut" => IconName::Sourcehut,
|
||||
_ => IconName::Link,
|
||||
}
|
||||
}
|
||||
|
||||
/// The source of an icon.
|
||||
#[derive(Clone)]
|
||||
enum IconSource {
|
||||
|
||||
Reference in new issue
Block a user