diff --git a/history/histview/histview.go b/history/histview/histview.go index 25dbea2..44df89b 100644 --- a/history/histview/histview.go +++ b/history/histview/histview.go @@ -12,15 +12,24 @@ import ( "github.com/gorilla/mux" "log" "net/http" + "strconv" "strings" "text/template" ) func InitHandlers(rtr *mux.Router) { rtr.PathPrefix("/primitive-diff/").HandlerFunc(handlerPrimitiveDiff) + rtr.HandleFunc("/recent-changes/{count:[0-9]+}", handlerRecentChanges) + rtr.HandleFunc("/recent-changes/", func(w http.ResponseWriter, rq *http.Request) { + http.Redirect(w, rq, "/recent-changes/20", http.StatusSeeOther) + }) + chainPrimitiveDiff = viewutil. En(viewutil.CopyEnWith(fs, "view_primitive_diff.html")). Ru(template.Must(viewutil.CopyRuWith(fs, "view_primitive_diff.html").Parse(ruTranslation))) + chainRecentChanges = viewutil. + En(viewutil.CopyEnWith(fs, "view_recent_changes.html")). + Ru(template.Must(viewutil.CopyRuWith(fs, "view_recent_changes.html").Parse(ruTranslation))) } func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) { @@ -52,6 +61,16 @@ func handlerPrimitiveDiff(w http.ResponseWriter, rq *http.Request) { } } +// handlerRecentChanges displays the /recent-changes/ page. +func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) { + // Error ignored: filtered by regex + editCount, _ := strconv.Atoi(mux.Vars(rq)["count"]) + if editCount > 100 { + return + } + recentChanges(viewutil.MetaFrom(w, rq), editCount, history.RecentChanges(editCount)) +} + var ( //go:embed *.html fs embed.FS @@ -61,8 +80,34 @@ var ( ` chainPrimitiveDiff viewutil.Chain + chainRecentChanges viewutil.Chain ) +type recentChangesData struct { + viewutil.BaseData + EditCount int + Changes []history.Revision + UserHypha string + Stops []int +} + +func recentChanges(meta viewutil.Meta, editCount int, changes []history.Revision) { + if err := chainRecentChanges.Get(meta).ExecuteTemplate(meta.W, "page", recentChangesData{ + BaseData: viewutil.BaseData{ + Meta: meta, + Addr: "/recent-changes/" + strconv.Itoa(editCount), + HeaderLinks: cfg.HeaderLinks, + CommonScripts: cfg.CommonScripts, + }, + EditCount: editCount, + Changes: changes, + UserHypha: cfg.UserHypha, + Stops: []int{20, 50, 100}, + }); err != nil { + log.Println(err) + } +} + type primitiveDiffData struct { viewutil.BaseData HyphaName string diff --git a/history/histview/view_recent_changes.html b/history/histview/view_recent_changes.html new file mode 100644 index 0000000..a359847 --- /dev/null +++ b/history/histview/view_recent_changes.html @@ -0,0 +1,70 @@ +{{define "subscribe via"}}{{end}} +{{define "recent changes"}}Recent changes{{end}} +{{define "n recent changes"}}{{.}} recent change{{if ne . 1}}s{{end}}{{end}} +{{define "title"}}{{template "n recent changes" .EditCount}}{{end}} + +{{define "body"}} +
+

{{template "recent changes"}}

+ +

+ {{block "count pre" .}}See{{end}} + {{ $editCount := .EditCount }} + {{range $i, $m := .Stops }} + {{if $i | gt 0}} + + {{end}} + {{if $m | eq $editCount}} + {{$m}} + {{else}} + {{$m}} + {{end}} + {{end}} + {{block "count post" .}}recent changes{{end}} +

+ +

+ + {{block "subscribe via" .}}Subscribe via RSS, Atom or JSON feed.{{end}} +

+ + {{$userHypha := .UserHypha}} + {{$year := 0}}{{$month := 0}}{{$day := 0}} +
+ {{range $i, $entry := .Changes}} + {{$time := $entry.Time.UTC}} + {{$y := $time.Year}}{{$m := $time.Month}}{{$d := $time.Day}} + {{if or (ne $d $day) (ne $m $month) (ne $y $year)}} +

+ {{printf "%04d-%02d-%02d" $y $m $d}} +

+ {{$year = $y}}{{$month = $m}}{{$day = $d}} + {{end}} + +
+
+ + {{$entry.Hash}} + {{ if $entry.Username | ne "anon" }} + + {{end}} +
+
+ + {{$entry.HyphaeLinksHTML}} + + + {{$entry.Message}} + +
+
+ {{else}} +

{{block "recent empty" .}}No recent changes found.{{end}}

