render.gno
2.95 Kb ยท 132 lines
1package events
2
3import (
4 "bytes"
5
6 "time"
7
8 "gno.land/p/demo/ufmt"
9 "gno.land/p/moul/md"
10)
11
12const (
13 MaxWidgetSize = 5
14)
15
16// RenderEventWidget shows up to eventsToRender of the latest events to a caller
17func RenderEventWidget(eventsToRender int) (string, error) {
18 numOfEvents := len(events)
19 if numOfEvents == 0 {
20 return "No events.", nil
21 }
22
23 if eventsToRender > MaxWidgetSize {
24 return "", ErrMaxWidgetSize
25 }
26
27 if eventsToRender < 1 {
28 return "", ErrMinWidgetSize
29 }
30
31 if eventsToRender > numOfEvents {
32 eventsToRender = numOfEvents
33 }
34
35 output := ""
36
37 for _, event := range events[:eventsToRender] {
38 output += ufmt.Sprintf("- [%s](%s)\n", event.name, event.link)
39 }
40
41 return output, nil
42}
43
44// renderHome renders the home page of the events realm
45func renderHome(admin bool) string {
46 output := "# gno.land events\n\n"
47
48 if len(events) == 0 {
49 output += "No upcoming or past events."
50 return output
51 }
52
53 output += "Below is a list of all gno.land events, including in progress, upcoming, and past ones.\n\n"
54 output += "---\n\n"
55
56 var (
57 inProgress []string
58 upcoming []string
59 past []string
60 now = time.Now()
61 )
62
63 for _, e := range events {
64 if now.Before(e.startTime) {
65 upcoming = append(upcoming, e.Render(admin))
66 } else if now.After(e.endTime) {
67 past = append(past, e.Render(admin))
68 } else {
69 inProgress = append(inProgress, e.Render(admin))
70 }
71 }
72
73 if len(upcoming) != 0 {
74 // Add upcoming events
75 output += "## Upcoming events\n\n"
76 output += md.ColumnsN(upcoming, 3, true)
77 output += "---\n\n"
78 }
79
80 if len(inProgress) != 0 {
81 output += "## Currently in progress\n\n"
82 output += md.ColumnsN(inProgress, 3, true)
83 output += "---\n\n"
84 }
85
86 if len(past) != 0 {
87 // Add past events
88 output += "## Past events\n\n"
89 output += md.ColumnsN(past, 3, true)
90 }
91
92 return output
93}
94
95// Render returns the markdown representation of a single event instance
96func (e Event) Render(admin bool) string {
97 var buf bytes.Buffer
98
99 buf.WriteString(ufmt.Sprintf("### %s\n\n", e.name))
100 buf.WriteString(ufmt.Sprintf("%s\n\n", e.description))
101 buf.WriteString(ufmt.Sprintf("**Location:** %s\n\n", e.location))
102
103 _, offset := e.startTime.Zone() // offset is in seconds
104 hoursOffset := offset / (60 * 60)
105 sign := ""
106 if offset >= 0 {
107 sign = "+"
108 }
109
110 buf.WriteString(ufmt.Sprintf("**Starts:** %s UTC%s%d\n\n", e.startTime.Format("02 Jan 2006, 03:04 PM"), sign, hoursOffset))
111 buf.WriteString(ufmt.Sprintf("**Ends:** %s UTC%s%d\n\n", e.endTime.Format("02 Jan 2006, 03:04 PM"), sign, hoursOffset))
112
113 if admin {
114 buf.WriteString(ufmt.Sprintf("[EDIT](/r/gnoland/events$help&func=EditEvent&id=%s)\n\n", e.id))
115 buf.WriteString(ufmt.Sprintf("[DELETE](/r/gnoland/events$help&func=DeleteEvent&id=%s)\n\n", e.id))
116 }
117
118 if e.link != "" {
119 buf.WriteString(ufmt.Sprintf("[See more](%s)\n\n", e.link))
120 }
121
122 return buf.String()
123}
124
125// Render is the main rendering entry point
126func Render(path string) string {
127 if path == "admin" {
128 return renderHome(true)
129 }
130
131 return renderHome(false)
132}