Add client helpers to plugins

This commit is contained in:
Chocobozzz 2019-07-16 16:09:58 +02:00 committed by Chocobozzz
parent d133f38582
commit f0c5e8b657
5 changed files with 52 additions and 15 deletions

View File

@ -92,7 +92,12 @@ export class PluginSearchComponent implements OnInit {
this.pagination.totalItems = res.total this.pagination.totalItems = res.total
}, },
err => this.notifier.error(err.message) err => {
console.error(err)
const message = this.i18n('The plugin index is not available. Please retry later.')
this.notifier.error(message)
}
) )
} }

View File

@ -8,7 +8,7 @@
<div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }"> <div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }">
<span class="icon icon-menu" (click)="toggleMenu()"></span> <span class="icon icon-menu" (click)="toggleMenu()"></span>
<a id="peertube-title" [routerLink]="defaultRoute" title="Homepage"> <a class="peertube-title" [routerLink]="defaultRoute" title="Homepage">
<span class="icon icon-logo"></span> <span class="icon icon-logo"></span>
<span class="instance-name">{{ instanceName }}</span> <span class="instance-name">{{ instanceName }}</span>
</a> </a>

View File

@ -38,8 +38,9 @@
} }
} }
#peertube-title { .peertube-title {
@include disable-default-a-behaviour; @include disable-default-a-behaviour;
font-size: 20px; font-size: 20px;
font-weight: $font-bold; font-weight: $font-bold;
color: inherit !important; color: inherit !important;
@ -64,7 +65,7 @@
@media screen and (max-width: 500px) { @media screen and (max-width: 500px) {
width: 70px; width: 70px;
#peertube-title { .peertube-title {
display: none; display: none;
} }
} }

View File

@ -14,12 +14,19 @@ interface HookStructValue extends RegisterHookOptions {
clientScript: ClientScript clientScript: ClientScript
} }
type PluginInfo = {
plugin: ServerConfigPlugin
clientScript: ClientScript
isTheme: boolean
}
@Injectable() @Injectable()
export class PluginService { export class PluginService {
pluginsLoaded = new ReplaySubject<boolean>(1) pluginsLoaded = new ReplaySubject<boolean>(1)
private plugins: ServerConfigPlugin[] = [] private plugins: ServerConfigPlugin[] = []
private scopes: { [ scopeName: string ]: { plugin: ServerConfigPlugin, clientScript: ClientScript }[] } = {} private scopes: { [ scopeName: string ]: PluginInfo[] } = {}
private loadedPlugins: { [ name: string ]: boolean } = {}
private loadedScripts: { [ script: string ]: boolean } = {} private loadedScripts: { [ script: string ]: boolean } = {}
private loadedScopes: PluginScope[] = [] private loadedScopes: PluginScope[] = []
@ -49,7 +56,7 @@ export class PluginService {
} }
addPlugin (plugin: ServerConfigPlugin, isTheme = false) { addPlugin (plugin: ServerConfigPlugin, isTheme = false) {
const pathPrefix = isTheme ? '/themes' : '/plugins' const pathPrefix = this.getPluginPathPrefix(isTheme)
for (const key of Object.keys(plugin.clientScripts)) { for (const key of Object.keys(plugin.clientScripts)) {
const clientScript = plugin.clientScripts[key] const clientScript = plugin.clientScripts[key]
@ -62,7 +69,8 @@ export class PluginService {
clientScript: { clientScript: {
script: environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`, script: environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`,
scopes: clientScript.scopes scopes: clientScript.scopes
} },
isTheme
}) })
this.loadedScripts[clientScript.script] = false this.loadedScripts[clientScript.script] = false
@ -78,24 +86,26 @@ export class PluginService {
async reloadLoadedScopes () { async reloadLoadedScopes () {
for (const scope of this.loadedScopes) { for (const scope of this.loadedScopes) {
await this.loadPluginsByScope(scope) await this.loadPluginsByScope(scope, true)
} }
} }
async loadPluginsByScope (scope: PluginScope) { async loadPluginsByScope (scope: PluginScope, isReload = false) {
try { try {
await this.ensurePluginsAreLoaded() await this.ensurePluginsAreLoaded()
this.loadedScopes.push(scope) if (!isReload) this.loadedScopes.push(scope)
const toLoad = this.scopes[ scope ] const toLoad = this.scopes[ scope ]
if (!Array.isArray(toLoad)) return if (!Array.isArray(toLoad)) return
const promises: Promise<any>[] = [] const promises: Promise<any>[] = []
for (const { plugin, clientScript } of toLoad) { for (const pluginInfo of toLoad) {
const clientScript = pluginInfo.clientScript
if (this.loadedScripts[ clientScript.script ]) continue if (this.loadedScripts[ clientScript.script ]) continue
promises.push(this.loadPlugin(plugin, clientScript)) promises.push(this.loadPlugin(pluginInfo))
this.loadedScripts[ clientScript.script ] = true this.loadedScripts[ clientScript.script ] = true
} }
@ -109,6 +119,8 @@ export class PluginService {
async runHook (hookName: string, param?: any) { async runHook (hookName: string, param?: any) {
let result = param let result = param
if (!this.hooks[hookName]) return result
const wait = hookName.startsWith('static:') const wait = hookName.startsWith('static:')
for (const hook of this.hooks[hookName]) { for (const hook of this.hooks[hookName]) {
@ -123,7 +135,9 @@ export class PluginService {
return result return result
} }
private loadPlugin (plugin: ServerConfigPlugin, clientScript: ClientScript) { private loadPlugin (pluginInfo: PluginInfo) {
const { plugin, clientScript } = pluginInfo
const registerHook = (options: RegisterHookOptions) => { const registerHook = (options: RegisterHookOptions) => {
if (!this.hooks[options.target]) this.hooks[options.target] = [] if (!this.hooks[options.target]) this.hooks[options.target] = []
@ -136,10 +150,12 @@ export class PluginService {
}) })
} }
const peertubeHelpers = this.buildPeerTubeHelpers(pluginInfo)
console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name) console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name)
return import(/* webpackIgnore: true */ clientScript.script) return import(/* webpackIgnore: true */ clientScript.script)
.then(script => script.register({ registerHook })) .then(script => script.register({ registerHook, peertubeHelpers }))
.then(() => this.sortHooksByPriority()) .then(() => this.sortHooksByPriority())
} }
@ -156,4 +172,19 @@ export class PluginService {
}) })
} }
} }
private buildPeerTubeHelpers (pluginInfo: PluginInfo) {
const { plugin } = pluginInfo
return {
getBaseStaticRoute: () => {
const pathPrefix = this.getPluginPathPrefix(pluginInfo.isTheme)
return environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/static`
}
}
}
private getPluginPathPrefix (isTheme: boolean) {
return isTheme ? '/themes' : '/plugins'
}
} }

View File

@ -87,7 +87,7 @@ export class ThemeService {
const theme = this.getTheme(currentTheme) const theme = this.getTheme(currentTheme)
if (theme) { if (theme) {
console.log('Adding scripts of theme %s.', currentTheme) console.log('Adding scripts of theme %s.', currentTheme)
this.pluginService.addPlugin(theme) this.pluginService.addPlugin(theme, true)
this.pluginService.reloadLoadedScopes() this.pluginService.reloadLoadedScopes()
} }