Add notification for project status updates (#511)

* Add notification for project status updates

* aaaaaa

* cargo sqlx prepare

* use friendly name of statuses

* Update src/models/projects.rs

Co-authored-by: triphora <emma@modrinth.com>

* only send notifications to accepted users

* only send notifications for people not on the team

* cargo sqlx prepare

* !=

* fully address pr comments

Co-authored-by: triphora <emma@modrinth.com>
Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
BasiqueEvangelist 2022-12-31 00:40:00 +03:00 committed by GitHub
parent 34af33607b
commit 161dee89ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 2 deletions

View File

@ -7186,6 +7186,26 @@
},
"query": "\n UPDATE mods\n SET status = $1\n WHERE (id = $2)\n "
},
"ea1525cbe7460d0d9e9da8f448c661f7209bc1a7a04e2ea0026fa69c3f550a14": {
"describe": {
"columns": [
{
"name": "id",
"ordinal": 0,
"type_info": "Int8"
}
],
"nullable": [
false
],
"parameters": {
"Left": [
"Int8"
]
}
},
"query": "\n SELECT tm.user_id id\n FROM team_members tm\n WHERE tm.team_id = $1 AND tm.accepted\n "
},
"ebef881a0dae70e990814e567ed3de9565bb29b772782bc974c953af195fd6d7": {
"describe": {
"columns": [

View File

@ -319,6 +319,20 @@ impl ProjectStatus {
ProjectStatus::Private => "private",
}
}
pub fn as_friendly_str(&self) -> &'static str {
match self {
ProjectStatus::Approved => "Listed",
ProjectStatus::Rejected => "Rejected",
ProjectStatus::Draft => "Draft",
ProjectStatus::Unlisted => "Unlisted",
ProjectStatus::Processing => "Under review",
ProjectStatus::Unknown => "Unknown",
ProjectStatus::Archived => "Archived",
ProjectStatus::Withheld => "Withheld",
ProjectStatus::Scheduled => "Scheduled",
ProjectStatus::Private => "Private",
}
}
pub fn iterator() -> impl Iterator<Item = ProjectStatus> {
[

View File

@ -1,4 +1,5 @@
use crate::database;
use crate::database::models::notification_item::NotificationBuilder;
use crate::file_hosting::FileHost;
use crate::models;
use crate::models::ids::UserId;
@ -13,7 +14,7 @@ use crate::util::routes::read_from_payload;
use crate::util::validate::validation_errors_to_string;
use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse};
use chrono::{DateTime, Utc};
use futures::StreamExt;
use futures::{StreamExt, TryStreamExt};
use serde::{Deserialize, Serialize};
use serde_json::json;
use sqlx::{PgPool, Row};
@ -395,7 +396,7 @@ pub async fn project_edit(
if user.role.is_admin() {
permissions = Some(Permissions::ALL)
} else if let Some(member) = team_member {
} else if let Some(ref member) = team_member {
permissions = Some(member.permissions)
} else if user.role.is_mod() {
permissions =
@ -551,6 +552,40 @@ pub async fn project_edit(
}
}
if team_member.map(|x| !x.accepted).unwrap_or(true) {
let notified_members = sqlx::query!(
"
SELECT tm.user_id id
FROM team_members tm
WHERE tm.team_id = $1 AND tm.accepted
",
project_item.inner.team_id as database::models::ids::TeamId
)
.fetch_many(&mut *transaction)
.try_filter_map(|e| async { Ok(e.right().map(|c| database::models::UserId(c.id))) })
.try_collect::<Vec<_>>()
.await?;
NotificationBuilder {
notification_type: Some("status_update".to_string()),
title: format!("**{}**'s status has changed!", project_item.inner.title),
text: format!(
"The project {}'s status has changed from {} to {}",
project_item.inner.title,
project_item.inner.status.as_friendly_str(),
status.as_friendly_str()
),
link: format!(
"/{}/{}",
project_item.project_type,
ProjectId::from(id)
),
actions: vec![],
}
.insert_many(notified_members, &mut transaction)
.await?;
}
sqlx::query!(
"
UPDATE mods