Redesign source link
This commit is contained in:
@@ -53,6 +53,7 @@ type indexPage struct {
|
|||||||
// field wants is "never", what the list wants is "unlimited".
|
// field wants is "never", what the list wants is "unlimited".
|
||||||
ExpiryHint string
|
ExpiryHint string
|
||||||
AbsBase string
|
AbsBase string
|
||||||
|
Source string // the repository this build came from, "" to say nothing
|
||||||
AllowVanity bool
|
AllowVanity bool
|
||||||
MaxSizeBytes int64 // 0 when unlimited; the script checks against it
|
MaxSizeBytes int64 // 0 when unlimited; the script checks against it
|
||||||
Stale bool // a login whose token no longer exists
|
Stale bool // a login whose token no longer exists
|
||||||
@@ -83,6 +84,7 @@ func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
|
|||||||
DefaultExpiry: config.FormatLifetime(lim.DefaultExpiry),
|
DefaultExpiry: config.FormatLifetime(lim.DefaultExpiry),
|
||||||
ExpiryHint: config.FormatDuration(lim.DefaultExpiry),
|
ExpiryHint: config.FormatDuration(lim.DefaultExpiry),
|
||||||
AbsBase: s.absBase(r),
|
AbsBase: s.absBase(r),
|
||||||
|
Source: s.cfg.SourceURL,
|
||||||
AllowVanity: lim.AllowVanity,
|
AllowVanity: lim.AllowVanity,
|
||||||
MaxSizeBytes: lim.MaxSize,
|
MaxSizeBytes: lim.MaxSize,
|
||||||
Stale: stale,
|
Stale: stale,
|
||||||
|
|||||||
@@ -241,9 +241,6 @@ type page struct {
|
|||||||
// case the markup carries no link rather than one that 404s.
|
// case the markup carries no link rather than one that 404s.
|
||||||
Favicon string
|
Favicon string
|
||||||
|
|
||||||
// Source is where the footer links; empty means no footer.
|
|
||||||
Source string
|
|
||||||
|
|
||||||
// Wide widens the page for content that is a table rather than a form.
|
// Wide widens the page for content that is a table rather than a form.
|
||||||
// The reading measure that suits the upload page is far too narrow for a
|
// The reading measure that suits the upload page is far too narrow for a
|
||||||
// listing, which otherwise ends up behind a horizontal scrollbar.
|
// listing, which otherwise ends up behind a horizontal scrollbar.
|
||||||
@@ -253,7 +250,7 @@ type page struct {
|
|||||||
// page builds the common fields, resolving the session so the header can show
|
// page builds the common fields, resolving the session so the header can show
|
||||||
// who is logged in and offer only the links they can use.
|
// who is logged in and offer only the links they can use.
|
||||||
func (s *Server) page(r *http.Request, title string, script bool) page {
|
func (s *Server) page(r *http.Request, title string, script bool) page {
|
||||||
p := page{Base: s.cfg.BasePath, Title: title, Script: script, Source: s.cfg.SourceURL}
|
p := page{Base: s.cfg.BasePath, Title: title, Script: script}
|
||||||
if s.favicon != "" {
|
if s.favicon != "" {
|
||||||
p.Favicon = s.cfg.BasePath + "static/" + s.favicon
|
p.Favicon = s.cfg.BasePath + "static/" + s.favicon
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1148,33 +1148,35 @@ func TestNoFaviconMeansNoLink(t *testing.T) {
|
|||||||
|
|
||||||
// --- the footer ------------------------------------------------------------
|
// --- the footer ------------------------------------------------------------
|
||||||
|
|
||||||
// The footer names where the source lives, and an instance that would rather
|
// The upload page says where the source is; no other page does, and an
|
||||||
// not say so can drop it. A fork gets to point at its own.
|
// instance that would rather not say so drops it there too.
|
||||||
func TestSourceLinkIsOptional(t *testing.T) {
|
func TestSourceLinkIsOptional(t *testing.T) {
|
||||||
|
body := func(h *harness, path string) string {
|
||||||
|
t.Helper()
|
||||||
|
resp := h.get(t, path, "")
|
||||||
|
raw, _ := io.ReadAll(resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
return string(raw)
|
||||||
|
}
|
||||||
|
|
||||||
shown := newHarness(t, nil)
|
shown := newHarness(t, nil)
|
||||||
resp := shown.get(t, "/", "")
|
if !strings.Contains(body(shown, "/"), `<a href="https://git.uncensored.hu/thayol/uncensored-send">`) {
|
||||||
page, _ := io.ReadAll(resp.Body)
|
t.Error("the upload page does not link its source")
|
||||||
resp.Body.Close()
|
}
|
||||||
if !strings.Contains(string(page), `<footer><a href="https://git.uncensored.hu/thayol/uncensored-send">Source</a>`) {
|
for _, path := range []string{"/login", "/files"} {
|
||||||
t.Error("the default build does not link its source")
|
if strings.Contains(body(shown, path), "git.uncensored.hu") {
|
||||||
|
t.Errorf("GET %s carries the source link, which belongs on the upload page alone", path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forked := newHarness(t, func(c *config.Config) { c.SourceURL = "https://example.org/me/fork" })
|
forked := newHarness(t, func(c *config.Config) { c.SourceURL = "https://example.org/me/fork" })
|
||||||
resp = forked.get(t, "/login", "")
|
if !strings.Contains(body(forked, "/"), `href="https://example.org/me/fork"`) {
|
||||||
page, _ = io.ReadAll(resp.Body)
|
|
||||||
resp.Body.Close()
|
|
||||||
if !strings.Contains(string(page), `href="https://example.org/me/fork"`) {
|
|
||||||
t.Error("a fork's own source URL is not used")
|
t.Error("a fork's own source URL is not used")
|
||||||
}
|
}
|
||||||
|
|
||||||
quiet := newHarness(t, func(c *config.Config) { c.SourceURL = "" })
|
quiet := newHarness(t, func(c *config.Config) { c.SourceURL = "" })
|
||||||
for _, path := range []string{"/", "/login", "/files"} {
|
if page := body(quiet, "/"); strings.Contains(page, ">Source<") || strings.Contains(page, "git.uncensored.hu") {
|
||||||
resp := quiet.get(t, path, "")
|
t.Error("the upload page still names a source with the link switched off")
|
||||||
page, _ := io.ReadAll(resp.Body)
|
|
||||||
resp.Body.Close()
|
|
||||||
if strings.Contains(string(page), "<footer>") {
|
|
||||||
t.Errorf("GET %s still carries a footer with the source link switched off", path)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,4 +76,13 @@
|
|||||||
-H 'Expiry: 3d' \
|
-H 'Expiry: 3d' \
|
||||||
{{.AbsBase}}upload</code></pre>
|
{{.AbsBase}}upload</code></pre>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
{{if .Source}}
|
||||||
|
<section class="card">
|
||||||
|
<h2>Source</h2>
|
||||||
|
<p class="hint">
|
||||||
|
The code this service runs is at <a href="{{.Source}}">{{.Source}}</a>.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
<main>
|
<main>
|
||||||
{{template "content" .}}
|
{{template "content" .}}
|
||||||
</main>
|
</main>
|
||||||
{{if .Source}}<footer><a href="{{.Source}}">Source</a></footer>{{end}}
|
|
||||||
{{if .Script}}<script src="{{.Base}}static/app.js" defer></script>{{end}}
|
{{if .Script}}<script src="{{.Base}}static/app.js" defer></script>{{end}}
|
||||||
</body>
|
</body>
|
||||||
</html>{{end}}
|
</html>{{end}}
|
||||||
|
|||||||
Reference in New Issue
Block a user