+ {{end}} +
+
+{{end}} diff --git a/l18n/en/ui.json b/l18n/en/ui.json index cc24883..ebaff65 100644 --- a/l18n/en/ui.json +++ b/l18n/en/ui.json @@ -59,16 +59,6 @@ "history_title": "History of %s", - "recent_title": "{{.n}} recent change%s", - "recent_title+one": "", - "recent_title+other": "s", - "recent_heading": "Recent Changes", - "recent_count_pre": "See", - "recent_count_post": "recent changes", - "recent_subscribe": "Subscribe via {{.rss}}, {{.atom}} or {{.json}}", - "recent_subscribe_json": "JSON feed", - "recent_empty": "Could not find any recent changes.", - "diff_title": "Diff of {{.name}} at {{.rev}}", "revision_title": "{{.name}} at {{.rev}}", diff --git a/views/history.qtpl b/views/history.qtpl index b28b00e..9a922dd 100644 --- a/views/history.qtpl +++ b/views/history.qtpl @@ -1,92 +1,7 @@ {% import "fmt" %} {% import "net/http" %} -{% import "time" %} -{% import "github.com/bouncepaw/mycorrhiza/cfg" %} {% import "github.com/bouncepaw/mycorrhiza/l18n" %} -{% import "github.com/bouncepaw/mycorrhiza/history" %} - - -{% func RecentChanges(n int, lc *l18n.Localizer) %} -
-

{%s lc.Get("ui.recent_heading") %}

- - - -

{%s= lc.Get("ui.recent_subscribe", &l18n.Replacements{"rss": "RSS", "atom": "Atom", "json": fmt.Sprintf("%s", lc.Get("ui.recent_subscribe_json"))}) %}

- - {% comment %} - Here I am, willing to add some accessibility using ARIA. Turns out, - role="feed" is not supported in any screen reader as of September - 2020. At least web search says so. Even JAWS doesn't support it! - How come? I'll add the role anyway. -- bouncepaw - {% endcomment %} - - {% code - changes := history.RecentChanges(n) - var year, day int - var month time.Month - %} -
- {% if len(changes) == 0 %} -

{%s lc.Get("ui.recent_empty") %}

- {% else %} - {% for i, entry := range changes %} - - {% code y, m, d := entry.Time.UTC().Date() %} - {% if d != day || m != month || y != year %} -

- {%s fmt.Sprintf("%04d-%02d-%02d", y, m, d) %} -

- {% code year, month, day = y, m, d %} - {% endif %} - -
- {%s= recentChanges(entry) %} -
- - {% endfor %} - {% endif %} -
-
-{% endfunc %} - -{% func recentChanges(rev history.Revision) %} -
- - {%s rev.Hash %} - - {% if rev.Username != "anon" %} - - — - - {% endif %} -
-
- - {%s= rev.HyphaeLinksHTML() %} - - - {%s rev.Message %} - -
-{% endfunc %} {% func History(rq *http.Request, hyphaName, list string, lc *l18n.Localizer) %}
diff --git a/views/history.qtpl.go b/views/history.qtpl.go index 490a401..5188414 100644 --- a/views/history.qtpl.go +++ b/views/history.qtpl.go @@ -10,368 +10,66 @@ import "fmt" //line views/history.qtpl:2 import "net/http" -//line views/history.qtpl:3 -import "time" - -//line views/history.qtpl:5 -import "github.com/bouncepaw/mycorrhiza/cfg" - -//line views/history.qtpl:6 +//line views/history.qtpl:4 import "github.com/bouncepaw/mycorrhiza/l18n" -//line views/history.qtpl:7 -import "github.com/bouncepaw/mycorrhiza/history" - -//line views/history.qtpl:10 +//line views/history.qtpl:6 import ( qtio422016 "io" qt422016 "github.com/valyala/quicktemplate" ) -//line views/history.qtpl:10 +//line views/history.qtpl:6 var ( _ = qtio422016.Copy _ = qt422016.AcquireByteBuffer ) -//line views/history.qtpl:10 -func StreamRecentChanges(qw422016 *qt422016.Writer, n int, lc *l18n.Localizer) { -//line views/history.qtpl:10 - qw422016.N().S(` -
-

`) -//line views/history.qtpl:12 - qw422016.E().S(lc.Get("ui.recent_heading")) -//line views/history.qtpl:12 - qw422016.N().S(`

- - - -

`) -//line views/history.qtpl:29 - qw422016.N().S(lc.Get("ui.recent_subscribe", &l18n.Replacements{"rss": "RSS", "atom": "Atom", "json": fmt.Sprintf("%s", lc.Get("ui.recent_subscribe_json"))})) -//line views/history.qtpl:29 - qw422016.N().S(`

