package fa import ( "context" "iter" "time" "github.com/PuerkitoBio/goquery" "git.anthrove.art/public/go-fa-api/internal/urls" ) // Comment is one entry from a submission's or journal's comment thread. // FA's beta theme renders the thread as a flat indented list; the parser // fills Depth and Parent so callers can rebuild the tree if needed. type Comment struct { ID CommentID Author UserRef PostedAt time.Time BodyHTML string BodyText string Depth int // 0 = top level Parent CommentID // 0 when Depth is 0 Deleted bool } // SubmissionComments yields every comment on a submission's view page. // Comments aren't paginated, so this iterator performs one fetch and then // yields each comment in document order; early termination still avoids // processing the rest of the slice. func (c *Client) SubmissionComments(ctx context.Context, id SubmissionID, opts ...Option) iter.Seq2[*Comment, error] { return c.yieldComments(ctx, urls.Submission(int64(id)), opts) } // JournalComments yields every comment on a journal page. Same iteration // shape as [Client.SubmissionComments]. func (c *Client) JournalComments(ctx context.Context, id JournalID, opts ...Option) iter.Seq2[*Comment, error] { return c.yieldComments(ctx, urls.Journal(int64(id)), opts) } // yieldComments performs the single fetch shared by submission and journal // comment iterators, then yields parsed comments to the caller. func (c *Client) yieldComments(ctx context.Context, pageURL string, opts []Option) iter.Seq2[*Comment, error] { return func(yield func(*Comment, error) bool) { var comments []*Comment err := c.fetch(ctx, pageURL, func(doc *goquery.Document) error { comments = parseComments(doc) return nil }, opts...) if err != nil { yield(nil, err) return } for _, cm := range comments { if !yield(cm, nil) { return } } } }