diff options
author | Chocobozzz <me@florianbigard.com> | 2019-07-16 16:09:58 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2019-07-24 10:58:16 +0200 |
commit | f0c5e8b65792e9f991bf006a3e1d03cfd2c80c24 (patch) | |
tree | c3e89788fc565b033d173d3442e2064ecbbdc39b /client/src/app | |
parent | d133f3858288b20d790e9bb57664fc6e22d9aeaf (diff) | |
download | PeerTube-f0c5e8b65792e9f991bf006a3e1d03cfd2c80c24.tar.gz PeerTube-f0c5e8b65792e9f991bf006a3e1d03cfd2c80c24.tar.zst PeerTube-f0c5e8b65792e9f991bf006a3e1d03cfd2c80c24.zip |
Add client helpers to plugins
Diffstat (limited to 'client/src/app')
-rw-r--r-- | client/src/app/+admin/plugins/plugin-search/plugin-search.component.ts | 7 | ||||
-rw-r--r-- | client/src/app/app.component.html | 2 | ||||
-rw-r--r-- | client/src/app/app.component.scss | 5 | ||||
-rw-r--r-- | client/src/app/core/plugins/plugin.service.ts | 51 | ||||
-rw-r--r-- | client/src/app/core/theme/theme.service.ts | 2 |
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 | ||
17 | type PluginInfo = { | ||
18 | plugin: ServerConfigPlugin | ||
19 | clientScript: ClientScript | ||
20 | isTheme: boolean | ||
21 | } | ||
22 | |||
17 | @Injectable() | 23 | @Injectable() |
18 | export class PluginService { | 24 | export 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 | } |