reactionbar.go
| 1 | package views |
| 2 | |
| 3 | import ( |
| 4 | "strconv" |
| 5 | |
| 6 | "hearthforge/internal/db" |
| 7 | |
| 8 | g "maragu.dev/gomponents" |
| 9 | . "maragu.dev/gomponents/html" |
| 10 | ) |
| 11 | |
| 12 | // AllowedReactions are the emoji a user may react with, in picker order. |
| 13 | var AllowedReactions = []string{"👍", "👎", "❤️", "🎉", "😕", "👀", "🚀"} |
| 14 | |
| 15 | // ReactionCount is one emoji with its total and whether the viewer reacted. |
| 16 | type ReactionCount struct { |
| 17 | Emoji string |
| 18 | Count int |
| 19 | UserReacted bool |
| 20 | } |
| 21 | |
| 22 | // ReactionBar renders the reaction buttons and the picker. |
| 23 | // commentID is 0 for the issue or patch body itself. |
| 24 | func ReactionBar(reactions []ReactionCount, postURL string, commentID int64, user *db.SessionUser) g.Node { |
| 25 | if user == nil && len(reactions) == 0 { |
| 26 | return nil |
| 27 | } |
| 28 | existing := make(map[string]bool, len(reactions)) |
| 29 | for _, r := range reactions { |
| 30 | existing[r.Emoji] = true |
| 31 | } |
| 32 | commentInput := func() g.Node { |
| 33 | return g.If(commentID != 0, |
| 34 | Input(Type("hidden"), Name("comment_id"), Value(strconv.FormatInt(commentID, 10)))) |
| 35 | } |
| 36 | return Div(Class("reaction-bar"), |
| 37 | g.Map(reactions, func(r ReactionCount) g.Node { |
| 38 | class := "reaction-btn" |
| 39 | if r.UserReacted { |
| 40 | class += " reacted" |
| 41 | } |
| 42 | return Form(Method("POST"), Action(postURL), Class("reaction-form"), |
| 43 | commentInput(), |
| 44 | Input(Type("hidden"), Name("emoji"), Value(r.Emoji)), |
| 45 | Button(Type("submit"), Class(class), g.If(user == nil, Disabled()), |
| 46 | g.Text(r.Emoji+" "+strconv.Itoa(r.Count))), |
| 47 | ) |
| 48 | }), |
| 49 | g.If(user != nil, |
| 50 | Details(Class("reaction-picker"), |
| 51 | Summary(Class("reaction-add-btn"), g.Text("+")), |
| 52 | Div(Class("reaction-picker-dropdown"), |
| 53 | g.Map(AllowedReactions, func(e string) g.Node { |
| 54 | if existing[e] { |
| 55 | return nil |
| 56 | } |
| 57 | return Form(Method("POST"), Action(postURL), Class("reaction-form"), |
| 58 | commentInput(), |
| 59 | Input(Type("hidden"), Name("emoji"), Value(e)), |
| 60 | Button(Type("submit"), Class("reaction-picker-btn"), g.Text(e)), |
| 61 | ) |
| 62 | }), |
| 63 | ), |
| 64 | )), |
| 65 | ) |
| 66 | } |
| 67 |