diff options
author | Chocobozzz <me@florianbigard.com> | 2021-12-29 14:08:07 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-12-29 14:08:07 +0100 |
commit | fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb (patch) | |
tree | 251e39490e83b6a0e40c25871188628e62819fa8 | |
parent | 2accfdd8ecd092de7e8c71fbd1235e139ad29832 (diff) | |
download | PeerTube-fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb.tar.gz PeerTube-fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb.tar.zst PeerTube-fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb.zip |
Translate plugin settings
7 files changed, 57 insertions, 39 deletions
diff --git a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts index 402bef1ea..1a40f6c65 100644 --- a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts | |||
@@ -126,25 +126,9 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
126 | 126 | ||
127 | private async translateSettings (settings: RegisterServerSettingOptions[]) { | 127 | private async translateSettings (settings: RegisterServerSettingOptions[]) { |
128 | for (const setting of settings) { | 128 | for (const setting of settings) { |
129 | for (const key of [ 'label', 'html', 'descriptionHTML' ]) { | 129 | await this.pluginService.translateSetting(this.npmName, setting) |
130 | if (setting[key]) setting[key] = await this.pluginService.translateBy(this.npmName, setting[key]) | ||
131 | } | ||
132 | |||
133 | if (Array.isArray(setting.options)) { | ||
134 | const newOptions = [] | ||
135 | |||
136 | for (const o of setting.options) { | ||
137 | newOptions.push({ | ||
138 | value: o.value, | ||
139 | label: await this.pluginService.translateBy(this.npmName, o.label) | ||
140 | }) | ||
141 | } | ||
142 | |||
143 | setting.options = newOptions | ||
144 | } | ||
145 | } | 130 | } |
146 | 131 | ||
147 | return settings | 132 | return settings |
148 | } | 133 | } |
149 | |||
150 | } | 134 | } |
diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts index a03005bcb..8ce36121d 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts | |||
@@ -22,6 +22,7 @@ import { | |||
22 | import { FormReactiveValidationMessages, FormValidatorService } from '@app/shared/shared-forms' | 22 | import { FormReactiveValidationMessages, FormValidatorService } from '@app/shared/shared-forms' |
23 | import { InstanceService } from '@app/shared/shared-instance' | 23 | import { InstanceService } from '@app/shared/shared-instance' |
24 | import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main' | 24 | import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main' |
25 | import { PluginInfo } from '@root-helpers/plugins-manager' | ||
25 | import { | 26 | import { |
26 | HTMLServerConfig, | 27 | HTMLServerConfig, |
27 | LiveVideo, | 28 | LiveVideo, |
@@ -37,6 +38,7 @@ import { VideoEditType } from './video-edit.type' | |||
37 | 38 | ||
38 | type VideoLanguages = VideoConstant<string> & { group?: string } | 39 | type VideoLanguages = VideoConstant<string> & { group?: string } |
39 | type PluginField = { | 40 | type PluginField = { |
41 | pluginInfo: PluginInfo | ||
40 | commonOptions: RegisterClientFormFieldOptions | 42 | commonOptions: RegisterClientFormFieldOptions |
41 | videoFormOptions: RegisterClientVideoFieldOptions | 43 | videoFormOptions: RegisterClientVideoFieldOptions |
42 | } | 44 | } |
@@ -294,7 +296,7 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
294 | }) | 296 | }) |
295 | } | 297 | } |
296 | 298 | ||
297 | private updatePluginFields () { | 299 | private async updatePluginFields () { |
298 | this.pluginFields = this.pluginService.getRegisteredVideoFormFields(this.type) | 300 | this.pluginFields = this.pluginService.getRegisteredVideoFormFields(this.type) |
299 | 301 | ||
300 | if (this.pluginFields.length === 0) return | 302 | if (this.pluginFields.length === 0) return |
@@ -305,6 +307,8 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
305 | const pluginDefaults: any = {} | 307 | const pluginDefaults: any = {} |
306 | 308 | ||
307 | for (const setting of this.pluginFields) { | 309 | for (const setting of this.pluginFields) { |
310 | await this.pluginService.translateSetting(setting.pluginInfo.plugin.npmName, setting.commonOptions) | ||
311 | |||
308 | const validator = (control: AbstractControl): ValidationErrors | null => { | 312 | const validator = (control: AbstractControl): ValidationErrors | null => { |
309 | if (!setting.commonOptions.error) return null | 313 | if (!setting.commonOptions.error) return null |
310 | 314 | ||
diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts index fdbbd2d56..bb9125fe1 100644 --- a/client/src/app/core/plugins/plugin.service.ts +++ b/client/src/app/core/plugins/plugin.service.ts | |||
@@ -20,8 +20,8 @@ import { | |||
20 | PluginType, | 20 | PluginType, |
21 | PublicServerSetting, | 21 | PublicServerSetting, |
22 | RegisterClientFormFieldOptions, | 22 | RegisterClientFormFieldOptions, |
23 | RegisterClientSettingsScriptOptions, | ||
24 | RegisterClientRouteOptions, | 23 | RegisterClientRouteOptions, |
24 | RegisterClientSettingsScriptOptions, | ||
25 | RegisterClientVideoFieldOptions, | 25 | RegisterClientVideoFieldOptions, |
26 | ServerConfigPlugin | 26 | ServerConfigPlugin |
27 | } from '@shared/models' | 27 | } from '@shared/models' |
@@ -30,6 +30,7 @@ import { RegisterClientHelpers } from '../../../types/register-client-option.mod | |||
30 | 30 | ||
31 | type FormFields = { | 31 | type FormFields = { |
32 | video: { | 32 | video: { |
33 | pluginInfo: PluginInfo | ||
33 | commonOptions: RegisterClientFormFieldOptions | 34 | commonOptions: RegisterClientFormFieldOptions |
34 | videoFormOptions: RegisterClientVideoFieldOptions | 35 | videoFormOptions: RegisterClientVideoFieldOptions |
35 | }[] | 36 | }[] |
@@ -44,8 +45,6 @@ export class PluginService implements ClientHook { | |||
44 | 45 | ||
45 | customModal: CustomModalComponent | 46 | customModal: CustomModalComponent |
46 | 47 | ||
47 | private helpers: { [ npmName: string ]: RegisterClientHelpers } = {} | ||
48 | |||
49 | private formFields: FormFields = { | 48 | private formFields: FormFields = { |
50 | video: [] | 49 | video: [] |
51 | } | 50 | } |
@@ -134,27 +133,49 @@ export class PluginService implements ClientHook { | |||
134 | return Object.keys(this.clientRoutes) | 133 | return Object.keys(this.clientRoutes) |
135 | } | 134 | } |
136 | 135 | ||
137 | translateBy (npmName: string, toTranslate: string) { | 136 | async translateSetting (npmName: string, setting: RegisterClientFormFieldOptions) { |
138 | const helpers = this.helpers[npmName] | 137 | for (const key of [ 'label', 'html', 'descriptionHTML' ]) { |
139 | if (!helpers) { | 138 | if (setting[key]) setting[key] = await this.translateBy(npmName, setting[key]) |
140 | console.error('Unknown helpers to translate %s from %s.', toTranslate, npmName) | ||
141 | return toTranslate | ||
142 | } | 139 | } |
143 | 140 | ||
144 | return helpers.translate(toTranslate) | 141 | if (Array.isArray(setting.options)) { |
142 | const newOptions = [] | ||
143 | |||
144 | for (const o of setting.options) { | ||
145 | newOptions.push({ | ||
146 | value: o.value, | ||
147 | label: await this.translateBy(npmName, o.label) | ||
148 | }) | ||
149 | } | ||
150 | |||
151 | setting.options = newOptions | ||
152 | } | ||
145 | } | 153 | } |
146 | 154 | ||
147 | private onFormFields (commonOptions: RegisterClientFormFieldOptions, videoFormOptions: RegisterClientVideoFieldOptions) { | 155 | translateBy (npmName: string, toTranslate: string) { |
156 | const obs = this.translationsObservable | ||
157 | .pipe( | ||
158 | map(allTranslations => allTranslations[npmName]), | ||
159 | map(translations => peertubeTranslate(toTranslate, translations)) | ||
160 | ) | ||
161 | |||
162 | return firstValueFrom(obs) | ||
163 | } | ||
164 | |||
165 | private onFormFields ( | ||
166 | pluginInfo: PluginInfo, | ||
167 | commonOptions: RegisterClientFormFieldOptions, | ||
168 | videoFormOptions: RegisterClientVideoFieldOptions | ||
169 | ) { | ||
148 | this.formFields.video.push({ | 170 | this.formFields.video.push({ |
171 | pluginInfo, | ||
149 | commonOptions, | 172 | commonOptions, |
150 | videoFormOptions | 173 | videoFormOptions |
151 | }) | 174 | }) |
152 | } | 175 | } |
153 | 176 | ||
154 | private onSettingsScripts (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) { | 177 | private onSettingsScripts (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) { |
155 | const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType) | 178 | this.settingsScripts[pluginInfo.plugin.npmName] = options |
156 | |||
157 | this.settingsScripts[npmName] = options | ||
158 | } | 179 | } |
159 | 180 | ||
160 | private onClientRoute (options: RegisterClientRouteOptions) { | 181 | private onClientRoute (options: RegisterClientRouteOptions) { |
@@ -167,7 +188,7 @@ export class PluginService implements ClientHook { | |||
167 | 188 | ||
168 | private buildPeerTubeHelpers (pluginInfo: PluginInfo): RegisterClientHelpers { | 189 | private buildPeerTubeHelpers (pluginInfo: PluginInfo): RegisterClientHelpers { |
169 | const { plugin } = pluginInfo | 190 | const { plugin } = pluginInfo |
170 | const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType) | 191 | const npmName = pluginInfo.plugin.npmName |
171 | 192 | ||
172 | return { | 193 | return { |
173 | getBaseStaticRoute: () => { | 194 | getBaseStaticRoute: () => { |
@@ -241,11 +262,7 @@ export class PluginService implements ClientHook { | |||
241 | }, | 262 | }, |
242 | 263 | ||
243 | translate: (value: string) => { | 264 | translate: (value: string) => { |
244 | const obs = this.translationsObservable | 265 | return this.translateBy(npmName, value) |
245 | .pipe(map(allTranslations => allTranslations[npmName])) | ||
246 | .pipe(map(translations => peertubeTranslate(value, translations))) | ||
247 | |||
248 | return firstValueFrom(obs) | ||
249 | } | 266 | } |
250 | } | 267 | } |
251 | } | 268 | } |
diff --git a/client/src/root-helpers/plugins-manager.ts b/client/src/root-helpers/plugins-manager.ts index 1157a274e..61731032a 100644 --- a/client/src/root-helpers/plugins-manager.ts +++ b/client/src/root-helpers/plugins-manager.ts | |||
@@ -37,8 +37,15 @@ type PluginInfo = { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | type PeertubeHelpersFactory = (pluginInfo: PluginInfo) => RegisterClientHelpers | 39 | type PeertubeHelpersFactory = (pluginInfo: PluginInfo) => RegisterClientHelpers |
40 | type OnFormFields = (options: RegisterClientFormFieldOptions, videoFormOptions: RegisterClientVideoFieldOptions) => void | 40 | |
41 | type OnFormFields = ( | ||
42 | pluginInfo: PluginInfo, | ||
43 | options: RegisterClientFormFieldOptions, | ||
44 | videoFormOptions: RegisterClientVideoFieldOptions | ||
45 | ) => void | ||
46 | |||
41 | type OnSettingsScripts = (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) => void | 47 | type OnSettingsScripts = (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) => void |
48 | |||
42 | type OnClientRoute = (options: RegisterClientRouteOptions) => void | 49 | type OnClientRoute = (options: RegisterClientRouteOptions) => void |
43 | 50 | ||
44 | const logger = debug('peertube:plugins') | 51 | const logger = debug('peertube:plugins') |
@@ -223,7 +230,7 @@ class PluginsManager { | |||
223 | throw new Error('Video field registration is not supported') | 230 | throw new Error('Video field registration is not supported') |
224 | } | 231 | } |
225 | 232 | ||
226 | return this.onFormFields(commonOptions, videoFormOptions) | 233 | return this.onFormFields(pluginInfo, commonOptions, videoFormOptions) |
227 | } | 234 | } |
228 | 235 | ||
229 | const registerSettingsScript = (options: RegisterClientSettingsScriptOptions) => { | 236 | const registerSettingsScript = (options: RegisterClientSettingsScriptOptions) => { |
diff --git a/server/lib/server-config-manager.ts b/server/lib/server-config-manager.ts index 18032ef86..d97f21eb7 100644 --- a/server/lib/server-config-manager.ts +++ b/server/lib/server-config-manager.ts | |||
@@ -3,6 +3,7 @@ import { CONFIG, isEmailEnabled } from '@server/initializers/config' | |||
3 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' | 3 | import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' |
4 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/lib/signup' | 4 | import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/lib/signup' |
5 | import { ActorCustomPageModel } from '@server/models/account/actor-custom-page' | 5 | import { ActorCustomPageModel } from '@server/models/account/actor-custom-page' |
6 | import { PluginModel } from '@server/models/server/plugin' | ||
6 | import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' | 7 | import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' |
7 | import { Hooks } from './plugins/hooks' | 8 | import { Hooks } from './plugins/hooks' |
8 | import { PluginManager } from './plugins/plugin-manager' | 9 | import { PluginManager } from './plugins/plugin-manager' |
@@ -269,6 +270,7 @@ class ServerConfigManager { | |||
269 | getRegisteredThemes () { | 270 | getRegisteredThemes () { |
270 | return PluginManager.Instance.getRegisteredThemes() | 271 | return PluginManager.Instance.getRegisteredThemes() |
271 | .map(t => ({ | 272 | .map(t => ({ |
273 | npmName: PluginModel.buildNpmName(t.name, t.type), | ||
272 | name: t.name, | 274 | name: t.name, |
273 | version: t.version, | 275 | version: t.version, |
274 | description: t.description, | 276 | description: t.description, |
@@ -280,6 +282,7 @@ class ServerConfigManager { | |||
280 | getRegisteredPlugins () { | 282 | getRegisteredPlugins () { |
281 | return PluginManager.Instance.getRegisteredPlugins() | 283 | return PluginManager.Instance.getRegisteredPlugins() |
282 | .map(p => ({ | 284 | .map(p => ({ |
285 | npmName: PluginModel.buildNpmName(p.name, p.type), | ||
283 | name: p.name, | 286 | name: p.name, |
284 | version: p.version, | 287 | version: p.version, |
285 | description: p.description, | 288 | description: p.description, |
diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts index e82096c48..76d3e2481 100644 --- a/server/tests/api/server/plugins.ts +++ b/server/tests/api/server/plugins.ts | |||
@@ -99,9 +99,11 @@ describe('Test plugins', function () { | |||
99 | 99 | ||
100 | const theme = config.theme.registered.find(r => r.name === 'background-red') | 100 | const theme = config.theme.registered.find(r => r.name === 'background-red') |
101 | expect(theme).to.not.be.undefined | 101 | expect(theme).to.not.be.undefined |
102 | expect(theme.npmName).to.equal('peertube-theme-background-red') | ||
102 | 103 | ||
103 | const plugin = config.plugin.registered.find(r => r.name === 'hello-world') | 104 | const plugin = config.plugin.registered.find(r => r.name === 'hello-world') |
104 | expect(plugin).to.not.be.undefined | 105 | expect(plugin).to.not.be.undefined |
106 | expect(plugin.npmName).to.equal('peertube-plugin-hello-world') | ||
105 | }) | 107 | }) |
106 | 108 | ||
107 | it('Should update the default theme in the configuration', async function () { | 109 | it('Should update the default theme in the configuration', async function () { |
diff --git a/shared/models/server/server-config.model.ts b/shared/models/server/server-config.model.ts index 8c0e21621..32be96b9d 100644 --- a/shared/models/server/server-config.model.ts +++ b/shared/models/server/server-config.model.ts | |||
@@ -5,6 +5,7 @@ import { BroadcastMessageLevel } from './broadcast-message-level.type' | |||
5 | 5 | ||
6 | export interface ServerConfigPlugin { | 6 | export interface ServerConfigPlugin { |
7 | name: string | 7 | name: string |
8 | npmName: string | ||
8 | version: string | 9 | version: string |
9 | description: string | 10 | description: string |
10 | clientScripts: { [name: string]: ClientScriptJSON } | 11 | clientScripts: { [name: string]: ClientScriptJSON } |