add: polls backend

TODO: polls frontend
This commit is contained in:
trisua 2025-06-03 23:35:34 -04:00
parent b5e060e8ae
commit 4dfa09207e
18 changed files with 574 additions and 17 deletions

View file

@ -240,6 +240,8 @@ pub struct Post {
pub uploads: Vec<usize>,
/// If the post was deleted.
pub is_deleted: bool,
/// The ID of the poll associated with this post. 0 means no poll is connected.
pub poll_id: usize,
}
impl Post {
@ -249,6 +251,7 @@ impl Post {
community: usize,
replying_to: Option<usize>,
owner: usize,
poll_id: usize,
) -> Self {
Self {
id: Snowflake::new().to_string().parse::<usize>().unwrap(),
@ -263,12 +266,13 @@ impl Post {
comment_count: 0,
uploads: Vec::new(),
is_deleted: false,
poll_id,
}
}
/// Create a new [`Post`] (as a repost of the given `post_id`).
pub fn repost(content: String, community: usize, owner: usize, post_id: usize) -> Self {
let mut post = Self::new(content, community, None, owner);
let mut post = Self::new(content, community, None, owner, 0);
post.context.repost = Some(RepostContext {
is_repost: false,
@ -369,3 +373,107 @@ impl PostDraft {
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Poll {
pub id: usize,
pub owner: usize,
pub created: usize,
/// The number of milliseconds until this poll can no longer receive votes.
pub expires: usize,
// options
pub option_a: String,
pub option_b: String,
pub option_c: String,
pub option_d: String,
// votes
pub votes_a: usize,
pub votes_b: usize,
pub votes_c: usize,
pub votes_d: usize,
}
impl Poll {
/// Create a new [`Poll`].
pub fn new(
owner: usize,
expires: usize,
option_a: String,
option_b: String,
option_c: String,
option_d: String,
) -> Self {
Self {
id: Snowflake::new().to_string().parse::<usize>().unwrap(),
owner,
created: unix_epoch_timestamp() as usize,
expires,
// options
option_a,
option_b,
option_c,
option_d,
// votes
votes_a: 0,
votes_b: 0,
votes_c: 0,
votes_d: 0,
}
}
}
/// Poll option (selectors) are stored in the database as numbers 0 to 3.
///
/// This enum allows us to convert from these numbers into letters.
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum PollOption {
A,
B,
C,
D,
}
impl From<u8> for PollOption {
fn from(value: u8) -> Self {
match value {
0 => Self::A,
1 => Self::B,
2 => Self::C,
3 => Self::D,
_ => Self::A,
}
}
}
impl Into<u8> for PollOption {
fn into(self) -> u8 {
match self {
Self::A => 0,
Self::B => 1,
Self::C => 2,
Self::D => 3,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PollVote {
pub id: usize,
pub owner: usize,
pub created: usize,
pub poll_id: usize,
pub vote: PollOption,
}
impl PollVote {
/// Create a new [`PollVote`].
pub fn new(owner: usize, poll_id: usize, vote: PollOption) -> Self {
Self {
id: Snowflake::new().to_string().parse::<usize>().unwrap(),
owner,
created: unix_epoch_timestamp() as usize,
poll_id,
vote,
}
}
}