Yōten: A social tracker for your language learning journey built on the atproto.
1package partials
2
3import "fmt"
4
5templ Comment(params CommentProps) {
6 {{ elementId := SanitiseHtmlId(fmt.Sprintf("comment-%s-%s", params.Comment.Did, params.Comment.Rkey)) }}
7 <div id={ elementId } class="flex flex-col gap-3" x-init="lucide.createIcons()">
8 <div class="flex items-center justify-between">
9 <div class="flex items-center gap-3">
10 if params.Comment.BskyProfile.Avatar == "" {
11 <div class="flex items-center justify-center w-10 h-10 rounded-full bg-primary">
12 <i class="w-7 h-7" data-lucide="user"></i>
13 </div>
14 } else {
15 <img src={ params.Comment.BskyProfile.Avatar } class="w-10 h-10 rounded-full"/>
16 }
17 <div>
18 <div class="flex items-center gap-2">
19 <a href={ templ.URL(fmt.Sprintf("/%s", params.Comment.Did)) } class="font-semibold">
20 { params.Comment.ProfileDisplayName }
21 </a>
22 <p class="pill pill-secondary px-2 py-0.5 h-fit items-center justify-center gap-1 w-fit flex">
23 <i class="w-3.5 h-3.5" data-lucide="star"></i>
24 <span class="text-xs">{ params.Comment.ProfileLevel }</span>
25 </p>
26 <span class="text-xs text-text-muted">{ params.Comment.CreatedAt.Format("2006-01-02") }</span>
27 </div>
28 <p class="text-text-muted text-sm">@{ params.Comment.BskyProfile.Handle }</p>
29 </div>
30 </div>
31 if params.DoesOwn {
32 <details class="relative inline-block text-left">
33 <summary class="cursor-pointer list-none">
34 <div class="btn btn-muted p-2">
35 <i class="w-4 h-4 flex-shrink-0" data-lucide="ellipsis"></i>
36 </div>
37 </summary>
38 <div class="absolute flex flex-col right-0 mt-2 p-1 gap-1 rounded w-32 bg-bg-light border border-bg-dark">
39 <button
40 class="btn hover:bg-bg group justify-start px-2"
41 type="button"
42 id="edit-button"
43 hx-disabled-elt="#delete-button,#edit-button"
44 hx-target={ fmt.Sprintf("#comment-body-%s-%s", SanitiseHtmlId(params.Comment.Did), SanitiseHtmlId(params.Comment.Rkey)) }
45 hx-swap="innerHTML"
46 hx-get={ templ.URL(fmt.Sprintf("/comment/edit/%s", params.Comment.Rkey)) }
47 >
48 <i class="w-4 h-4" data-lucide="square-pen"></i>
49 <span class="text-sm">Edit</span>
50 <i class="w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" data-lucide="loader-circle"></i>
51 </button>
52 <button
53 class="btn text-red-600 hover:bg-bg group justify-start px-2"
54 type="button"
55 id="delete-button"
56 hx-disabled-elt="#delete-button,#edit-button"
57 hx-target={ "#" + elementId }
58 hx-swap="outerHTML"
59 hx-delete={ templ.URL(fmt.Sprintf("/comment/%s", params.Comment.Rkey)) }
60 >
61 <i class="w-4 h-4" data-lucide="trash-2"></i>
62 <span class="text-sm">Delete</span>
63 <i class="w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" data-lucide="loader-circle"></i>
64 </button>
65 </div>
66 </details>
67 }
68 </div>
69 <p
70 id={ fmt.Sprintf("comment-body-%s-%s", SanitiseHtmlId(params.Comment.Did), SanitiseHtmlId(params.Comment.Rkey)) }
71 class="leading-relaxed break-words"
72 >
73 { params.Comment.Body }
74 </p>
75 <button
76 hx-swap="afterend"
77 id="reply-button"
78 type="button"
79 hx-get={ templ.URL(fmt.Sprintf("/comment/reply?root=%s&parent=%s", params.Comment.StudySessionUri.String(), params.Comment.CommentAt().String())) }
80 class="btn text-xs text-text-muted self-start w-fit p-0"
81 >
82 Reply
83 </button>
84 <div class="flex flex-col mt-2">
85 for _, reply := range params.Comment.Replies {
86 {{ isSelf := params.User != nil && params.User.Did == reply.Did }}
87 @Reply(ReplyProps{
88 Reply: reply,
89 DoesOwn: isSelf,
90 })
91 }
92 </div>
93 </div>
94}