refactor: prefer Arc<str> to String
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
use gpui::{
|
||||
InteractiveElement, IntoElement, ParentElement, StatefulInteractiveElement, Styled, div, list,
|
||||
point, prelude::FluentBuilder, px,
|
||||
@@ -13,6 +11,7 @@ use crate::{
|
||||
text::text,
|
||||
},
|
||||
query::{self, QueryStatus, read_query, use_query},
|
||||
util::str::ToSharedString,
|
||||
};
|
||||
|
||||
pub(crate) struct IssueList {
|
||||
@@ -20,7 +19,6 @@ pub(crate) struct IssueList {
|
||||
|
||||
list_state: gpui::ListState,
|
||||
list_items: Vec<IssueListItem>,
|
||||
selected_item: Option<(usize, gpui::SharedString)>,
|
||||
}
|
||||
|
||||
pub(crate) enum Event {
|
||||
@@ -29,7 +27,7 @@ pub(crate) enum Event {
|
||||
|
||||
#[derive(gpui::IntoElement, Clone)]
|
||||
pub(crate) struct IssueListItem {
|
||||
id: gpui::SharedString,
|
||||
id: api::issues::Id,
|
||||
repo_name: Option<gpui::SharedString>,
|
||||
title: gpui::SharedString,
|
||||
description: Option<gpui::SharedString>,
|
||||
@@ -51,7 +49,6 @@ pub(crate) fn new(cx: &mut gpui::Context<IssueList>) -> IssueList {
|
||||
|
||||
list_state: gpui::ListState::new(0, gpui::ListAlignment::Top, px(100.)),
|
||||
list_items: Vec::new(),
|
||||
selected_item: None,
|
||||
};
|
||||
list.on_create(cx);
|
||||
list
|
||||
@@ -66,16 +63,12 @@ impl IssueList {
|
||||
let new_len = res.items.len();
|
||||
|
||||
let new_items = res.items.iter().enumerate().map(|(i, it)| IssueListItem {
|
||||
id: gpui::SharedString::from(it.id.deref()),
|
||||
repo_name: Some(gpui::SharedString::new(it.repo_slug.as_str())),
|
||||
title: gpui::SharedString::new(it.title.as_str()),
|
||||
id: it.id.clone(),
|
||||
repo_name: Some(it.repo_slug.to_shared_string()),
|
||||
title: it.title.to_shared_string(),
|
||||
description: None,
|
||||
status: it.state,
|
||||
is_selected: this
|
||||
.selected_item
|
||||
.as_ref()
|
||||
.map(|(_, id)| id.as_str() == it.id.as_str())
|
||||
.unwrap_or(false),
|
||||
is_selected: false,
|
||||
is_last: i == new_len - 1,
|
||||
is_draft: it.is_draft,
|
||||
});
|
||||
@@ -95,7 +88,7 @@ impl IssueList {
|
||||
item.is_selected = i == j;
|
||||
}
|
||||
cx.notify();
|
||||
cx.emit(Event::ItemSelected(item_id.as_str().into()));
|
||||
cx.emit(Event::ItemSelected(item_id));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,8 +141,8 @@ impl gpui::RenderOnce for IssueListItem {
|
||||
}
|
||||
|
||||
let repo_name_text = match self.repo_name {
|
||||
| Some(name) => text(name),
|
||||
| None => text("Unknown repo"),
|
||||
| Some(name) => text(name),
|
||||
| None => text("Unknown repo"),
|
||||
}
|
||||
.text_xs()
|
||||
.opacity(0.5);
|
||||
@@ -162,21 +155,21 @@ impl gpui::RenderOnce for IssueListItem {
|
||||
.bg(theme.colors.surface)
|
||||
} else {
|
||||
match self.status {
|
||||
| api::issues::PullRequestState::Closed => pill(
|
||||
text("Closed").text_color(theme.colors.danger_on_solid),
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.danger_on_solid),
|
||||
)
|
||||
.bg(theme.colors.danger_solid),
|
||||
| api::issues::PullRequestState::Merged => pill(
|
||||
text("Merged").text_color(theme.colors.accent_on_solid),
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.accent_on_solid),
|
||||
)
|
||||
.bg(theme.colors.accent_solid),
|
||||
| _ => pill(
|
||||
text("Open").text_color(theme.colors.success_on_solid),
|
||||
font_icon(FontIcon::PullRequestArrow).text_color(theme.colors.success_on_solid),
|
||||
)
|
||||
.bg(theme.colors.success_solid),
|
||||
| api::issues::PullRequestState::Closed => pill(
|
||||
text("Closed").text_color(theme.colors.danger_on_solid),
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.danger_on_solid),
|
||||
)
|
||||
.bg(theme.colors.danger_solid),
|
||||
| api::issues::PullRequestState::Merged => pill(
|
||||
text("Merged").text_color(theme.colors.accent_on_solid),
|
||||
font_icon(FontIcon::PullRequestClosed).text_color(theme.colors.accent_on_solid),
|
||||
)
|
||||
.bg(theme.colors.accent_solid),
|
||||
| _ => pill(
|
||||
text("Open").text_color(theme.colors.success_on_solid),
|
||||
font_icon(FontIcon::PullRequestArrow).text_color(theme.colors.success_on_solid),
|
||||
)
|
||||
.bg(theme.colors.success_solid),
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use gpui::{
|
||||
AppContext, InteractiveElement, IntoElement, ParentElement, StatefulInteractiveElement, Styled,
|
||||
div, img, prelude::FluentBuilder,
|
||||
@@ -65,7 +67,7 @@ impl PullRequestView {
|
||||
let maybe_content = {
|
||||
let data = read_query(&query, cx);
|
||||
if let QueryStatus::Loaded(pr) = data {
|
||||
Some(gpui::SharedString::new(pr.body.as_str()))
|
||||
Some(Arc::clone(&pr.body))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -130,8 +132,8 @@ impl PullRequestView {
|
||||
}
|
||||
|
||||
let merge_text = pr.author.as_ref().map(|author| {
|
||||
let base_branch = pr.base_branch_name.as_str();
|
||||
let head_branch = pr.head_branch_name.as_str();
|
||||
let base_branch = &pr.base_branch_name;
|
||||
let head_branch = &pr.head_branch_name;
|
||||
let str = format!(
|
||||
"{} requested to merge {} into {}",
|
||||
author.login, head_branch, base_branch
|
||||
@@ -172,6 +174,8 @@ impl PullRequestView {
|
||||
)
|
||||
});
|
||||
|
||||
let pr_title = gpui::SharedString::new(Arc::clone(&pr.title));
|
||||
|
||||
let metadata_line =
|
||||
div()
|
||||
.flex()
|
||||
@@ -184,7 +188,7 @@ impl PullRequestView {
|
||||
.flex_row()
|
||||
.items_center()
|
||||
.gap_1p5()
|
||||
.child(img(author.avatar_url.clone()).size_4().rounded_full())
|
||||
.child(img(author.avatar_url.as_ref()).size_4().rounded_full())
|
||||
.child(
|
||||
div()
|
||||
.min_w_0()
|
||||
@@ -222,7 +226,7 @@ impl PullRequestView {
|
||||
.flex()
|
||||
.flex_col()
|
||||
.items_start()
|
||||
.child(text(pr.title.clone()).w_full().text_xl().mb_1())
|
||||
.child(text(pr_title).w_full().text_xl().mb_1())
|
||||
.child(metadata_line),
|
||||
)
|
||||
.child(div().flex().flex_col().items_end().gap_1().when_some(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::time::Duration;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
use futures_lite::StreamExt;
|
||||
use gpui::{
|
||||
@@ -16,7 +16,7 @@ use crate::{
|
||||
},
|
||||
query::{self, QueryStatus, fetch_query, read_query, use_query},
|
||||
storage,
|
||||
util::timeout::set_timeout,
|
||||
util::{str::ToSharedString, timeout::set_timeout},
|
||||
};
|
||||
|
||||
pub(crate) struct GithubStepView {
|
||||
@@ -83,7 +83,7 @@ impl GithubStepView {
|
||||
_ = weak.update(cx, |this, cx| {
|
||||
this.has_opened_link = true;
|
||||
this.is_opening_link = false;
|
||||
this.begin_auth_flow(&device_code, cx);
|
||||
this.begin_auth_flow(device_code, cx);
|
||||
cx.notify();
|
||||
});
|
||||
},
|
||||
@@ -110,7 +110,7 @@ impl GithubStepView {
|
||||
timer.clear();
|
||||
} else {
|
||||
let _ = this.update(cx, |this, cx| {
|
||||
this.placeholder_code = this.generate_random_code(cx);
|
||||
this.generate_random_code(cx);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
@@ -127,14 +127,13 @@ impl GithubStepView {
|
||||
cx.open_url(api::auth::DEVICE_LOGIN_FLOW_URL);
|
||||
}
|
||||
|
||||
fn generate_random_code(&mut self, cx: &mut gpui::Context<Self>) -> String {
|
||||
fn generate_random_code(&mut self, cx: &mut gpui::Context<Self>) {
|
||||
let rng = app::rng(cx);
|
||||
(0..8)
|
||||
.map(|_| {
|
||||
let idx = rng.random_range(0..Self::CHAR_POOL.len());
|
||||
Self::CHAR_POOL.chars().nth(idx).unwrap()
|
||||
})
|
||||
.collect()
|
||||
self.placeholder_code.clear();
|
||||
self.placeholder_code.extend((0..8).map(|_| {
|
||||
let idx = rng.random_range(0..Self::CHAR_POOL.len());
|
||||
Self::CHAR_POOL.chars().nth(idx).unwrap()
|
||||
}));
|
||||
}
|
||||
|
||||
fn copy_user_code(&mut self, code: &str, cx: &mut gpui::Context<Self>) {
|
||||
@@ -155,15 +154,10 @@ impl GithubStepView {
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn begin_auth_flow(&mut self, device_code: &str, cx: &mut gpui::Context<Self>) {
|
||||
fn begin_auth_flow(&mut self, device_code: Arc<str>, cx: &mut gpui::Context<Self>) {
|
||||
GithubStepView::open_github_auth_page(cx);
|
||||
|
||||
let query = use_query(
|
||||
api::auth::RequestAccessToken {
|
||||
device_code: device_code.to_owned(),
|
||||
},
|
||||
cx,
|
||||
);
|
||||
let query = use_query(api::auth::RequestAccessToken { device_code }, cx);
|
||||
|
||||
cx.observe(&query, |this, _, cx| {
|
||||
this.handle_access_token_query_response(cx);
|
||||
@@ -189,60 +183,60 @@ impl GithubStepView {
|
||||
let poll_interval = u64::from(*interval);
|
||||
|
||||
match read_query(query, cx) {
|
||||
| QueryStatus::Loaded(data) => {
|
||||
let auth_tokens = api::AuthTokens {
|
||||
access_token: data.access_token.clone(),
|
||||
};
|
||||
| QueryStatus::Loaded(data) => {
|
||||
let auth_tokens = api::AuthTokens {
|
||||
access_token: data.access_token.clone(),
|
||||
};
|
||||
|
||||
cx.update_global::<query::Store<api::QueryContext>, _>(|store, _| {
|
||||
store.update_query_context(|c| {
|
||||
c.auth = Some(auth_tokens.clone());
|
||||
});
|
||||
cx.update_global::<query::Store<api::QueryContext>, _>(|store, _| {
|
||||
store.update_query_context(|c| {
|
||||
c.auth = Some(auth_tokens.clone());
|
||||
});
|
||||
});
|
||||
|
||||
self.user_query = Some(use_query(api::user::Fetch, cx));
|
||||
self.user_query = Some(use_query(api::user::Fetch, cx));
|
||||
|
||||
cx.spawn(async move |weak, cx| {
|
||||
let ent = fetch_query(api::user::Fetch, cx).await;
|
||||
|
||||
let fut = weak
|
||||
.update(cx, move |_this, cx| {
|
||||
let Ok(query) = ent else {
|
||||
return None;
|
||||
};
|
||||
let QueryStatus::Loaded(user) = read_query(&query, cx) else {
|
||||
return None;
|
||||
};
|
||||
Some(storage::store_auth_tokens(&auth_tokens, user, cx))
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
_ = if let Some(task) = fut {
|
||||
task.await
|
||||
} else {
|
||||
Err(anyhow::Error::msg(""))
|
||||
};
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
|
||||
| QueryStatus::Err(api::Error::Github(api::GithubError { error, .. })) => {
|
||||
if error == "authorization_pending" {
|
||||
cx.spawn(async move |weak, cx| {
|
||||
let ent = fetch_query(api::user::Fetch, cx).await;
|
||||
|
||||
let fut = weak
|
||||
.update(cx, move |_this, cx| {
|
||||
let Ok(query) = ent else {
|
||||
return None;
|
||||
};
|
||||
let QueryStatus::Loaded(user) = read_query(&query, cx) else {
|
||||
return None;
|
||||
};
|
||||
Some(storage::store_auth_tokens(&auth_tokens, user, cx))
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
_ = if let Some(task) = fut {
|
||||
task.await
|
||||
} else {
|
||||
Err(anyhow::Error::msg(""))
|
||||
};
|
||||
Timer::after(Duration::from_secs(poll_interval)).await;
|
||||
if let Ok(Some(query)) =
|
||||
weak.read_with(cx, |this, _cx| this.request_access_token_query.clone())
|
||||
{
|
||||
let _ = weak.update(cx, |_this, cx| {
|
||||
query.refetch(cx);
|
||||
});
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
|
||||
| QueryStatus::Err(api::Error::Github(api::GithubError { error, .. })) => {
|
||||
if error == "authorization_pending" {
|
||||
cx.spawn(async move |weak, cx| {
|
||||
Timer::after(Duration::from_secs(poll_interval)).await;
|
||||
if let Ok(Some(query)) =
|
||||
weak.read_with(cx, |this, _cx| this.request_access_token_query.clone())
|
||||
{
|
||||
let _ = weak.update(cx, |_this, cx| {
|
||||
query.refetch(cx);
|
||||
});
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
}
|
||||
}
|
||||
|
||||
| _ => {}
|
||||
| _ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,8 +257,8 @@ impl GithubStepView {
|
||||
let theme = app::current_theme(cx);
|
||||
|
||||
let (displayed_code, copyable_code) = match create_device_code_query {
|
||||
| QueryStatus::Loaded(data) => (data.user_code.as_str(), Some(data.user_code.clone())),
|
||||
| _ => (self.placeholder_code.as_str(), None),
|
||||
| QueryStatus::Loaded(data) => (data.user_code.as_ref(), Some(data.user_code.clone())),
|
||||
| _ => (self.placeholder_code.as_str(), None),
|
||||
};
|
||||
|
||||
let border_color = theme.colors.border.clone();
|
||||
@@ -358,16 +352,14 @@ impl gpui::Render for GithubStepView {
|
||||
cx: &mut gpui::Context<Self>,
|
||||
) -> impl gpui::IntoElement {
|
||||
let (can_go_next, header, body) = match self.user_query {
|
||||
| None => (false, self.header(), self.device_code_area(cx)),
|
||||
| Some(ref q) => {
|
||||
let user_query = read_query(q, cx);
|
||||
match user_query {
|
||||
| QueryStatus::Loaded(user) => {
|
||||
(true, connected_header(), connected_body(user, cx))
|
||||
}
|
||||
| _ => (false, self.header(), self.device_code_area(cx)),
|
||||
}
|
||||
| None => (false, self.header(), self.device_code_area(cx)),
|
||||
| Some(ref q) => {
|
||||
let user_query = read_query(q, cx);
|
||||
match user_query {
|
||||
| QueryStatus::Loaded(user) => (true, connected_header(), connected_body(user, cx)),
|
||||
| _ => (false, self.header(), self.device_code_area(cx)),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
div()
|
||||
@@ -417,7 +409,7 @@ fn connected_header() -> gpui::Div {
|
||||
fn connected_body(user: &api::user::User, cx: &gpui::Context<GithubStepView>) -> gpui::Div {
|
||||
let theme = app::current_theme(cx);
|
||||
|
||||
let display_name = user.name.as_deref().unwrap_or(&user.login).to_owned();
|
||||
let display_name = user.name.as_ref().unwrap_or(&user.login).to_shared_string();
|
||||
|
||||
div()
|
||||
.flex()
|
||||
@@ -444,7 +436,7 @@ fn connected_body(user: &api::user::User, cx: &gpui::Context<GithubStepView>) ->
|
||||
.flex_row()
|
||||
.gap_4()
|
||||
.items_center()
|
||||
.child(img(user.avatar_url.clone()).size_12().rounded_full())
|
||||
.child(img(user.avatar_url.as_ref()).size_12().rounded_full())
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
@@ -455,7 +447,7 @@ fn connected_body(user: &api::user::User, cx: &gpui::Context<GithubStepView>) ->
|
||||
.text_xl()
|
||||
.leading_tight(),
|
||||
)
|
||||
.child(text(user.login.clone()).text_sm().opacity(0.5)),
|
||||
.child(text(user.login.to_shared_string()).text_sm().opacity(0.5)),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
|
||||
Reference in New Issue
Block a user