Enhance plugin video fields
Add video form tab selection Add ability to display an error
This commit is contained in:
parent
61cc1c03bf
commit
3c065fe3b3
31
client/e2e/src/po/admin-plugin.po.ts
Normal file
31
client/e2e/src/po/admin-plugin.po.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { browserSleep, go } from '../utils'
|
||||||
|
|
||||||
|
export class AdminPluginPage {
|
||||||
|
|
||||||
|
async navigateToSearch () {
|
||||||
|
await go('/admin/plugins/search')
|
||||||
|
|
||||||
|
await $('my-plugin-search').waitForDisplayed()
|
||||||
|
}
|
||||||
|
|
||||||
|
async search (name: string) {
|
||||||
|
const input = $('.search-bar input')
|
||||||
|
await input.waitForDisplayed()
|
||||||
|
await input.clearValue()
|
||||||
|
await input.setValue(name)
|
||||||
|
|
||||||
|
await browserSleep(1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
async installHelloWorld () {
|
||||||
|
$('.plugin-name=hello-world').waitForDisplayed()
|
||||||
|
|
||||||
|
await $('.card-body my-button[icon=cloud-download]').click()
|
||||||
|
|
||||||
|
const submitModalButton = $('.modal-content input[type=submit]')
|
||||||
|
await submitModalButton.waitForClickable()
|
||||||
|
await submitModalButton.click()
|
||||||
|
|
||||||
|
await $('.card-body my-edit-button').waitForDisplayed()
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ export class AnonymousSettingsPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickOnP2PCheckbox () {
|
async clickOnP2PCheckbox () {
|
||||||
const p2p = getCheckbox('p2pEnabled')
|
const p2p = await getCheckbox('p2pEnabled')
|
||||||
await p2p.waitForClickable()
|
await p2p.waitForClickable()
|
||||||
|
|
||||||
await p2p.click()
|
await p2p.click()
|
||||||
|
|
|
@ -31,7 +31,7 @@ export class MyAccountPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickOnP2PCheckbox () {
|
async clickOnP2PCheckbox () {
|
||||||
const p2p = getCheckbox('p2pEnabled')
|
const p2p = await getCheckbox('p2pEnabled')
|
||||||
|
|
||||||
await p2p.waitForClickable()
|
await p2p.waitForClickable()
|
||||||
await p2p.scrollIntoView(false) // Avoid issues with fixed header on firefox
|
await p2p.scrollIntoView(false) // Avoid issues with fixed header on firefox
|
||||||
|
|
|
@ -3,7 +3,10 @@ import { getCheckbox, selectCustomSelect } from '../utils'
|
||||||
|
|
||||||
export class VideoUploadPage {
|
export class VideoUploadPage {
|
||||||
async navigateTo () {
|
async navigateTo () {
|
||||||
await $('.header .publish-button').click()
|
const publishButton = await $('.header .publish-button')
|
||||||
|
|
||||||
|
await publishButton.waitForClickable()
|
||||||
|
await publishButton.click()
|
||||||
|
|
||||||
await $('.upload-video-container').waitForDisplayed()
|
await $('.upload-video-container').waitForDisplayed()
|
||||||
}
|
}
|
||||||
|
@ -24,15 +27,17 @@ export class VideoUploadPage {
|
||||||
|
|
||||||
// Wait for the upload to finish
|
// Wait for the upload to finish
|
||||||
await browser.waitUntil(async () => {
|
await browser.waitUntil(async () => {
|
||||||
const actionButton = this.getSecondStepSubmitButton().$('.action-button')
|
const warning = await $('=Publish will be available when upload is finished').isDisplayed()
|
||||||
|
const progress = await $('.progress-bar=100%').isDisplayed()
|
||||||
|
|
||||||
const klass = await actionButton.getAttribute('class')
|
return !warning && progress
|
||||||
return !klass.includes('disabled')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
setAsNSFW () {
|
async setAsNSFW () {
|
||||||
return getCheckbox('nsfw').click()
|
const checkbox = await getCheckbox('nsfw')
|
||||||
|
|
||||||
|
return checkbox.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
async validSecondUploadStep (videoName: string) {
|
async validSecondUploadStep (videoName: string) {
|
||||||
|
@ -51,6 +56,10 @@ export class VideoUploadPage {
|
||||||
return selectCustomSelect('privacy', 'Public')
|
return selectCustomSelect('privacy', 'Public')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAsPrivate () {
|
||||||
|
return selectCustomSelect('privacy', 'Private')
|
||||||
|
}
|
||||||
|
|
||||||
private getSecondStepSubmitButton () {
|
private getSecondStepSubmitButton () {
|
||||||
return $('.submit-container my-button')
|
return $('.submit-container my-button')
|
||||||
}
|
}
|
||||||
|
|
79
client/e2e/src/suites-local/plugins.e2e-spec.ts
Normal file
79
client/e2e/src/suites-local/plugins.e2e-spec.ts
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
import { AdminPluginPage } from '../po/admin-plugin.po'
|
||||||
|
import { LoginPage } from '../po/login.po'
|
||||||
|
import { VideoUploadPage } from '../po/video-upload.po'
|
||||||
|
import { browserSleep, getCheckbox, waitServerUp } from '../utils'
|
||||||
|
|
||||||
|
describe('Plugins', () => {
|
||||||
|
let videoUploadPage: VideoUploadPage
|
||||||
|
let loginPage: LoginPage
|
||||||
|
let adminPluginPage: AdminPluginPage
|
||||||
|
|
||||||
|
function getPluginCheckbox () {
|
||||||
|
return getCheckbox('hello-world-field-4')
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expectSubmitState ({ disabled }: { disabled: boolean }) {
|
||||||
|
const disabledSubmit = await $('my-button .disabled')
|
||||||
|
|
||||||
|
if (disabled) expect(await disabledSubmit.isDisplayed()).toBeTruthy()
|
||||||
|
else expect(await disabledSubmit.isDisplayed()).toBeFalsy()
|
||||||
|
}
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
await waitServerUp()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
loginPage = new LoginPage()
|
||||||
|
videoUploadPage = new VideoUploadPage()
|
||||||
|
adminPluginPage = new AdminPluginPage()
|
||||||
|
|
||||||
|
await browser.maximizeWindow()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should install hello world plugin', async () => {
|
||||||
|
await loginPage.loginAsRootUser()
|
||||||
|
|
||||||
|
await adminPluginPage.navigateToSearch()
|
||||||
|
await adminPluginPage.search('hello-world')
|
||||||
|
await adminPluginPage.installHelloWorld()
|
||||||
|
await browser.refresh()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should have checkbox in video edit page', async () => {
|
||||||
|
await videoUploadPage.navigateTo()
|
||||||
|
await videoUploadPage.uploadVideo()
|
||||||
|
|
||||||
|
await $('span=Super field 4 in main tab').waitForDisplayed()
|
||||||
|
|
||||||
|
const checkbox = await getPluginCheckbox()
|
||||||
|
expect(await checkbox.isDisplayed()).toBeTruthy()
|
||||||
|
|
||||||
|
await expectSubmitState({ disabled: true })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should check the checkbox and be able to submit the video', async function () {
|
||||||
|
const checkbox = await getPluginCheckbox()
|
||||||
|
await checkbox.click()
|
||||||
|
|
||||||
|
await expectSubmitState({ disabled: false })
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should uncheck the checkbox and not be able to submit the video', async function () {
|
||||||
|
const checkbox = await getPluginCheckbox()
|
||||||
|
await checkbox.click()
|
||||||
|
|
||||||
|
await browserSleep(5000)
|
||||||
|
|
||||||
|
await expectSubmitState({ disabled: true })
|
||||||
|
|
||||||
|
const error = await $('.form-error*=Should be enabled')
|
||||||
|
expect(await error.isDisplayed()).toBeTruthy()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('Should change the privacy and should hide the checkbox', async function () {
|
||||||
|
await videoUploadPage.setAsPrivate()
|
||||||
|
|
||||||
|
await expectSubmitState({ disabled: false })
|
||||||
|
})
|
||||||
|
})
|
|
@ -1,5 +1,5 @@
|
||||||
function getCheckbox (name: string) {
|
function getCheckbox (name: string) {
|
||||||
return $(`my-peertube-checkbox[inputname=${name}] label`)
|
return $(`my-peertube-checkbox input[id=${name}]`).parentElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
async function selectCustomSelect (id: string, valueLabel: string) {
|
async function selectCustomSelect (id: string, valueLabel: string) {
|
||||||
|
|
|
@ -146,6 +146,13 @@
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</my-peertube-checkbox>
|
</my-peertube-checkbox>
|
||||||
|
|
||||||
|
<ng-container ngbNavItem *ngIf="getPluginsFields('main').length !== 0">
|
||||||
|
|
||||||
|
<div *ngFor="let pluginSetting of getPluginsFields('main')" class="form-group" [hidden]="isPluginFieldHidden(pluginSetting)">
|
||||||
|
<my-dynamic-form-field [form]="pluginDataFormGroup" [formErrors]="formErrors['pluginData']" [setting]="pluginSetting.commonOptions"></my-dynamic-form-field>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -339,15 +346,15 @@
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container ngbNavItem *ngIf="pluginFields.length !== 0">
|
<ng-container ngbNavItem *ngIf="getPluginsFields('plugin-settings').length !== 0">
|
||||||
<a ngbNavLink i18n>Plugin settings</a>
|
<a ngbNavLink i18n>Plugin settings</a>
|
||||||
|
|
||||||
<ng-template ngbNavContent>
|
<ng-template ngbNavContent>
|
||||||
<div class="row plugin-settings">
|
<div class="row plugin-settings">
|
||||||
|
|
||||||
<div class="col-md-12 col-xl-8">
|
<div class="col-md-12 col-xl-8">
|
||||||
<div *ngFor="let pluginSetting of pluginFields" class="form-group" [hidden]="isPluginFieldHidden(pluginSetting)">
|
<div *ngFor="let pluginSetting of getPluginsFields('plugin-settings')" class="form-group" [hidden]="isPluginFieldHidden(pluginSetting)">
|
||||||
<my-dynamic-form-field [form]="pluginDataFormGroup" [formErrors]="formErrors" [setting]="pluginSetting.commonOptions"></my-dynamic-form-field>
|
<my-dynamic-form-field [form]="pluginDataFormGroup" [formErrors]="formErrors['pluginData']" [setting]="pluginSetting.commonOptions"></my-dynamic-form-field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { forkJoin } from 'rxjs'
|
import { forkJoin } from 'rxjs'
|
||||||
import { map } from 'rxjs/operators'
|
import { map } from 'rxjs/operators'
|
||||||
import { SelectChannelItem } from 'src/types/select-options-item.model'
|
import { SelectChannelItem } from 'src/types/select-options-item.model'
|
||||||
import { Component, EventEmitter, Input, NgZone, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
|
import { ChangeDetectorRef, Component, EventEmitter, Input, NgZone, OnDestroy, OnInit, Output, ViewChild } from '@angular/core'
|
||||||
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms'
|
import { AbstractControl, FormArray, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms'
|
||||||
import { HooksService, PluginService, ServerService } from '@app/core'
|
import { HooksService, PluginService, ServerService } from '@app/core'
|
||||||
import { removeElementFromArray } from '@app/helpers'
|
import { removeElementFromArray } from '@app/helpers'
|
||||||
|
import { BuildFormValidator } from '@app/shared/form-validators'
|
||||||
import {
|
import {
|
||||||
VIDEO_CATEGORY_VALIDATOR,
|
VIDEO_CATEGORY_VALIDATOR,
|
||||||
VIDEO_CHANNEL_VALIDATOR,
|
VIDEO_CHANNEL_VALIDATOR,
|
||||||
|
@ -101,7 +102,8 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
||||||
private instanceService: InstanceService,
|
private instanceService: InstanceService,
|
||||||
private i18nPrimengCalendarService: I18nPrimengCalendarService,
|
private i18nPrimengCalendarService: I18nPrimengCalendarService,
|
||||||
private ngZone: NgZone,
|
private ngZone: NgZone,
|
||||||
private hooks: HooksService
|
private hooks: HooksService,
|
||||||
|
private cd: ChangeDetectorRef
|
||||||
) {
|
) {
|
||||||
this.calendarTimezone = this.i18nPrimengCalendarService.getTimezone()
|
this.calendarTimezone = this.i18nPrimengCalendarService.getTimezone()
|
||||||
this.calendarDateFormat = this.i18nPrimengCalendarService.getDateFormat()
|
this.calendarDateFormat = this.i18nPrimengCalendarService.getDateFormat()
|
||||||
|
@ -116,7 +118,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
||||||
licence: this.serverConfig.defaults.publish.licence,
|
licence: this.serverConfig.defaults.publish.licence,
|
||||||
tags: []
|
tags: []
|
||||||
}
|
}
|
||||||
const obj: any = {
|
const obj: { [ id: string ]: BuildFormValidator } = {
|
||||||
name: VIDEO_NAME_VALIDATOR,
|
name: VIDEO_NAME_VALIDATOR,
|
||||||
privacy: VIDEO_PRIVACY_VALIDATOR,
|
privacy: VIDEO_PRIVACY_VALIDATOR,
|
||||||
channelId: VIDEO_CHANNEL_VALIDATOR,
|
channelId: VIDEO_CHANNEL_VALIDATOR,
|
||||||
|
@ -138,7 +140,7 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
||||||
saveReplay: null
|
saveReplay: null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.formValidatorService.updateForm(
|
this.formValidatorService.updateFormGroup(
|
||||||
this.form,
|
this.form,
|
||||||
this.formErrors,
|
this.formErrors,
|
||||||
this.validationMessages,
|
this.validationMessages,
|
||||||
|
@ -275,6 +277,14 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPluginsFields (tab: 'main' | 'plugin-settings') {
|
||||||
|
return this.pluginFields.filter(p => {
|
||||||
|
const wanted = p.videoFormOptions.tab ?? 'plugin-settings'
|
||||||
|
|
||||||
|
return wanted === tab
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
private sortVideoCaptions () {
|
private sortVideoCaptions () {
|
||||||
this.videoCaptions.sort((v1, v2) => {
|
this.videoCaptions.sort((v1, v2) => {
|
||||||
if (v1.language.label < v2.language.label) return -1
|
if (v1.language.label < v2.language.label) return -1
|
||||||
|
@ -289,15 +299,44 @@ export class VideoEditComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
if (this.pluginFields.length === 0) return
|
if (this.pluginFields.length === 0) return
|
||||||
|
|
||||||
const obj: any = {}
|
const pluginObj: { [ id: string ]: BuildFormValidator } = {}
|
||||||
|
const pluginValidationMessages: FormReactiveValidationMessages = {}
|
||||||
|
const pluginFormErrors: any = {}
|
||||||
|
const pluginDefaults: any = {}
|
||||||
|
|
||||||
for (const setting of this.pluginFields) {
|
for (const setting of this.pluginFields) {
|
||||||
obj[setting.commonOptions.name] = new FormControl(setting.commonOptions.default)
|
const validator = (control: AbstractControl): ValidationErrors | null => {
|
||||||
|
if (!setting.commonOptions.error) return null
|
||||||
|
|
||||||
|
const error = setting.commonOptions.error({ formValues: this.form.value, value: control.value })
|
||||||
|
|
||||||
|
return error?.error ? { [setting.commonOptions.name]: error.text } : null
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = setting.commonOptions.name
|
||||||
|
|
||||||
|
pluginObj[name] = {
|
||||||
|
VALIDATORS: [ validator ],
|
||||||
|
MESSAGES: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pluginDefaults[name] = setting.commonOptions.default
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pluginDataFormGroup = new FormGroup(obj)
|
this.pluginDataFormGroup = new FormGroup({})
|
||||||
this.form.addControl('pluginData', this.pluginDataFormGroup)
|
this.formValidatorService.updateFormGroup(
|
||||||
|
this.pluginDataFormGroup,
|
||||||
|
pluginFormErrors,
|
||||||
|
pluginValidationMessages,
|
||||||
|
pluginObj,
|
||||||
|
pluginDefaults
|
||||||
|
)
|
||||||
|
|
||||||
|
this.form.addControl('pluginData', this.pluginDataFormGroup)
|
||||||
|
this.formErrors['pluginData'] = pluginFormErrors
|
||||||
|
this.validationMessages['pluginData'] = pluginValidationMessages
|
||||||
|
|
||||||
|
this.cd.detectChanges()
|
||||||
this.pluginFieldsAdded.emit()
|
this.pluginFieldsAdded.emit()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
isPublishingButtonDisabled () {
|
isPublishingButtonDisabled () {
|
||||||
return !this.form.valid ||
|
return !this.checkForm() ||
|
||||||
this.isUpdatingVideo === true ||
|
this.isUpdatingVideo === true ||
|
||||||
this.videoUploaded !== true ||
|
this.videoUploaded !== true ||
|
||||||
!this.videoUploadedIds.id
|
!this.videoUploadedIds.id
|
||||||
|
@ -240,7 +240,7 @@ export class VideoUploadComponent extends VideoSend implements OnInit, OnDestroy
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSecondStep () {
|
updateSecondStep () {
|
||||||
if (this.isPublishingButtonDisabled() || !this.checkForm()) {
|
if (this.isPublishingButtonDisabled()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,13 +56,18 @@ export abstract class FormReactive {
|
||||||
|
|
||||||
if (control.dirty) this.formChanged = true
|
if (control.dirty) this.formChanged = true
|
||||||
|
|
||||||
// Don't care if dirty on force check
|
if (forceCheck) control.updateValueAndValidity({ emitEvent: false })
|
||||||
const isDirty = control.dirty || forceCheck === true
|
if (!control || !control.dirty || !control.enabled || control.valid) continue
|
||||||
if (control && isDirty && control.enabled && !control.valid) {
|
|
||||||
const messages = validationMessages[field]
|
const staticMessages = validationMessages[field]
|
||||||
for (const key of Object.keys(control.errors)) {
|
for (const key of Object.keys(control.errors)) {
|
||||||
formErrors[field] += messages[key] + ' '
|
const formErrorValue = control.errors[key]
|
||||||
}
|
|
||||||
|
// Try to find error message in static validation messages first
|
||||||
|
// Then check if the validator returns a string that is the error
|
||||||
|
if (typeof formErrorValue === 'boolean') formErrors[field] += staticMessages[key] + ' '
|
||||||
|
else if (typeof formErrorValue === 'string') formErrors[field] += control.errors[key]
|
||||||
|
else throw new Error('Form error value of ' + field + ' is invalid')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ export class FormValidatorService {
|
||||||
return { form, formErrors, validationMessages }
|
return { form, formErrors, validationMessages }
|
||||||
}
|
}
|
||||||
|
|
||||||
updateForm (
|
updateFormGroup (
|
||||||
form: FormGroup,
|
form: FormGroup,
|
||||||
formErrors: FormReactiveErrors,
|
formErrors: FormReactiveErrors,
|
||||||
validationMessages: FormReactiveValidationMessages,
|
validationMessages: FormReactiveValidationMessages,
|
||||||
|
@ -52,7 +52,7 @@ export class FormValidatorService {
|
||||||
|
|
||||||
const field = obj[name]
|
const field = obj[name]
|
||||||
if (this.isRecursiveField(field)) {
|
if (this.isRecursiveField(field)) {
|
||||||
this.updateForm(
|
this.updateFormGroup(
|
||||||
form[name],
|
form[name],
|
||||||
formErrors[name] as FormReactiveErrors,
|
formErrors[name] as FormReactiveErrors,
|
||||||
validationMessages[name] as FormReactiveValidationMessages,
|
validationMessages[name] as FormReactiveValidationMessages,
|
||||||
|
@ -66,8 +66,10 @@ export class FormValidatorService {
|
||||||
|
|
||||||
const defaultValue = defaultValues[name] || ''
|
const defaultValue = defaultValues[name] || ''
|
||||||
|
|
||||||
if (field?.VALIDATORS) form.addControl(name, new FormControl(defaultValue, field.VALIDATORS as ValidatorFn[]))
|
form.addControl(
|
||||||
else form.addControl(name, new FormControl(defaultValue))
|
name,
|
||||||
|
new FormControl(defaultValue, field?.VALIDATORS as ValidatorFn[])
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,15 @@ export type RegisterClientFormFieldOptions = {
|
||||||
|
|
||||||
// Not supported by plugin setting registration, use registerSettingsScript instead
|
// Not supported by plugin setting registration, use registerSettingsScript instead
|
||||||
hidden?: (options: any) => boolean
|
hidden?: (options: any) => boolean
|
||||||
|
|
||||||
|
// Return undefined | null if there is no error or return a string with the detailed error
|
||||||
|
// Not supported by plugin setting registration
|
||||||
|
error?: (options: any) => { error: boolean, text?: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RegisterClientVideoFieldOptions {
|
export interface RegisterClientVideoFieldOptions {
|
||||||
type: 'update' | 'upload' | 'import-url' | 'import-torrent' | 'go-live'
|
type: 'update' | 'upload' | 'import-url' | 'import-torrent' | 'go-live'
|
||||||
|
|
||||||
|
// Default to 'plugin-settings'
|
||||||
|
tab?: 'main' | 'plugin-settings'
|
||||||
}
|
}
|
||||||
|
|
|
@ -692,16 +692,31 @@ async function register ({ registerVideoField, peertubeHelpers }) {
|
||||||
type: 'input-textarea',
|
type: 'input-textarea',
|
||||||
|
|
||||||
default: '',
|
default: '',
|
||||||
|
|
||||||
// Optional, to hide a field depending on the current form state
|
// Optional, to hide a field depending on the current form state
|
||||||
// liveVideo is in the options object when the user is creating/updating a live
|
// liveVideo is in the options object when the user is creating/updating a live
|
||||||
// videoToUpdate is in the options object when the user is updating a video
|
// videoToUpdate is in the options object when the user is updating a video
|
||||||
hidden: ({ formValues, videoToUpdate, liveVideo }) => {
|
hidden: ({ formValues, videoToUpdate, liveVideo }) => {
|
||||||
return formValues.pluginData['other-field'] === 'toto'
|
return formValues.pluginData['other-field'] === 'toto'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Optional, to display an error depending on the form state
|
||||||
|
error: ({ formValues, value }) => {
|
||||||
|
if (formValues['privacy'] !== 1 && formValues['privacy'] !== 2) return { error: false }
|
||||||
|
if (value === true) return { error: false }
|
||||||
|
|
||||||
|
return { error: true, text: 'Should be enabled' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const videoFormOptions = {
|
||||||
|
// Optional, to choose to put your setting in a specific tab in video form
|
||||||
|
// type: 'main' | 'plugin-settings'
|
||||||
|
tab: 'main'
|
||||||
|
}
|
||||||
|
|
||||||
for (const type of [ 'upload', 'import-url', 'import-torrent', 'update', 'go-live' ]) {
|
for (const type of [ 'upload', 'import-url', 'import-torrent', 'update', 'go-live' ]) {
|
||||||
registerVideoField(commonOptions, { type })
|
registerVideoField(commonOptions, { type, ...videoFormOptions })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue
Block a user