Add client helpers to plugins
This commit is contained in:
parent
d133f38582
commit
f0c5e8b657
|
@ -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)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue