[skip ci] Feat: Hot reload for plugins
This commit is contained in:
@@ -21,6 +21,7 @@ import { FixedSizeList, ListChildComponentProps } from 'react-window';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { AppState } from '@redux/store';
|
||||
import { selectPlugin } from '@redux/pluginSlice';
|
||||
import usePlugin from '@hooks/usePlugin';
|
||||
|
||||
const resovleIcon = (iconPath: string) => {
|
||||
return '/icons/' + iconPath;
|
||||
@@ -30,9 +31,7 @@ export default function () {
|
||||
const [searchedPlugins, setSearchPlugins] = useState<Plugin.PluginBase[]>([]);
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const [listVisible, setListVisible] = useState(false);
|
||||
const selectedPlugin = useSelector(
|
||||
(state: AppState) => state.plugin.selected,
|
||||
);
|
||||
const plugin = usePlugin();
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const plugins = searchPlugins(keyword);
|
||||
@@ -128,15 +127,15 @@ export default function () {
|
||||
Language
|
||||
</Button>
|
||||
</InputAdornment>
|
||||
{selectedPlugin ? (
|
||||
{plugin ? (
|
||||
<Box sx={{ pl: 2, display: 'flex', alignItems: 'center' }}>
|
||||
<Avatar
|
||||
sx={{ mr: 1 }}
|
||||
src={resovleIcon(selectedPlugin.icon)}
|
||||
src={resovleIcon(plugin.icon)}
|
||||
variant="square"
|
||||
/>
|
||||
<a href={selectedPlugin.site} target="_blank">
|
||||
{selectedPlugin.name} - v{selectedPlugin.version}
|
||||
<a href={plugin.site} target="_blank">
|
||||
{plugin.name} - v{plugin.version}
|
||||
</a>
|
||||
</Box>
|
||||
) : null}
|
||||
|
||||
Vendored
+1
-4
@@ -1,4 +1 @@
|
||||
declare module '*.jpg';
|
||||
declare module '*.png';
|
||||
declare module '*.svg';
|
||||
declare module '*.jpeg';
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
import { Plugin } from '@typings/plugin';
|
||||
|
||||
export default [] as Plugin.PluginBase[];
|
||||
@@ -1,18 +1,11 @@
|
||||
import React, { ReactNode, useEffect } from 'react';
|
||||
import DialogProvider from './DialogProvider';
|
||||
import { Backdrop, Box, CircularProgress, Container } from '@mui/material';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { AppState } from '@redux/store';
|
||||
import { loadPlugins } from './plugins';
|
||||
import { hideLoading } from '@redux/overlaySlice';
|
||||
|
||||
export default function AppProvider() {
|
||||
const loading = useSelector((state: AppState) => state.overlay.loading);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
loadPlugins().then(() => dispatch(hideLoading()));
|
||||
}, []);
|
||||
return (
|
||||
<Container sx={{ position: 'absolute' }}>
|
||||
<Backdrop
|
||||
|
||||
+1
-16
@@ -1,19 +1,4 @@
|
||||
import { Plugin } from '@typings/plugin';
|
||||
|
||||
const plugins: Plugin.PluginBase[] = [];
|
||||
|
||||
export const loadPlugins = async () => {
|
||||
const paths = await fetch('pluginPaths').then(res => res.json());
|
||||
const fetchedPlugins: Plugin.PluginBase[] = [];
|
||||
for (const path of paths) {
|
||||
const relativePath = '../plugins/' + path;
|
||||
const plugin: Plugin.PluginBase = (
|
||||
await import(/* @vite-ignore */ relativePath)
|
||||
).default;
|
||||
fetchedPlugins.push(plugin);
|
||||
}
|
||||
plugins.splice(0, plugins.length, ...fetchedPlugins);
|
||||
};
|
||||
import plugins from '../plugins';
|
||||
|
||||
export const searchPlugins = (keyword: string) => {
|
||||
return plugins.filter(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
const initialState = {
|
||||
loading: true,
|
||||
loading: false,
|
||||
};
|
||||
|
||||
export const overlaySlice = createSlice({
|
||||
|
||||
Reference in New Issue
Block a user