Allow muting accounts #1
6 changed files with 89 additions and 1 deletions
|
@ -614,6 +614,44 @@ pub async fn show_replies(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn mute_posts(
|
||||
db_client: &impl DatabaseClient,
|
||||
source_id: &Uuid,
|
||||
target_id: &Uuid,
|
||||
) -> Result<(), DatabaseError> {
|
||||
db_client
|
||||
.execute(
|
||||
"
|
||||
INSERT INTO relationship (source_id, target_id, relationship_type)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (source_id, target_id, relationship_type) DO NOTHING
|
||||
",
|
||||
&[&source_id, &target_id, &RelationshipType::Mute],
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn unmute_posts(
|
||||
db_client: &impl DatabaseClient,
|
||||
source_id: &Uuid,
|
||||
target_id: &Uuid,
|
||||
) -> Result<(), DatabaseError> {
|
||||
// Does not return NotFound error
|
||||
db_client
|
||||
.execute(
|
||||
"
|
||||
DELETE FROM relationship
|
||||
WHERE
|
||||
source_id = $1 AND target_id = $2
|
||||
AND relationship_type = $3
|
||||
",
|
||||
&[&source_id, &target_id, &RelationshipType::Mute],
|
||||
)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
@ -17,6 +17,7 @@ pub enum RelationshipType {
|
|||
Subscription,
|
||||
HideReposts,
|
||||
HideReplies,
|
||||
Mute,
|
||||
}
|
||||
|
||||
impl From<&RelationshipType> for i16 {
|
||||
|
@ -27,6 +28,7 @@ impl From<&RelationshipType> for i16 {
|
|||
RelationshipType::Subscription => 3,
|
||||
RelationshipType::HideReposts => 4,
|
||||
RelationshipType::HideReplies => 5,
|
||||
RelationshipType::Mute => 6,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +43,7 @@ impl TryFrom<i16> for RelationshipType {
|
|||
3 => Self::Subscription,
|
||||
4 => Self::HideReposts,
|
||||
5 => Self::HideReplies,
|
||||
6 => Self::Mute,
|
||||
_ => return Err(DatabaseTypeError),
|
||||
};
|
||||
Ok(relationship_type)
|
||||
|
|
|
@ -52,6 +52,11 @@ pub async fn get_relationship(
|
|||
relationship_map.showing_replies = false;
|
||||
};
|
||||
}
|
||||
RelationshipType::Mute => {
|
||||
if relationship.is_direct(source_id, target_id)? {
|
||||
relationship_map.muting = true;
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(relationship_map)
|
||||
|
|
|
@ -402,6 +402,7 @@ pub struct RelationshipMap {
|
|||
pub subscription_from: bool,
|
||||
pub showing_reblogs: bool,
|
||||
pub showing_replies: bool,
|
||||
pub muting: bool,
|
||||
}
|
||||
|
||||
fn default_showing_reblogs() -> bool {
|
||||
|
@ -423,6 +424,7 @@ impl Default for RelationshipMap {
|
|||
subscription_from: false,
|
||||
showing_reblogs: default_showing_reblogs(),
|
||||
showing_replies: default_showing_replies(),
|
||||
muting: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ use actix_web_httpauth::extractors::bearer::BearerAuth;
|
|||
use uuid::Uuid;
|
||||
|
||||
use fedimovies_config::{Config, DefaultRole, RegistrationType};
|
||||
use fedimovies_models::relationships::queries::{mute_posts, unmute_posts};
|
||||
use fedimovies_models::{
|
||||
database::{get_database_client, DatabaseError, DbPool},
|
||||
posts::queries::get_posts_by_author,
|
||||
|
@ -367,6 +368,41 @@ async fn unfollow_account(
|
|||
Ok(HttpResponse::Ok().json(relationship))
|
||||
}
|
||||
|
||||
#[post("/{account_id}/mute")]
|
||||
async fn mute_account(
|
||||
auth: BearerAuth,
|
||||
db_pool: web::Data<DbPool>,
|
||||
account_id: web::Path<Uuid>,
|
||||
) -> Result<HttpResponse, MastodonError> {
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||
let target = get_profile_by_id(db_client, &account_id).await?;
|
||||
|
||||
mute_posts(db_client, ¤t_user.id, &target.id).await?;
|
||||
|
||||
let relationship = get_relationship(db_client, ¤t_user.id, &target.id).await?;
|
||||
Ok(HttpResponse::Ok().json(relationship))
|
||||
}
|
||||
|
||||
#[post("/{account_id}/unmute")]
|
||||
async fn unmute_account(
|
||||
auth: BearerAuth,
|
||||
db_pool: web::Data<DbPool>,
|
||||
account_id: web::Path<Uuid>,
|
||||
) -> Result<HttpResponse, MastodonError> {
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
let current_user = get_current_user(db_client, auth.token()).await?;
|
||||
let target = get_profile_by_id(db_client, &account_id).await?;
|
||||
match unmute_posts(db_client, ¤t_user.id, &target.id).await {
|
||||
Ok(()) => (),
|
||||
Err(DatabaseError::NotFound(_)) => (), // not following
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
|
||||
let relationship = get_relationship(db_client, ¤t_user.id, &target.id).await?;
|
||||
Ok(HttpResponse::Ok().json(relationship))
|
||||
}
|
||||
|
||||
#[get("/{account_id}/statuses")]
|
||||
async fn get_account_statuses(
|
||||
auth: Option<BearerAuth>,
|
||||
|
@ -566,6 +602,8 @@ pub fn account_api_scope() -> Scope {
|
|||
.service(get_account)
|
||||
.service(follow_account)
|
||||
.service(unfollow_account)
|
||||
.service(mute_account)
|
||||
.service(unmute_account)
|
||||
.service(get_account_statuses)
|
||||
.service(get_account_followers)
|
||||
.service(get_account_following)
|
||||
|
|
|
@ -18,6 +18,7 @@ struct InstanceStats {
|
|||
struct InstanceStatusLimits {
|
||||
max_characters: usize,
|
||||
max_media_attachments: usize,
|
||||
characters_reserved_per_url: usize,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -105,6 +106,7 @@ impl InstanceInfo {
|
|||
statuses: InstanceStatusLimits {
|
||||
max_characters: config.limits.posts.character_limit,
|
||||
max_media_attachments: ATTACHMENT_LIMIT,
|
||||
characters_reserved_per_url: 32, // not real, but for compatibility
|
||||
},
|
||||
media_attachments: InstanceMediaLimits {
|
||||
supported_mime_types: SUPPORTED_MEDIA_TYPES
|
||||
|
@ -117,7 +119,7 @@ impl InstanceInfo {
|
|||
},
|
||||
thumbnail: None,
|
||||
email: "".to_string(),
|
||||
languages: vec![],
|
||||
languages: vec!["en".to_string()],
|
||||
rules: vec![],
|
||||
urls: None,
|
||||
login_message: config.login_message.clone(),
|
||||
|
|
Loading…
Reference in a new issue