vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Celebrate a landed change request, once
c8fa5759b293126f1b247abc746bc339791568cb · Keenan Nemetz · 13d ago · parent 53ff967b
Celebrate a landed change request, once A successful landing now redirects with ?merged=1, and app.js answers that parameter by fetching static/confetti.browser.js (canvas-confetti 1.9.3, ISC) and firing one burst. The flag is removed from the address as soon as it is read, so a reload, a bookmark or a shared link is an ordinary visit, and no page without the parameter ever requests the bundle. The library honours prefers-reduced-motion through disableForReducedMotion, and reset() before firing means a page restored from the back/forward cache cannot stack a second canvas. The asset is vendored the way htmx and Lucide are: the file is unmodified from the published npm tarball, with the license beside it, so script-src 'self' stays as it is. It is deliberately not in the page shell, because Static() serves assets uncompressed and a shell script would make every page pay for a celebration only one page uses. Refs #01M5XZ7T4R88BA9KV1KTSV7ZXP
server/web/writes.go +4−1
| @@ -470,7 +470,10 @@ func (w *Web) MergeRequest(rw http.ResponseWriter, r *http.Request) { | |||
| 470 | 470 | if problems := metadata.ValidateRequests(m.Git(), metadata.Ref); len(problems) > 0 { | |
| 471 | 471 | w.Logger("web: merge left the request tree invalid: %v", problems) | |
| 472 | 472 | } | |
| 473 | http.Redirect(rw, r, "/r/"+m.Name+"/requests/"+id, http.StatusSeeOther) | ||
| 473 | // The parameter is how the page knows a landing just happened rather than a | ||
| 474 | // reader arriving: it is what makes a one-off celebration possible without | ||
| 475 | // replaying it on every visit, reload or shared link. | ||
| 476 | http.Redirect(rw, r, "/r/"+m.Name+"/requests/"+id+"?merged=1", http.StatusSeeOther) | ||
| 474 | 477 | } | |
| 475 | 478 | ||
| 476 | 479 | // closesField splits the closes input: spaces, commas and newlines all work, because | |