Search Apps Documentation Source Content File Folder Download Copy Actions Download

checkin.gno

1.71 Kb · 62 lines
 1// Package checkin is a public check-in board: anyone can check in once,
 2// the board records their address, and Render lists everyone so far.
 3package checkin
 4
 5import (
 6	"strconv"
 7	"strings"
 8
 9	"chain"
10
11	"gno.land/p/nt/avl/v0"
12)
13
14var (
15	checkins avl.Tree // caller address (bech32 string) -> arrival number (int)
16	total    int      // check-ins so far; assigns arrival numbers
17)
18
19// CheckIn records the caller's address on the board. Anyone may check in —
20// an EOA or another realm — but only once; a second check-in reverts.
21func CheckIn(cur realm) {
22	if !cur.IsCurrent() {
23		panic("invalid realm")
24	}
25	caller := cur.Previous().Address().String()
26	if checkins.Has(caller) {
27		panic("already checked in")
28	}
29	total++
30	checkins.Set(caller, total)
31	chain.Emit("CheckIn", "address", caller, "n", strconv.Itoa(total))
32}
33
34// Total returns the number of addresses checked in so far.
35func Total() int {
36	return checkins.Size()
37}
38
39// HasCheckedIn reports whether addr has checked in.
40func HasCheckedIn(addr address) bool {
41	return checkins.Has(addr.String())
42}
43
44// Render lists everyone checked in so far, sorted by address, with each
45// entry's arrival number. Only the home path is served.
46func Render(path string) string {
47	if path != "" {
48		return "> [!WARNING]\n> Path not found. Only the home page exists.\n"
49	}
50	var b strings.Builder
51	b.WriteString("# Check-in board\n\n")
52	if checkins.Size() == 0 {
53		b.WriteString("Nobody has checked in yet. Call `CheckIn` to be the first.\n")
54		return b.String()
55	}
56	b.WriteString(strconv.Itoa(checkins.Size()) + " checked in so far:\n\n")
57	checkins.Iterate("", "", func(key string, value any) bool {
58		b.WriteString("- `" + key + "` (#" + strconv.Itoa(value.(int)) + ")\n")
59		return false
60	})
61	return b.String()
62}