- - `) -//line views/history.qtpl:36 - qw422016.N().S(` - - `) -//line views/history.qtpl:39 - changes := history.RecentChanges(n) - var year, day int - var month time.Month - -//line views/history.qtpl:42 - qw422016.N().S(` -
- `) -//line views/history.qtpl:44 - if len(changes) == 0 { -//line views/history.qtpl:44 - qw422016.N().S(` -

`) -//line views/history.qtpl:45 - qw422016.E().S(lc.Get("ui.recent_empty")) -//line views/history.qtpl:45 - qw422016.N().S(`

- `) -//line views/history.qtpl:46 - } else { -//line views/history.qtpl:46 - qw422016.N().S(` - `) -//line views/history.qtpl:47 - for i, entry := range changes { -//line views/history.qtpl:47 - qw422016.N().S(` - - `) -//line views/history.qtpl:49 - y, m, d := entry.Time.UTC().Date() - -//line views/history.qtpl:49 - qw422016.N().S(` - `) -//line views/history.qtpl:50 - if d != day || m != month || y != year { -//line views/history.qtpl:50 - qw422016.N().S(` -

- `) -//line views/history.qtpl:52 - qw422016.E().S(fmt.Sprintf("%04d-%02d-%02d", y, m, d)) -//line views/history.qtpl:52 - qw422016.N().S(` -

- `) -//line views/history.qtpl:54 - year, month, day = y, m, d - -//line views/history.qtpl:54 - qw422016.N().S(` - `) -//line views/history.qtpl:55 - } -//line views/history.qtpl:55 - qw422016.N().S(` - -
- `) -//line views/history.qtpl:59 - qw422016.N().S(recentChanges(entry)) -//line views/history.qtpl:59 - qw422016.N().S(` -
- - `) -//line views/history.qtpl:62 - } -//line views/history.qtpl:62 - qw422016.N().S(` - `) -//line views/history.qtpl:63 - } -//line views/history.qtpl:63 - qw422016.N().S(` -
-
-`) -//line views/history.qtpl:66 -} - -//line views/history.qtpl:66 -func WriteRecentChanges(qq422016 qtio422016.Writer, n int, lc *l18n.Localizer) { -//line views/history.qtpl:66 - qw422016 := qt422016.AcquireWriter(qq422016) -//line views/history.qtpl:66 - StreamRecentChanges(qw422016, n, lc) -//line views/history.qtpl:66 - qt422016.ReleaseWriter(qw422016) -//line views/history.qtpl:66 -} - -//line views/history.qtpl:66 -func RecentChanges(n int, lc *l18n.Localizer) string { -//line views/history.qtpl:66 - qb422016 := qt422016.AcquireByteBuffer() -//line views/history.qtpl:66 - WriteRecentChanges(qb422016, n, lc) -//line views/history.qtpl:66 - qs422016 := string(qb422016.B) -//line views/history.qtpl:66 - qt422016.ReleaseByteBuffer(qb422016) -//line views/history.qtpl:66 - return qs422016 -//line views/history.qtpl:66 -} - -//line views/history.qtpl:68 -func streamrecentChanges(qw422016 *qt422016.Writer, rev history.Revision) { -//line views/history.qtpl:68 - qw422016.N().S(` -
- - `) -//line views/history.qtpl:73 - qw422016.E().S(rev.Hash) -//line views/history.qtpl:73 - qw422016.N().S(` - - `) -//line views/history.qtpl:75 - if rev.Username != "anon" { -//line views/history.qtpl:75 - qw422016.N().S(` - - `) -//line views/history.qtpl:79 - } -//line views/history.qtpl:79 - qw422016.N().S(` -
-
- - `) -//line views/history.qtpl:83 - qw422016.N().S(rev.HyphaeLinksHTML()) -//line views/history.qtpl:83 - qw422016.N().S(` - - - `) -//line views/history.qtpl:86 - qw422016.E().S(rev.Message) -//line views/history.qtpl:86 - qw422016.N().S(` - -
-`) -//line views/history.qtpl:89 -} - -//line views/history.qtpl:89 -func writerecentChanges(qq422016 qtio422016.Writer, rev history.Revision) { -//line views/history.qtpl:89 - qw422016 := qt422016.AcquireWriter(qq422016) -//line views/history.qtpl:89 - streamrecentChanges(qw422016, rev) -//line views/history.qtpl:89 - qt422016.ReleaseWriter(qw422016) -//line views/history.qtpl:89 -} - -//line views/history.qtpl:89 -func recentChanges(rev history.Revision) string { -//line views/history.qtpl:89 - qb422016 := qt422016.AcquireByteBuffer() -//line views/history.qtpl:89 - writerecentChanges(qb422016, rev) -//line views/history.qtpl:89 - qs422016 := string(qb422016.B) -//line views/history.qtpl:89 - qt422016.ReleaseByteBuffer(qb422016) -//line views/history.qtpl:89 - return qs422016 -//line views/history.qtpl:89 -} - -//line views/history.qtpl:91 +//line views/history.qtpl:6 func StreamHistory(qw422016 *qt422016.Writer, rq *http.Request, hyphaName, list string, lc *l18n.Localizer) { -//line views/history.qtpl:91 +//line views/history.qtpl:6 qw422016.N().S(`

