added support for plugins loaded into window

This commit is contained in:
vitorsemeano 2020-11-18 23:13:56 +00:00
parent 138e8460f6
commit 051033c9b3

View file

@ -1,5 +1,8 @@
import { Events } from 'jellyfin-apiclient'; import { Events } from 'jellyfin-apiclient';
import globalize from '../scripts/globalize'; import globalize from '../scripts/globalize';
import loading from './loading/loading';
import appSettings from '../scripts/settings/appSettings';
import { playbackManager } from './playback/playbackmanager';
/* eslint-disable indent */ /* eslint-disable indent */
@ -28,7 +31,7 @@ import globalize from '../scripts/globalize';
Emby.App.defineRoute(route, plugin.id); Emby.App.defineRoute(route, plugin.id);
} }
#registerPlugin(plugin) { async #registerPlugin(plugin) {
this.#register(plugin); this.#register(plugin);
if (plugin.getRoutes) { if (plugin.getRoutes) {
@ -39,50 +42,62 @@ import globalize from '../scripts/globalize';
if (plugin.type === 'skin') { if (plugin.type === 'skin') {
// translations won't be loaded for skins until needed // translations won't be loaded for skins until needed
return Promise.resolve(plugin); return plugin;
} else { } else {
return new Promise((resolve, reject) => { return await this.#loadStrings(plugin);
this.#loadStrings(plugin)
.then(function () {
resolve(plugin);
})
.catch(reject);
});
} }
} }
loadPlugin(pluginSpec) { async #preparePlugin(pluginSpec, plugin) {
if (typeof pluginSpec === 'string') { if (typeof pluginSpec === 'string') {
console.debug('Loading plugin (via dynamic import): ' + pluginSpec); // See if it's already installed
const existing = this.plugins.filter(function (p) {
return p.id === plugin.id;
})[0];
import(/* webpackChunkName: "[request]" */ `../plugins/${pluginSpec}`).then((plugin) => { if (existing) {
// See if it's already installed return pluginSpec;
const existing = this.plugins.filter(function (p) { }
return p.id === plugin.id;
})[0];
if (existing) { plugin.installUrl = pluginSpec;
return Promise.resolve(pluginSpec);
}
plugin.installUrl = pluginSpec; const separatorIndex = Math.max(pluginSpec.lastIndexOf('/'), pluginSpec.lastIndexOf('\\'));
plugin.baseUrl = pluginSpec.substring(0, separatorIndex);
}
const separatorIndex = Math.max(pluginSpec.lastIndexOf('/'), pluginSpec.lastIndexOf('\\')); return this.#registerPlugin(plugin);
plugin.baseUrl = pluginSpec.substring(0, separatorIndex); }
this.#registerPlugin(plugin).then(Promise.resolve).catch(Promise.reject); async loadPlugin(pluginSpec) {
}); let plugin;
if (typeof pluginSpec === 'string') {
if (pluginSpec in window) {
console.log(`Loading plugin (via window): ${pluginSpec}`);
// init plugin and pass basic dependencies
plugin = new window[pluginSpec]({
events: Events,
loading,
appSettings,
playbackManager
});
} else {
console.debug(`Loading plugin (via dynamic import): ${pluginSpec}`);
plugin = await import(/* webpackChunkName: "[request]" */ `../plugins/${pluginSpec}`);
}
} else if (pluginSpec.then) { } else if (pluginSpec.then) {
return pluginSpec.then(({ default: pluginBuilder }) => { console.debug('Loading plugin (via promise/async function)');
const plugin = new pluginBuilder;
console.debug(`Plugin loaded: ${plugin.id}`); const pluginResult = await pluginSpec;
return this.#registerPlugin(plugin); plugin = new pluginResult.default;
});
} else { } else {
const err = new TypeError('Plugins have to be a Promise that resolves to a plugin builder function'); const err = new TypeError('Plugins have to be a Promise that resolves to a plugin builder function');
console.error(err); console.error(err);
return Promise.reject(err); throw err;
} }
return this.#preparePlugin(pluginSpec, plugin);
} }
// In lieu of automatic discovery, plugins will register dynamic objects // In lieu of automatic discovery, plugins will register dynamic objects