Skip to content

Commit 109fb07

Browse files
author
stackdump
authored
Merge pull request #90 from allinbits/feat/support-calendar-links
Feat/support calendar links
2 parents ed611f3 + daa44e4 commit 109fb07

File tree

18 files changed

+430
-319
lines changed

18 files changed

+430
-319
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package component
2+
3+
import (
4+
"net/url"
5+
"strings"
6+
"strconv"
7+
"time"
8+
9+
"gno.land/p/demo/ufmt"
10+
)
11+
12+
func CalenderDataUrl(path string, a *Flyer) string {
13+
if path == "" {
14+
path = "?format=ics"
15+
}
16+
data := IcsCalendarFile(path, a)
17+
return "data:text/calendar;charset=utf-8," + url.QueryEscape(data)
18+
}
19+
20+
func IcsCalendarFile(path string, a *Flyer) string {
21+
var f = ufmt.Sprintf
22+
var b strings.Builder
23+
w := func(s string) {
24+
b.WriteString(s + "\n")
25+
}
26+
27+
q := ParseQuery(path)
28+
sessionIDs := q["session"]
29+
format := strings.ToLower(q.Get("format"))
30+
31+
useAll := len(sessionIDs) == 0
32+
allowed := make(map[string]bool)
33+
for _, id := range sessionIDs {
34+
allowed[id] = true
35+
}
36+
include := func(id string) bool { return useAll || allowed[id] }
37+
38+
switch format {
39+
case "json":
40+
b.WriteString(a.ToJson())
41+
return b.String()
42+
43+
case "ics":
44+
w("BEGIN:VCALENDAR")
45+
w("VERSION:2.0")
46+
w("CALSCALE:GREGORIAN")
47+
w("PRODID:-//gno.land//Launch Calendar//EN")
48+
w("METHOD:PUBLISH\n")
49+
50+
w("BEGIN:VEVENT")
51+
w(f("UID:event-%s@%s", slugify(a.Name), "gno.land/r/buidlthefuture000/events/gnolandlaunch/calendar"))
52+
w("SEQUENCE:0")
53+
w(f("DTSTAMP:%s", time.Now().UTC().Format("20060102T150405Z")))
54+
w(f("DTSTART;VALUE=DATE:%s", a.StartDate.Format("20060102")))
55+
w(f("DTEND;VALUE=DATE:%s", a.StartDate.AddDate(0, 0, 1).Format("20060102"))) // 👈 Fix: DTEND is exclusive
56+
w(f("SUMMARY:%s", a.Name))
57+
w(f("DESCRIPTION:%s", a.Description))
58+
if a.Location != nil && a.Location.Name != "" {
59+
w(f("LOCATION:%s", a.Location.Name))
60+
}
61+
w("END:VEVENT\n")
62+
63+
for i, s := range a.Sessions {
64+
id := Pad3(strconv.Itoa(i))
65+
if !include(id) {
66+
continue
67+
}
68+
69+
w("BEGIN:VEVENT")
70+
w(f("UID:%s-%d@%s",
71+
slugify(s.Title)[:5],
72+
s.StartTime.Unix(),
73+
"gno.land/r/buidlthefuture000/events/gnolandlaunch/calendar",
74+
))
75+
w(f("SEQUENCE:%d", s.Sequence))
76+
w(f("DTSTAMP:%s", time.Now().UTC().Format("20060102T150405Z")))
77+
w(f("DTSTART:%s", s.StartTime.UTC().Format("20060102T150000Z")))
78+
w(f("DTEND:%s", s.EndTime.UTC().Format("20060102T150000Z")))
79+
w(f("SUMMARY:%s", s.Title))
80+
w(f("DESCRIPTION:%s", s.Description))
81+
w(f("LOCATION:%s", s.Location.Name))
82+
if s.Cancelled {
83+
w("STATUS:CANCELLED")
84+
}
85+
w("END:VEVENT\n")
86+
}
87+
88+
w("END:VCALENDAR")
89+
return b.String()
90+
91+
default:
92+
w(f("# %s\n\n%s", a.Name, a.Description))
93+
for i, s := range a.Sessions {
94+
id := Pad3(strconv.Itoa(i))
95+
if !include(id) {
96+
continue
97+
}
98+
w(s.ToMarkdown())
99+
}
100+
return b.String()
101+
}
102+
}

0 commit comments

Comments
 (0)