Skip to content

Commit e33dad5

Browse files
committed
chore: improved vote & login
1 parent 1b21d05 commit e33dad5

File tree

21 files changed

+490
-155
lines changed

21 files changed

+490
-155
lines changed

api/src/guilds/votes/controllers.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ struct CreateVoteDto {
5353
channel_id: Id<ChannelMarker>,
5454
close_at: Option<DateTime<Utc>>,
5555
role_list: HashSet<Id<RoleMarker>>,
56-
role_list_type: RoleListType
56+
role_list_type: RoleListType,
57+
is_multi_select: bool,
5758
}
5859

5960
async fn post_votes(
@@ -84,7 +85,8 @@ async fn post_votes(
8485
close_at: vote_req.close_at,
8586
open: true,
8687
role_list: vote_req.role_list,
87-
role_list_type: vote_req.role_list_type
88+
role_list_type: vote_req.role_list_type,
89+
is_multi_select: vote_req.is_multi_select,
8890
};
8991
guild.vote.votes.push(new_vote.clone());
9092
guild.save(&app_state.dynamo).await;
@@ -163,7 +165,8 @@ async fn post_votes_id_close(
163165
guild.save(&app_state.dynamo).await;
164166

165167
let vote: &VoteVote = guild.vote.votes.iter().find(|v| v.message_id == message_id).unwrap();
166-
let _message = update_message(vote.channel_id, vote.message_id, None, Some(Some(group_to_rows(vote.options.iter().map(|o| {
168+
let _message = update_message(vote.channel_id, vote.message_id, Some(Some(&format!("# [CLOSED] {}\n{}\n", vote.title, vote.description))),
169+
Some(Some(group_to_rows(vote.options.iter().map(|o| {
167170
let mut c = o.to_component();
168171
match c {
169172
Component::Button(ref mut b) => b.disabled = true,

api/src/guilds/votes/interactions.rs

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
use std::default::Default;
22
use axum::Json;
33
use http::StatusCode;
4-
use lambda_http::tracing::info;
54
use serde_json::{json, Value};
65
use twilight_model::application::interaction::{Interaction, InteractionData};
76
use twilight_model::channel::message::MessageFlags;
87
use twilight_model::guild::PartialMember;
98
use twilight_model::http::interaction::{InteractionResponse, InteractionResponseData, InteractionResponseType};
109
use crate::AppState;
1110
use crate::guilds::models::Guild;
12-
use crate::guilds::votes::models::{RoleListType, VoteOption, VoteVote};
11+
use crate::guilds::votes::models::{RoleListType, VoteVote};
1312
use crate::guilds::votes::utils::VoteOptionComponent;
1413

1514
pub(crate) async fn handle_component_interaction(
@@ -31,16 +30,14 @@ pub(crate) async fn handle_component_interaction(
3130
let user_id = user.unwrap().id;
3231

3332
let mut guild = Guild::from_db(guild_id.unwrap(), &app_state.dynamo).await.unwrap();
34-
info!("guild retreived");
3533

36-
let VoteVote { options, role_list, role_list_type, .. } = match guild.vote.votes.iter_mut().find(|v| v.message_id == message_id) {
34+
let VoteVote { options, role_list, role_list_type,
35+
is_multi_select, .. } = match guild.vote.votes.iter_mut().find(|v| v.message_id == message_id) {
3736
Some(v) => v,
3837
None => return Err(StatusCode::NOT_FOUND),
3938
};
40-
info!("debug 1");
4139

4240
let role_in_role_list = roles.iter().any(|r| role_list.contains(r));
43-
info!("debug 2");
4441

4542
let allowed = match role_list_type {
4643
RoleListType::BLACKLIST => {
@@ -50,7 +47,6 @@ pub(crate) async fn handle_component_interaction(
5047
role_in_role_list
5148
}
5249
};
53-
info!("debug 3");
5450
if !allowed {
5551
return Ok(Json(json!(
5652
InteractionResponse {
@@ -63,31 +59,24 @@ pub(crate) async fn handle_component_interaction(
6359
}
6460
)));
6561
}
66-
info!("debug 4");
62+
let mut responses = vec![];
6763

68-
let VoteOption { users, label, .. } = options.iter_mut().find(|o| o.custom_id() == data.custom_id).unwrap();
69-
let exists = users.iter().any(|&u| u == user_id);
70-
if exists {
71-
// Already voted, need to remove.
72-
users.retain(|&u| u != user_id);
73-
74-
} else {
75-
users.insert(user_id);
64+
for o in options.iter_mut() {
65+
if o.users.contains(&user_id) && (data.custom_id == o.custom_id() || !*is_multi_select) {
66+
o.users.remove(&user_id);
67+
responses.push(format!("You have removed your vote for {o}."));
68+
} else if !o.users.contains(&user_id) && data.custom_id == o.custom_id() {
69+
o.users.insert(user_id);
70+
responses.push(format!("You have added a vote for {o}."));
71+
}
7672
}
77-
let label = label.as_ref().unwrap();
78-
let content = Some(if exists {
79-
format!("You have removed your vote for {:?}.", label).to_string()
80-
} else {
81-
format!("You have voted for {:?}.", label).to_string()
82-
});
83-
info!("guild about to be saved");
8473
guild.save(&app_state.dynamo).await;
8574

8675
Ok(Json(json!(
8776
InteractionResponse {
8877
kind: InteractionResponseType::ChannelMessageWithSource,
8978
data: Some(InteractionResponseData {
90-
content,
79+
content: Some(responses.join("\n")),
9180
flags: Some(MessageFlags::EPHEMERAL),
9281
..Default::default()
9382
}),

api/src/guilds/votes/models.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ pub struct VoteOption {
1616
pub users: HashSet<Id<UserMarker>>
1717
}
1818

19+
impl Display for VoteOption {
20+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21+
write!(f, "{}", self.label.as_ref().unwrap())
22+
}
23+
}
24+
1925
impl From<&HashMap<String, AttributeValue>> for VoteOption {
2026
fn from(item: &HashMap<String, AttributeValue>) -> Self {
2127
VoteOption {
@@ -59,6 +65,8 @@ impl Display for RoleListType {
5965
}
6066
}
6167

68+
fn default_multi_select() -> bool {true}
69+
6270
#[derive(Clone, Serialize, Deserialize, PartialEq)]
6371
pub struct VoteVote {
6472
pub message_id: Id<MessageMarker>,
@@ -69,7 +77,9 @@ pub struct VoteVote {
6977
pub close_at: Option<DateTime<Utc>>,
7078
pub open: bool,
7179
pub role_list: HashSet<Id<RoleMarker>>,
72-
pub role_list_type: RoleListType
80+
pub role_list_type: RoleListType,
81+
#[serde(default="default_multi_select")]
82+
pub is_multi_select: bool
7383
}
7484

7585
impl From<&HashMap<String, AttributeValue>> for VoteVote {
@@ -84,6 +94,7 @@ impl From<&HashMap<String, AttributeValue>> for VoteVote {
8494
open: as_bool(item.get("open"), false),
8595
role_list: as_u64_set(item.get("role_list")).into_iter().map(|s| Id::new(s)).collect(),
8696
role_list_type: as_string_opt(item.get("role_list_type")).filter(|v| !v.is_empty()).and_then(|v| serde_json::from_str(&*v).unwrap()).unwrap_or_default(),
97+
is_multi_select: as_bool(item.get("is_multi_select"), false),
8798
}
8899
}
89100
}
@@ -100,6 +111,7 @@ impl From<VoteVote> for HashMap<String, AttributeValue> {
100111
item.insert("open".to_string(), AttributeValue::Bool(vote.open));
101112
item.insert("role_list".to_string(), AttributeValue::L(vote.role_list.iter().map(|u| AttributeValue::N(u.to_string())).collect()));
102113
item.insert("role_list_type".to_string(), AttributeValue::S(serde_json::to_string(&vote.role_list_type).unwrap()));
114+
item.insert("is_multi_select".to_string(), AttributeValue::Bool(vote.is_multi_select));
103115
item
104116
}
105117
}

api/src/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ use lambda_http::{run, tracing, Error};
66
use serde::{Deserialize, Serialize};
77
use serde_json::{json, Value};
88
use std::sync::Arc;
9-
use lambda_http::tracing::info;
109
use tower_http::cors::CorsLayer;
1110

1211
mod dynamo;

ui/package-lock.json

Lines changed: 117 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)