commit view: Fix layout shift while loading commit (#44548)
Fixes a few cases where the commit view would layout shift as the diff loaded. This was caused by: - Adding the commit message buffer after all the diff files - Using the gutter dimensions from the last frame for the avatar spacing Release Notes: - commit view: Fix layout shift while loading commit --------- Co-authored-by: MrSubidubi <dev@bahn.sh>
This commit is contained in:
co-authored by
MrSubidubi
parent
dd431631b4
commit
21f7e6a9e6
@@ -1,9 +1,7 @@
|
||||
use anyhow::{Context as _, Result};
|
||||
use buffer_diff::{BufferDiff, BufferDiffSnapshot};
|
||||
use editor::display_map::{BlockPlacement, BlockProperties, BlockStyle};
|
||||
use editor::{
|
||||
Editor, EditorEvent, ExcerptId, ExcerptRange, MultiBuffer, multibuffer_context_lines,
|
||||
};
|
||||
use editor::{Editor, EditorEvent, ExcerptRange, MultiBuffer, multibuffer_context_lines};
|
||||
use git::repository::{CommitDetails, CommitDiff, RepoPath};
|
||||
use git::{GitHostingProviderRegistry, GitRemote, parse_git_remote_url};
|
||||
use gpui::{
|
||||
@@ -13,7 +11,7 @@ use gpui::{
|
||||
};
|
||||
use language::{
|
||||
Anchor, Buffer, Capability, DiskState, File, LanguageRegistry, LineEnding, OffsetRangeExt as _,
|
||||
ReplicaId, Rope, TextBuffer,
|
||||
Point, ReplicaId, Rope, TextBuffer,
|
||||
};
|
||||
use multi_buffer::PathKey;
|
||||
use project::{Project, WorktreeId, git_store::Repository};
|
||||
@@ -70,6 +68,7 @@ struct GitBlob {
|
||||
display_name: Arc<str>,
|
||||
}
|
||||
|
||||
const COMMIT_MESSAGE_SORT_PREFIX: u64 = 0;
|
||||
const FILE_NAMESPACE_SORT_PREFIX: u64 = 1;
|
||||
|
||||
impl CommitView {
|
||||
@@ -147,6 +146,32 @@ impl CommitView {
|
||||
) -> Self {
|
||||
let language_registry = project.read(cx).languages().clone();
|
||||
let multibuffer = cx.new(|_| MultiBuffer::new(Capability::ReadOnly));
|
||||
|
||||
let message_buffer = cx.new(|cx| {
|
||||
let mut buffer = Buffer::local(commit.message.clone(), cx);
|
||||
buffer.set_capability(Capability::ReadOnly, cx);
|
||||
buffer
|
||||
});
|
||||
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
let snapshot = message_buffer.read(cx).snapshot();
|
||||
let full_range = Point::zero()..snapshot.max_point();
|
||||
let range = ExcerptRange {
|
||||
context: full_range.clone(),
|
||||
primary: full_range,
|
||||
};
|
||||
multibuffer.set_excerpt_ranges_for_path(
|
||||
PathKey::with_sort_prefix(
|
||||
COMMIT_MESSAGE_SORT_PREFIX,
|
||||
RelPath::unix("commit message").unwrap().into(),
|
||||
),
|
||||
message_buffer.clone(),
|
||||
&snapshot,
|
||||
vec![range],
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
let editor = cx.new(|cx| {
|
||||
let mut editor =
|
||||
Editor::for_multibuffer(multibuffer.clone(), Some(project.clone()), window, cx);
|
||||
@@ -154,9 +179,38 @@ impl CommitView {
|
||||
editor.disable_inline_diagnostics();
|
||||
editor.set_show_breakpoints(false, cx);
|
||||
editor.set_expand_all_diff_hunks(cx);
|
||||
editor.disable_header_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
editor.disable_indent_guides_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
|
||||
editor.insert_blocks(
|
||||
[BlockProperties {
|
||||
placement: BlockPlacement::Above(editor::Anchor::min()),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(
|
||||
editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.buffer_anchor_to_anchor(&message_buffer, Anchor::MAX, cx)
|
||||
.map(|anchor| BlockProperties {
|
||||
placement: BlockPlacement::Below(anchor),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}),
|
||||
),
|
||||
None,
|
||||
cx,
|
||||
);
|
||||
|
||||
editor
|
||||
});
|
||||
|
||||
let commit_sha = Arc::<str>::from(commit.sha.as_ref());
|
||||
|
||||
let first_worktree_id = project
|
||||
@@ -166,7 +220,6 @@ impl CommitView {
|
||||
.map(|worktree| worktree.read(cx).id());
|
||||
|
||||
let repository_clone = repository.clone();
|
||||
let commit_message = commit.message.clone();
|
||||
|
||||
cx.spawn(async move |this, cx| {
|
||||
for file in commit_diff.files {
|
||||
@@ -228,59 +281,6 @@ impl CommitView {
|
||||
})?;
|
||||
}
|
||||
|
||||
let message_buffer = cx.new(|cx| {
|
||||
let mut buffer = Buffer::local(commit_message, cx);
|
||||
buffer.set_capability(Capability::ReadOnly, cx);
|
||||
buffer
|
||||
})?;
|
||||
|
||||
this.update(cx, |this, cx| {
|
||||
this.multibuffer.update(cx, |multibuffer, cx| {
|
||||
let range = ExcerptRange {
|
||||
context: Anchor::MIN..Anchor::MAX,
|
||||
primary: Anchor::MIN..Anchor::MAX,
|
||||
};
|
||||
multibuffer.insert_excerpts_after(
|
||||
ExcerptId::min(),
|
||||
message_buffer.clone(),
|
||||
[range],
|
||||
cx,
|
||||
)
|
||||
});
|
||||
|
||||
this.editor.update(cx, |editor, cx| {
|
||||
editor.disable_header_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
editor
|
||||
.disable_indent_guides_for_buffer(message_buffer.read(cx).remote_id(), cx);
|
||||
|
||||
editor.insert_blocks(
|
||||
[BlockProperties {
|
||||
placement: BlockPlacement::Above(editor::Anchor::min()),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}]
|
||||
.into_iter()
|
||||
.chain(
|
||||
editor
|
||||
.buffer()
|
||||
.read(cx)
|
||||
.buffer_anchor_to_anchor(&message_buffer, Anchor::MAX, cx)
|
||||
.map(|anchor| BlockProperties {
|
||||
placement: BlockPlacement::Below(anchor),
|
||||
height: Some(1),
|
||||
style: BlockStyle::Sticky,
|
||||
render: Arc::new(|_| gpui::Empty.into_any_element()),
|
||||
priority: 0,
|
||||
}),
|
||||
),
|
||||
None,
|
||||
cx,
|
||||
)
|
||||
});
|
||||
})?;
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach();
|
||||
@@ -417,12 +417,23 @@ impl CommitView {
|
||||
None
|
||||
};
|
||||
|
||||
let gutter_width = self.editor.update(cx, |editor, cx| {
|
||||
let snapshot = editor.snapshot(window, cx);
|
||||
let style = editor.style(cx);
|
||||
let font_id = window.text_system().resolve_font(&style.text.font());
|
||||
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
||||
snapshot
|
||||
.gutter_dimensions(font_id, font_size, style, window, cx)
|
||||
.full_width()
|
||||
});
|
||||
|
||||
h_flex()
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().colors().border_variant)
|
||||
.w_full()
|
||||
.child(
|
||||
h_flex()
|
||||
.w(self.editor.read(cx).last_gutter_dimensions().full_width())
|
||||
.w(gutter_width)
|
||||
.justify_center()
|
||||
.child(self.render_commit_avatar(&commit.sha, rems_from_px(48.), window, cx)),
|
||||
)
|
||||
@@ -1011,7 +1022,9 @@ impl Render for CommitView {
|
||||
.size_full()
|
||||
.bg(cx.theme().colors().editor_background)
|
||||
.child(self.render_header(window, cx))
|
||||
.child(div().flex_grow().child(self.editor.clone()))
|
||||
.when(!self.editor.read(cx).is_empty(cx), |this| {
|
||||
this.child(div().flex_grow().child(self.editor.clone()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user