tiny 88x31 lexicon for atproto
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

like

+80 -5
-1
blobs/validation.go
··· 23 23 log.Println(err) 24 24 return false 25 25 } 26 - log.Println(cfg) 27 26 return cfg.Width == 88 && cfg.Height == 31 28 27 }
+1
handler/handler.go
··· 36 36 mux.HandleFunc("POST /logout", h.oauthMiddleware(h.logout)) 37 37 mux.HandleFunc("GET /upload", h.oauthMiddleware(getupload)) 38 38 mux.HandleFunc("POST /upload", h.oauthMiddleware(h.upload)) 39 + mux.HandleFunc("POST /like", h.oauthMiddleware(h.like)) 39 40 mux.HandleFunc("GET /button", h.oauthMiddleware(h.getbutton)) 40 41 mux.HandleFunc("GET /xrpc/store.88x31.getButton", h.WithCORS(h.getButton)) 41 42 mux.HandleFunc("GET /xrpc/store.88x31.getButtons", h.WithCORS(h.getButtons))
+47
handler/upload.go
··· 15 15 "tangled.org/moth11.net/88x31/types" 16 16 ) 17 17 18 + func (h *Handler) like(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) { 19 + if cs == nil { 20 + http.Error(w, "like requires auth", http.StatusUnauthorized) 21 + return 22 + } 23 + err := r.ParseForm() 24 + if err != nil { 25 + http.Error(w, "form failed to parse", http.StatusBadRequest) 26 + return 27 + } 28 + uri := r.FormValue("uri") 29 + if uri == "" { 30 + http.Error(w, "must provide uri, don't tamper with form", http.StatusBadRequest) 31 + return 32 + } 33 + cid := r.FormValue("cid") 34 + if cid == "" { 35 + http.Error(w, "must provide a cid, don't tamper with form", http.StatusBadRequest) 36 + return 37 + } 38 + var llr lex.LikeRecord 39 + lls := lex.LikeSubject{URI: uri, CID: cid} 40 + llr.Subject = lls 41 + nowsyn := syntax.DatetimeNow() 42 + llr.CreatedAt = nowsyn.String() 43 + luri, lcid, err := myoauth.CreateLike(cs, &llr, r.Context()) 44 + if err != nil { 45 + log.Println(err) 46 + http.Error(w, "error creating post", http.StatusInternalServerError) 47 + return 48 + } 49 + var like types.Like 50 + like.CID = lcid 51 + like.URI = luri 52 + like.CreatedAt = nowsyn.Time() 53 + like.SubjectCID = cid 54 + like.SubjectURI = uri 55 + like.DID = cs.Data.AccountDID.String() 56 + err = h.db.StoreLike(&like, r.Context()) 57 + if err != nil { 58 + log.Println(err) 59 + http.Error(w, "error storing like", http.StatusInternalServerError) 60 + return 61 + } 62 + http.Redirect(w, r, r.URL.Path, http.StatusCreated) 63 + } 64 + 18 65 func (h *Handler) upload(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) { 19 66 if cs == nil { 20 67 http.Error(w, "upload requires auth", http.StatusUnauthorized)
+20 -2
oauth/client.go
··· 49 49 return uploadResp.Blob, nil 50 50 } 51 51 52 - func CreateButton(cs *oauth.ClientSession, channel *lex.ButtonRecord, ctx context.Context) (uri string, cid string, err error) { 52 + func CreateButton(cs *oauth.ClientSession, button *lex.ButtonRecord, ctx context.Context) (uri string, cid string, err error) { 53 53 c := cs.APIClient() 54 54 body := map[string]any{ 55 55 "collection": "store.88x31.button", 56 56 "repo": *c.AccountDID, 57 - "record": channel, 57 + "record": button, 58 + } 59 + var out atproto.RepoCreateRecord_Output 60 + err = c.Post(ctx, "com.atproto.repo.createRecord", body, &out) 61 + if err != nil { 62 + err = errors.New("oops! failed to create a channel: " + err.Error()) 63 + return 64 + } 65 + uri = out.Uri 66 + cid = out.Cid 67 + return 68 + } 69 + 70 + func CreateLike(cs *oauth.ClientSession, like *lex.LikeRecord, ctx context.Context) (uri string, cid string, err error) { 71 + c := cs.APIClient() 72 + body := map[string]any{ 73 + "collection": "store.88x31.like", 74 + "repo": *c.AccountDID, 75 + "record": like, 58 76 } 59 77 var out atproto.RepoCreateRecord_Output 60 78 err = c.Post(ctx, "com.atproto.repo.createRecord", body, &out)
+7
tmpl/button.html
··· 1 1 {{define "content"}} 2 2 {{template "buttonpart" .Button}} 3 + {{if .DID}} 4 + <form action="/like" method="POST"> 5 + <input type="text" name="uri" value="{{.Button.URI}}" hidden /> 6 + <input type="text" name="cid" value="{{.Button.CID}}" hidden /> 7 + <input type="submit" value='"like"'/> 8 + </form> 9 + {{end}} 3 10 {{end}}
+5 -2
tmpl/home.html
··· 1 1 {{define "content"}} 2 2 {{range .Buttons}} 3 - {{template "buttonpart" .}} 4 - <a href="/upload">upload a button!</a> 3 + <div> 4 + {{template "buttonpart" .}} 5 + <a href="/button?uri={{.URI}}">view</a> 6 + </div> 5 7 {{else}} 6 8 no buttons yet, <a href="/upload">post the first!</a> 7 9 {{end}} 10 + <a href="/upload">upload a button!</a> 8 11 {{end}}