2626 lineCleanupRegex = regexp .MustCompile (`((\n)+|^)([^\r\n]*\|[^\r\n]*(\n)?)+` )
2727 commentPrompt = "Leave a comment..."
2828 approvalPrompt = "Approve with comment..."
29+ foldBodyLen = 600
2930)
3031
3132type Model struct {
@@ -40,6 +41,7 @@ type Model struct {
4041 isApproving bool
4142 isAssigning bool
4243 isUnassigning bool
44+ summaryViewMore bool
4345
4446 inputBox inputbox.Model
4547}
@@ -191,68 +193,83 @@ func (m Model) Update(msg tea.Msg) (Model, tea.Cmd) {
191193}
192194
193195func (m Model ) View () string {
194- s := strings.Builder {}
195-
196- s .WriteString (m .renderFullNameAndNumber ())
197- s .WriteString ("\n " )
198-
199- s .WriteString (m .renderTitle ())
200- s .WriteString ("\n \n " )
201- s .WriteString (m .renderBranches ())
202- s .WriteString ("\n \n " )
203- s .WriteString (lipgloss .NewStyle ().Width (m .width ).
196+ header := strings.Builder {}
197+
198+ header .WriteString (m .renderFullNameAndNumber ())
199+ header .WriteString ("\n " )
200+
201+ header .WriteString (m .renderTitle ())
202+ header .WriteString ("\n \n " )
203+ header .WriteString (m .renderBranches ())
204+ header .WriteString ("\n \n " )
205+ header .WriteString (m .renderAuthor ())
206+ header .WriteString ("\n \n " )
207+ header .WriteString (lipgloss .NewStyle ().Width (m .width ).
204208 Border (lipgloss .NormalBorder (), false , false , true , false ).
205209 BorderForeground (m .ctx .Theme .FaintBorder ).
206210 Render (m .carousel .View ()),
207211 )
208212
209- s .WriteString ("\n \n " )
213+ header .WriteString ("\n " )
214+
215+ body := strings.Builder {}
210216
211217 switch m .carousel .SelectedItem () {
212218 case tabs [0 ]:
213219 labels := m .renderLabels ()
214220 if labels != "" {
215- s .WriteString (labels )
216- s .WriteString ("\n \n " )
221+ body .WriteString (labels )
222+ body .WriteString ("\n \n " )
217223 }
218224
219- s .WriteString (m .renderDescription ())
220- s .WriteString ("\n \n " )
221- s .WriteString (m .ctx .Styles .Common .MainTextStyle .MarginBottom (1 ).Underline (true ).Render (" Checks" ))
222- s .WriteString ("\n " )
223- s .WriteString (m .renderChecksOverview ())
225+ body .WriteString (m .renderSummary ())
226+ body .WriteString ("\n \n " )
227+ body .WriteString (m .ctx .Styles .Common .MainTextStyle .MarginBottom (1 ).Underline (true ).Render (" Checks" ))
228+ body .WriteString ("\n " )
229+ body .WriteString (m .renderChecksOverview ())
224230
225231 if m .isCommenting || m .isApproving || m .isAssigning || m .isUnassigning {
226- s .WriteString (m .inputBox .View ())
232+ body .WriteString (m .inputBox .View ())
227233 }
228234
229235 case tabs [1 ]:
230- s .WriteString (m .renderChecksOverview ())
231- s .WriteString ("\n \n " )
232- s .WriteString (m .renderChecks ())
236+ body .WriteString (m .renderChecksOverview ())
237+ body .WriteString ("\n \n " )
238+ body .WriteString (m .renderChecks ())
233239
234240 case tabs [2 ]:
235- s .WriteString (m .renderActivity ())
241+ body .WriteString (m .renderActivity ())
236242 case tabs [3 ]:
237- s .WriteString (m .renderChangedFiles ())
243+ body .WriteString (m .renderChangedFiles ())
238244 }
239245
240- return s .String ()
246+ return lipgloss .JoinVertical (lipgloss .Left ,
247+ header .String (),
248+ lipgloss .NewStyle ().Padding (0 , m .ctx .Styles .Sidebar .ContentPadding ).Render (body .String ()),
249+ )
241250}
242251
243252func (m * Model ) renderFullNameAndNumber () string {
244- return lipgloss .NewStyle ().Foreground (m .ctx .Theme .SecondaryText ).Render (fmt .Sprintf ("#%d · %s" , m .pr .Data .GetNumber (), m .pr .Data .GetRepoNameWithOwner ()))
253+ return lipgloss .NewStyle ().
254+ PaddingLeft (1 ).
255+ Width (m .width ).
256+ Background (m .ctx .Theme .SelectedBackground ).
257+ Foreground (m .ctx .Theme .SecondaryText ).
258+ Render (fmt .Sprintf ("%s · #%d" , m .pr .Data .GetRepoNameWithOwner (), m .pr .Data .GetNumber ()))
245259}
246260
247261func (m * Model ) renderTitle () string {
248- return lipgloss .JoinHorizontal (
249- lipgloss .Top ,
250- m .ctx .Styles .Common .MainTextStyle .Width (m .getIndentedContentWidth ()).Render (m .pr .Data .Title ),
262+ return lipgloss .NewStyle ().Height (3 ).Width (m .width ).Background (m .ctx .Theme .SelectedBackground ).PaddingLeft (1 ).Render (
263+ lipgloss .PlaceVertical (3 , lipgloss .Center , m .ctx .Styles .Common .MainTextStyle .
264+ Background (m .ctx .Theme .SelectedBackground ).
265+ Render (m .pr .Data .Title ),
266+ ),
251267 )
252268}
253269
254270func (m * Model ) renderBranches () string {
255271 return lipgloss .JoinHorizontal (lipgloss .Left ,
272+ " " ,
256273 m .renderStatusPill (),
257274 " " ,
258275 lipgloss .NewStyle ().
@@ -297,27 +314,35 @@ func (m *Model) renderLabels() string {
297314 )
298315}
299316
300- func (m * Model ) renderDescription () string {
317+ func (m * Model ) renderAuthor () string {
318+ authorAssociation := m .pr .Data .AuthorAssociation
319+ if authorAssociation == "" {
320+ authorAssociation = "unknown role"
321+ }
322+ time := lipgloss .NewStyle ().Render (utils .TimeElapsed (m .pr .Data .CreatedAt ))
323+ return lipgloss .JoinHorizontal (lipgloss .Top ,
324+ " by " ,
325+ lipgloss .NewStyle ().Foreground (m .ctx .Theme .PrimaryText ).Render (lipgloss .NewStyle ().Bold (true ).Render ("@" + m .pr .Data .Author .Login )),
326+ lipgloss .NewStyle ().Foreground (m .ctx .Theme .FaintText ).Render (lipgloss .JoinHorizontal (lipgloss .Top , " ⋅ " , time , " ago" , " ⋅ " )),
327+ lipgloss .NewStyle ().Foreground (m .ctx .Theme .FaintText ).Render (
328+ lipgloss .JoinHorizontal (lipgloss .Top , data .GetAuthorRoleIcon (m .pr .Data .AuthorAssociation , m .ctx .Theme ), " " , lipgloss .NewStyle ().Foreground (m .ctx .Theme .FaintText ).Render (strings .ToLower (authorAssociation ))),
329+ ),
330+ )
331+ }
332+
333+ func (m * Model ) renderSummary () string {
301334 width := m .getIndentedContentWidth ()
302335 // Strip HTML comments from body and cleanup body.
303336 body := htmlCommentRegex .ReplaceAllString (m .pr .Data .Body , "" )
304337 body = lineCleanupRegex .ReplaceAllString (body , "" )
305338
306- desc := m .ctx .Styles .Common .MainTextStyle .Bold (true ).Underline (true ).Render (" Description" )
307- time := lipgloss .NewStyle ().Render (utils .TimeElapsed (m .pr .Data .CreatedAt ))
339+ desc := m .ctx .Styles .Common .MainTextStyle .Bold (true ).Underline (true ).Render (" Summary" )
308340 title := lipgloss .JoinVertical (
309341 lipgloss .Left ,
310342 desc ,
311343 "" ,
312- lipgloss .JoinHorizontal (lipgloss .Top ,
313- lipgloss .NewStyle ().Foreground (m .ctx .Theme .PrimaryText ).Render (lipgloss .NewStyle ().Bold (true ).Render ("@" + m .pr .Data .Author .Login )),
314- " " ,
315- lipgloss .NewStyle ().Foreground (m .ctx .Theme .FaintText ).Render ("commented" , time , "ago" ),
316- ),
317- "" ,
318344 )
319- sbody := lipgloss .NewStyle ().Border (lipgloss .RoundedBorder (), true ).BorderForeground (m .ctx .Theme .FaintBorder ).Width (width )
320-
345+ sbody := lipgloss .NewStyle ().Width (m .getIndentedContentWidth ())
321346 body = strings .TrimSpace (body )
322347 if body == "" {
323348 return lipgloss .JoinVertical (
@@ -333,6 +358,20 @@ func (m *Model) renderDescription() string {
333358 return ""
334359 }
335360
361+ if ! m .summaryViewMore && len (rendered ) > foldBodyLen {
362+ rendered = rendered [0 :foldBodyLen ]
363+ rendered = lipgloss .JoinVertical (lipgloss .Left ,
364+ rendered ,
365+ "" ,
366+ lipgloss .PlaceHorizontal (m .getIndentedContentWidth (), lipgloss .Center ,
367+ lipgloss .JoinHorizontal (lipgloss .Top ,
368+ lipgloss .NewStyle ().Bold (true ).Italic (true ).Render ("Press " ),
369+ lipgloss .NewStyle ().Background (m .ctx .Theme .SelectedBackground ).Foreground (m .ctx .Theme .PrimaryText ).Render ("e" ),
370+ lipgloss .NewStyle ().Bold (true ).Italic (true ).Render (" to read more..." )),
371+ ),
372+ )
373+ }
374+
336375 return lipgloss .JoinVertical (lipgloss .Left , title ,
337376 lipgloss .NewStyle ().
338377 Width (width ).
@@ -410,7 +449,7 @@ func (m *Model) SetIsCommenting(isCommenting bool) tea.Cmd {
410449}
411450
412451func (m * Model ) getIndentedContentWidth () int {
413- return m .width - 4
452+ return m .width - 3 * m . ctx . Styles . Sidebar . ContentPadding
414453}
415454
416455func (m * Model ) GetIsApproving () bool {
@@ -501,3 +540,11 @@ func (m *Model) prAssignees() []string {
501540func (m * Model ) GoToFirstTab () {
502541 m .carousel .SetCursor (0 )
503542}
543+
544+ func (m * Model ) SetSummaryViewMore () {
545+ m .summaryViewMore = true
546+ }
547+
548+ func (m * Model ) SetSummaryViewLess () {
549+ m .summaryViewMore = false
550+ }
0 commit comments