forked from jmug/stoatchat
fix: add back missing early adopter badge
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use futures::future::join_all;
|
||||||
use revolt_database::{
|
use revolt_database::{
|
||||||
events::client::{EventV1, ReadyPayloadFields},
|
events::client::{EventV1, ReadyPayloadFields},
|
||||||
util::permissions::DatabasePermissionQuery,
|
util::permissions::DatabasePermissionQuery,
|
||||||
@@ -198,13 +199,12 @@ impl State {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// Make all users appear from our perspective.
|
// Make all users appear from our perspective.
|
||||||
let mut users: Vec<v0::User> = users
|
let mut users: Vec<v0::User> = join_all(users
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|other_user| {
|
.map(|other_user| async {
|
||||||
let is_online = online_ids.contains(&other_user.id);
|
let is_online = online_ids.contains(&other_user.id);
|
||||||
other_user.into_known(&user, is_online)
|
other_user.into_known(&user, is_online).await
|
||||||
})
|
})).await;
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Make sure we see our own user correctly.
|
// Make sure we see our own user correctly.
|
||||||
users.push(user.into_self(true).await);
|
users.push(user.into_self(true).await);
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ hcaptcha_sitekey = ""
|
|||||||
# Maximum concurrent connections (to proxy server)
|
# Maximum concurrent connections (to proxy server)
|
||||||
max_concurrent_connections = 50
|
max_concurrent_connections = 50
|
||||||
|
|
||||||
|
[api.users]
|
||||||
|
|
||||||
|
|
||||||
[pushd]
|
[pushd]
|
||||||
# this changes the names of the queues to not overlap
|
# this changes the names of the queues to not overlap
|
||||||
# prod/beta if they happen to be on the same exchange/instance.
|
# prod/beta if they happen to be on the same exchange/instance.
|
||||||
|
|||||||
@@ -175,12 +175,18 @@ pub struct ApiWorkers {
|
|||||||
pub max_concurrent_connections: usize,
|
pub max_concurrent_connections: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub struct ApiUsers {
|
||||||
|
pub early_adopter_cutoff: Option<u64>
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct Api {
|
pub struct Api {
|
||||||
pub registration: ApiRegistration,
|
pub registration: ApiRegistration,
|
||||||
pub smtp: ApiSmtp,
|
pub smtp: ApiSmtp,
|
||||||
pub security: ApiSecurity,
|
pub security: ApiSecurity,
|
||||||
pub workers: ApiWorkers,
|
pub workers: ApiWorkers,
|
||||||
|
pub users: ApiUsers,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ use std::{collections::HashSet, str::FromStr, time::Duration};
|
|||||||
use crate::{events::client::EventV1, Database, File, RatelimitEvent, AMQP};
|
use crate::{events::client::EventV1, Database, File, RatelimitEvent, AMQP};
|
||||||
|
|
||||||
use authifier::config::{EmailVerificationConfig, Template};
|
use authifier::config::{EmailVerificationConfig, Template};
|
||||||
|
use futures::future::join_all;
|
||||||
use iso8601_timestamp::Timestamp;
|
use iso8601_timestamp::Timestamp;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use revolt_config::{config, FeaturesLimits};
|
use revolt_config::{config, FeaturesLimits};
|
||||||
use revolt_models::v0::{self, UserFlags};
|
use revolt_models::v0::{self, UserFlags, UserBadges};
|
||||||
use revolt_presence::filter_online;
|
use revolt_presence::filter_online;
|
||||||
use revolt_result::{create_error, Result};
|
use revolt_result::{create_error, Result};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
@@ -348,15 +349,16 @@ impl User {
|
|||||||
) -> Result<Vec<v0::User>> {
|
) -> Result<Vec<v0::User>> {
|
||||||
let online_ids = filter_online(ids).await;
|
let online_ids = filter_online(ids).await;
|
||||||
|
|
||||||
Ok(db
|
Ok(join_all(
|
||||||
|
db
|
||||||
.fetch_users(ids)
|
.fetch_users(ids)
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|user| {
|
.map(|user| async {
|
||||||
let is_online = online_ids.contains(&user.id);
|
let is_online = online_ids.contains(&user.id);
|
||||||
user.into_known(perspective, is_online)
|
user.into_known(perspective, is_online).await
|
||||||
})
|
})
|
||||||
.collect())
|
).await)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find a free discriminator for a given username
|
/// Find a free discriminator for a given username
|
||||||
@@ -807,4 +809,18 @@ impl User {
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the user's badges along with calculating any dynamic badges
|
||||||
|
pub async fn get_badges(&self) -> u32 {
|
||||||
|
let config = config().await;
|
||||||
|
let badges = self.badges.unwrap_or_default() as u32;
|
||||||
|
|
||||||
|
if let Some(cutoff) = config.api.users.early_adopter_cutoff {
|
||||||
|
if Ulid::from_string(&self.id).unwrap().timestamp_ms() < cutoff {
|
||||||
|
return badges + UserBadges::EarlyAdopter as u32
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
badges
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -994,6 +994,8 @@ impl crate::User {
|
|||||||
(RelationshipStatus::None, false)
|
(RelationshipStatus::None, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let badges = self.get_badges().await;
|
||||||
|
|
||||||
User {
|
User {
|
||||||
username: self.username,
|
username: self.username,
|
||||||
discriminator: self.discriminator,
|
discriminator: self.discriminator,
|
||||||
@@ -1012,7 +1014,7 @@ impl crate::User {
|
|||||||
} else {
|
} else {
|
||||||
vec![]
|
vec![]
|
||||||
},
|
},
|
||||||
badges: self.badges.unwrap_or_default() as u32,
|
badges,
|
||||||
online: can_see_profile
|
online: can_see_profile
|
||||||
&& revolt_presence::is_online(&self.id).await
|
&& revolt_presence::is_online(&self.id).await
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
@@ -1038,7 +1040,7 @@ impl crate::User {
|
|||||||
/// Convert user object into user model assuming mutual connection
|
/// Convert user object into user model assuming mutual connection
|
||||||
///
|
///
|
||||||
/// Relations will never be included, i.e. when we process ourselves
|
/// Relations will never be included, i.e. when we process ourselves
|
||||||
pub fn into_known<'a, P>(self, perspective: P, is_online: bool) -> User
|
pub async fn into_known<'a, P>(self, perspective: P, is_online: bool) -> User
|
||||||
where
|
where
|
||||||
P: Into<Option<&'a crate::User>>,
|
P: Into<Option<&'a crate::User>>,
|
||||||
{
|
{
|
||||||
@@ -1068,13 +1070,15 @@ impl crate::User {
|
|||||||
(RelationshipStatus::None, false)
|
(RelationshipStatus::None, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let badges = self.get_badges().await;
|
||||||
|
|
||||||
User {
|
User {
|
||||||
username: self.username,
|
username: self.username,
|
||||||
discriminator: self.discriminator,
|
discriminator: self.discriminator,
|
||||||
display_name: self.display_name,
|
display_name: self.display_name,
|
||||||
avatar: self.avatar.map(|file| file.into()),
|
avatar: self.avatar.map(|file| file.into()),
|
||||||
relations: vec![],
|
relations: vec![],
|
||||||
badges: self.badges.unwrap_or_default() as u32,
|
badges,
|
||||||
online: can_see_profile
|
online: can_see_profile
|
||||||
&& is_online
|
&& is_online
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
@@ -1098,14 +1102,16 @@ impl crate::User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert user object into user model without presence information
|
/// Convert user object into user model without presence information
|
||||||
pub fn into_known_static(self, is_online: bool) -> User {
|
pub async fn into_known_static<'a>(self, is_online: bool) -> User {
|
||||||
|
let badges = self.get_badges().await;
|
||||||
|
|
||||||
User {
|
User {
|
||||||
username: self.username,
|
username: self.username,
|
||||||
discriminator: self.discriminator,
|
discriminator: self.discriminator,
|
||||||
display_name: self.display_name,
|
display_name: self.display_name,
|
||||||
avatar: self.avatar.map(|file| file.into()),
|
avatar: self.avatar.map(|file| file.into()),
|
||||||
relations: vec![],
|
relations: vec![],
|
||||||
badges: self.badges.unwrap_or_default() as u32,
|
badges,
|
||||||
online: is_online
|
online: is_online
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
self.status,
|
self.status,
|
||||||
@@ -1124,6 +1130,8 @@ impl crate::User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn into_self(self, force_online: bool) -> User {
|
pub async fn into_self(self, force_online: bool) -> User {
|
||||||
|
let badges = self.get_badges().await;
|
||||||
|
|
||||||
User {
|
User {
|
||||||
username: self.username,
|
username: self.username,
|
||||||
discriminator: self.discriminator,
|
discriminator: self.discriminator,
|
||||||
@@ -1138,7 +1146,7 @@ impl crate::User {
|
|||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
badges: self.badges.unwrap_or_default() as u32,
|
badges,
|
||||||
online: (force_online || revolt_presence::is_online(&self.id).await)
|
online: (force_online || revolt_presence::is_online(&self.id).await)
|
||||||
&& !matches!(
|
&& !matches!(
|
||||||
self.status,
|
self.status,
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ pub async fn message_send(
|
|||||||
// Create model user / members
|
// Create model user / members
|
||||||
let model_user = user
|
let model_user = user
|
||||||
.clone()
|
.clone()
|
||||||
.into_known_static(revolt_presence::is_online(&user.id).await);
|
.into_known_static(revolt_presence::is_online(&user.id).await).await;
|
||||||
|
|
||||||
let model_member: Option<v0::Member> = query
|
let model_member: Option<v0::Member> = query
|
||||||
.member_ref()
|
.member_ref()
|
||||||
|
|||||||
Reference in New Issue
Block a user