Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

moodstone.gno

3.99 Kb Β· 183 lines
  1package moodstone
  2
  3import (
  4	"chain/runtime"
  5	"chain/runtime/unsafe"
  6	"strconv"
  7	"strings"
  8)
  9
 10// Entry holds a single mood log.
 11type Entry struct {
 12	Author address
 13	Mood   string
 14	Note   string
 15	Block  int64
 16}
 17
 18var entries []Entry
 19
 20var validMoods = []string{"happy", "sad", "excited", "calm", "anxious", "angry", "neutral"}
 21
 22func isValid(mood string) bool {
 23	for _, m := range validMoods {
 24		if m == mood {
 25			return true
 26		}
 27	}
 28	return false
 29}
 30
 31func emoji(mood string) string {
 32	switch mood {
 33	case "happy":
 34		return "😊"
 35	case "sad":
 36		return "😒"
 37	case "excited":
 38		return "πŸŽ‰"
 39	case "calm":
 40		return "😌"
 41	case "anxious":
 42		return "😰"
 43	case "angry":
 44		return "😠"
 45	case "neutral":
 46		return "😐"
 47	}
 48	return "❓"
 49}
 50
 51func shortAddr(addr address) string {
 52	s := addr.String()
 53	if len(s) <= 12 {
 54		return s
 55	}
 56	return s[:6] + "…" + s[len(s)-4:]
 57}
 58
 59func bar(count, total int) string {
 60	if total == 0 {
 61		return strings.Repeat("β–‘", 20)
 62	}
 63	filled := (count * 20) / total
 64	return strings.Repeat("β–“", filled) + strings.Repeat("β–‘", 20-filled)
 65}
 66
 67// LogMood records the caller's current mood with an optional note.
 68// mood must be one of: happy sad excited calm anxious angry neutral
 69func LogMood(_ realm, mood, note string) {
 70	mood = strings.ToLower(strings.TrimSpace(mood))
 71	if !isValid(mood) {
 72		panic("invalid mood; choose from: " + strings.Join(validMoods, ", "))
 73	}
 74	entries = append(entries, Entry{
 75		Author: unsafe.OriginCaller(),
 76		Mood:   mood,
 77		Note:   strings.TrimSpace(note),
 78		Block:  runtime.ChainHeight(),
 79	})
 80}
 81
 82// TotalEntries returns the total number of mood logs on record.
 83func TotalEntries() int {
 84	return len(entries)
 85}
 86
 87// MoodCount returns how many times the given mood has been logged.
 88func MoodCount(mood string) int {
 89	mood = strings.ToLower(strings.TrimSpace(mood))
 90	n := 0
 91	for _, e := range entries {
 92		if e.Mood == mood {
 93			n++
 94		}
 95	}
 96	return n
 97}
 98
 99// DominantMood returns the most-logged mood, or "none" if no entries.
100func DominantMood() string {
101	if len(entries) == 0 {
102		return "none"
103	}
104	counts := make(map[string]int)
105	for _, e := range entries {
106		counts[e.Mood]++
107	}
108	best := ""
109	bestN := 0
110	for _, m := range validMoods {
111		if counts[m] > bestN {
112			bestN = counts[m]
113			best = m
114		}
115	}
116	return best
117}
118
119func Render(path string) string {
120	out := "# πŸͺ¨ Moodstone β€” On-chain Mood Tracker\n\n"
121	out += "> Log how you feel. Watch how the community feels. Immutably, on Gno.\n\n"
122
123	total := len(entries)
124
125	// Community stats table
126	out += "## πŸ“Š Community Vibes\n\n"
127	if total == 0 {
128		out += "*No moods logged yet β€” be the first!*\n\n"
129	} else {
130		counts := make(map[string]int)
131		for _, e := range entries {
132			counts[e.Mood]++
133		}
134		out += "| Mood | Count | Distribution |\n"
135		out += "|------|-------|--------------|\n"
136		for _, m := range validMoods {
137			c := counts[m]
138			pct := 0
139			if total > 0 {
140				pct = (c * 100) / total
141			}
142			out += "| " + emoji(m) + " " + m + " | " + strconv.Itoa(c) +
143				" | `" + bar(c, total) + "` " + strconv.Itoa(pct) + "% |\n"
144		}
145		dom := DominantMood()
146		out += "\n**Total entries:** " + strconv.Itoa(total) +
147			" Β· **Dominant mood:** " + emoji(dom) + " " + dom + "\n\n"
148	}
149
150	// Recent entries (newest first, max 10)
151	out += "## πŸ“ Recent Entries\n\n"
152	if total == 0 {
153		out += "*Nothing here yet.*\n\n"
154	} else {
155		start := total - 10
156		if start < 0 {
157			start = 0
158		}
159		for i := total - 1; i >= start; i-- {
160			e := entries[i]
161			line := "- " + emoji(e.Mood) + " **" + e.Mood + "**"
162			if e.Note != "" {
163				line += ": *" + e.Note + "*"
164			}
165			line += " β€” `" + shortAddr(e.Author) + "` at block " +
166				strconv.FormatInt(e.Block, 10)
167			out += line + "\n"
168		}
169		out += "\n"
170	}
171
172	// How to use
173	out += "## πŸš€ How to Use\n\n"
174	out += "```bash\n"
175	out += "gnokey maketx call \\\n"
176	out += "  -pkgpath gno.land/r/g12cs4cehujpffpjpywmkqj43m6u5ya53nj69sjz/moodstone \\\n"
177	out += "  -func LogMood \\\n"
178	out += "  -args 'happy' -args 'Just shipped something awesome!'\n"
179	out += "```\n\n"
180	out += "**Valid moods:** " + strings.Join(validMoods, " Β· ") + "\n"
181
182	return out
183}