From afe2f0c9e2b99accbfb62a75f4defa9ad2555340 Mon Sep 17 00:00:00 2001 From: Danila Gorelko Date: Sun, 10 Mar 2024 22:39:56 +0300 Subject: [PATCH] Add clickable diffs to recent changes view (#215) * Add clickable diffs to recent changes view * Reuse entries * Insert non-breaking space * Show hash only once, remove parenthesis --- history/histweb/view_recent_changes.html | 4 +- history/view.qtpl | 22 ++ history/view.qtpl.go | 327 +++++++++++++++-------- 3 files changed, 237 insertions(+), 116 deletions(-) diff --git a/history/histweb/view_recent_changes.html b/history/histweb/view_recent_changes.html index 02842ff..b744f61 100644 --- a/history/histweb/view_recent_changes.html +++ b/history/histweb/view_recent_changes.html @@ -24,7 +24,9 @@ - {{$entry.Hash}} + + {{$entry.HyphaeDiffsHTML}} + {{ if $entry.Username | ne "anon" }} diff --git a/history/view.qtpl b/history/view.qtpl index 67e5cfd..150ba9f 100644 --- a/history/view.qtpl +++ b/history/view.qtpl @@ -13,6 +13,28 @@ HyphaeLinksHTML returns a comma-separated list of hyphae that were affected by t {% endstripspace %} {% endfunc %} + +HyphaeDiffsHTML returns a comma-separated list of diffs links of current revision for every affected file as HTML string. +{% func (rev Revision) HyphaeDiffsHTML() %} + {% code entries := rev.hyphaeAffected() %} +{% stripspace %} + {% if len(entries) == 1 %} + {%s rev.Hash %} + {% else %} + {% for i, hyphaName := range entries %} + {% if i > 0 %} + + {% endif %} + + {% if i == 0 %} + {%s rev.Hash %}  + {% endif %} + {%s hyphaName %} + {% endfor %} + {% endif %} +{% endstripspace %} +{% endfunc %} + descriptionForFeed generates a good enough HTML contents for a web feed. {% func (rev *Revision) descriptionForFeed() %}

{%s rev.Message %} (by {%s rev.Username %} at {%s rev.TimeString() %})

diff --git a/history/view.qtpl.go b/history/view.qtpl.go index 64bc380..796a527 100644 --- a/history/view.qtpl.go +++ b/history/view.qtpl.go @@ -82,245 +82,342 @@ func (rev Revision) HyphaeLinksHTML() string { //line history/view.qtpl:14 } -// descriptionForFeed generates a good enough HTML contents for a web feed. +// HyphaeDiffsHTML returns a comma-separated list of diffs links of current revision for every affected file as HTML string. -//line history/view.qtpl:17 -func (rev *Revision) streamdescriptionForFeed(qw422016 *qt422016.Writer) { -//line history/view.qtpl:17 +//line history/view.qtpl:18 +func (rev Revision) StreamHyphaeDiffsHTML(qw422016 *qt422016.Writer) { +//line history/view.qtpl:18 qw422016.N().S(` -

`) -//line history/view.qtpl:18 - qw422016.E().S(rev.Message) -//line history/view.qtpl:18 - qw422016.N().S(` (by `) -//line history/view.qtpl:18 - qw422016.E().S(rev.Username) -//line history/view.qtpl:18 - qw422016.N().S(` at `) -//line history/view.qtpl:18 - qw422016.E().S(rev.TimeString()) -//line history/view.qtpl:18 - qw422016.N().S(`)

-

Hyphae affected: `) + `) //line history/view.qtpl:19 - rev.StreamHyphaeLinksHTML(qw422016) + entries := rev.hyphaeAffected() + //line history/view.qtpl:19 - qw422016.N().S(`

-
`)
-//line history/view.qtpl:20
-	qw422016.E().S(rev.textDiff())
-//line history/view.qtpl:20
-	qw422016.N().S(`
+ qw422016.N().S(` `) //line history/view.qtpl:21 + if len(entries) == 1 { +//line history/view.qtpl:21 + qw422016.N().S(``) +//line history/view.qtpl:22 + qw422016.E().S(rev.Hash) +//line history/view.qtpl:22 + qw422016.N().S(``) +//line history/view.qtpl:23 + } else { +//line history/view.qtpl:24 + for i, hyphaName := range entries { +//line history/view.qtpl:25 + if i > 0 { +//line history/view.qtpl:25 + qw422016.N().S(``) +//line history/view.qtpl:27 + } +//line history/view.qtpl:27 + qw422016.N().S(``) +//line history/view.qtpl:29 + if i == 0 { +//line history/view.qtpl:30 + qw422016.E().S(rev.Hash) +//line history/view.qtpl:30 + qw422016.N().S(` `) +//line history/view.qtpl:31 + } +//line history/view.qtpl:32 + qw422016.E().S(hyphaName) +//line history/view.qtpl:32 + qw422016.N().S(``) +//line history/view.qtpl:33 + } +//line history/view.qtpl:34 + } +//line history/view.qtpl:35 + qw422016.N().S(` +`) +//line history/view.qtpl:36 } -//line history/view.qtpl:21 -func (rev *Revision) writedescriptionForFeed(qq422016 qtio422016.Writer) { -//line history/view.qtpl:21 +//line history/view.qtpl:36 +func (rev Revision) WriteHyphaeDiffsHTML(qq422016 qtio422016.Writer) { +//line history/view.qtpl:36 qw422016 := qt422016.AcquireWriter(qq422016) -//line history/view.qtpl:21 - rev.streamdescriptionForFeed(qw422016) -//line history/view.qtpl:21 +//line history/view.qtpl:36 + rev.StreamHyphaeDiffsHTML(qw422016) +//line history/view.qtpl:36 qt422016.ReleaseWriter(qw422016) -//line history/view.qtpl:21 +//line history/view.qtpl:36 } -//line history/view.qtpl:21 -func (rev *Revision) descriptionForFeed() string { -//line history/view.qtpl:21 +//line history/view.qtpl:36 +func (rev Revision) HyphaeDiffsHTML() string { +//line history/view.qtpl:36 qb422016 := qt422016.AcquireByteBuffer() -//line history/view.qtpl:21 - rev.writedescriptionForFeed(qb422016) -//line history/view.qtpl:21 +//line history/view.qtpl:36 + rev.WriteHyphaeDiffsHTML(qb422016) +//line history/view.qtpl:36 qs422016 := string(qb422016.B) -//line history/view.qtpl:21 +//line history/view.qtpl:36 qt422016.ReleaseByteBuffer(qb422016) -//line history/view.qtpl:21 +//line history/view.qtpl:36 return qs422016 -//line history/view.qtpl:21 +//line history/view.qtpl:36 +} + +// descriptionForFeed generates a good enough HTML contents for a web feed. + +//line history/view.qtpl:39 +func (rev *Revision) streamdescriptionForFeed(qw422016 *qt422016.Writer) { +//line history/view.qtpl:39 + qw422016.N().S(` +

`) +//line history/view.qtpl:40 + qw422016.E().S(rev.Message) +//line history/view.qtpl:40 + qw422016.N().S(` (by `) +//line history/view.qtpl:40 + qw422016.E().S(rev.Username) +//line history/view.qtpl:40 + qw422016.N().S(` at `) +//line history/view.qtpl:40 + qw422016.E().S(rev.TimeString()) +//line history/view.qtpl:40 + qw422016.N().S(`)

+

Hyphae affected: `) +//line history/view.qtpl:41 + rev.StreamHyphaeLinksHTML(qw422016) +//line history/view.qtpl:41 + qw422016.N().S(`

+
`)
+//line history/view.qtpl:42
+	qw422016.E().S(rev.textDiff())
+//line history/view.qtpl:42
+	qw422016.N().S(`
+`) +//line history/view.qtpl:43 +} + +//line history/view.qtpl:43 +func (rev *Revision) writedescriptionForFeed(qq422016 qtio422016.Writer) { +//line history/view.qtpl:43 + qw422016 := qt422016.AcquireWriter(qq422016) +//line history/view.qtpl:43 + rev.streamdescriptionForFeed(qw422016) +//line history/view.qtpl:43 + qt422016.ReleaseWriter(qw422016) +//line history/view.qtpl:43 +} + +//line history/view.qtpl:43 +func (rev *Revision) descriptionForFeed() string { +//line history/view.qtpl:43 + qb422016 := qt422016.AcquireByteBuffer() +//line history/view.qtpl:43 + rev.writedescriptionForFeed(qb422016) +//line history/view.qtpl:43 + qs422016 := string(qb422016.B) +//line history/view.qtpl:43 + qt422016.ReleaseByteBuffer(qb422016) +//line history/view.qtpl:43 + return qs422016 +//line history/view.qtpl:43 } // WithRevisions returns an html representation of `revs` that is meant to be inserted in a history page. -//line history/view.qtpl:24 +//line history/view.qtpl:46 func StreamWithRevisions(qw422016 *qt422016.Writer, hyphaName string, revs []Revision) { -//line history/view.qtpl:24 +//line history/view.qtpl:46 qw422016.N().S(` `) -//line history/view.qtpl:25 +//line history/view.qtpl:47 for _, grp := range groupRevisionsByMonth(revs) { -//line history/view.qtpl:25 +//line history/view.qtpl:47 qw422016.N().S(` `) -//line history/view.qtpl:27 +//line history/view.qtpl:49 currentYear := grp[0].Time.Year() currentMonth := grp[0].Time.Month() sectionId := fmt.Sprintf("%04d-%02d", currentYear, currentMonth) -//line history/view.qtpl:30 +//line history/view.qtpl:52 qw422016.N().S(`

`) -//line history/view.qtpl:33 +//line history/view.qtpl:55 qw422016.N().D(currentYear) -//line history/view.qtpl:33 +//line history/view.qtpl:55 qw422016.N().S(` `) -//line history/view.qtpl:33 +//line history/view.qtpl:55 qw422016.E().S(currentMonth.String()) -//line history/view.qtpl:33 +//line history/view.qtpl:55 qw422016.N().S(`

    `) -//line history/view.qtpl:36 +//line history/view.qtpl:58 for _, rev := range grp { -//line history/view.qtpl:36 +//line history/view.qtpl:58 qw422016.N().S(` `) -//line history/view.qtpl:37 +//line history/view.qtpl:59 rev.streamasHistoryEntry(qw422016, hyphaName) -//line history/view.qtpl:37 +//line history/view.qtpl:59 qw422016.N().S(` `) -//line history/view.qtpl:38 +//line history/view.qtpl:60 } -//line history/view.qtpl:38 +//line history/view.qtpl:60 qw422016.N().S(`
`) -//line history/view.qtpl:41 +//line history/view.qtpl:63 } -//line history/view.qtpl:41 +//line history/view.qtpl:63 qw422016.N().S(` `) -//line history/view.qtpl:42 +//line history/view.qtpl:64 } -//line history/view.qtpl:42 +//line history/view.qtpl:64 func WriteWithRevisions(qq422016 qtio422016.Writer, hyphaName string, revs []Revision) { -//line history/view.qtpl:42 +//line history/view.qtpl:64 qw422016 := qt422016.AcquireWriter(qq422016) -//line history/view.qtpl:42 +//line history/view.qtpl:64 StreamWithRevisions(qw422016, hyphaName, revs) -//line history/view.qtpl:42 +//line history/view.qtpl:64 qt422016.ReleaseWriter(qw422016) -//line history/view.qtpl:42 +//line history/view.qtpl:64 } -//line history/view.qtpl:42 +//line history/view.qtpl:64 func WithRevisions(hyphaName string, revs []Revision) string { -//line history/view.qtpl:42 +//line history/view.qtpl:64 qb422016 := qt422016.AcquireByteBuffer() -//line history/view.qtpl:42 +//line history/view.qtpl:64 WriteWithRevisions(qb422016, hyphaName, revs) -//line history/view.qtpl:42 +//line history/view.qtpl:64 qs422016 := string(qb422016.B) -//line history/view.qtpl:42 +//line history/view.qtpl:64 qt422016.ReleaseByteBuffer(qb422016) -//line history/view.qtpl:42 +//line history/view.qtpl:64 return qs422016 -//line history/view.qtpl:42 +//line history/view.qtpl:64 } -//line history/view.qtpl:44 +//line history/view.qtpl:66 func (rev *Revision) streamasHistoryEntry(qw422016 *qt422016.Writer, hyphaName string) { -//line history/view.qtpl:44 +//line history/view.qtpl:66 qw422016.N().S(`
  • `) -//line history/view.qtpl:49 +//line history/view.qtpl:71 qw422016.E().S(rev.Hash) -//line history/view.qtpl:49 +//line history/view.qtpl:71 qw422016.N().S(` `) -//line history/view.qtpl:50 +//line history/view.qtpl:72 qw422016.E().S(rev.Message) -//line history/view.qtpl:50 +//line history/view.qtpl:72 qw422016.N().S(` `) -//line history/view.qtpl:51 +//line history/view.qtpl:73 if rev.Username != "anon" { -//line history/view.qtpl:51 +//line history/view.qtpl:73 qw422016.N().S(` `) -//line history/view.qtpl:53 +//line history/view.qtpl:75 } -//line history/view.qtpl:53 +//line history/view.qtpl:75 qw422016.N().S(`
  • `) -//line history/view.qtpl:55 +//line history/view.qtpl:77 } -//line history/view.qtpl:55 +//line history/view.qtpl:77 func (rev *Revision) writeasHistoryEntry(qq422016 qtio422016.Writer, hyphaName string) { -//line history/view.qtpl:55 +//line history/view.qtpl:77 qw422016 := qt422016.AcquireWriter(qq422016) -//line history/view.qtpl:55 +//line history/view.qtpl:77 rev.streamasHistoryEntry(qw422016, hyphaName) -//line history/view.qtpl:55 +//line history/view.qtpl:77 qt422016.ReleaseWriter(qw422016) -//line history/view.qtpl:55 +//line history/view.qtpl:77 } -//line history/view.qtpl:55 +//line history/view.qtpl:77 func (rev *Revision) asHistoryEntry(hyphaName string) string { -//line history/view.qtpl:55 +//line history/view.qtpl:77 qb422016 := qt422016.AcquireByteBuffer() -//line history/view.qtpl:55 +//line history/view.qtpl:77 rev.writeasHistoryEntry(qb422016, hyphaName) -//line history/view.qtpl:55 +//line history/view.qtpl:77 qs422016 := string(qb422016.B) -//line history/view.qtpl:55 +//line history/view.qtpl:77 qt422016.ReleaseByteBuffer(qb422016) -//line history/view.qtpl:55 +//line history/view.qtpl:77 return qs422016 -//line history/view.qtpl:55 +//line history/view.qtpl:77 }