@@ -16,10 +16,13 @@ use crate::SharedState;
16
16
use http_body_util:: BodyExt ;
17
17
use diesel:: QueryDsl ;
18
18
use diesel:: ExpressionMethods ;
19
+ use futures_util:: FutureExt ;
19
20
use crate :: entity:: reactions:: reaction_users:: user_id;
21
+ use crate :: server:: gateway:: context:: send_packet_to_context;
22
+ use crate :: server:: messages:: { ReactionAdded , ReactionRemoved } ;
20
23
21
24
pub async fn add_reaction (
22
- Path ( message_reaction_id ) : Path < i64 > ,
25
+ Path ( ( channel_id , message_identifier ) ) : Path < ( i64 , i64 ) > ,
23
26
Extension ( state) : Extension < SharedState > ,
24
27
request : Request < Body >
25
28
) -> IrisResponse < ReactionAddResponse > {
@@ -29,97 +32,121 @@ pub async fn add_reaction(
29
32
return error ( StatusCode :: BAD_REQUEST , "Invalid reaction" ) ;
30
33
}
31
34
let request: ReactionAddRequest = request. unwrap ( ) . 0 ;
35
+ let emoticon = request. reaction_type . clone ( ) ;
32
36
33
- let database = & mut state. write ( ) . await . database ;
34
- let transaction_result = database. transaction :: < _ , diesel:: result:: Error , _ > ( |connection| {
35
- let reaction_details: Option < ( i32 , i32 ) > = match request. reaction_id {
36
- Some ( message_reaction_id) => {
37
- let count = diesel:: update ( reactionsTable)
38
- . filter ( reaction_id. eq ( message_reaction_id) )
39
- . set ( reaction_count. eq ( reaction_count + 1 ) )
40
- . returning ( reaction_count)
41
- . get_result :: < i32 > ( connection) ?;
42
- Some ( ( message_reaction_id, count) )
43
- } ,
44
- None => {
45
- let reaction = diesel:: update ( reactionsTable)
46
- . filter ( message_id. eq ( message_reaction_id) )
47
- . filter ( emoji. eq ( request. reaction_type . clone ( ) ) )
48
- . set ( reaction_count. eq ( reaction_count + 1 ) )
49
- . returning ( ( reaction_id, reaction_count) )
50
- . get_result :: < ( i32 , i32 ) > ( connection)
51
- . optional ( ) ?;
52
-
53
- if let Some ( tuple) = reaction {
54
- println ! ( "Already found a reaction, no need for new one" ) ;
55
- Some ( tuple)
56
- } else {
57
- println ! ( "Inserted" ) ;
58
- let new_reaction = ReactionInsert {
59
- message_id : message_reaction_id,
60
- emoji : request. reaction_type
61
- } ;
62
- let query = diesel:: insert_into ( reactionsTable)
63
- . values ( & new_reaction)
64
- . returning ( reaction_id)
37
+ let state = & mut state. write ( ) . await ;
38
+ let transaction_result = {
39
+ state. database . transaction :: < _ , diesel:: result:: Error , _ > ( |connection| {
40
+ let reaction_details: Option < ( i32 , i32 ) > = match request. reaction_id {
41
+ Some ( message_reaction_id) => {
42
+ let count = diesel:: update ( reactionsTable)
43
+ . filter ( reaction_id. eq ( message_reaction_id) )
44
+ . set ( reaction_count. eq ( reaction_count + 1 ) )
45
+ . returning ( reaction_count)
65
46
. get_result :: < i32 > ( connection) ?;
47
+ Some ( ( message_reaction_id, count) )
48
+ }
49
+ None => {
50
+ let reaction = diesel:: update ( reactionsTable)
51
+ . filter ( message_id. eq ( message_identifier) )
52
+ . filter ( emoji. eq ( request. reaction_type . clone ( ) ) )
53
+ . set ( reaction_count. eq ( reaction_count + 1 ) )
54
+ . returning ( ( reaction_id, reaction_count) )
55
+ . get_result :: < ( i32 , i32 ) > ( connection)
56
+ . optional ( ) ?;
57
+
58
+ if let Some ( tuple) = reaction {
59
+ println ! ( "Already found a reaction, no need for new one" ) ;
60
+ Some ( tuple)
61
+ } else {
62
+ println ! ( "Inserted" ) ;
63
+ let new_reaction = ReactionInsert {
64
+ message_id : message_identifier,
65
+ emoji : request. reaction_type ,
66
+ } ;
67
+ let query = diesel:: insert_into ( reactionsTable)
68
+ . values ( & new_reaction)
69
+ . returning ( reaction_id)
70
+ . get_result :: < i32 > ( connection) ?;
66
71
67
- Some ( ( query, 1 ) )
72
+ Some ( ( query, 1 ) )
73
+ }
68
74
}
75
+ } ;
76
+ if reaction_details. is_none ( ) {
77
+ return Err ( diesel:: result:: Error :: NotFound ) ;
69
78
}
70
- } ;
71
- if reaction_details. is_none ( ) {
72
- return Err ( diesel:: result:: Error :: NotFound ) ;
73
- }
74
-
75
- let ( message_reaction_id, count) = reaction_details. unwrap ( ) ;
76
- let reaction_user = ReactionUserInsert {
77
- reaction_id : message_reaction_id,
78
- user_id : user. id ,
79
- } ;
80
-
81
- let user_query = diesel:: insert_into ( reactionUsersTable)
82
- . values ( & reaction_user)
83
- . execute ( connection) ?;
84
- Ok ( ( message_reaction_id, count) )
85
- } ) ;
79
+
80
+ let ( message_reaction_id, count) = reaction_details. unwrap ( ) ;
81
+ let reaction_user = ReactionUserInsert {
82
+ reaction_id : message_reaction_id,
83
+ user_id : user. id ,
84
+ } ;
85
+
86
+ let user_query = diesel:: insert_into ( reactionUsersTable)
87
+ . values ( & reaction_user)
88
+ . execute ( connection) ?;
89
+ Ok ( ( message_reaction_id, count) )
90
+ } )
91
+ } ;
86
92
87
93
if transaction_result. is_err ( ) {
88
94
return error ( StatusCode :: INTERNAL_SERVER_ERROR , "Failed to add reaction" ) ;
89
95
}
90
96
let ( message_reaction_id, count) = transaction_result. unwrap ( ) ;
91
97
98
+ send_packet_to_context ( & mut state. packet_queue , channel_id. clone ( ) , Box :: new ( ReactionAdded {
99
+ message_id : message_identifier,
100
+ user_id : user. id ,
101
+ emoji : emoticon,
102
+ reaction_count : count,
103
+ reaction_id : message_reaction_id,
104
+ context_id : channel_id
105
+ } ) ) . await ;
106
+
92
107
ok ( ReactionAddResponse {
93
108
reaction_id : message_reaction_id,
94
109
reaction_count : count
95
110
} )
96
111
}
97
112
98
113
pub async fn remove_reaction (
99
- Path ( ( message_identifier, reaction_identifier) ) : Path < ( i64 , i32 ) > ,
114
+ Path ( ( channel_id , message_identifier, reaction_identifier) ) : Path < ( i64 , i64 , i32 ) > ,
100
115
Extension ( state) : Extension < SharedState > ,
101
116
request : Request < Body >
102
117
) -> IrisResponse < ( ) > {
103
118
let user = request. extensions ( ) . get :: < User > ( ) . cloned ( ) . expect ( "User not found" ) ;
104
119
105
- let database = & mut state. write ( ) . await . database ;
106
- let transaction_result = database. transaction :: < _ , diesel:: result:: Error , _ > ( |connection| {
107
- // reduce one from reaction count
108
- let reaction = diesel:: update ( reactionsTable)
109
- . filter ( reaction_id. eq ( reaction_identifier) )
110
- . set ( reaction_count. eq ( reaction_count - 1 ) )
111
- . execute ( connection) ?;
112
-
113
- let user_query = diesel:: delete ( reactionUsersTable)
114
- . filter ( reactionUsersTableReactionId. eq ( reaction_identifier) )
115
- . filter ( user_id. eq ( user. id ) )
116
- . execute ( connection) ?;
117
- Ok ( ( ) )
118
- } ) ;
120
+ let state = & mut state. write ( ) . await ;
121
+ let transaction_result = {
122
+ state. database . transaction :: < _ , diesel:: result:: Error , _ > ( |connection| {
123
+ // reduce one from reaction count
124
+ let count = diesel:: update ( reactionsTable)
125
+ . filter ( reaction_id. eq ( reaction_identifier) )
126
+ . set ( reaction_count. eq ( reaction_count - 1 ) )
127
+ . returning ( reaction_count)
128
+ . get_result :: < i32 > ( connection) ?;
129
+
130
+ diesel:: delete ( reactionUsersTable)
131
+ . filter ( reactionUsersTableReactionId. eq ( reaction_identifier) )
132
+ . filter ( user_id. eq ( user. id ) )
133
+ . execute ( connection) ?;
134
+ Ok ( ( count) )
135
+ } )
136
+ } ;
119
137
120
138
if transaction_result. is_err ( ) {
121
139
return error ( StatusCode :: INTERNAL_SERVER_ERROR , "Failed to remove reaction" ) ;
122
140
}
123
141
142
+ send_packet_to_context ( & mut state. packet_queue , channel_id. clone ( ) , Box :: new ( ReactionRemoved {
143
+ message_id : message_identifier,
144
+ user_id : user. id ,
145
+ emoji : String :: from ( "" ) ,
146
+ reaction_count : transaction_result. unwrap ( ) ,
147
+ reaction_id : reaction_identifier,
148
+ context_id : channel_id
149
+ } ) ) . await ;
150
+
124
151
no_content ( )
125
152
}
0 commit comments