mirror of
https://github.com/modrinth/code.git
synced 2026-08-24 16:44:51 +00:00
qa: shared instances post release (#6893)
* fix: 20 user cap * qa: invite modal dropdown + other + clamp limits * fix: hide filters if just one type * feat: update req banner * feat: invite management frontend * fix: moderation issues with shared instances * feat: instance icon improvements * fix: better offline handling * fix: lint * feat: show avatar in install to play modal * feat: smaller qa points * fix: fmt * fix: fmt * fix: yeet svg * fix: 50 user limit
This commit is contained in:
@@ -4,6 +4,7 @@ use crate::database::models::ids::*;
|
||||
use crate::database::models::notifications_template_item::{
|
||||
NotificationTemplate, get_or_set_cached_dynamic_html,
|
||||
};
|
||||
use crate::database::models::report_item::DBReport;
|
||||
use crate::database::models::{
|
||||
DBOrganization, DBProject, DBUser, DatabaseError,
|
||||
};
|
||||
@@ -11,10 +12,12 @@ use crate::env::ENV;
|
||||
use crate::models::v3::notifications::NotificationBody;
|
||||
use crate::routes::ApiError;
|
||||
use crate::util::error::Context;
|
||||
use crate::util::http::HTTP_CLIENT;
|
||||
use ariadne::ids::base62_impl::to_base62;
|
||||
use futures::TryFutureExt;
|
||||
use lettre::Message;
|
||||
use lettre::message::{Mailbox, MultiPart, SinglePart};
|
||||
use serde::Deserialize;
|
||||
use sqlx::query;
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
@@ -312,6 +315,70 @@ enum EmailTemplate {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SharedInstance {
|
||||
name: String,
|
||||
}
|
||||
|
||||
async fn resolve_report_title(
|
||||
exec: &mut PgTransaction<'_>,
|
||||
report_id: DBReportId,
|
||||
title: String,
|
||||
) -> Result<String, ApiError> {
|
||||
if title != "unknown" {
|
||||
return Ok(title);
|
||||
}
|
||||
|
||||
let Some(report) = DBReport::get(report_id, &mut *exec).await? else {
|
||||
return Ok(title);
|
||||
};
|
||||
let Some(shared_instance_id) = report.shared_instance_id else {
|
||||
return Ok(title);
|
||||
};
|
||||
|
||||
let instance_id = to_base62(shared_instance_id.0 as u64);
|
||||
let with_version = |name: String| match report.shared_instance_version_id {
|
||||
Some(version) => format!("{name} (version {version})"),
|
||||
None => name,
|
||||
};
|
||||
let fallback = with_version(format!("shared instance {instance_id}"));
|
||||
let response = HTTP_CLIENT
|
||||
.get(format!(
|
||||
"{}/v1/instances/{instance_id}",
|
||||
ENV.SHARED_INSTANCES_URL
|
||||
))
|
||||
.bearer_auth(&ENV.SHARED_INSTANCES_KEY)
|
||||
.send()
|
||||
.await
|
||||
.and_then(reqwest::Response::error_for_status);
|
||||
|
||||
let response = match response {
|
||||
Ok(response) => response,
|
||||
Err(error) => {
|
||||
warn!(
|
||||
%error,
|
||||
report_id = report_id.0,
|
||||
%instance_id,
|
||||
"Failed to fetch shared instance name for report email"
|
||||
);
|
||||
return Ok(fallback);
|
||||
}
|
||||
};
|
||||
|
||||
match response.json::<SharedInstance>().await {
|
||||
Ok(instance) => Ok(with_version(instance.name)),
|
||||
Err(error) => {
|
||||
warn!(
|
||||
%error,
|
||||
report_id = report_id.0,
|
||||
%instance_id,
|
||||
"Failed to parse shared instance name for report email"
|
||||
);
|
||||
Ok(fallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn collect_template_variables(
|
||||
exec: &mut PgTransaction<'_>,
|
||||
redis: &RedisPool,
|
||||
@@ -359,7 +426,15 @@ async fn collect_template_variables(
|
||||
.await?;
|
||||
|
||||
map.insert(REPORT_ID, to_base62(report_id.0));
|
||||
map.insert(REPORT_TITLE, result.title);
|
||||
map.insert(
|
||||
REPORT_TITLE,
|
||||
resolve_report_title(
|
||||
exec,
|
||||
DBReportId(report_id.0 as i64),
|
||||
result.title,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
map.insert(REPORT_DATE, date_human_readable(result.created));
|
||||
Ok(EmailTemplate::Static(map))
|
||||
}
|
||||
@@ -380,7 +455,15 @@ async fn collect_template_variables(
|
||||
.fetch_one(&mut *exec)
|
||||
.await?;
|
||||
|
||||
map.insert(REPORT_TITLE, result.title);
|
||||
map.insert(
|
||||
REPORT_TITLE,
|
||||
resolve_report_title(
|
||||
exec,
|
||||
DBReportId(report_id.0 as i64),
|
||||
result.title,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
map.insert(NEWREPORT_ID, to_base62(report_id.0));
|
||||
Ok(EmailTemplate::Static(map))
|
||||
}
|
||||
|
||||
@@ -60,16 +60,13 @@ pub async fn report_create(
|
||||
pub struct ReportsRequestOptions {
|
||||
#[serde(default = "default_count")]
|
||||
count: u16,
|
||||
#[serde(default = "default_all")]
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
}
|
||||
|
||||
fn default_count() -> u16 {
|
||||
100
|
||||
}
|
||||
fn default_all() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Get open reports for the current user.
|
||||
#[utoipa::path(
|
||||
|
||||
@@ -320,16 +320,13 @@ pub struct ReportsRequestOptions {
|
||||
pub count: u16,
|
||||
#[serde(default)]
|
||||
pub offset: u32,
|
||||
#[serde(default = "default_all")]
|
||||
#[serde(default)]
|
||||
pub all: bool,
|
||||
}
|
||||
|
||||
fn default_count() -> u16 {
|
||||
100
|
||||
}
|
||||
fn default_all() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
tag = "reports",
|
||||
|
||||
Reference in New Issue
Block a user