carlos / movement Public

Clone
git clone https://amadan.net/carlos/movement

Plain git — no account needed to clone.

Download

Download this file

1package movement
2
3import (
4 "net/http"
5 "time"
6)
7
8// stanceData is what a stance page needs to render its form.
9//
10// The challenge travels as four hidden fields. Nothing is written when it is
11// minted — the seal already proves the server issued it, so a row per page
12// view would buy nothing and would turn any crawler into a stream of
13// serialised writes against the one SQLite writer every signup needs.
14type stanceData struct {
15 Stance string
16 // Message is the response to this position, split into paragraphs. Copy
17 // is written the way a person writes it, with the breaks meant; rendered
18 // as one string they collapse into a wall.
19 Message []string
20 // Disclosure is set only where a stance's reply carries one. Today that
21 // is the all-in page, whose reply is the model's output handed over
22 // verbatim — the note says so, under the text it describes.
23 Disclosure string
24 Challenge Challenge
25 Honeypot string
26 Error string
27}
28
29// stancePage renders one of the three positions and the form beneath it.
30//
31// Addressed by reviewed slug — /no-ai, /uneasy, /all-in — while the value
32// stored against a signup stays the internal key. Anyone who shares a link
33// shares the slug, so it is copy; the stored key has to outlive any wording
34// change or every row already written means something different afterwards.
35func (a *app) stancePage(stance Stance) http.HandlerFunc {
36 return func(w http.ResponseWriter, r *http.Request) {
37 a.renderStance(w, stance, "")
38 }
39}
40
41func (a *app) renderStance(w http.ResponseWriter, stance Stance, errMsg string) {
42 disclosure := ""
43 if stance == StanceEnthusiast {
44 disclosure = T("stance.enthusiast.disclosure")
45 }
46 render(w, "stance", stanceData{
47 Stance: string(stance),
48 Message: Paragraphs("stance." + string(stance) + ".message"),
49 Disclosure: disclosure,
50 Challenge: NewChallenge(a.challengeKey, time.Now(), DefaultDifficulty),
51 Honeypot: honeypotField,
52 Error: errMsg,
53 })
54}
55
56// renderSent is the page every submission ends on: accepted, suppressed,
57// replayed, already confirmed, or refused. One page, one set of bytes.
58func (a *app) renderSent(w http.ResponseWriter) {
59 render(w, "sent", nil)
60}
61