aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-12-29 14:08:07 +0100
committerChocobozzz <me@florianbigard.com>2021-12-29 14:08:07 +0100
commitfb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb (patch)
tree251e39490e83b6a0e40c25871188628e62819fa8
parent2accfdd8ecd092de7e8c71fbd1235e139ad29832 (diff)
downloadPeerTube-fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb.tar.gz
PeerTube-fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb.tar.zst
PeerTube-fb3c9e2bf5b45d6d283cea4d55cc0d49eb58e3cb.zip
Translate plugin settings
-rw-r--r--client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts18
-rw-r--r--client/src/app/+videos/+video-edit/shared/video-edit.component.ts6
-rw-r--r--client/src/app/core/plugins/plugin.service.ts55
-rw-r--r--client/src/root-helpers/plugins-manager.ts11
-rw-r--r--server/lib/server-config-manager.ts3
-rw-r--r--server/tests/api/server/plugins.ts2
-rw-r--r--shared/models/server/server-config.model.ts1
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 {
22import { FormReactiveValidationMessages, FormValidatorService } from '@app/shared/shared-forms' 22import { FormReactiveValidationMessages, FormValidatorService } from '@app/shared/shared-forms'
23import { InstanceService } from '@app/shared/shared-instance' 23import { InstanceService } from '@app/shared/shared-instance'
24import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main' 24import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main'
25import { PluginInfo } from '@root-helpers/plugins-manager'
25import { 26import {
26 HTMLServerConfig, 27 HTMLServerConfig,
27 LiveVideo, 28 LiveVideo,
@@ -37,6 +38,7 @@ import { VideoEditType } from './video-edit.type'
37 38
38type VideoLanguages = VideoConstant<string> & { group?: string } 39type VideoLanguages = VideoConstant<string> & { group?: string }
39type PluginField = { 40type 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
31type FormFields = { 31type 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
39type PeertubeHelpersFactory = (pluginInfo: PluginInfo) => RegisterClientHelpers 39type PeertubeHelpersFactory = (pluginInfo: PluginInfo) => RegisterClientHelpers
40type OnFormFields = (options: RegisterClientFormFieldOptions, videoFormOptions: RegisterClientVideoFieldOptions) => void 40
41type OnFormFields = (
42 pluginInfo: PluginInfo,
43 options: RegisterClientFormFieldOptions,
44 videoFormOptions: RegisterClientVideoFieldOptions
45) => void
46
41type OnSettingsScripts = (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) => void 47type OnSettingsScripts = (pluginInfo: PluginInfo, options: RegisterClientSettingsScriptOptions) => void
48
42type OnClientRoute = (options: RegisterClientRouteOptions) => void 49type OnClientRoute = (options: RegisterClientRouteOptions) => void
43 50
44const logger = debug('peertube:plugins') 51const 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'
3import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants' 3import { CONSTRAINTS_FIELDS, DEFAULT_THEME_NAME, PEERTUBE_VERSION } from '@server/initializers/constants'
4import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/lib/signup' 4import { isSignupAllowed, isSignupAllowedForCurrentIP } from '@server/lib/signup'
5import { ActorCustomPageModel } from '@server/models/account/actor-custom-page' 5import { ActorCustomPageModel } from '@server/models/account/actor-custom-page'
6import { PluginModel } from '@server/models/server/plugin'
6import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models' 7import { HTMLServerConfig, RegisteredExternalAuthConfig, RegisteredIdAndPassAuthConfig, ServerConfig } from '@shared/models'
7import { Hooks } from './plugins/hooks' 8import { Hooks } from './plugins/hooks'
8import { PluginManager } from './plugins/plugin-manager' 9import { 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
6export interface ServerConfigPlugin { 6export 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 }