@@ -3,6 +3,10 @@ defmodule CF.Graphql.Resolvers.Comments do
33 import Ecto.Query
44 alias DB.Repo
55 alias DB.Schema.Vote
6+ alias DB.Schema.Comment
7+ alias DB.Schema.Statement
8+ alias CF.Comments
9+ alias CF.Graphql.Subscriptions
610
711 def score ( comment , _args , _info ) do
812 batch ( { __MODULE__ , :comments_scores } , comment . id , fn results ->
@@ -18,4 +22,75 @@ defmodule CF.Graphql.Resolvers.Comments do
1822 |> Repo . all ( )
1923 |> Enum . into ( % { } )
2024 end
25+
26+ # Mutations
27+
28+ def create ( _root , args = % { statement_id: statement_id } , % { context: % { user: user } } ) do
29+ # Get statement to find video_id
30+ statement = Repo . get! ( Statement , statement_id )
31+ video_id = statement . video_id
32+ reply_to_id = Map . get ( args , :reply_to_id )
33+
34+ params = % {
35+ "statement_id" => statement_id ,
36+ "text" => Map . get ( args , :text ) ,
37+ "reply_to_id" => reply_to_id ,
38+ "approve" => Map . get ( args , :approve )
39+ }
40+
41+ source_url = Map . get ( args , :source )
42+
43+ # Comments.add_comment returns the comment directly or {:error, reason}
44+ case Comments . add_comment ( user , video_id , params , source_url ) do
45+ { :error , reason } ->
46+ { :error , reason }
47+
48+ comment ->
49+ # Preload associations for GraphQL response
50+ comment = Repo . preload ( comment , [ :source , :user , :statement ] )
51+
52+ Subscriptions . publish_comment_added ( comment , video_id )
53+ { :ok , comment }
54+ end
55+ end
56+
57+ def delete ( _root , % { id: id } , % { context: % { user: user } } ) do
58+ comment = Repo . get! ( Comment , id ) |> Repo . preload ( :statement )
59+ video_id = comment . statement . video_id
60+
61+ case Comments . delete_comment ( user , video_id , comment ) do
62+ nil ->
63+ { :ok , % { id: id , statement_id: comment . statement_id , reply_to_id: comment . reply_to_id } }
64+
65+ _ ->
66+ Subscriptions . publish_comment_removed ( comment , video_id )
67+ { :ok , % { id: id , statement_id: comment . statement_id , reply_to_id: comment . reply_to_id } }
68+ end
69+ end
70+
71+ def vote ( _root , % { comment_id: comment_id , value: value } , % { context: % { user: user } } ) do
72+ # Get comment and preload statement to access video_id
73+ comment = Repo . get! ( Comment , comment_id ) |> Repo . preload ( :statement )
74+ video_id = comment . statement . video_id
75+
76+ case Comments . vote! ( user , video_id , comment_id , value ) do
77+ { :ok , comment , vote , prev_value } ->
78+ # Calculate score diff (same logic as comments_channel.ex)
79+ diff = value_diff ( prev_value , vote . value )
80+
81+ # Publish score diff via subscription
82+ Subscriptions . publish_comment_score_diff ( comment , diff , video_id )
83+
84+ # Preload associations for GraphQL response
85+ comment = Repo . preload ( comment , [ :source , :user , :statement ] )
86+ { :ok , comment }
87+
88+ { :error , reason } ->
89+ { :error , reason }
90+ end
91+ end
92+
93+ # Helper function to calculate vote value diff (matches comments_channel.ex logic)
94+ defp value_diff ( 0 , new_value ) , do: new_value
95+ defp value_diff ( prev_value , new_value ) , do: new_value - prev_value
2196end
0 commit comments