1use std::path::PathBuf;
 2use std::sync::Arc;
 3
 4use anyhow::Result;
 5use extension::{ExtensionHostProxy, ExtensionThemeProxy};
 6use fs::Fs;
 7use gpui::{App, BackgroundExecutor, SharedString, Task};
 8use theme::{GlobalTheme, ThemeRegistry};
 9
10pub fn init(
11    extension_host_proxy: Arc<ExtensionHostProxy>,
12    theme_registry: Arc<ThemeRegistry>,
13    executor: BackgroundExecutor,
14) {
15    extension_host_proxy.register_theme_proxy(ThemeRegistryProxy {
16        theme_registry,
17        executor,
18    });
19}
20
21struct ThemeRegistryProxy {
22    theme_registry: Arc<ThemeRegistry>,
23    executor: BackgroundExecutor,
24}
25
26impl ExtensionThemeProxy for ThemeRegistryProxy {
27    fn set_extensions_loaded(&self) {
28        self.theme_registry.set_extensions_loaded();
29    }
30
31    fn list_theme_names(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<Vec<String>>> {
32        self.executor.spawn(async move {
33            let themes = theme::read_user_theme(&theme_path, fs).await?;
34            Ok(themes.themes.into_iter().map(|theme| theme.name).collect())
35        })
36    }
37
38    fn remove_user_themes(&self, themes: Vec<SharedString>) {
39        self.theme_registry.remove_user_themes(&themes);
40    }
41
42    fn load_user_theme(&self, theme_path: PathBuf, fs: Arc<dyn Fs>) -> Task<Result<()>> {
43        let theme_registry = self.theme_registry.clone();
44        self.executor
45            .spawn(async move { theme_registry.load_user_theme(&theme_path, fs).await })
46    }
47
48    fn reload_current_theme(&self, cx: &mut App) {
49        GlobalTheme::reload_theme(cx)
50    }
51
52    fn list_icon_theme_names(
53        &self,
54        icon_theme_path: PathBuf,
55        fs: Arc<dyn Fs>,
56    ) -> Task<Result<Vec<String>>> {
57        self.executor.spawn(async move {
58            let icon_theme_family = theme::read_icon_theme(&icon_theme_path, fs).await?;
59            Ok(icon_theme_family
60                .themes
61                .into_iter()
62                .map(|theme| theme.name)
63                .collect())
64        })
65    }
66
67    fn remove_icon_themes(&self, icon_themes: Vec<SharedString>) {
68        self.theme_registry.remove_icon_themes(&icon_themes);
69    }
70
71    fn load_icon_theme(
72        &self,
73        icon_theme_path: PathBuf,
74        icons_root_dir: PathBuf,
75        fs: Arc<dyn Fs>,
76    ) -> Task<Result<()>> {
77        let theme_registry = self.theme_registry.clone();
78        self.executor.spawn(async move {
79            theme_registry
80                .load_icon_theme(&icon_theme_path, &icons_root_dir, fs)
81                .await
82        })
83    }
84
85    fn reload_current_icon_theme(&self, cx: &mut App) {
86        GlobalTheme::reload_icon_theme(cx)
87    }
88}