@@ -16,6 +16,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
16
16
17
17
alias CMS . {
18
18
ArticleComment ,
19
+ ArticlePinedComment ,
19
20
ArticleCommentUpvote ,
20
21
ArticleCommentReply ,
21
22
ArticleCommentUserEmotion ,
@@ -35,6 +36,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
35
36
@ report_threshold_for_fold ArticleComment . report_threshold_for_fold ( )
36
37
37
38
@ default_comment_meta Embeds.ArticleCommentMeta . default_meta ( )
39
+ @ pined_comment_limit ArticleComment . pined_comment_limit ( )
38
40
39
41
@ doc """
40
42
list paged article comments
@@ -43,9 +45,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
43
45
with { :ok , thread_query } <- match ( thread , :query , article_id ) do
44
46
ArticleComment
45
47
|> where ( ^ thread_query )
46
- |> where ( [ c ] , c . is_folded == false and c . is_reported == false )
48
+ |> where ( [ c ] , c . is_folded == false and c . is_reported == false and c . is_pined == false )
47
49
|> QueryBuilder . filter_pack ( filters )
48
50
|> ORM . paginater ( ~m( page size) a )
51
+ |> add_pined_comments_ifneed ( thread , article_id , filters )
49
52
|> done ( )
50
53
end
51
54
end
@@ -59,19 +62,53 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
59
62
with { :ok , thread_query } <- match ( thread , :query , article_id ) do
60
63
ArticleComment
61
64
|> where ( ^ thread_query )
62
- |> where ( [ c ] , c . is_folded == false and c . is_reported == false )
65
+ |> where ( [ c ] , c . is_folded == false and c . is_reported == false and c . is_pined == false )
63
66
|> QueryBuilder . filter_pack ( filters )
64
67
|> ORM . paginater ( ~m( page size) a )
65
68
|> check_viewer_has_emotioned ( user )
69
+ |> add_pined_comments_ifneed ( thread , article_id , filters )
66
70
|> done ( )
67
71
end
68
72
end
69
73
74
+ # TODO: @pined_comment_limit 10
75
+ defp add_pined_comments_ifneed ( % { entries: entries } = paged_comments , thread , article_id , % {
76
+ page: 1
77
+ } ) do
78
+ with { :ok , info } <- match ( thread ) ,
79
+ query <-
80
+ from ( p in ArticlePinedComment ,
81
+ join: c in ArticleComment ,
82
+ on: p . article_comment_id == c . id ,
83
+ where: field ( p , ^ info . foreign_key ) == ^ article_id ,
84
+ select: c
85
+ ) ,
86
+ { :ok , pined_comments } <- query |> Repo . all ( ) |> done ( ) do
87
+ case pined_comments do
88
+ [ ] ->
89
+ paged_comments
90
+
91
+ _ ->
92
+ updated_entries =
93
+ Enum . concat ( Enum . slice ( pined_comments , 0 , @ pined_comment_limit ) , entries )
94
+
95
+ pined_comment_count = length ( pined_comments )
96
+
97
+ Map . merge ( paged_comments , % {
98
+ entries: updated_entries ,
99
+ total_count: paged_comments . total_count + pined_comment_count
100
+ } )
101
+ end
102
+ end
103
+ end
104
+
105
+ defp add_pined_comments_ifneed ( paged_comments , _thread , _article_id , _ ) , do: paged_comments
106
+
70
107
def list_folded_article_comments ( thread , article_id , % { page: page , size: size } = filters ) do
71
108
with { :ok , thread_query } <- match ( thread , :query , article_id ) do
72
109
ArticleComment
73
110
|> where ( ^ thread_query )
74
- |> where ( [ c ] , c . is_folded == true and c . is_reported == false )
111
+ |> where ( [ c ] , c . is_folded == true and c . is_reported == false and c . is_pined == false )
75
112
|> QueryBuilder . filter_pack ( filters )
76
113
|> ORM . paginater ( ~m( page size) a )
77
114
|> done ( )
@@ -87,7 +124,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
87
124
with { :ok , thread_query } <- match ( thread , :query , article_id ) do
88
125
ArticleComment
89
126
|> where ( ^ thread_query )
90
- |> where ( [ c ] , c . is_folded == true and c . is_reported == false )
127
+ |> where ( [ c ] , c . is_folded == true and c . is_reported == false and c . is_pined == false )
91
128
|> QueryBuilder . filter_pack ( filters )
92
129
|> ORM . paginater ( ~m( page size) a )
93
130
|> check_viewer_has_emotioned ( user )
@@ -136,6 +173,55 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
136
173
|> done ( )
137
174
end
138
175
176
+ @ doc "pin a comment"
177
+ def pin_article_comment ( comment_id ) do
178
+ with { :ok , comment } <- ORM . find ( ArticleComment , comment_id ) ,
179
+ { :ok , full_comment } <- get_full_comment ( comment . id ) ,
180
+ { :ok , info } <- match ( full_comment . thread ) do
181
+ Multi . new ( )
182
+ |> Multi . run ( :checked_pined_comments_count , fn _ , _ ->
183
+ count_query =
184
+ from ( p in ArticlePinedComment ,
185
+ where: field ( p , ^ info . foreign_key ) == ^ full_comment . article . id
186
+ )
187
+
188
+ pined_comments_count = Repo . aggregate ( count_query , :count )
189
+
190
+ case pined_comments_count >= @ pined_comment_limit do
191
+ true -> { :error , "only support #{ @ pined_comment_limit } pined comment for each article" }
192
+ false -> { :ok , :pass }
193
+ end
194
+ end )
195
+ |> Multi . run ( :update_comment_flag , fn _ , _ ->
196
+ ORM . update ( comment , % { is_pined: true } )
197
+ end )
198
+ |> Multi . run ( :add_pined_comment , fn _ , _ ->
199
+ ArticlePinedComment
200
+ |> ORM . create (
201
+ % { article_comment_id: comment . id }
202
+ |> Map . put ( info . foreign_key , full_comment . article . id )
203
+ )
204
+ end )
205
+ |> Repo . transaction ( )
206
+ |> upsert_comment_result ( )
207
+ end
208
+ end
209
+
210
+ def undo_pin_article_comment ( comment_id ) do
211
+ with { :ok , comment } <- ORM . find ( ArticleComment , comment_id ) do
212
+ Multi . new ( )
213
+ |> Multi . run ( :update_comment_flag , fn _ , _ ->
214
+ ORM . update ( comment , % { is_pined: false } )
215
+ end )
216
+ |> Multi . run ( :remove_pined_comment , fn _ , _ ->
217
+ ORM . findby_delete ( ArticlePinedComment , % { article_comment_id: comment . id } )
218
+ end )
219
+ |> Repo . transaction ( )
220
+ |> upsert_comment_result ( )
221
+ end
222
+ end
223
+
224
+ # TODO: remove pined record if need
139
225
def delete_article_comment ( comment_id , % User { } = _user ) do
140
226
with { :ok , comment } <-
141
227
ORM . find ( ArticleComment , comment_id ) do
@@ -514,7 +600,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
514
600
with { :ok , article_with_author } <- Repo . preload ( article , author: :user ) |> done ( ) ,
515
601
article_author <- get_in ( article_with_author , [ :author , :user ] ) do
516
602
#
517
- article_info = % { title: article . title }
603
+ article_info = % { title: article . title , id: article . id }
518
604
519
605
author_info = % {
520
606
id: article_author . id ,
@@ -531,6 +617,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
531
617
defp upsert_comment_result ( { :ok , % { check_article_author_upvoted: result } } ) , do: { :ok , result }
532
618
defp upsert_comment_result ( { :ok , % { update_report_flag: result } } ) , do: { :ok , result }
533
619
defp upsert_comment_result ( { :ok , % { update_comment_emotion: result } } ) , do: { :ok , result }
620
+ defp upsert_comment_result ( { :ok , % { update_comment_flag: result } } ) , do: { :ok , result }
534
621
535
622
defp upsert_comment_result ( { :error , :create_comment , result , _steps } ) do
536
623
{ :error , result }
0 commit comments