use crate::config::Config;
use crate::extension::{Extension, Lang};
use serde::Serialize;
use sqlx::SqlitePool;
use std::sync::Arc;
#[derive(Serialize)]
pub struct ManifestSite {
pub name: String,
pub base_url: String,
pub default_lang: String,
pub languages: Vec<String>,
}
#[derive(Serialize, Clone)]
pub struct ManifestLocalized {
pub ko: String,
pub en: String,
}
#[derive(Serialize, Clone, Default)]
pub struct LobbyConfigInfo {
pub enabled: bool,
pub display_mode: String,
pub display_order: i64,
pub style_params: serde_json::Value,
}
#[derive(Serialize)]
pub struct ManifestExtension {
pub id: String,
pub display_name: ManifestLocalized,
pub lobby: LobbyConfigInfo,
}
#[derive(Serialize)]
pub struct Manifest {
pub site: ManifestSite,
pub extensions: Vec<ManifestExtension>,
}
pub async fn lobby_config_for(
db: &SqlitePool,
config: &Config,
ext_id: &str,
default_order: i64,
) -> LobbyConfigInfo {
let row: Option<(bool, String, i64, String)> = sqlx::query_as(
"SELECT enabled, display_mode, display_order, style_params
FROM lobby_config WHERE extension_id = ?",
)
.bind(ext_id)
.fetch_optional(db)
.await
.ok()
.flatten();
match row {
Some((enabled, mode, order, params)) => LobbyConfigInfo {
enabled,
display_mode: mode,
display_order: order,
style_params: serde_json::from_str(¶ms).unwrap_or_default(),
},
None => LobbyConfigInfo {
enabled: true,
display_mode: config.lobby.default_mode.clone(),
display_order: default_order,
style_params: serde_json::json!({}),
},
}
}
pub async fn assemble(
db: &SqlitePool,
config: &Config,
site_name: &str,
base_url: &str,
extensions: &[Arc<dyn Extension>],
) -> Manifest {
let mut ext_list = Vec::with_capacity(extensions.len());
for (idx, e) in extensions.iter().enumerate() {
if !is_active(db, e.id()).await {
continue;
}
let lobby = lobby_config_for(db, config, e.id(), idx as i64).await;
ext_list.push(ManifestExtension {
id: e.id().to_string(),
display_name: ManifestLocalized {
ko: e.display_name(Lang::Ko),
en: e.display_name(Lang::En),
},
lobby,
});
}
Manifest {
site: ManifestSite {
name: site_name.to_string(),
base_url: base_url.to_string(),
default_lang: config.site.default_lang.clone(),
languages: config.site.languages.clone(),
},
extensions: ext_list,
}
}
async fn is_active(db: &SqlitePool, ext_id: &str) -> bool {
let row: Option<(i64, i64)> =
sqlx::query_as("SELECT enabled, purged FROM extension_state WHERE extension_id = ?")
.bind(ext_id)
.fetch_optional(db)
.await
.ok()
.flatten();
match row {
Some((enabled, purged)) => enabled != 0 && purged == 0,
None => true,
}
}