Initial git panel refinements (#21912)
- Wire up settings - Update static Panel impl - Tidy up renders Release Notes: - N/A
This commit is contained in:
parent
02fbad18ce
commit
8e0ae441f3
8 changed files with 157 additions and 21 deletions
|
@ -13,10 +13,18 @@ name = "git_ui"
|
|||
path = "src/git_ui.rs"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
db.workspace = true
|
||||
gpui.workspace = true
|
||||
project.workspace = true
|
||||
schemars.workspace = true
|
||||
serde.workspace = true
|
||||
workspace.workspace = true
|
||||
serde_derive.workspace = true
|
||||
serde_json.workspace = true
|
||||
settings.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
windows.workspace = true
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
use std::sync::Arc;
|
||||
use util::TryFutureExt;
|
||||
|
||||
use db::kvp::KEY_VALUE_STORE;
|
||||
use gpui::*;
|
||||
use project::Fs;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::Settings as _;
|
||||
use ui::{prelude::*, Checkbox, Divider, DividerColor, ElevationIndex};
|
||||
use workspace::dock::{DockPosition, Panel, PanelEvent};
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::settings::GitPanelSettings;
|
||||
|
||||
const GIT_PANEL_KEY: &str = "GitPanel";
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
cx.observe_new_views(
|
||||
|workspace: &mut Workspace, _cx: &mut ViewContext<Workspace>| {
|
||||
|
@ -14,11 +25,17 @@ pub fn init(cx: &mut AppContext) {
|
|||
.detach();
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct SerializedGitPanel {
|
||||
width: Option<Pixels>,
|
||||
}
|
||||
|
||||
actions!(git_panel, [Deploy, ToggleFocus]);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GitPanel {
|
||||
_workspace: WeakView<Workspace>,
|
||||
pending_serialization: Task<Option<()>>,
|
||||
fs: Arc<dyn Fs>,
|
||||
focus_handle: FocusHandle,
|
||||
width: Option<Pixels>,
|
||||
}
|
||||
|
@ -29,20 +46,39 @@ impl GitPanel {
|
|||
cx: AsyncWindowContext,
|
||||
) -> Task<Result<View<Self>>> {
|
||||
cx.spawn(|mut cx| async move {
|
||||
workspace.update(&mut cx, |workspace, cx| {
|
||||
let workspace_handle = workspace.weak_handle();
|
||||
|
||||
cx.new_view(|cx| Self::new(workspace_handle, cx))
|
||||
})
|
||||
// Clippy incorrectly classifies this as a redundant closure
|
||||
#[allow(clippy::redundant_closure)]
|
||||
workspace.update(&mut cx, |workspace, cx| Self::new(workspace, cx))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new(workspace: WeakView<Workspace>, cx: &mut ViewContext<Self>) -> Self {
|
||||
Self {
|
||||
_workspace: workspace,
|
||||
pub fn new(workspace: &mut Workspace, cx: &mut ViewContext<Workspace>) -> View<Self> {
|
||||
let fs = workspace.app_state().fs.clone();
|
||||
let weak_workspace = workspace.weak_handle();
|
||||
|
||||
cx.new_view(|cx| Self {
|
||||
fs,
|
||||
_workspace: weak_workspace,
|
||||
pending_serialization: Task::ready(None),
|
||||
focus_handle: cx.focus_handle(),
|
||||
width: Some(px(360.)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn serialize(&mut self, cx: &mut ViewContext<Self>) {
|
||||
let width = self.width;
|
||||
self.pending_serialization = cx.background_executor().spawn(
|
||||
async move {
|
||||
KEY_VALUE_STORE
|
||||
.write_kvp(
|
||||
GIT_PANEL_KEY.into(),
|
||||
serde_json::to_string(&SerializedGitPanel { width })?,
|
||||
)
|
||||
.await?;
|
||||
anyhow::Ok(())
|
||||
}
|
||||
.log_err(),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn render_panel_header(&self, cx: &mut ViewContext<Self>) -> impl IntoElement {
|
||||
|
@ -53,14 +89,14 @@ impl GitPanel {
|
|||
.bg(ElevationIndex::Surface.bg(cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.gap_2()
|
||||
.child(Checkbox::new("all-changes", true.into()).disabled(true))
|
||||
.child(div().text_buffer(cx).text_ui_sm(cx).child("0 changes")),
|
||||
)
|
||||
.child(div().flex_grow())
|
||||
.child(
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.gap_2()
|
||||
.child(
|
||||
IconButton::new("discard-changes", IconName::Undo)
|
||||
.icon_size(IconSize::Small)
|
||||
|
@ -104,6 +140,22 @@ impl GitPanel {
|
|||
.opacity(0.5),
|
||||
)
|
||||
}
|
||||
|
||||
fn render_empty_state(&self, cx: &ViewContext<Self>) -> impl IntoElement {
|
||||
h_flex()
|
||||
.h_full()
|
||||
.flex_1()
|
||||
.justify_center()
|
||||
.items_center()
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_3()
|
||||
.child("No changes to commit")
|
||||
.text_ui_sm(cx)
|
||||
.mx_auto()
|
||||
.text_color(Color::Placeholder.color(cx)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for GitPanel {
|
||||
|
@ -124,7 +176,7 @@ impl Render for GitPanel {
|
|||
.h(px(8.))
|
||||
.child(Divider::horizontal_dashed().color(DividerColor::Border)),
|
||||
)
|
||||
.child(div().flex_1())
|
||||
.child(self.render_empty_state(cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.items_center()
|
||||
|
@ -148,27 +200,35 @@ impl Panel for GitPanel {
|
|||
"GitPanel"
|
||||
}
|
||||
|
||||
fn position(&self, _cx: &gpui::WindowContext) -> DockPosition {
|
||||
DockPosition::Left
|
||||
fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
|
||||
GitPanelSettings::get_global(cx).dock
|
||||
}
|
||||
|
||||
fn position_is_valid(&self, position: DockPosition) -> bool {
|
||||
matches!(position, DockPosition::Left | DockPosition::Right)
|
||||
}
|
||||
|
||||
fn set_position(&mut self, _position: DockPosition, _cx: &mut ViewContext<Self>) {}
|
||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
|
||||
settings::update_settings_file::<GitPanelSettings>(
|
||||
self.fs.clone(),
|
||||
cx,
|
||||
move |settings, _| settings.dock = Some(position),
|
||||
);
|
||||
}
|
||||
|
||||
fn size(&self, _cx: &gpui::WindowContext) -> Pixels {
|
||||
self.width.unwrap_or(px(360.))
|
||||
fn size(&self, cx: &gpui::WindowContext) -> Pixels {
|
||||
self.width
|
||||
.unwrap_or_else(|| GitPanelSettings::get_global(cx).default_width)
|
||||
}
|
||||
|
||||
fn set_size(&mut self, size: Option<Pixels>, cx: &mut ViewContext<Self>) {
|
||||
self.width = size;
|
||||
self.serialize(cx);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn icon(&self, _cx: &gpui::WindowContext) -> Option<ui::IconName> {
|
||||
Some(ui::IconName::GitBranch)
|
||||
fn icon(&self, cx: &WindowContext) -> Option<ui::IconName> {
|
||||
Some(ui::IconName::GitBranch).filter(|_| GitPanelSettings::get_global(cx).button)
|
||||
}
|
||||
|
||||
fn icon_tooltip(&self, _cx: &WindowContext) -> Option<&'static str> {
|
||||
|
|
|
@ -1 +1,10 @@
|
|||
use ::settings::Settings;
|
||||
use gpui::AppContext;
|
||||
use settings::GitPanelSettings;
|
||||
|
||||
pub mod git_panel;
|
||||
mod settings;
|
||||
|
||||
pub fn init(cx: &mut AppContext) {
|
||||
GitPanelSettings::register(cx);
|
||||
}
|
||||
|
|
41
crates/git_ui/src/settings.rs
Normal file
41
crates/git_ui/src/settings.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use gpui::Pixels;
|
||||
use schemars::JsonSchema;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use settings::{Settings, SettingsSources};
|
||||
use workspace::dock::DockPosition;
|
||||
|
||||
#[derive(Deserialize, Debug)]
|
||||
pub struct GitPanelSettings {
|
||||
pub button: bool,
|
||||
pub dock: DockPosition,
|
||||
pub default_width: Pixels,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||
pub struct PanelSettingsContent {
|
||||
/// Whether to show the panel button in the status bar.
|
||||
///
|
||||
/// Default: true
|
||||
pub button: Option<bool>,
|
||||
/// Where to dock the panel.
|
||||
///
|
||||
/// Default: left
|
||||
pub dock: Option<DockPosition>,
|
||||
/// Default width of the panel in pixels.
|
||||
///
|
||||
/// Default: 360
|
||||
pub default_width: Option<f32>,
|
||||
}
|
||||
|
||||
impl Settings for GitPanelSettings {
|
||||
const KEY: Option<&'static str> = Some("git_panel");
|
||||
|
||||
type FileContent = PanelSettingsContent;
|
||||
|
||||
fn load(
|
||||
sources: SettingsSources<Self::FileContent>,
|
||||
_: &mut gpui::AppContext,
|
||||
) -> anyhow::Result<Self> {
|
||||
sources.json_merge()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue