Add client helpers to plugins
authorChocobozzz <me@florianbigard.com>
Tue, 16 Jul 2019 14:09:58 +0000 (16:09 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Wed, 24 Jul 2019 08:58:16 +0000 (10:58 +0200)
client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
client/src/app/app.component.html
client/src/app/app.component.scss
client/src/app/core/plugins/plugin.service.ts
client/src/app/core/theme/theme.service.ts

index 0058fa691d5fe9f251f1df453559288aa3148536..a6fbeed842748c47bbaec3f3b2292ee1a37dee5e 100644 (file)
@@ -92,7 +92,12 @@ export class PluginSearchComponent implements OnInit {
             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)
+          }
         )
   }
 
index d398d4f351a61574138a0bc28e32ba6d47a3aff8..07a576083ca85b18d9d47e11e2cc1513d73720e7 100644 (file)
@@ -8,7 +8,7 @@
     <div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }">
       <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="instance-name">{{ instanceName }}</span>
       </a>
index 3f8b9777af3aa667696effeb8df366141da3fb95..c95b21ca37ef8fe0346154224111a4585442e4a9 100644 (file)
@@ -38,8 +38,9 @@
       }
     }
 
-    #peertube-title {
+    .peertube-title {
       @include disable-default-a-behaviour;
+
       font-size: 20px;
       font-weight: $font-bold;
       color: inherit !important;
@@ -64,7 +65,7 @@
     @media screen and (max-width: 500px) {
       width: 70px;
 
-      #peertube-title {
+      .peertube-title {
         display: none;
       }
     }
index c6ba3dd17bf59dca7adb5846a02dc4ab14217eb2..525740a01b37cd31d3efa8b00567937460e33b07 100644 (file)
@@ -14,12 +14,19 @@ interface HookStructValue extends RegisterHookOptions {
   clientScript: ClientScript
 }
 
+type PluginInfo = {
+  plugin: ServerConfigPlugin
+  clientScript: ClientScript
+  isTheme: boolean
+}
+
 @Injectable()
 export class PluginService {
   pluginsLoaded = new ReplaySubject<boolean>(1)
 
   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 loadedScopes: PluginScope[] = []
 
@@ -49,7 +56,7 @@ export class PluginService {
   }
 
   addPlugin (plugin: ServerConfigPlugin, isTheme = false) {
-    const pathPrefix = isTheme ? '/themes' : '/plugins'
+    const pathPrefix = this.getPluginPathPrefix(isTheme)
 
     for (const key of Object.keys(plugin.clientScripts)) {
       const clientScript = plugin.clientScripts[key]
@@ -62,7 +69,8 @@ export class PluginService {
           clientScript: {
             script: environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`,
             scopes: clientScript.scopes
-          }
+          },
+          isTheme
         })
 
         this.loadedScripts[clientScript.script] = false
@@ -78,24 +86,26 @@ export class PluginService {
 
   async reloadLoadedScopes () {
     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 {
       await this.ensurePluginsAreLoaded()
 
-      this.loadedScopes.push(scope)
+      if (!isReload) this.loadedScopes.push(scope)
 
       const toLoad = this.scopes[ scope ]
       if (!Array.isArray(toLoad)) return
 
       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
 
-        promises.push(this.loadPlugin(plugin, clientScript))
+        promises.push(this.loadPlugin(pluginInfo))
 
         this.loadedScripts[ clientScript.script ] = true
       }
@@ -109,6 +119,8 @@ export class PluginService {
   async runHook (hookName: string, param?: any) {
     let result = param
 
+    if (!this.hooks[hookName]) return result
+
     const wait = hookName.startsWith('static:')
 
     for (const hook of this.hooks[hookName]) {
@@ -123,7 +135,9 @@ export class PluginService {
     return result
   }
 
-  private loadPlugin (plugin: ServerConfigPlugin, clientScript: ClientScript) {
+  private loadPlugin (pluginInfo: PluginInfo) {
+    const { plugin, clientScript } = pluginInfo
+
     const registerHook = (options: RegisterHookOptions) => {
       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)
 
     return import(/* webpackIgnore: true */ clientScript.script)
-      .then(script => script.register({ registerHook }))
+      .then(script => script.register({ registerHook, peertubeHelpers }))
       .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'
+  }
 }
index 76199d1cc03215a96cdc4261932f287e69716587..0124880751ec041769dce87fda37eafff1fcf7b9 100644 (file)
@@ -87,7 +87,7 @@ export class ThemeService {
     const theme = this.getTheme(currentTheme)
     if (theme) {
       console.log('Adding scripts of theme %s.', currentTheme)
-      this.pluginService.addPlugin(theme)
+      this.pluginService.addPlugin(theme, true)
 
       this.pluginService.reloadLoadedScopes()
     }