diff --git a/gulpfile.ts b/gulpfile.ts
index 85305cd0e..a518e0d47 100644
--- a/gulpfile.ts
+++ b/gulpfile.ts
@@ -47,7 +47,14 @@ gulp.task('build:copy:views', () =>
gulp.src('./src/server/web/views/**/*').pipe(gulp.dest('./built/server/web/views'))
);
-gulp.task('build:copy', gulp.parallel('build:copy:views', () =>
+gulp.task('build:copy:plugins', () =>
+ gulp.src([
+ './src/plugins/**/*',
+ '!./src/plugins/**/*.ts'
+ ]).pipe(gulp.dest('./built/plugins'))
+);
+
+gulp.task('build:copy', gulp.parallel('build:copy:views', 'build:copy:plugins', () =>
gulp.src([
'./src/const.json',
'./src/server/web/views/**/*',
diff --git a/src/boot/index.ts b/src/boot/index.ts
index 2c86d8ed8..9532e6694 100644
--- a/src/boot/index.ts
+++ b/src/boot/index.ts
@@ -21,11 +21,11 @@ export default async function() {
process.title = `Misskey (${cluster.isMaster ? 'master' : 'worker'})`;
if (cluster.isMaster || program.disableClustering) {
- await masterMain();
-
if (cluster.isMaster) {
ev.mount();
}
+
+ await masterMain();
}
if (cluster.isWorker || program.disableClustering) {
diff --git a/src/boot/master.ts b/src/boot/master.ts
index 6c23a528f..2e97e5fe1 100644
--- a/src/boot/master.ts
+++ b/src/boot/master.ts
@@ -1,3 +1,4 @@
+import * as path from 'path';
import * as os from 'os';
import * as cluster from 'cluster';
import chalk from 'chalk';
@@ -12,6 +13,7 @@ import * as pkg from '../../package.json';
import { program } from '../argv';
import { showMachineInfo } from '../misc/show-machine-info';
import { initDb } from '../db/postgre';
+import Xev from 'xev';
const logger = new Logger('core', 'cyan');
const bootLogger = logger.createSubLogger('boot', 'magenta', false);
@@ -75,6 +77,10 @@ export async function masterMain() {
await spawnWorkers(config.clusterLimit);
}
+ loadPlugins();
+
+ bootLogger.succ('All plugins loaded');
+
if (!program.noDaemons) {
require('../daemons/server-stats').default();
require('../daemons/notes-stats').default();
@@ -109,6 +115,24 @@ function showEnvironment(): void {
logger.info(`You ${isRoot() ? '' : 'do not '}have root privileges`);
}
+const pluginService = {
+ registerTheme(theme: any) {
+ const ev = new Xev();
+ ev.emit('registerPluginTheme', theme);
+ }
+};
+
+function loadPlugins(): void {
+ const plugins = [
+ path.resolve(`${__dirname}/../plugins/featured-themes`)
+ ];
+ for (const plugin of plugins) {
+ const pluginMeta = require(`${plugin}/plugin-meta.json`);
+ bootLogger.info(`Plugin loaded: ${pluginMeta.name} v${pluginMeta.version}`);
+ require(`${plugin}/main.js`).onActivate(pluginService);
+ }
+}
+
/**
* Init app
*/
diff --git a/src/boot/worker.ts b/src/boot/worker.ts
index 362fa3f26..d7b453d4c 100644
--- a/src/boot/worker.ts
+++ b/src/boot/worker.ts
@@ -1,5 +1,9 @@
import * as cluster from 'cluster';
import { initDb } from '../db/postgre';
+import Xev from 'xev';
+import { registerTheme } from '../pluginThemes';
+
+const ev = new Xev();
/**
* Init worker process
@@ -16,5 +20,9 @@ export async function workerMain() {
if (cluster.isWorker) {
// Send a 'ready' message to parent process
process.send!('ready');
+
+ ev.on('registerPluginTheme', theme => {
+ registerTheme(theme);
+ });
}
}
diff --git a/src/client/app/common/views/components/settings/theme.vue b/src/client/app/common/views/components/settings/theme.vue
index 3e6b9133c..4de0b5345 100644
--- a/src/client/app/common/views/components/settings/theme.vue
+++ b/src/client/app/common/views/components/settings/theme.vue
@@ -93,7 +93,7 @@
{{ $t('manage-themes') }}