1use crate::database::Database;
2use crate::model::{AssetType, DatabaseError, ReactionCreate};
3use authbeam::model::{NotificationCreate, RelationshipStatus};
4use databeam::prelude::DefaultReturn;
5
6use axum::response::IntoResponse;
7use axum::{
8 extract::{Path, State},
9 routing::{delete, get, post},
10 Json, Router,
11};
12
13use axum_extra::extract::cookie::CookieJar;
14
15pub fn routes(database: Database) -> Router {
16 Router::new()
17 .route("/{id}", post(create_request))
18 .route("/{id}", get(get_request))
19 .route("/{id}", delete(delete_request))
20 .with_state(database)
22}
23
24pub async fn create_request(
28 jar: CookieJar,
29 Path(id): Path<String>,
30 State(database): State<Database>,
31 Json(props): Json<ReactionCreate>,
32) -> impl IntoResponse {
33 let auth_user = match jar.get("__Secure-Token") {
35 Some(c) => match database
36 .auth
37 .get_profile_by_unhashed(c.value_trimmed())
38 .await
39 {
40 Ok(ua) => ua,
41 Err(_) => return Json(DatabaseError::NotAllowed.into()),
42 },
43 None => return Json(DatabaseError::NotAllowed.into()),
44 };
45
46 match props.r#type {
48 AssetType::Question => {
49 let asset = match database.get_question(id.clone()).await {
50 Ok(r) => r,
51 Err(e) => {
52 return Json(DefaultReturn {
53 success: false,
54 message: e.to_string(),
55 payload: None,
56 })
57 }
58 };
59
60 if let Err(_) = database
62 .auth
63 .create_notification(
64 NotificationCreate {
65 title: format!(
66 "[@{}](/+u/{}) has reacted to a question you created!",
67 auth_user.username, auth_user.id
68 ),
69 content: String::new(),
70 address: format!("/question/{id}"),
71 recipient: asset.author.id,
72 },
73 None,
74 )
75 .await
76 {
77 return Json(DefaultReturn {
78 success: false,
79 message: DatabaseError::Other.to_string(),
80 payload: None,
81 });
82 }
83 }
84 AssetType::Response => {
85 let asset = match database.get_response(id.clone()).await {
86 Ok(r) => r.1,
87 Err(e) => {
88 return Json(DefaultReturn {
89 success: false,
90 message: e.to_string(),
91 payload: None,
92 })
93 }
94 };
95
96 let relationship = database
98 .auth
99 .get_user_relationship(&asset.author.id, &auth_user.id)
100 .await
101 .0;
102
103 if relationship == RelationshipStatus::Blocked {
104 return Json(DefaultReturn {
105 success: false,
106 message: DatabaseError::NotAllowed.to_string(),
107 payload: None,
108 });
109 }
110
111 if let Err(_) = database
113 .auth
114 .create_notification(
115 NotificationCreate {
116 title: format!(
117 "[@{}](/+u/{}) has reacted to a response you created!",
118 auth_user.username, auth_user.id
119 ),
120 content: String::new(),
121 address: format!("/response/{id}"),
122 recipient: asset.author.id,
123 },
124 None,
125 )
126 .await
127 {
128 return Json(DefaultReturn {
129 success: false,
130 message: DatabaseError::Other.to_string(),
131 payload: None,
132 });
133 }
134 }
135 AssetType::Comment => {
136 let asset = match database.get_comment(id.clone(), false).await {
137 Ok(r) => r.0,
138 Err(e) => {
139 return Json(DefaultReturn {
140 success: false,
141 message: e.to_string(),
142 payload: None,
143 })
144 }
145 };
146
147 let relationship = database
149 .auth
150 .get_user_relationship(&asset.author.id, &auth_user.id)
151 .await
152 .0;
153
154 if relationship == RelationshipStatus::Blocked {
155 return Json(DefaultReturn {
156 success: false,
157 message: DatabaseError::NotAllowed.to_string(),
158 payload: None,
159 });
160 }
161
162 if let Err(_) = database
164 .auth
165 .create_notification(
166 NotificationCreate {
167 title: format!(
168 "[@{}](/+u/{}) has reacted to a comment you created!",
169 auth_user.username, auth_user.id
170 ),
171 content: String::new(),
172 address: format!("/comment/{id}"),
173 recipient: asset.author.id,
174 },
175 None,
176 )
177 .await
178 {
179 return Json(DefaultReturn {
180 success: false,
181 message: DatabaseError::Other.to_string(),
182 payload: None,
183 });
184 }
185 }
186 AssetType::Item => {
187 let asset = match database.auth.get_item(&id).await {
188 Ok(i) => i,
189 Err(e) => {
190 return Json(DefaultReturn {
191 success: false,
192 message: e.to_string(),
193 payload: None,
194 })
195 }
196 };
197
198 let relationship = database
200 .auth
201 .get_user_relationship(&asset.creator, &auth_user.id)
202 .await
203 .0;
204
205 if relationship == RelationshipStatus::Blocked {
206 return Json(DefaultReturn {
207 success: false,
208 message: DatabaseError::NotAllowed.to_string(),
209 payload: None,
210 });
211 }
212
213 if let Err(_) = database
215 .auth
216 .create_notification(
217 NotificationCreate {
218 title: format!(
219 "[@{}](/+u/{}) has reacted to an item you created!",
220 auth_user.username, auth_user.id
221 ),
222 content: String::new(),
223 address: format!("/market/item/{id}"),
224 recipient: asset.creator,
225 },
226 None,
227 )
228 .await
229 {
230 return Json(DefaultReturn {
231 success: false,
232 message: DatabaseError::Other.to_string(),
233 payload: None,
234 });
235 }
236 }
237 };
238
239 Json(match database.create_reaction(id, auth_user).await {
241 Ok(r) => DefaultReturn {
242 success: true,
243 message: String::new(),
244 payload: Some(r),
245 },
246 Err(e) => e.into(),
247 })
248}
249
250pub async fn get_request(
252 jar: CookieJar,
253 Path(id): Path<String>,
254 State(database): State<Database>,
255) -> impl IntoResponse {
256 let auth_user = match jar.get("__Secure-Token") {
258 Some(c) => match database
259 .auth
260 .get_profile_by_unhashed(c.value_trimmed())
261 .await
262 {
263 Ok(ua) => ua,
264 Err(_) => {
265 return Json(DatabaseError::NotAllowed.into());
266 }
267 },
268 None => {
269 return Json(DatabaseError::NotAllowed.into());
270 }
271 };
272
273 Json(match database.get_reaction(auth_user.id, id).await {
274 Ok(r) => DefaultReturn {
275 success: true,
276 message: String::new(),
277 payload: Some(r),
278 },
279 Err(e) => e.into(),
280 })
281}
282
283pub async fn delete_request(
285 jar: CookieJar,
286 Path(id): Path<String>,
287 State(database): State<Database>,
288) -> impl IntoResponse {
289 let auth_user = match jar.get("__Secure-Token") {
291 Some(c) => match database
292 .auth
293 .get_profile_by_unhashed(c.value_trimmed())
294 .await
295 {
296 Ok(ua) => ua,
297 Err(_) => {
298 return Json(DatabaseError::NotAllowed.into());
299 }
300 },
301 None => {
302 return Json(DatabaseError::NotAllowed.into());
303 }
304 };
305
306 Json(match database.delete_reaction(id, auth_user).await {
308 Ok(r) => DefaultReturn {
309 success: true,
310 message: String::new(),
311 payload: Some(r),
312 },
313 Err(e) => e.into(),
314 })
315}