feat(plugins): implement plugin loading and management system
- Added PluginLoader component to dynamically load and initialize plugins. - Created Plugins component for managing installed and marketplace plugins. - Introduced PluginAPI for plugin interaction and settings management. - Defined types for plugin metadata, installed plugins, and plugin index. - Implemented settings rendering for plugins based on their schema. - Integrated marketplace plugin fetching and installation logic. - Added support for enabling/disabling and uninstalling plugins.
This commit is contained in:
@@ -4,6 +4,7 @@ import { onDarkFontWeight, onLightFontWeight } from '../../config.css';
|
||||
import { butterTheme, catppuccinMochaTheme, darkTheme, discordTheme, discordDarkerTheme, mochaTheme, silverTheme, twilightTheme } from '../../colors.css';
|
||||
import { settingsAtom } from '../state/settings';
|
||||
import { useSetting } from '../state/hooks/settings';
|
||||
import { pluginRegistry } from '../features/settings/plugins/PluginAPI';
|
||||
|
||||
export enum ThemeKind {
|
||||
Light = 'light',
|
||||
@@ -64,14 +65,51 @@ export const CatppuccinMochaTheme: Theme = {
|
||||
};
|
||||
|
||||
export const useThemes = (): Theme[] => {
|
||||
const themes: Theme[] = useMemo(() => [LightTheme, SilverTheme, DarkTheme, ButterTheme, DiscordTheme, DiscordDarkerTheme, TwilightTheme, MochaTheme, CatppuccinMochaTheme], []);
|
||||
const [pluginThemesUpdate, setPluginThemesUpdate] = useState(0);
|
||||
|
||||
// Force update when plugins change (this is a simple approach)
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setPluginThemesUpdate(prev => prev + 1);
|
||||
}, 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const builtInThemes: Theme[] = useMemo(() => [
|
||||
LightTheme, SilverTheme, DarkTheme, ButterTheme,
|
||||
DiscordTheme, DiscordDarkerTheme, TwilightTheme,
|
||||
MochaTheme, CatppuccinMochaTheme
|
||||
], []);
|
||||
|
||||
// Convert plugin themes to Theme format
|
||||
const pluginThemes: Theme[] = useMemo(() => {
|
||||
const themes = pluginRegistry.getPluginThemes();
|
||||
return themes.map(pluginTheme => ({
|
||||
id: pluginTheme.id,
|
||||
kind: pluginTheme.kind === 'dark' ? ThemeKind.Dark : ThemeKind.Light,
|
||||
classNames: [
|
||||
pluginTheme.className,
|
||||
pluginTheme.kind === 'dark' ? onDarkFontWeight : onLightFontWeight,
|
||||
pluginTheme.kind === 'dark' ? 'prism-dark' : 'prism-light'
|
||||
]
|
||||
}));
|
||||
}, [pluginThemesUpdate]);
|
||||
|
||||
return themes;
|
||||
return [...builtInThemes, ...pluginThemes];
|
||||
};
|
||||
|
||||
export const useThemeNames = (): Record<string, string> =>
|
||||
useMemo(
|
||||
() => ({
|
||||
export const useThemeNames = (): Record<string, string> => {
|
||||
const [pluginThemesUpdate, setPluginThemesUpdate] = useState(0);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setPluginThemesUpdate(prev => prev + 1);
|
||||
}, 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
return useMemo(() => {
|
||||
const builtInNames = {
|
||||
[LightTheme.id]: 'Light',
|
||||
[SilverTheme.id]: 'Silver',
|
||||
[DarkTheme.id]: 'Dark',
|
||||
@@ -81,9 +119,17 @@ export const useThemeNames = (): Record<string, string> =>
|
||||
[TwilightTheme.id]: 'Twilight',
|
||||
[MochaTheme.id]: 'Mocha',
|
||||
[CatppuccinMochaTheme.id]: 'Catppuccin Mocha',
|
||||
}),
|
||||
[]
|
||||
);
|
||||
};
|
||||
|
||||
const pluginThemes = pluginRegistry.getPluginThemes();
|
||||
const pluginNames = pluginThemes.reduce((acc, theme) => {
|
||||
acc[theme.id] = theme.name;
|
||||
return acc;
|
||||
}, {} as Record<string, string>);
|
||||
|
||||
return { ...builtInNames, ...pluginNames };
|
||||
}, [pluginThemesUpdate]);
|
||||
};
|
||||
|
||||
export const useSystemThemeKind = (): ThemeKind => {
|
||||
const darkModeQueryList = useMemo(() => window.matchMedia('(prefers-color-scheme: dark)'), []);
|
||||
|
||||
Reference in New Issue
Block a user