aboutsummaryrefslogtreecommitdiffhomepage
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts7
-rw-r--r--client/src/app/app.component.html2
-rw-r--r--client/src/app/app.component.scss5
-rw-r--r--client/src/app/core/plugins/plugin.service.ts51
-rw-r--r--client/src/app/core/theme/theme.service.ts2
5 files changed, 52 insertions, 15 deletions
diff --git a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
index 0058fa691..a6fbeed84 100644
--- a/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
+++ b/client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts
@@ -92,7 +92,12 @@ export class PluginSearchComponent implements OnInit {
92 this.pagination.totalItems = res.total 92 this.pagination.totalItems = res.total
93 }, 93 },
94 94
95 err => this.notifier.error(err.message) 95 err => {
96 console.error(err)
97
98 const message = this.i18n('The plugin index is not available. Please retry later.')
99 this.notifier.error(message)
100 }
96 ) 101 )
97 } 102 }
98 103
diff --git a/client/src/app/app.component.html b/client/src/app/app.component.html
index d398d4f35..07a576083 100644
--- a/client/src/app/app.component.html
+++ b/client/src/app/app.component.html
@@ -8,7 +8,7 @@
8 <div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }"> 8 <div class="top-left-block" [ngClass]="{ 'border-bottom': isMenuDisplayed === false }">
9 <span class="icon icon-menu" (click)="toggleMenu()"></span> 9 <span class="icon icon-menu" (click)="toggleMenu()"></span>
10 10
11 <a id="peertube-title" [routerLink]="defaultRoute" title="Homepage"> 11 <a class="peertube-title" [routerLink]="defaultRoute" title="Homepage">
12 <span class="icon icon-logo"></span> 12 <span class="icon icon-logo"></span>
13 <span class="instance-name">{{ instanceName }}</span> 13 <span class="instance-name">{{ instanceName }}</span>
14 </a> 14 </a>
diff --git a/client/src/app/app.component.scss b/client/src/app/app.component.scss
index 3f8b9777a..c95b21ca3 100644
--- a/client/src/app/app.component.scss
+++ b/client/src/app/app.component.scss
@@ -38,8 +38,9 @@
38 } 38 }
39 } 39 }
40 40
41 #peertube-title { 41 .peertube-title {
42 @include disable-default-a-behaviour; 42 @include disable-default-a-behaviour;
43
43 font-size: 20px; 44 font-size: 20px;
44 font-weight: $font-bold; 45 font-weight: $font-bold;
45 color: inherit !important; 46 color: inherit !important;
@@ -64,7 +65,7 @@
64 @media screen and (max-width: 500px) { 65 @media screen and (max-width: 500px) {
65 width: 70px; 66 width: 70px;
66 67
67 #peertube-title { 68 .peertube-title {
68 display: none; 69 display: none;
69 } 70 }
70 } 71 }
diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts
index c6ba3dd17..525740a01 100644
--- a/client/src/app/core/plugins/plugin.service.ts
+++ b/client/src/app/core/plugins/plugin.service.ts
@@ -14,12 +14,19 @@ interface HookStructValue extends RegisterHookOptions {
14 clientScript: ClientScript 14 clientScript: ClientScript
15} 15}
16 16
17type PluginInfo = {
18 plugin: ServerConfigPlugin
19 clientScript: ClientScript
20 isTheme: boolean
21}
22
17@Injectable() 23@Injectable()
18export class PluginService { 24export class PluginService {
19 pluginsLoaded = new ReplaySubject<boolean>(1) 25 pluginsLoaded = new ReplaySubject<boolean>(1)
20 26
21 private plugins: ServerConfigPlugin[] = [] 27 private plugins: ServerConfigPlugin[] = []
22 private scopes: { [ scopeName: string ]: { plugin: ServerConfigPlugin, clientScript: ClientScript }[] } = {} 28 private scopes: { [ scopeName: string ]: PluginInfo[] } = {}
29 private loadedPlugins: { [ name: string ]: boolean } = {}
23 private loadedScripts: { [ script: string ]: boolean } = {} 30 private loadedScripts: { [ script: string ]: boolean } = {}
24 private loadedScopes: PluginScope[] = [] 31 private loadedScopes: PluginScope[] = []
25 32
@@ -49,7 +56,7 @@ export class PluginService {
49 } 56 }
50 57
51 addPlugin (plugin: ServerConfigPlugin, isTheme = false) { 58 addPlugin (plugin: ServerConfigPlugin, isTheme = false) {
52 const pathPrefix = isTheme ? '/themes' : '/plugins' 59 const pathPrefix = this.getPluginPathPrefix(isTheme)
53 60
54 for (const key of Object.keys(plugin.clientScripts)) { 61 for (const key of Object.keys(plugin.clientScripts)) {
55 const clientScript = plugin.clientScripts[key] 62 const clientScript = plugin.clientScripts[key]
@@ -62,7 +69,8 @@ export class PluginService {
62 clientScript: { 69 clientScript: {
63 script: environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`, 70 script: environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/client-scripts/${clientScript.script}`,
64 scopes: clientScript.scopes 71 scopes: clientScript.scopes
65 } 72 },
73 isTheme
66 }) 74 })
67 75
68 this.loadedScripts[clientScript.script] = false 76 this.loadedScripts[clientScript.script] = false
@@ -78,24 +86,26 @@ export class PluginService {
78 86
79 async reloadLoadedScopes () { 87 async reloadLoadedScopes () {
80 for (const scope of this.loadedScopes) { 88 for (const scope of this.loadedScopes) {
81 await this.loadPluginsByScope(scope) 89 await this.loadPluginsByScope(scope, true)
82 } 90 }
83 } 91 }
84 92
85 async loadPluginsByScope (scope: PluginScope) { 93 async loadPluginsByScope (scope: PluginScope, isReload = false) {
86 try { 94 try {
87 await this.ensurePluginsAreLoaded() 95 await this.ensurePluginsAreLoaded()
88 96
89 this.loadedScopes.push(scope) 97 if (!isReload) this.loadedScopes.push(scope)
90 98
91 const toLoad = this.scopes[ scope ] 99 const toLoad = this.scopes[ scope ]
92 if (!Array.isArray(toLoad)) return 100 if (!Array.isArray(toLoad)) return
93 101
94 const promises: Promise<any>[] = [] 102 const promises: Promise<any>[] = []
95 for (const { plugin, clientScript } of toLoad) { 103 for (const pluginInfo of toLoad) {
104 const clientScript = pluginInfo.clientScript
105
96 if (this.loadedScripts[ clientScript.script ]) continue 106 if (this.loadedScripts[ clientScript.script ]) continue
97 107
98 promises.push(this.loadPlugin(plugin, clientScript)) 108 promises.push(this.loadPlugin(pluginInfo))
99 109
100 this.loadedScripts[ clientScript.script ] = true 110 this.loadedScripts[ clientScript.script ] = true
101 } 111 }
@@ -109,6 +119,8 @@ export class PluginService {
109 async runHook (hookName: string, param?: any) { 119 async runHook (hookName: string, param?: any) {
110 let result = param 120 let result = param
111 121
122 if (!this.hooks[hookName]) return result
123
112 const wait = hookName.startsWith('static:') 124 const wait = hookName.startsWith('static:')
113 125
114 for (const hook of this.hooks[hookName]) { 126 for (const hook of this.hooks[hookName]) {
@@ -123,7 +135,9 @@ export class PluginService {
123 return result 135 return result
124 } 136 }
125 137
126 private loadPlugin (plugin: ServerConfigPlugin, clientScript: ClientScript) { 138 private loadPlugin (pluginInfo: PluginInfo) {
139 const { plugin, clientScript } = pluginInfo
140
127 const registerHook = (options: RegisterHookOptions) => { 141 const registerHook = (options: RegisterHookOptions) => {
128 if (!this.hooks[options.target]) this.hooks[options.target] = [] 142 if (!this.hooks[options.target]) this.hooks[options.target] = []
129 143
@@ -136,10 +150,12 @@ export class PluginService {
136 }) 150 })
137 } 151 }
138 152
153 const peertubeHelpers = this.buildPeerTubeHelpers(pluginInfo)
154
139 console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name) 155 console.log('Loading script %s of plugin %s.', clientScript.script, plugin.name)
140 156
141 return import(/* webpackIgnore: true */ clientScript.script) 157 return import(/* webpackIgnore: true */ clientScript.script)
142 .then(script => script.register({ registerHook })) 158 .then(script => script.register({ registerHook, peertubeHelpers }))
143 .then(() => this.sortHooksByPriority()) 159 .then(() => this.sortHooksByPriority())
144 } 160 }
145 161
@@ -156,4 +172,19 @@ export class PluginService {
156 }) 172 })
157 } 173 }
158 } 174 }
175
176 private buildPeerTubeHelpers (pluginInfo: PluginInfo) {
177 const { plugin } = pluginInfo
178
179 return {
180 getBaseStaticRoute: () => {
181 const pathPrefix = this.getPluginPathPrefix(pluginInfo.isTheme)
182 return environment.apiUrl + `${pathPrefix}/${plugin.name}/${plugin.version}/static`
183 }
184 }
185 }
186
187 private getPluginPathPrefix (isTheme: boolean) {
188 return isTheme ? '/themes' : '/plugins'
189 }
159} 190}
diff --git a/client/src/app/core/theme/theme.service.ts b/client/src/app/core/theme/theme.service.ts
index 76199d1cc..012488075 100644
--- a/client/src/app/core/theme/theme.service.ts
+++ b/client/src/app/core/theme/theme.service.ts
@@ -87,7 +87,7 @@ export class ThemeService {
87 const theme = this.getTheme(currentTheme) 87 const theme = this.getTheme(currentTheme)
88 if (theme) { 88 if (theme) {
89 console.log('Adding scripts of theme %s.', currentTheme) 89 console.log('Adding scripts of theme %s.', currentTheme)
90 this.pluginService.addPlugin(theme) 90 this.pluginService.addPlugin(theme, true)
91 91
92 this.pluginService.reloadLoadedScopes() 92 this.pluginService.reloadLoadedScopes()
93 } 93 }