From b56d7cdad043643747d5e293e42587fd26e4f304 Mon Sep 17 00:00:00 2001 From: LinkinStar Date: Tue, 31 Jan 2023 11:44:29 +0800 Subject: [PATCH 1/2] feat(comment): Notification of comments based on different priorities --- internal/service/comment/comment_service.go | 78 ++++++++++++++------- 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/internal/service/comment/comment_service.go b/internal/service/comment/comment_service.go index cb45c7d1..18b755ab 100644 --- a/internal/service/comment/comment_service.go +++ b/internal/service/comment/comment_service.go @@ -121,34 +121,14 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment return nil, err } - if objInfo.ObjectType == constant.QuestionObjectType { - cs.notificationQuestionComment(ctx, objInfo.ObjectCreatorUserID, - objInfo.QuestionID, objInfo.Title, comment.ID, req.UserID, comment.OriginalText) - } else if objInfo.ObjectType == constant.AnswerObjectType { - cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID, - objInfo.ObjectCreatorUserID, comment.ID, req.UserID, comment.OriginalText) - } - if len(req.MentionUsernameList) > 0 { - cs.notificationMention(ctx, req.MentionUsernameList, comment.ID, req.UserID) - } - resp = &schema.GetCommentResp{} resp.SetFromComment(comment) resp.MemberActions = permission.GetCommentPermission(ctx, req.UserID, resp.UserID, time.Now(), req.CanEdit, req.CanDelete) - // get reply user info - if len(resp.ReplyUserID) > 0 && resp.ReplyUserID != req.UserID { - replyUser, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.ReplyUserID) - if err != nil { - return nil, err - } - if exist { - resp.ReplyUsername = replyUser.Username - resp.ReplyUserDisplayName = replyUser.DisplayName - resp.ReplyUserStatus = replyUser.Status - } - cs.notificationCommentReply(ctx, replyUser.ID, comment.ID, req.UserID) + commentResp, err := cs.addCommentNotification(ctx, req, resp, comment, objInfo) + if err != nil { + return commentResp, err } // get user info @@ -179,6 +159,50 @@ func (cs *CommentService) AddComment(ctx context.Context, req *schema.AddComment return resp, nil } +func (cs *CommentService) addCommentNotification( + ctx context.Context, req *schema.AddCommentReq, resp *schema.GetCommentResp, + comment *entity.Comment, objInfo *schema.SimpleObjectInfo) (*schema.GetCommentResp, error) { + // The priority of the notification + // 1. reply to user + // 2. comment mention to user + // 3. answer or question was commented + alreadyNotifiedUserID := make(map[string]bool) + + // get reply user info + if len(resp.ReplyUserID) > 0 && resp.ReplyUserID != req.UserID { + replyUser, exist, err := cs.userCommon.GetUserBasicInfoByID(ctx, resp.ReplyUserID) + if err != nil { + return nil, err + } + if exist { + resp.ReplyUsername = replyUser.Username + resp.ReplyUserDisplayName = replyUser.DisplayName + resp.ReplyUserStatus = replyUser.Status + } + cs.notificationCommentReply(ctx, replyUser.ID, comment.ID, req.UserID) + alreadyNotifiedUserID[replyUser.ID] = true + return nil, nil + } + + if len(req.MentionUsernameList) > 0 { + alreadyNotifiedUserIDs := cs.notificationMention( + ctx, req.MentionUsernameList, comment.ID, req.UserID, alreadyNotifiedUserID) + for _, userID := range alreadyNotifiedUserIDs { + alreadyNotifiedUserID[userID] = true + } + return nil, nil + } + + if objInfo.ObjectType == constant.QuestionObjectType && !alreadyNotifiedUserID[objInfo.ObjectCreatorUserID] { + cs.notificationQuestionComment(ctx, objInfo.ObjectCreatorUserID, + objInfo.QuestionID, objInfo.Title, comment.ID, req.UserID, comment.OriginalText) + } else if objInfo.ObjectType == constant.AnswerObjectType && !alreadyNotifiedUserID[objInfo.ObjectCreatorUserID] { + cs.notificationAnswerComment(ctx, objInfo.QuestionID, objInfo.Title, objInfo.AnswerID, + objInfo.ObjectCreatorUserID, comment.ID, req.UserID, comment.OriginalText) + } + return nil, nil +} + // RemoveComment delete comment func (cs *CommentService) RemoveComment(ctx context.Context, req *schema.RemoveCommentReq) (err error) { return cs.commentRepo.RemoveComment(ctx, req.CommentID) @@ -536,14 +560,16 @@ func (cs *CommentService) notificationCommentReply(ctx context.Context, replyUse notice_queue.AddNotification(msg) } -func (cs *CommentService) notificationMention(ctx context.Context, mentionUsernameList []string, commentID, commentUserID string) { +func (cs *CommentService) notificationMention( + ctx context.Context, mentionUsernameList []string, commentID, commentUserID string, + alreadyNotifiedUserID map[string]bool) (alreadyNotifiedUserIDs []string) { for _, username := range mentionUsernameList { userInfo, exist, err := cs.userCommon.GetUserBasicInfoByUserName(ctx, username) if err != nil { log.Error(err) continue } - if exist { + if exist && !alreadyNotifiedUserID[userInfo.ID] { msg := &schema.NotificationMsg{ ReceiverUserID: userInfo.ID, TriggerUserID: commentUserID, @@ -553,6 +579,8 @@ func (cs *CommentService) notificationMention(ctx context.Context, mentionUserna msg.ObjectType = constant.CommentObjectType msg.NotificationAction = constant.MentionYou notice_queue.AddNotification(msg) + alreadyNotifiedUserIDs = append(alreadyNotifiedUserIDs, userInfo.ID) } } + return alreadyNotifiedUserIDs } From 2c366b865f402918fbb2b6b9a2d2be79982d4884 Mon Sep 17 00:00:00 2001 From: aichy126 <16996097+aichy126@users.noreply.github.com> Date: Tue, 31 Jan 2023 12:02:51 +0800 Subject: [PATCH 2/2] update markdown url --- docs/docs.go | 5 +++++ docs/swagger.json | 5 +++++ docs/swagger.yaml | 4 ++++ go.mod | 1 + go.sum | 2 ++ pkg/converter/markdown.go | 30 ++++++++++++++++++++++++++++++ 6 files changed, 47 insertions(+) diff --git a/docs/docs.go b/docs/docs.go index 75d0a49d..24693e47 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -7510,6 +7510,11 @@ const docTemplate = `{ "type": "string", "maxLength": 4096 }, + "bio_html": { + "description": "bio", + "type": "string", + "maxLength": 4096 + }, "display_name": { "description": "display_name", "type": "string", diff --git a/docs/swagger.json b/docs/swagger.json index 899de45a..fb2f297b 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -7498,6 +7498,11 @@ "type": "string", "maxLength": 4096 }, + "bio_html": { + "description": "bio", + "type": "string", + "maxLength": 4096 + }, "display_name": { "description": "display_name", "type": "string", diff --git a/docs/swagger.yaml b/docs/swagger.yaml index aed8b3ea..fef405df 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1589,6 +1589,10 @@ definitions: description: bio maxLength: 4096 type: string + bio_html: + description: bio + maxLength: 4096 + type: string display_name: description: display_name maxLength: 30 diff --git a/go.mod b/go.mod index 33c4a499..7c7aac21 100644 --- a/go.mod +++ b/go.mod @@ -55,6 +55,7 @@ require ( github.com/Microsoft/go-winio v0.5.2 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/andybalholm/brotli v1.0.4 // indirect + github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/containerd/continuity v0.3.0 // indirect diff --git a/go.sum b/go.sum index a808586a..2d51e7be 100644 --- a/go.sum +++ b/go.sum @@ -79,6 +79,8 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= diff --git a/pkg/converter/markdown.go b/pkg/converter/markdown.go index d302c1be..4f4a3c41 100644 --- a/pkg/converter/markdown.go +++ b/pkg/converter/markdown.go @@ -3,6 +3,7 @@ package converter import ( "bytes" + "github.com/asaskevich/govalidator" "github.com/microcosm-cc/bluemonday" "github.com/segmentfault/pacman/log" "github.com/yuin/goldmark" @@ -10,6 +11,7 @@ import ( "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" goldmarkHTML "github.com/yuin/goldmark/renderer/html" "github.com/yuin/goldmark/util" ) @@ -54,6 +56,7 @@ type DangerousHTMLRenderer struct { func (r *DangerousHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(ast.KindHTMLBlock, r.renderHTMLBlock) reg.Register(ast.KindRawHTML, r.renderRawHTML) + reg.Register(ast.KindLink, r.renderLink) } func (r *DangerousHTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { @@ -85,3 +88,30 @@ func (r *DangerousHTMLRenderer) renderHTMLBlock(w util.BufWriter, source []byte, } return ast.WalkContinue, nil } + +func (r *DangerousHTMLRenderer) renderLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.Link) + if entering && r.renderLinkIsUrl(string(n.Destination)) { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("") + } + return ast.WalkContinue, nil +} + +func (r *DangerousHTMLRenderer) renderLinkIsUrl(verifyUrl string) bool { + return govalidator.IsURL(verifyUrl) +}