package components
import (
"fmt"
"net/url"
"tangled.org/oolong.social/oolong/internal/firehose"
"tangled.org/oolong.social/oolong/internal/web/bff"
)
// CommentButtonProps defines properties for the comment button
type CommentButtonProps struct {
SubjectURI string // AT-URI of the record to comment on
SubjectCID string // CID of the record
CommentCount int // Number of comments on this record
IsAuthenticated bool // Whether the user is authenticated
}
// CommentButton renders a comment button with count that links to comments section
templ CommentButton(props CommentButtonProps) {
}
// CommentModerationContext holds moderation state for rendering comment actions
type CommentModerationContext struct {
IsModerator bool // User has moderator role
CanHideRecord bool // User has hide_record permission
CanBlockUser bool // User has blacklist_user permission
}
// CommentSectionProps defines properties for the comment section
type CommentSectionProps struct {
SubjectURI string // AT-URI of the record
SubjectCID string // CID of the record
Comments []firehose.IndexedComment // List of comments (threaded order with depth)
IsAuthenticated bool // Whether the user is authenticated
CurrentUserDID string // DID of the current user (for delete buttons)
ModCtx CommentModerationContext // Moderation context for comment actions
ViewURL string // URL of the parent brew (for sharing comments)
}
// CommentSection renders the full comment section with list and form
templ CommentSection(props CommentSectionProps) {
}
// CommentFormProps defines properties for the comment form
type CommentFormProps struct {
SubjectURI string // AT-URI of the record
SubjectCID string // CID of the record
}
// CommentForm renders a form for creating new comments
templ CommentForm(props CommentFormProps) {
}
// CommentListProps defines properties for the comment list
type CommentListProps struct {
Comments []firehose.IndexedComment // List of comments (threaded order with depth)
CurrentUserDID string // DID of the current user (for delete buttons)
SubjectURI string // AT-URI of the root subject (for reply forms)
SubjectCID string // CID of the root subject (for reply forms)
IsAuthenticated bool // Whether the user is authenticated (for reply buttons)
ModCtx CommentModerationContext // Moderation context for comment actions
ViewURL string // URL of the parent brew (for sharing comments)
}
// CommentList renders a list of comments with threading support
templ CommentList(props CommentListProps) {
}
// CommentItemProps defines properties for a single comment
type CommentItemProps struct {
Comment firehose.IndexedComment
CanDelete bool // Whether the current user can delete this comment
CanReply bool // Whether the user can reply (authenticated and depth < 2)
IsOwner bool // Whether the current user owns this comment
SubjectURI string // AT-URI of the root subject (for reply form)
SubjectCID string // CID of the root subject (for reply form)
IsAuthenticated bool // Whether the user is authenticated
ModCtx CommentModerationContext // Moderation context for comment actions
ViewURL string // URL of the parent brew (for sharing)
}
// CommentItem renders a single comment with optional threading indentation
templ CommentItem(props CommentItemProps) {
if props.Comment.Depth > 0 {
}
}
// ReplyFormProps defines properties for the reply form
type ReplyFormProps struct {
SubjectURI string // AT-URI of the root subject
SubjectCID string // CID of the root subject
ParentURI string // AT-URI of the parent comment
ParentCID string // CID of the parent comment
}
// ReplyForm renders a compact inline reply form
templ ReplyForm(props ReplyFormProps) {
}
// Helper functions for comment display
func getCommentHandle(comment firehose.IndexedComment) string {
if comment.Handle != "" {
return comment.Handle
}
return comment.ActorDID
}
func getCommentDisplayName(comment firehose.IndexedComment) string {
if comment.DisplayName != nil {
return *comment.DisplayName
}
return ""
}
func getCommentAvatarURL(comment firehose.IndexedComment) string {
if comment.Avatar != nil {
return *comment.Avatar
}
return ""
}
// getDepthClass returns the CSS class for comment depth
func getDepthClass(depth int) string {
switch depth {
case 1:
return "comment-depth-1"
case 2:
return "comment-depth-2"
default:
return ""
}
}
// getCommentShareURL returns the share URL for a comment, linking to the comment anchor on the brew page
func getCommentShareURL(viewURL string, comment firehose.IndexedComment) string {
if viewURL == "" {
return ""
}
return viewURL + "#comment-" + comment.RKey
}
// buildCommentURI constructs the AT-URI for a comment from its indexed data
func buildCommentURI(comment firehose.IndexedComment) string {
// The subject URI contains the DID, format: at://did:plc:xxx/social.oolong.alpha.brew/rkey
// We need to extract the DID and build a comment URI: at://did:plc:xxx/social.oolong.alpha.comment/rkey
return fmt.Sprintf("at://%s/social.oolong.alpha.comment/%s", comment.ActorDID, comment.RKey)
}
func commentActionURL(subjectURI, subjectCID string) string {
values := url.Values{}
values.Set("subject_uri", subjectURI)
values.Set("subject_cid", subjectCID)
return "/api/comments?" + values.Encode()
}
No comments yet
Be the first to share your thoughts