use crate::core::action::add_action;
use crate::core::extension::ExtensionRef;
use crate::core::theme::all::THEMES;
use crate::{global, service, static_files_service, trace};
use parking_lot::RwLock;
use std::sync::LazyLock;
static ENABLED_EXTENSIONS: LazyLock<RwLock<Vec<ExtensionRef>>> =
LazyLock::new(|| RwLock::new(Vec::new()));
static DROPPED_EXTENSIONS: LazyLock<RwLock<Vec<ExtensionRef>>> =
LazyLock::new(|| RwLock::new(Vec::new()));
pub fn register_extensions(root_extension: Option<ExtensionRef>) {
let mut enabled_list: Vec<ExtensionRef> = Vec::new();
add_to_enabled(&mut enabled_list, &crate::base::theme::Basic);
if let Some(extension) = root_extension {
add_to_enabled(&mut enabled_list, extension);
}
if global::SETTINGS.app.welcome {
add_to_enabled(&mut enabled_list, &crate::base::extension::Welcome);
}
ENABLED_EXTENSIONS.write().append(&mut enabled_list);
let mut dropped_list: Vec<ExtensionRef> = Vec::new();
if let Some(extension) = root_extension {
add_to_dropped(&mut dropped_list, extension);
}
DROPPED_EXTENSIONS.write().append(&mut dropped_list);
}
fn add_to_enabled(list: &mut Vec<ExtensionRef>, extension: ExtensionRef) {
if !list.iter().any(|e| e.type_id() == extension.type_id()) {
for d in extension.dependencies().iter().rev() {
add_to_enabled(list, *d);
}
list.push(extension);
if let Some(theme) = extension.theme() {
let mut registered_themes = THEMES.write();
if !registered_themes
.iter()
.any(|t| t.type_id() == theme.type_id())
{
registered_themes.push(theme);
trace::debug!("Enabling \"{}\" theme", theme.short_name());
}
} else {
trace::debug!("Enabling \"{}\" extension", extension.short_name());
}
}
}
fn add_to_dropped(list: &mut Vec<ExtensionRef>, extension: ExtensionRef) {
for d in &extension.drop_extensions() {
if !list.iter().any(|e| e.type_id() == d.type_id()) {
if ENABLED_EXTENSIONS
.read()
.iter()
.any(|e| e.type_id() == extension.type_id())
{
trace::warn!(
"Trying to drop \"{}\" extension which is enabled",
extension.short_name()
);
} else {
list.push(*d);
trace::debug!("Extension \"{}\" dropped", d.short_name());
for dependency in &extension.dependencies() {
add_to_dropped(list, *dependency);
}
}
}
}
}
pub fn register_actions() {
for extension in ENABLED_EXTENSIONS.read().iter() {
for a in extension.actions().into_iter() {
add_action(a);
}
}
}
pub fn initialize_extensions() {
trace::info!("Calling application bootstrap");
for extension in ENABLED_EXTENSIONS.read().iter() {
extension.initialize();
}
}
pub fn configure_services(scfg: &mut service::web::ServiceConfig) {
#[cfg(debug_assertions)]
scfg.route(
"/.well-known/appspecific/com.chrome.devtools.json",
service::web::get().to(|| async { service::HttpResponse::NotFound().finish() }),
);
for extension in ENABLED_EXTENSIONS.read().iter() {
extension.configure_service(scfg);
}
static_files_service!(scfg, [&global::SETTINGS.dev.pagetop_static_dir, assets] => "/");
}