2023-01-20 10:10:13 +00:00
|
|
|
|
package plugins
|
2023-01-26 16:07:42 +00:00
|
|
|
|
|
|
|
|
|
import (
|
2023-12-20 14:30:55 +00:00
|
|
|
|
"context"
|
2023-05-04 12:37:06 +00:00
|
|
|
|
"github.com/fthvgb1/wp-go/app/pkg/models"
|
|
|
|
|
"github.com/fthvgb1/wp-go/app/wpconfig"
|
2023-12-20 14:30:55 +00:00
|
|
|
|
"github.com/fthvgb1/wp-go/helper/number"
|
2023-01-26 16:07:42 +00:00
|
|
|
|
"github.com/fthvgb1/wp-go/helper/slice"
|
2023-02-16 03:53:24 +00:00
|
|
|
|
str "github.com/fthvgb1/wp-go/helper/strings"
|
2023-01-26 16:07:42 +00:00
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
|
"strconv"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type CommentHandler struct {
|
|
|
|
|
*gin.Context
|
2023-12-20 14:30:55 +00:00
|
|
|
|
comments []*Comments
|
|
|
|
|
maxDepth int
|
|
|
|
|
depth int
|
|
|
|
|
isTls bool
|
|
|
|
|
i CommentHtml
|
|
|
|
|
isThreadComments bool
|
2023-01-26 16:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Comments struct {
|
|
|
|
|
models.Comments
|
|
|
|
|
Children []*Comments
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CommentHtml interface {
|
2023-12-20 14:30:55 +00:00
|
|
|
|
FormatLi(c context.Context, m models.Comments, depth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string
|
|
|
|
|
FloorOrder(wpOrder string, i, j models.PostComments) bool
|
2023-01-26 16:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func FormatComments(c *gin.Context, i CommentHtml, comments []models.Comments, maxDepth int) string {
|
|
|
|
|
tree := treeComments(comments)
|
2023-08-26 14:01:20 +00:00
|
|
|
|
|
2023-01-30 12:48:30 +00:00
|
|
|
|
var isTls bool
|
2023-08-26 14:01:20 +00:00
|
|
|
|
if c.Request.TLS != nil {
|
|
|
|
|
isTls = true
|
|
|
|
|
} else {
|
|
|
|
|
isTls = "https" == strings.ToLower(c.Request.Header.Get("X-Forwarded-Proto"))
|
2023-01-30 12:48:30 +00:00
|
|
|
|
}
|
2023-01-26 16:07:42 +00:00
|
|
|
|
h := CommentHandler{
|
|
|
|
|
Context: c,
|
|
|
|
|
comments: tree,
|
|
|
|
|
maxDepth: maxDepth,
|
|
|
|
|
depth: 1,
|
2023-01-30 12:48:30 +00:00
|
|
|
|
isTls: isTls,
|
2023-01-26 16:07:42 +00:00
|
|
|
|
i: i,
|
|
|
|
|
}
|
2023-12-20 14:30:55 +00:00
|
|
|
|
return h.formatComment(h.comments)
|
2023-01-26 16:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-12-20 14:30:55 +00:00
|
|
|
|
func (d CommentHandler) formatComment(comments []*Comments) (html string) {
|
2023-02-16 03:53:24 +00:00
|
|
|
|
s := str.NewBuilder()
|
2023-12-12 10:59:08 +00:00
|
|
|
|
if d.depth >= d.maxDepth {
|
2023-01-26 16:07:42 +00:00
|
|
|
|
comments = d.findComments(comments)
|
|
|
|
|
}
|
2023-12-12 10:59:08 +00:00
|
|
|
|
order := wpconfig.GetOption("comment_order")
|
|
|
|
|
slice.Sort(comments, func(i, j *Comments) bool {
|
|
|
|
|
if order == "asc" {
|
|
|
|
|
return i.CommentDate.Sub(j.CommentDate) < 0
|
|
|
|
|
}
|
|
|
|
|
return i.CommentDate.Sub(j.CommentDate) > 0
|
|
|
|
|
})
|
2023-01-26 16:07:42 +00:00
|
|
|
|
for i, comment := range comments {
|
|
|
|
|
eo := "even"
|
|
|
|
|
if (i+1)%2 == 0 {
|
|
|
|
|
eo = "odd"
|
|
|
|
|
}
|
|
|
|
|
parent := ""
|
|
|
|
|
fl := false
|
|
|
|
|
if len(comment.Children) > 0 && d.depth < d.maxDepth+1 {
|
|
|
|
|
parent = "parent"
|
|
|
|
|
fl = true
|
|
|
|
|
}
|
2023-12-20 14:30:55 +00:00
|
|
|
|
s.WriteString(d.i.FormatLi(d.Context, comment.Comments, d.depth, d.maxDepth, 1, d.isTls, d.isThreadComments, eo, parent))
|
2023-01-26 16:07:42 +00:00
|
|
|
|
if fl {
|
|
|
|
|
d.depth++
|
2023-12-20 14:30:55 +00:00
|
|
|
|
s.WriteString(`<ol class="children">`, d.formatComment(comment.Children), `</ol>`)
|
|
|
|
|
d.depth--
|
2023-01-26 16:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
s.WriteString("</li><!-- #comment-## -->")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
html = s.String()
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (d CommentHandler) findComments(comments []*Comments) []*Comments {
|
|
|
|
|
var r []*Comments
|
|
|
|
|
for _, comment := range comments {
|
|
|
|
|
tmp := *comment
|
2023-12-12 10:59:08 +00:00
|
|
|
|
tmp.Children = nil
|
2023-01-26 16:07:42 +00:00
|
|
|
|
r = append(r, &tmp)
|
|
|
|
|
if len(comment.Children) > 0 {
|
|
|
|
|
t := d.findComments(comment.Children)
|
|
|
|
|
r = append(r, t...)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func treeComments(comments []models.Comments) []*Comments {
|
|
|
|
|
var r = map[uint64]*Comments{
|
|
|
|
|
0: {
|
|
|
|
|
Comments: models.Comments{},
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
var top []*Comments
|
|
|
|
|
for _, comment := range comments {
|
|
|
|
|
c := Comments{
|
|
|
|
|
Comments: comment,
|
|
|
|
|
Children: []*Comments{},
|
|
|
|
|
}
|
|
|
|
|
r[comment.CommentId] = &c
|
|
|
|
|
if comment.CommentParent == 0 {
|
|
|
|
|
top = append(top, &c)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for id, son := range r {
|
|
|
|
|
if id == son.CommentParent {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
parent := r[son.CommentParent]
|
|
|
|
|
parent.Children = append(parent.Children, son)
|
|
|
|
|
}
|
|
|
|
|
return top
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func CommonLi() string {
|
|
|
|
|
return li
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var commonCommentFormat = CommonCommentFormat{}
|
|
|
|
|
|
|
|
|
|
func CommentRender() CommonCommentFormat {
|
|
|
|
|
return commonCommentFormat
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type CommonCommentFormat struct {
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-20 14:30:55 +00:00
|
|
|
|
func (c CommonCommentFormat) FormatLi(_ context.Context, m models.Comments, currentDepth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string {
|
|
|
|
|
return FormatLi(CommonLi(), m, currentDepth, maxDepth, page, isTls, isThreadComments, eo, parent)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c CommonCommentFormat) FloorOrder(wpOrder string, i, j models.PostComments) bool {
|
|
|
|
|
return i.CommentId > j.CommentId
|
|
|
|
|
}
|
|
|
|
|
func respond(m models.Comments, isShow bool) string {
|
|
|
|
|
if !isShow {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
pId := number.IntToString(m.CommentPostId)
|
|
|
|
|
cId := number.IntToString(m.CommentId)
|
|
|
|
|
return str.Replace(respondTml, map[string]string{
|
|
|
|
|
"{{PostId}}": pId,
|
|
|
|
|
"{{CommentId}}": cId,
|
|
|
|
|
"{{CommentAuthor}}": m.CommentAuthor,
|
|
|
|
|
})
|
2023-01-26 16:07:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var li = `
|
|
|
|
|
<li id="comment-{{CommentId}}" class="comment {{eo}} thread-even depth-{{Depth}} {{parent}}">
|
|
|
|
|
<article id="div-comment-{{CommentId}}" class="comment-body">
|
|
|
|
|
<footer class="comment-meta">
|
|
|
|
|
<div class="comment-author vcard">
|
|
|
|
|
<img alt=""
|
|
|
|
|
src="{{Gravatar}}"
|
|
|
|
|
srcset="{{Gravatar}} 2x"
|
|
|
|
|
class="avatar avatar-56 photo" height="56" width="56" loading="lazy">
|
2023-12-20 14:30:55 +00:00
|
|
|
|
<b class="fn">{{CommentAuthor}}</b>
|
2023-01-26 16:07:42 +00:00
|
|
|
|
<span class="says">说道:</span></div><!-- .comment-author -->
|
|
|
|
|
|
|
|
|
|
<div class="comment-metadata">
|
2023-12-20 14:30:55 +00:00
|
|
|
|
<a href="/p/{{PostId}}/comment-page-{{page}}#comment-{{CommentId}}">
|
2023-01-26 16:07:42 +00:00
|
|
|
|
<time datetime="{{CommentDateGmt}}">{{CommentDate}}</time>
|
|
|
|
|
</a></div><!-- .comment-metadata -->
|
|
|
|
|
|
|
|
|
|
</footer><!-- .comment-meta -->
|
|
|
|
|
|
|
|
|
|
<div class="comment-content">
|
|
|
|
|
<p>{{CommentContent}}</p>
|
|
|
|
|
</div><!-- .comment-content -->
|
|
|
|
|
|
2023-12-20 14:30:55 +00:00
|
|
|
|
{{respond}}
|
|
|
|
|
</article><!-- .comment-body -->
|
|
|
|
|
|
|
|
|
|
`
|
|
|
|
|
|
|
|
|
|
var respondTml = `<div class="reply">
|
2023-01-26 16:07:42 +00:00
|
|
|
|
<a rel="nofollow" class="comment-reply-link"
|
|
|
|
|
href="/p/{{PostId}}?replytocom={{CommentId}}#respond" data-commentid="{{CommentId}}" data-postid="{{PostId}}"
|
|
|
|
|
data-belowelement="div-comment-{{CommentId}}" data-respondelement="respond"
|
|
|
|
|
data-replyto="回复给{{CommentAuthor}}"
|
|
|
|
|
aria-label="回复给{{CommentAuthor}}">回复</a>
|
2023-12-20 14:30:55 +00:00
|
|
|
|
</div>`
|
2023-01-26 16:07:42 +00:00
|
|
|
|
|
2023-12-20 14:30:55 +00:00
|
|
|
|
func FormatLi(li string, comments models.Comments, currentDepth, maxDepth, page int, isTls, isThreadComments bool, eo, parent string) string {
|
|
|
|
|
isShow := false
|
|
|
|
|
if isThreadComments && currentDepth < maxDepth {
|
|
|
|
|
isShow = true
|
|
|
|
|
}
|
2023-01-26 16:07:42 +00:00
|
|
|
|
for k, v := range map[string]string{
|
|
|
|
|
"{{CommentId}}": strconv.FormatUint(comments.CommentId, 10),
|
2023-12-20 14:30:55 +00:00
|
|
|
|
"{{Depth}}": strconv.Itoa(currentDepth),
|
2023-01-30 12:48:30 +00:00
|
|
|
|
"{{Gravatar}}": Gravatar(comments.CommentAuthorEmail, isTls),
|
2023-01-26 16:07:42 +00:00
|
|
|
|
"{{CommentAuthorUrl}}": comments.CommentAuthorUrl,
|
|
|
|
|
"{{CommentAuthor}}": comments.CommentAuthor,
|
|
|
|
|
"{{PostId}}": strconv.FormatUint(comments.CommentPostId, 10),
|
2023-12-20 14:30:55 +00:00
|
|
|
|
"{{page}}": strconv.Itoa(page),
|
2023-01-26 16:07:42 +00:00
|
|
|
|
"{{CommentDateGmt}}": comments.CommentDateGmt.String(),
|
|
|
|
|
"{{CommentDate}}": comments.CommentDate.Format("2006-01-02 15:04"),
|
|
|
|
|
"{{CommentContent}}": comments.CommentContent,
|
|
|
|
|
"{{eo}}": eo,
|
|
|
|
|
"{{parent}}": parent,
|
2023-12-20 14:30:55 +00:00
|
|
|
|
"{{respond}}": respond(comments, isShow),
|
2023-01-26 16:07:42 +00:00
|
|
|
|
} {
|
|
|
|
|
li = strings.Replace(li, k, v, -1)
|
|
|
|
|
}
|
|
|
|
|
return li
|
|
|
|
|
}
|