An experimental IndieWeb site built in Go.
1package posts
2
3import (
4 "encoding/json"
5 "fmt"
6
7 "github.com/puregarlic/space/models"
8 "github.com/samber/lo"
9 "go.hacdias.com/indielib/microformats"
10)
11
12var ImplementedPostTypes = []microformats.Type{
13 microformats.TypeNote,
14 microformats.TypePhoto,
15}
16
17func GetPostJSONProperty(post *models.Post, name string) []string {
18 var tmp map[string]any
19 if err := json.Unmarshal(post.Properties, &tmp); err != nil {
20 panic(err)
21 }
22
23 prop, ok := tmp[name]
24 if !ok {
25 return []string{""}
26 }
27
28 var out []string
29 for _, val := range prop.([]any) {
30 out = append(out, val.(string))
31 }
32
33 return out
34}
35
36func formatPostTypeName(mfType microformats.Type) string {
37 has := lo.ContainsBy(ImplementedPostTypes, func(postType microformats.Type) bool {
38 return postType == mfType
39 })
40
41 if has {
42 return string(mfType)
43 } else {
44 return fmt.Sprintf("%s (oops!)", string(mfType))
45 }
46}
47
48templ PostFeedHeader(post *models.Post) {
49 <div class="px-3 py-2 bg-surface text-xs text-muted flex items-center justify-between rounded-t border-2 border-b-0 border-overlay">
50 <p>{ post.Timestamp() }</p>
51 <p class="flex gap-1.5">
52 { formatPostTypeName(post.MicroformatType) }
53 <span class="text-muted/40">•</span>
54 <a
55 class="hover:underline hover:text-iris flex items-center gap-1 transition"
56 target="_blank"
57 rel="noopener noreferrer"
58 href={ templ.URL("/posts/" + post.ID.String()) }
59 >
60 open
61 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4 -mt-px">
62 <path d="M6.22 8.72a.75.75 0 0 0 1.06 1.06l5.22-5.22v1.69a.75.75 0 0 0 1.5 0v-3.5a.75.75 0 0 0-.75-.75h-3.5a.75.75 0 0 0 0 1.5h1.69L6.22 8.72Z"></path>
63 <path d="M3.5 6.75c0-.69.56-1.25 1.25-1.25H7A.75.75 0 0 0 7 4H4.75A2.75 2.75 0 0 0 2 6.75v4.5A2.75 2.75 0 0 0 4.75 14h4.5A2.75 2.75 0 0 0 12 11.25V9a.75.75 0 0 0-1.5 0v2.25c0 .69-.56 1.25-1.25 1.25h-4.5c-.69 0-1.25-.56-1.25-1.25v-4.5Z"></path>
64 </svg>
65 </a>
66 </p>
67 </div>
68}
69
70templ PostDetails(post *models.Post) {
71 <dl class="grid md:grid-cols-2 gap-4">
72 <div>
73 <dt class="mb-1 text-sm text-muted">Posted At</dt>
74 <dd class="text-subtle">{ post.Timestamp() }</dd>
75 </div>
76 <div>
77 <dt class="mb-1 text-sm text-muted">Post Type</dt>
78 <dd class="text-subtle">{ string(post.MicroformatType) }</dd>
79 </div>
80 </dl>
81}
82
83templ PostContent(post *models.Post) {
84 switch post.MicroformatType {
85 case microformats.TypePhoto:
86 @Photo(post)
87 case microformats.TypeNote:
88 @Note(post)
89 default:
90 @Unsupported(post)
91 }
92}