`) -//line views/history.qtpl:94 +//line views/history.qtpl:9 qw422016.N().S(fmt.Sprintf(lc.Get("ui.history_title"), beautifulLink(hyphaName))) -//line views/history.qtpl:94 +//line views/history.qtpl:9 qw422016.N().S(`

`) -//line views/history.qtpl:95 +//line views/history.qtpl:10 qw422016.N().S(list) -//line views/history.qtpl:95 +//line views/history.qtpl:10 qw422016.N().S(`
`) -//line views/history.qtpl:98 +//line views/history.qtpl:13 } -//line views/history.qtpl:98 +//line views/history.qtpl:13 func WriteHistory(qq422016 qtio422016.Writer, rq *http.Request, hyphaName, list string, lc *l18n.Localizer) { -//line views/history.qtpl:98 +//line views/history.qtpl:13 qw422016 := qt422016.AcquireWriter(qq422016) -//line views/history.qtpl:98 +//line views/history.qtpl:13 StreamHistory(qw422016, rq, hyphaName, list, lc) -//line views/history.qtpl:98 +//line views/history.qtpl:13 qt422016.ReleaseWriter(qw422016) -//line views/history.qtpl:98 +//line views/history.qtpl:13 } -//line views/history.qtpl:98 +//line views/history.qtpl:13 func History(rq *http.Request, hyphaName, list string, lc *l18n.Localizer) string { -//line views/history.qtpl:98 +//line views/history.qtpl:13 qb422016 := qt422016.AcquireByteBuffer() -//line views/history.qtpl:98 +//line views/history.qtpl:13 WriteHistory(qb422016, rq, hyphaName, list, lc) -//line views/history.qtpl:98 +//line views/history.qtpl:13 qs422016 := string(qb422016.B) -//line views/history.qtpl:98 +//line views/history.qtpl:13 qt422016.ReleaseByteBuffer(qb422016) -//line views/history.qtpl:98 +//line views/history.qtpl:13 return qs422016 -//line views/history.qtpl:98 +//line views/history.qtpl:13 } diff --git a/web/history.go b/web/history.go index bcac81b..de5fc4b 100644 --- a/web/history.go +++ b/web/history.go @@ -3,11 +3,9 @@ package web import ( "fmt" "github.com/bouncepaw/mycorrhiza/viewutil" + "github.com/gorilla/mux" "log" "net/http" - "strconv" - - "github.com/gorilla/mux" "github.com/bouncepaw/mycorrhiza/history" "github.com/bouncepaw/mycorrhiza/l18n" @@ -18,11 +16,6 @@ import ( func initHistory(r *mux.Router) { r.PathPrefix("/history/").HandlerFunc(handlerHistory) - r.HandleFunc("/recent-changes/{count:[0-9]+}", handlerRecentChanges) - r.HandleFunc("/recent-changes/", func(w http.ResponseWriter, rq *http.Request) { - http.Redirect(w, rq, "/recent-changes/20", http.StatusSeeOther) - }) - r.HandleFunc("/recent-changes-rss", handlerRecentChangesRSS) r.HandleFunc("/recent-changes-atom", handlerRecentChangesAtom) r.HandleFunc("/recent-changes-json", handlerRecentChangesJSON) @@ -48,21 +41,6 @@ func handlerHistory(w http.ResponseWriter, rq *http.Request) { )) } -// handlerRecentChanges displays the /recent-changes/ page. -func handlerRecentChanges(w http.ResponseWriter, rq *http.Request) { - // Error ignored: filtered by regex - n, _ := strconv.Atoi(mux.Vars(rq)["count"]) - if n > 100 { - return - } - var lc = l18n.FromRequest(rq) - util.HTTP200Page(w, views.Base( - viewutil.MetaFrom(w, rq), - lc.GetPlural("ui.recent_title", n), - views.RecentChanges(n, lc), - )) -} - // genericHandlerOfFeeds is a helper function for the web feed handlers. func genericHandlerOfFeeds(w http.ResponseWriter, rq *http.Request, f func(history.FeedOptions) (string, error), name string, contentType string) { opts, err := history.ParseFeedOptions(rq.URL.Query())