refactor: migrate to github gql api

This commit is contained in:
2026-05-08 02:23:28 +08:00
parent 7de0039d38
commit 19769a7b75
11 changed files with 177422 additions and 228 deletions

View File

@@ -29,15 +29,16 @@ struct IssueListItem {
repo_name: Option<gpui::SharedString>,
title: gpui::SharedString,
description: Option<gpui::SharedString>,
status: IssueStatus,
status: api::issues::IssueState,
is_last: bool,
is_draft: bool,
}
pub(crate) fn new(cx: &mut gpui::Context<IssueList>) -> IssueList {
let mut list = IssueList {
pr_query: use_query(
api::issues::ListPullRequests {
filter: Some(api::issues::Issue::FILTER_ALL),
filter: Some("author:@me state:open"),
page: 1,
},
cx,
@@ -54,33 +55,20 @@ impl IssueList {
fn on_create(&mut self, cx: &mut gpui::Context<Self>) {
cx.observe(&self.pr_query, |this, _, cx| {
let data = read_query(&this.pr_query, cx);
if let QueryStatus::Loaded(issues) = data {
if let QueryStatus::Loaded(res) = data {
let old_len = this.list_state.item_count();
let new_len = issues.len();
let new_len = res.items.len();
this.list_items = issues
.iter()
.enumerate()
.map(|(i, it)| IssueListItem {
repo_name: it.repository.as_ref().map(|it| {
gpui::SharedString::new(format!("{}/{}", it.owner.login, it.name))
}),
title: gpui::SharedString::new(it.title.as_str()),
description: it
.body_text
.as_ref()
.map(|it| gpui::SharedString::new(it.as_str())),
status: if it.state == "open" {
IssueStatus::Open
} else if it.state == "closed" {
IssueStatus::Closed
} else {
IssueStatus::Draft
},
is_last: i == new_len - 1,
})
.collect::<Vec<_>>();
let new_items = res.items.iter().enumerate().map(|(i, it)| IssueListItem {
repo_name: Some(gpui::SharedString::new(it.repo_slug.as_str())),
title: gpui::SharedString::new(it.title.as_str()),
description: None,
status: it.state,
is_last: i == new_len - 1,
is_draft: it.is_draft,
});
this.list_items.splice(old_len..old_len, new_items);
this.list_state.splice(old_len..old_len, new_len);
}
})
@@ -114,15 +102,19 @@ impl gpui::RenderOnce for IssueListItem {
.text_xs()
.opacity(0.5);
let icon = match self.status {
IssueStatus::Draft => font_icon(FontIcon::PullRequestDraft)
let icon = if self.is_draft {
font_icon(FontIcon::PullRequestDraft)
.text_color(theme.colors.text)
.opacity(0.5),
IssueStatus::Open => {
font_icon(FontIcon::PullRequestArrow).text_color(theme.colors.success)
}
IssueStatus::Closed => {
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.danger)
.opacity(0.5)
} else {
match self.status {
api::issues::IssueState::Closed => {
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.danger)
}
api::issues::IssueState::Merged => {
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.success)
}
_ => font_icon(FontIcon::PullRequestArrow).text_color(theme.colors.success),
}
}
.flex_shrink_0()

View File

@@ -4,7 +4,7 @@ use gpui::{
};
use crate::{
api, app,
app,
component::{
font_icon::{FontIcon, font_icon},
text::text,
@@ -34,29 +34,19 @@ pub enum SidebarItemValue {
pub fn new() -> Sidebar {
Sidebar {
selected_item_id: Some("all"),
selected_item_id: Some("authored"),
on_item_change: None,
}
}
impl Sidebar {
const ALL_ITEMS: [SidebarItem; 3] = [
SidebarItem {
id: "all",
title: "All",
icon: FontIcon::List,
value: SidebarItemValue::PullRequest {
filter: api::issues::Issue::FILTER_ALL,
},
is_selected: false,
on_click: None,
},
const ALL_ITEMS: [SidebarItem; 2] = [
SidebarItem {
id: "authored",
title: "Authored",
icon: FontIcon::PencilLine,
value: SidebarItemValue::PullRequest {
filter: api::issues::Issue::FILTER_CREATED,
filter: "author:@me",
},
is_selected: false,
on_click: None,
@@ -66,20 +56,12 @@ impl Sidebar {
title: "Assigned",
icon: FontIcon::UserPlus,
value: SidebarItemValue::PullRequest {
filter: api::issues::Issue::FILTER_ASSIGNED,
filter: "review-requested:@me",
},
is_selected: false,
on_click: None,
},
];
fn select_sidebar_item(&mut self, id: &str, cx: &mut gpui::Context<Self>) {
let Some(item) = Sidebar::ALL_ITEMS.iter().find(|item| item.id == id) else {
return;
};
self.selected_item_id = Some(item.id);
cx.notify();
}
}
impl Sidebar {