1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use tetratto_shared::{snow::Snowflake, unix_epoch_timestamp};
5use super::communities_permissions::CommunityPermission;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Community {
9 pub id: usize,
10 pub created: usize,
11 pub title: String,
12 pub context: CommunityContext,
13 pub owner: usize,
15 pub read_access: CommunityReadAccess,
17 pub write_access: CommunityWriteAccess,
22 pub join_access: CommunityJoinAccess,
24 pub likes: isize,
25 pub dislikes: isize,
26 pub member_count: usize,
27 pub post_count: usize,
28 pub is_forum: bool,
29 pub topics: HashMap<usize, ForumTopic>,
37}
38
39impl Community {
40 pub fn new(title: String, owner: usize) -> Self {
42 Self {
43 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
44 created: unix_epoch_timestamp(),
45 title: title.clone(),
46 context: CommunityContext {
47 display_name: title,
48 ..Default::default()
49 },
50 owner,
51 read_access: CommunityReadAccess::default(),
52 write_access: CommunityWriteAccess::default(),
53 join_access: CommunityJoinAccess::default(),
54 likes: 0,
55 dislikes: 0,
56 member_count: 0,
57 post_count: 0,
58 is_forum: false,
59 topics: HashMap::new(),
60 }
61 }
62
63 pub fn void() -> Self {
66 Self {
67 id: 0,
68 created: 0,
69 title: "void".to_string(),
70 context: CommunityContext::default(),
71 owner: 0,
72 read_access: CommunityReadAccess::Joined,
73 write_access: CommunityWriteAccess::Owner,
74 join_access: CommunityJoinAccess::Nobody,
75 likes: 0,
76 dislikes: 0,
77 member_count: 0,
78 post_count: 0,
79 is_forum: false,
80 topics: HashMap::new(),
81 }
82 }
83}
84
85#[derive(Clone, Debug, Serialize, Deserialize, Default)]
86pub struct CommunityContext {
87 #[serde(default)]
88 pub display_name: String,
89 #[serde(default)]
90 pub description: String,
91 #[serde(default)]
92 pub is_nsfw: bool,
93 #[serde(default)]
94 pub enable_questions: bool,
95 #[serde(default)]
97 pub enable_titles: bool,
98 #[serde(default)]
102 pub require_titles: bool,
103}
104
105#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
107pub enum CommunityReadAccess {
108 #[default]
110 Everybody,
111 Joined,
113}
114
115#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
117pub enum CommunityWriteAccess {
118 Everybody,
120 #[default]
124 Joined,
125 Owner,
127}
128
129#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Default)]
131pub enum CommunityJoinAccess {
132 Nobody,
134 #[default]
136 Everybody,
137 Request,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct CommunityMembership {
143 pub id: usize,
144 pub created: usize,
145 pub owner: usize,
146 pub community: usize,
147 pub role: CommunityPermission,
148}
149
150impl CommunityMembership {
151 pub fn new(owner: usize, community: usize, role: CommunityPermission) -> Self {
153 Self {
154 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
155 created: unix_epoch_timestamp(),
156 owner,
157 community,
158 role,
159 }
160 }
161}
162
163#[derive(Clone, Debug, Serialize, Deserialize)]
164pub struct PostContext {
165 #[serde(default = "default_comments_enabled")]
166 pub comments_enabled: bool,
167 #[serde(default)]
168 pub is_pinned: bool,
169 #[serde(default)]
170 pub is_profile_pinned: bool,
171 #[serde(default)]
172 pub edited: usize,
173 #[serde(default)]
174 pub is_nsfw: bool,
175 #[serde(default)]
176 pub repost: Option<RepostContext>,
177 #[serde(default = "default_reposts_enabled")]
178 pub reposts_enabled: bool,
179 #[serde(default)]
181 pub answering: usize,
182 #[serde(default = "default_reactions_enabled")]
183 pub reactions_enabled: bool,
184 #[serde(default)]
185 pub content_warning: String,
186 #[serde(default)]
187 pub tags: Vec<String>,
188 #[serde(default)]
189 pub full_unlist: bool,
190}
191
192fn default_comments_enabled() -> bool {
193 true
194}
195
196fn default_reposts_enabled() -> bool {
197 true
198}
199
200fn default_reactions_enabled() -> bool {
201 true
202}
203
204impl Default for PostContext {
205 fn default() -> Self {
206 Self {
207 comments_enabled: default_comments_enabled(),
208 reposts_enabled: default_reposts_enabled(),
209 is_pinned: false,
210 is_profile_pinned: false,
211 edited: 0,
212 is_nsfw: false,
213 repost: None,
214 answering: 0,
215 reactions_enabled: default_reactions_enabled(),
216 content_warning: String::new(),
217 tags: Vec::new(),
218 full_unlist: false,
219 }
220 }
221}
222
223#[derive(Clone, Debug, Serialize, Deserialize)]
224pub struct RepostContext {
225 pub is_repost: bool,
229 pub reposting: Option<usize>,
233}
234
235#[derive(Clone, Debug, Serialize, Deserialize)]
236pub struct Post {
237 pub id: usize,
238 pub created: usize,
239 pub content: String,
240 pub owner: usize,
242 pub community: usize,
244 pub context: PostContext,
246 pub replying_to: Option<usize>,
248 pub likes: isize,
249 pub dislikes: isize,
250 pub comment_count: usize,
251 pub uploads: Vec<usize>,
253 pub is_deleted: bool,
255 pub poll_id: usize,
257 pub title: String,
259 pub stack: usize,
263 pub topic: usize,
268 pub views: usize,
269}
270
271impl Post {
272 pub fn new(
274 content: String,
275 community: usize,
276 replying_to: Option<usize>,
277 owner: usize,
278 poll_id: usize,
279 ) -> Self {
280 Self {
281 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
282 created: unix_epoch_timestamp(),
283 content,
284 owner,
285 community,
286 context: PostContext::default(),
287 replying_to,
288 likes: 0,
289 dislikes: 0,
290 comment_count: 0,
291 uploads: Vec::new(),
292 is_deleted: false,
293 poll_id,
294 title: String::new(),
295 stack: 0,
296 topic: 0,
297 views: 0,
298 }
299 }
300
301 pub fn repost(content: String, community: usize, owner: usize, post_id: usize) -> Self {
303 let mut post = Self::new(content, community, None, owner, 0);
304
305 post.context.repost = Some(RepostContext {
306 is_repost: false,
307 reposting: Some(post_id),
308 });
309
310 post
311 }
312
313 pub fn mark_as_repost(&mut self) {
315 self.context.repost = Some(RepostContext {
316 is_repost: true,
317 reposting: None,
318 });
319 }
320}
321
322#[derive(Clone, Debug, Serialize, Deserialize)]
323pub struct PostView {
324 pub id: usize,
325 pub created: usize,
326 pub owner: usize,
327 pub post: usize,
328}
329
330impl PostView {
331 pub fn new(owner: usize, post: usize) -> Self {
333 Self {
334 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
335 created: unix_epoch_timestamp(),
336 owner,
337 post,
338 }
339 }
340}
341
342#[derive(Clone, Debug, Serialize, Deserialize)]
343pub struct Question {
344 pub id: usize,
345 pub created: usize,
346 pub owner: usize,
347 pub receiver: usize,
348 pub content: String,
349 pub is_global: bool,
354 pub answer_count: usize,
357 pub community: usize,
360 #[serde(default)]
362 pub likes: isize,
363 #[serde(default)]
364 pub dislikes: isize,
365 #[serde(default)]
367 pub context: QuestionContext,
368 #[serde(default)]
370 pub ip: String,
371 #[serde(default)]
373 pub drawings: Vec<usize>,
374}
375
376impl Question {
377 pub fn new(
379 owner: usize,
380 receiver: usize,
381 content: String,
382 is_global: bool,
383 ip: String,
384 ) -> Self {
385 Self {
386 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
387 created: unix_epoch_timestamp(),
388 owner,
389 receiver,
390 content,
391 is_global,
392 answer_count: 0,
393 community: 0,
394 likes: 0,
395 dislikes: 0,
396 context: QuestionContext::default(),
397 ip,
398 drawings: Vec::new(),
399 }
400 }
401}
402
403#[derive(Debug, Clone, Serialize, Deserialize, Default)]
404pub struct QuestionContext {
405 #[serde(default)]
406 pub is_nsfw: bool,
407 #[serde(default)]
409 pub mask_owner: bool,
410 #[serde(default)]
412 pub asking_about: Option<usize>,
413}
414
415#[derive(Clone, Debug, Serialize, Deserialize)]
416pub struct PostDraft {
417 pub id: usize,
418 pub created: usize,
419 pub content: String,
420 pub owner: usize,
421}
422
423impl PostDraft {
424 pub fn new(content: String, owner: usize) -> Self {
426 Self {
427 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
428 created: unix_epoch_timestamp(),
429 content,
430 owner,
431 }
432 }
433}
434
435#[derive(Clone, Debug, Serialize, Deserialize)]
436pub struct Poll {
437 pub id: usize,
438 pub owner: usize,
439 pub created: usize,
440 pub expires: usize,
442 pub option_a: String,
444 pub option_b: String,
445 pub option_c: String,
446 pub option_d: String,
447 pub votes_a: usize,
449 pub votes_b: usize,
450 pub votes_c: usize,
451 pub votes_d: usize,
452}
453
454impl Poll {
455 pub fn new(
457 owner: usize,
458 expires: usize,
459 option_a: String,
460 option_b: String,
461 option_c: String,
462 option_d: String,
463 ) -> Self {
464 Self {
465 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
466 owner,
467 created: unix_epoch_timestamp(),
468 expires,
469 option_a,
471 option_b,
472 option_c,
473 option_d,
474 votes_a: 0,
476 votes_b: 0,
477 votes_c: 0,
478 votes_d: 0,
479 }
480 }
481}
482
483#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
487pub enum PollOption {
488 A,
489 B,
490 C,
491 D,
492}
493
494impl From<u8> for PollOption {
495 fn from(value: u8) -> Self {
496 match value {
497 0 => Self::A,
498 1 => Self::B,
499 2 => Self::C,
500 3 => Self::D,
501 _ => Self::A,
502 }
503 }
504}
505
506impl From<PollOption> for u8 {
507 fn from(val: PollOption) -> Self {
508 match val {
509 PollOption::A => 0,
510 PollOption::B => 1,
511 PollOption::C => 2,
512 PollOption::D => 3,
513 }
514 }
515}
516
517#[derive(Clone, Debug, Serialize, Deserialize)]
518pub struct PollVote {
519 pub id: usize,
520 pub owner: usize,
521 pub created: usize,
522 pub poll_id: usize,
523 pub vote: PollOption,
524}
525
526impl PollVote {
527 pub fn new(owner: usize, poll_id: usize, vote: PollOption) -> Self {
529 Self {
530 id: Snowflake::new().to_string().parse::<usize>().unwrap(),
531 owner,
532 created: unix_epoch_timestamp(),
533 poll_id,
534 vote,
535 }
536 }
537}
538
539#[derive(Clone, Debug, Serialize, Deserialize)]
540pub struct ForumTopic {
541 pub title: String,
542 pub description: String,
543 pub color: String,
544 pub position: i32,
545 #[serde(default)]
546 pub write_access: CommunityWriteAccess,
547}
548
549impl ForumTopic {
550 pub fn new(
556 title: String,
557 description: String,
558 color: String,
559 position: i32,
560 write_access: CommunityWriteAccess,
561 ) -> (usize, Self) {
562 (
563 Snowflake::new().to_string().parse::<usize>().unwrap(),
564 Self {
565 title,
566 description,
567 color,
568 position,
569 write_access,
570 },
571 )
572 }
573}