github.com/ngocphuongnb/tetua@v0.0.7-alpha/app/web/post/post.go (about) 1 package webpost 2 3 import ( 4 "fmt" 5 "net/http" 6 "strconv" 7 "strings" 8 "sync" 9 10 "github.com/ngocphuongnb/tetua/app/entities" 11 "github.com/ngocphuongnb/tetua/app/repositories" 12 "github.com/ngocphuongnb/tetua/app/server" 13 "github.com/ngocphuongnb/tetua/app/utils" 14 "github.com/ngocphuongnb/tetua/views" 15 ) 16 17 func List(c server.Context) error { 18 paginate, err := repositories.Post.Paginate(c.Context(), &entities.PostFilter{ 19 Filter: &entities.Filter{ 20 BaseUrl: utils.Url("/posts"), 21 Page: c.QueryInt("page"), 22 IgnoreUrlParams: []string{"user"}, 23 }, 24 UserIDs: []int{c.User().ID}, 25 Approve: "all", 26 Publish: "all", 27 }) 28 29 if err != nil { 30 c.WithError("Something went wrong", err) 31 } 32 33 return c.Render(views.PostList(paginate)) 34 } 35 36 func Delete(c server.Context) error { 37 if err := repositories.Post.DeleteByID(c.Context(), c.ParamInt("id")); err != nil { 38 c.Logger().Error("Error deleting post", err) 39 return c.Status(http.StatusBadRequest).Json(&entities.Message{ 40 Type: "error", 41 Message: "Error deleting post", 42 }) 43 } 44 45 return c.Status(http.StatusOK).Json(&entities.Message{ 46 Type: "success", 47 Message: "Post deleted", 48 }) 49 } 50 51 func View(c server.Context) error { 52 var post = &entities.Post{} 53 var slug = c.Param("slug") 54 var slugParts = strings.Split(slug, "-") 55 56 if len(slugParts) < 2 { 57 return ViewPage(c) 58 } 59 60 var slugId = slugParts[len(slugParts)-1] 61 var relatedPosts []*entities.Post 62 var comments = []*entities.Comment{} 63 var wg sync.WaitGroup 64 var postId, err = strconv.Atoi(slugId) 65 66 if err != nil { 67 return ViewPage(c) 68 } 69 70 if post, err = repositories.Post.PublishedPostByID(c.Context(), postId); err != nil || post == nil { 71 return ViewPage(c) 72 } 73 74 postSlug := fmt.Sprintf("%s-%d", post.Slug, post.ID) 75 76 if postSlug != slug { 77 return c.RedirectToRoute("post.view", entities.Map{"slug": postSlug}) 78 } 79 80 wg.Add(2) 81 go func() { 82 if err := repositories.Post.IncreaseViewCount(c.Context(), postId, 1); err != nil { 83 c.Logger().Error("Error incrementing post view", err) 84 } 85 }() 86 87 go func(wg *sync.WaitGroup) { 88 defer wg.Done() 89 relatedPosts = getRelatedPosts(c, post) 90 }(&wg) 91 92 go func(wg *sync.WaitGroup) { 93 defer wg.Done() 94 comments, err = repositories.Comment.Find(c.Context(), &entities.CommentFilter{ 95 PostIDs: []int{postId}, 96 Filter: &entities.Filter{ 97 Limit: 10000, 98 }, 99 }) 100 }(&wg) 101 102 wg.Wait() 103 c.Meta().Title = post.Name 104 c.Meta().Description = post.Description 105 106 if post.FeaturedImage != nil { 107 c.Meta().Image = post.FeaturedImage.Url() 108 } 109 110 return c.Render(views.PostView(post, relatedPosts, comments)) 111 } 112 113 func getRelatedPosts(c server.Context, post *entities.Post) []*entities.Post { 114 var relatedPosts []*entities.Post 115 var err error 116 117 if relatedPosts, err = repositories.Post.Find(c.Context(), &entities.PostFilter{ 118 Filter: &entities.Filter{ 119 Limit: 8, 120 ExcludeIDs: []int{post.ID}, 121 Sorts: []*entities.Sort{{ 122 Field: "view_count", 123 Order: "desc", 124 }}, 125 }, 126 TopicIDs: utils.SliceMap(post.Topics, func(topic *entities.Topic) int { 127 return topic.ID 128 }), 129 }); err != nil { 130 c.Logger().Error("Error finding related posts", err) 131 } 132 133 return relatedPosts 134 }