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