@@ -8,6 +8,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
8
8
import GroupherServer.CMS.Utils.Matcher2
9
9
import ShortMaps
10
10
11
+ alias Helper.Types , as: T
11
12
alias Helper . { ORM , QueryBuilder }
12
13
alias GroupherServer . { Accounts , CMS , Repo }
13
14
@@ -33,6 +34,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
33
34
@ delete_hint ArticleComment . delete_hint ( )
34
35
@ report_threshold_for_fold ArticleComment . report_threshold_for_fold ( )
35
36
37
+ @ default_comment_meta Embeds.ArticleCommentMeta . default_meta ( )
38
+
36
39
@ doc """
37
40
list paged article comments
38
41
"""
@@ -263,7 +266,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
263
266
with { :ok , info } <- match ( thread ) ,
264
267
# make sure the article exsit
265
268
# author is passed by middleware, it's exsit for sure
266
- { :ok , article } <- ORM . find ( info . model , article_id ) do
269
+ { :ok , article } <- ORM . find ( info . model , article_id , preload: [ author: :user ] ) do
267
270
Multi . new ( )
268
271
|> Multi . run ( :create_article_comment , fn _ , _ ->
269
272
do_create_comment ( content , info . foreign_key , article , user )
@@ -317,10 +320,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
317
320
end
318
321
319
322
@ doc "upvote a comment"
320
- # TODO: user has upvoted logic, move to GraphQL
321
323
def upvote_article_comment ( comment_id , % User { id: user_id } ) do
322
324
with { :ok , comment } <- ORM . find ( ArticleComment , comment_id ) ,
323
325
false <- comment . is_deleted do
326
+ # IO.inspect(comment, label: "the comment")
324
327
Multi . new ( )
325
328
|> Multi . run ( :create_comment_upvote , fn _ , _ ->
326
329
ORM . create ( ArticleCommentUpvote , % { article_comment_id: comment . id , user_id: user_id } )
@@ -330,24 +333,58 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
330
333
upvotes_count = Repo . aggregate ( count_query , :count )
331
334
ORM . update ( comment , % { upvotes_count: upvotes_count } )
332
335
end )
336
+ |> Multi . run ( :check_article_author_upvoted , fn _ , _ ->
337
+ update_article_author_upvoted_info ( comment , user_id )
338
+ end )
339
+ |> Repo . transaction ( )
340
+ |> upsert_comment_result ( )
341
+ end
342
+ end
343
+
344
+ @ doc "upvote a comment"
345
+ def undo_upvote_article_comment ( comment_id , % User { id: user_id } ) do
346
+ with { :ok , comment } <- ORM . find ( ArticleComment , comment_id ) ,
347
+ false <- comment . is_deleted do
348
+ Multi . new ( )
349
+ |> Multi . run ( :delete_comment_upvote , fn _ , _ ->
350
+ ORM . findby_delete ( ArticleCommentUpvote , % {
351
+ article_comment_id: comment . id ,
352
+ user_id: user_id
353
+ } )
354
+ end )
355
+ |> Multi . run ( :desc_upvotes_count , fn _ , _ ->
356
+ count_query = from ( c in ArticleCommentUpvote , where: c . article_comment_id == ^ comment_id )
357
+ upvotes_count = Repo . aggregate ( count_query , :count )
358
+
359
+ ORM . update ( comment , % { upvotes_count: Enum . max ( [ upvotes_count - 1 , 0 ] ) } )
360
+ end )
361
+ |> Multi . run ( :check_article_author_upvoted , fn _ , % { desc_upvotes_count: updated_comment } ->
362
+ update_article_author_upvoted_info ( updated_comment , user_id )
363
+ end )
333
364
|> Repo . transaction ( )
334
365
|> upsert_comment_result ( )
335
366
end
336
367
end
337
368
369
+ defp update_article_author_upvoted_info ( % ArticleComment { } = comment , user_id ) do
370
+ with { :ok , article } = get_full_comment ( comment . id ) do
371
+ is_article_author_upvoted = article . author . id == user_id
372
+
373
+ new_meta =
374
+ comment . meta
375
+ |> Map . from_struct ( )
376
+ |> Map . merge ( % { is_article_author_upvoted: is_article_author_upvoted } )
377
+
378
+ comment |> ORM . update ( % { meta: new_meta } )
379
+ end
380
+ end
381
+
338
382
# creat article comment for parent or reply
339
383
# set floor
340
384
# TODO: parse editor-json
341
385
# set default emotions
342
- defp do_create_comment (
343
- content ,
344
- foreign_key ,
345
- % { id: article_id , author_id: article_author_id } ,
346
- % User {
347
- id: user_id
348
- }
349
- ) do
350
- count_query = from ( c in ArticleComment , where: field ( c , ^ foreign_key ) == ^ article_id )
386
+ defp do_create_comment ( content , foreign_key , article , % User { id: user_id } ) do
387
+ count_query = from ( c in ArticleComment , where: field ( c , ^ foreign_key ) == ^ article . id )
351
388
floor = Repo . aggregate ( count_query , :count ) + 1
352
389
353
390
ArticleComment
@@ -358,10 +395,11 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
358
395
body_html: content ,
359
396
emotions: @ default_emotions ,
360
397
floor: floor ,
361
- is_article_author: user_id == article_author_id
398
+ is_article_author: user_id == article . author . user . id ,
399
+ meta: @ default_comment_meta
362
400
} ,
363
401
foreign_key ,
364
- article_id
402
+ article . id
365
403
)
366
404
)
367
405
end
@@ -416,13 +454,13 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
416
454
defp add_participator_to_article ( _ , _ ) , do: { :ok , :pass }
417
455
418
456
defp get_article ( % ArticleComment { post_id: post_id } = comment ) when not is_nil ( post_id ) do
419
- with { :ok , article } <- ORM . find ( Post , comment . post_id ) do
457
+ with { :ok , article } <- ORM . find ( Post , comment . post_id , preload: [ author: :user ] ) do
420
458
{ :post , article }
421
459
end
422
460
end
423
461
424
462
defp get_article ( % ArticleComment { job_id: job_id } = comment ) when not is_nil ( job_id ) do
425
- with { :ok , article } <- ORM . find ( Job , comment . job_id ) do
463
+ with { :ok , article } <- ORM . find ( Job , comment . job_id , preload: [ author: :user ] ) do
426
464
{ :job , article }
427
465
end
428
466
end
@@ -454,9 +492,43 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
454
492
% { paged_comments | entries: new_entries }
455
493
end
456
494
495
+ @ spec get_full_comment ( String . t ( ) ) :: { :ok , T . article_info ( ) } | { :error , nil }
496
+ defp get_full_comment ( comment_id ) do
497
+ query = from ( c in ArticleComment , where: c . id == ^ comment_id , preload: :post , preload: :job )
498
+
499
+ with { :ok , comment } <- Repo . one ( query ) |> done ( ) do
500
+ extract_article_info ( comment )
501
+ end
502
+ end
503
+
504
+ defp extract_article_info ( % ArticleComment { post: % Post { } = post } ) when not is_nil ( post ) do
505
+ do_extract_article_info ( :post , post )
506
+ end
507
+
508
+ defp extract_article_info ( % ArticleComment { job: % Job { } = job } ) when not is_nil ( job ) do
509
+ do_extract_article_info ( :job , job )
510
+ end
511
+
512
+ @ spec do_extract_article_info ( T . article_thread ( ) , T . article_common ( ) ) :: { :ok , T . article_info ( ) }
513
+ defp do_extract_article_info ( thread , article ) do
514
+ with { :ok , article_with_author } <- Repo . preload ( article , author: :user ) |> done ( ) ,
515
+ article_author <- get_in ( article_with_author , [ :author , :user ] ) do
516
+ #
517
+ article_info = % { title: article . title }
518
+
519
+ author_info = % {
520
+ id: article_author . id ,
521
+ login: article_author . login ,
522
+ nickname: article_author . nickname
523
+ }
524
+
525
+ { :ok , % { thread: thread , article: article_info , author: author_info } }
526
+ end
527
+ end
528
+
457
529
defp upsert_comment_result ( { :ok , % { create_article_comment: result } } ) , do: { :ok , result }
458
530
defp upsert_comment_result ( { :ok , % { add_reply_to: result } } ) , do: { :ok , result }
459
- defp upsert_comment_result ( { :ok , % { inc_upvotes_count :result } } ) , do: { :ok , result }
531
+ defp upsert_comment_result ( { :ok , % { check_article_author_upvoted :result } } ) , do: { :ok , result }
460
532
defp upsert_comment_result ( { :ok , % { update_report_flag: result } } ) , do: { :ok , result }
461
533
defp upsert_comment_result ( { :ok , % { update_comment_emotion: result } } ) , do: { :ok , result }
462
534