import { ServerConfigPlugin } from '@shared/models'
import { ServerService } from '@app/core/server/server.service'
import { ClientScript } from '@shared/models/plugins/plugin-package-json.model'
+import { ClientScript as ClientScriptModule } from '../../../types/client-script.model'
import { environment } from '../../../environments/environment'
-import { RegisterHookOptions } from '@shared/models/plugins/register-hook.model'
import { ReplaySubject } from 'rxjs'
import { first, shareReplay } from 'rxjs/operators'
import { getHookType, internalRunHook } from '@shared/core-utils/plugins/hooks'
-import { ClientHook, ClientHookName } from '@shared/models/plugins/client-hook.model'
+import { ClientHook, ClientHookName, clientHookObject } from '@shared/models/plugins/client-hook.model'
import { PluginClientScope } from '@shared/models/plugins/plugin-client-scope.type'
+import { RegisterClientHookOptions } from '@shared/models/plugins/register-client-hook.model'
-interface HookStructValue extends RegisterHookOptions {
+interface HookStructValue extends RegisterClientHookOptions {
plugin: ServerConfigPlugin
clientScript: ClientScript
}
pluginsLoaded: { [ scope in PluginClientScope ]: ReplaySubject<boolean> } = {
common: new ReplaySubject<boolean>(1),
+ search: new ReplaySubject<boolean>(1),
'video-watch': new ReplaySubject<boolean>(1)
}
private scopes: { [ scopeName: string ]: PluginInfo[] } = {}
private loadedScripts: { [ script: string ]: boolean } = {}
private loadedScopes: PluginClientScope[] = []
+ private loadingScopes: { [id in PluginClientScope]?: boolean } = {}
private hooks: { [ name: string ]: HookStructValue[] } = {}
}
ensurePluginsAreLoaded (scope: PluginClientScope) {
+ this.loadPluginsByScope(scope)
+
return this.pluginsLoaded[scope].asObservable()
.pipe(first(), shareReplay())
.toPromise()
}
async loadPluginsByScope (scope: PluginClientScope, isReload = false) {
+ if (this.loadingScopes[scope]) return
+ if (!isReload && this.loadedScopes.includes(scope)) return
+
+ this.loadingScopes[scope] = true
+
try {
await this.ensurePluginsAreBuilt()
if (!isReload) this.loadedScopes.push(scope)
const toLoad = this.scopes[ scope ]
- if (!Array.isArray(toLoad)) return
+ if (!Array.isArray(toLoad)) {
+ this.loadingScopes[scope] = false
+ this.pluginsLoaded[scope].next(true)
+
+ return
+ }
const promises: Promise<any>[] = []
for (const pluginInfo of toLoad) {
await Promise.all(promises)
this.pluginsLoaded[scope].next(true)
+ this.loadingScopes[scope] = false
} catch (err) {
console.error('Cannot load plugins by scope %s.', scope, err)
}
private loadPlugin (pluginInfo: PluginInfo) {
const { plugin, clientScript } = pluginInfo
- const registerHook = (options: RegisterHookOptions) => {
+ const registerHook = (options: RegisterClientHookOptions) => {
+ if (clientHookObject[options.target] !== true) {
+ console.error('Unknown hook %s of plugin %s. Skipping.', options.target, plugin.name)
+ return
+ }
+
if (!this.hooks[options.target]) this.hooks[options.target] = []
this.hooks[options.target].push({
console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name)
return import(/* webpackIgnore: true */ clientScript.script)
- .then(script => script.register({ registerHook, peertubeHelpers }))
+ .then((script: ClientScriptModule) => script.register({ registerHook, peertubeHelpers }))
.then(() => this.sortHooksByPriority())
}