fix: pr body scrolling

This commit is contained in:
2026-05-11 02:14:05 +08:00
parent 5d741f39eb
commit 6c0283d7a3
3 changed files with 51 additions and 25 deletions

View File

@@ -507,7 +507,6 @@ impl gpui::Render for MarkdownText {
_window: &mut gpui::Window, _window: &mut gpui::Window,
cx: &mut gpui::prelude::Context<Self>, cx: &mut gpui::prelude::Context<Self>,
) -> impl gpui::prelude::IntoElement { ) -> impl gpui::prelude::IntoElement {
let theme = app::current_theme(cx);
let children = self.blocks.iter().enumerate().map(|(i, block)| { let children = self.blocks.iter().enumerate().map(|(i, block)| {
match block { match block {
| ContentBlock::Text { | ContentBlock::Text {
@@ -520,13 +519,8 @@ impl gpui::Render for MarkdownText {
let styled_text = let styled_text =
gpui::StyledText::new(text.clone()).with_highlights(highlights.clone()); gpui::StyledText::new(text.clone()).with_highlights(highlights.clone());
let div = decoration let content = if links.is_empty() {
.map(|d| div().flex().flex_row().gap_2().items_start().child(d)) div().w_full().child(styled_text)
.unwrap_or_else(|| div());
let mut div = if links.is_empty() {
// if no link in block, interactive text is not needed
div.child(styled_text)
} else { } else {
// if link in block, interactive text is needed // if link in block, interactive text is needed
// to handle link clicks // to handle link clicks
@@ -545,7 +539,19 @@ impl gpui::Render for MarkdownText {
}, },
); );
div.child(t) div().w_full().child(t)
};
let mut div = match decoration {
| Some(d) => div()
.w_full()
.flex()
.flex_row()
.gap_2()
.items_start()
.child(*d)
.child(div().flex_1().min_w_0().child(content)),
| None => div().w_full().child(content),
}; };
div.style().refine(&style); div.style().refine(&style);
@@ -555,6 +561,6 @@ impl gpui::Render for MarkdownText {
} }
}); });
div().flex().flex_col().children(children) div().w_full().children(children)
} }
} }

View File

@@ -1,7 +1,10 @@
use gpui::{AppContext, IntoElement, ParentElement, Styled, div, prelude::FluentBuilder}; use gpui::{
AppContext, InteractiveElement, IntoElement, ParentElement, StatefulInteractiveElement, Styled,
div, prelude::FluentBuilder,
};
use crate::{ use crate::{
api::{self, issues::PullRequest}, api::{self},
app, app,
component::{ component::{
font_icon::{FontIcon, font_icon}, font_icon::{FontIcon, font_icon},
@@ -57,7 +60,7 @@ impl PullRequestView {
&self, &self,
pr: &api::issues::DetailedPullRequest, pr: &api::issues::DetailedPullRequest,
cx: &gpui::Context<Self>, cx: &gpui::Context<Self>,
) -> gpui::Div { ) -> gpui::AnyElement {
let theme = app::current_theme(cx); let theme = app::current_theme(cx);
let mut status_pill = div() let mut status_pill = div()
@@ -121,6 +124,7 @@ impl PullRequestView {
.size_full() .size_full()
.flex() .flex()
.flex_col() .flex_col()
.overflow_hidden()
.child( .child(
div() div()
.w_full() .w_full()
@@ -131,26 +135,40 @@ impl PullRequestView {
.child(text(pr.title.clone()).w_full().text_xl().mb_2()) .child(text(pr.title.clone()).w_full().text_xl().mb_2())
.child(row), .child(row),
) )
.when_some(self.markdown_viewer.as_ref(), |it, viewer| { .child(
it.child(div().h_full().p_3p5().child(viewer.clone())) div().flex_1().min_h_0().w_full().child(
}) div()
.id("pr-body-content")
.size_full()
.overflow_y_scroll()
.when_some(self.markdown_viewer.as_ref(), |it, viewer| {
it.child(div().w_full().p_3p5().child(viewer.clone()))
}),
),
)
.into_any_element()
} }
} }
impl gpui::Render for PullRequestView { impl gpui::Render for PullRequestView {
fn render( fn render(
&mut self, &mut self,
window: &mut gpui::Window, _window: &mut gpui::Window,
cx: &mut gpui::Context<Self>, cx: &mut gpui::Context<Self>,
) -> impl gpui::IntoElement { ) -> impl gpui::IntoElement {
match &self.pull_request_query { div().size_full().child(match &self.pull_request_query {
| Some(q) => match read_query(q, cx) { | Some(q) => match read_query(q, cx) {
| QueryStatus::Loaded(pr) => self.pr_content(pr, cx), | QueryStatus::Loaded(pr) => self.pr_content(pr, cx),
| QueryStatus::Err(e) => div().child(format!("{:?}", e)), | QueryStatus::Err(e) => div()
| QueryStatus::Loading => div().child("loading pr content"), .size_full()
.child(format!("{:?}", e))
.into_any_element(),
| QueryStatus::Loading => div()
.size_full()
.child("loading pr content")
.into_any_element(),
}, },
| None => div().size_full().child("no pr selected").into_any_element(),
| None => div().child("no pr selected"), })
}
} }
} }

View File

@@ -66,8 +66,7 @@ impl Screen {
fn handle_issue_list_item_selected( fn handle_issue_list_item_selected(
&mut self, &mut self,
id: &api::issues::Id, id: &api::issues::Id,
cx: &mut gpui::Context<Self>, cx: &mut gpui::Context<Self>, ) {
) {
println!("handle issue list item selected: {:?}", id); println!("handle issue list item selected: {:?}", id);
self.pull_request_view.update(cx, |view, cx| { self.pull_request_view.update(cx, |view, cx| {
view.change_displayed_pull_request(id.clone(), cx); view.change_displayed_pull_request(id.clone(), cx);
@@ -95,6 +94,7 @@ impl gpui::Render for Screen {
.flex() .flex()
.flex_row() .flex_row()
.flex_1() .flex_1()
.min_h_0()
.w_full() .w_full()
.child( .child(
div() div()
@@ -119,7 +119,9 @@ impl gpui::Render for Screen {
div() div()
.flex_1() .flex_1()
.min_w_0() .min_w_0()
.min_h_0()
.h_full() .h_full()
.overflow_hidden()
.bg(theme.colors.surface) .bg(theme.colors.surface)
.border_l_1() .border_l_1()
.border_color(theme.colors.border) .border_color(theme.colors.border)