Terms&Conditions (#18):

* new settings for instance's terms
* new channel option for channel's terms
This commit is contained in:
John Livingston
2024-06-21 18:18:11 +02:00
parent 4b49037f68
commit 45a63eaecd
13 changed files with 93 additions and 3 deletions

View File

@ -14,6 +14,7 @@ import { customElement, property, state } from 'lit/decorators.js'
import { ptTr } from '../../lib/directives/translation'
import { Task } from '@lit/task'
import { provide } from '@lit/context'
import { channelTermsMaxLength } from 'shared/lib/constants'
@customElement('livechat-channel-configuration')
export class ChannelConfigurationElement extends LivechatElement {
@ -51,6 +52,10 @@ export class ChannelConfigurationElement extends LivechatElement {
})
}
public termsMaxLength (): number {
return channelTermsMaxLength
}
/**
* Resets the form by reloading data from backend.
*/
@ -120,7 +125,11 @@ export class ChannelConfigurationElement extends LivechatElement {
const validationErrorTypes: ValidationErrorType[] | undefined =
this.validationError?.properties[`${propertyName}`] ?? undefined
// FIXME: this code is duplicated in dymamic table form
if (validationErrorTypes && validationErrorTypes.length !== 0) {
if (validationErrorTypes.includes(ValidationErrorType.Missing)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_MISSING)}`)
}
if (validationErrorTypes.includes(ValidationErrorType.WrongType)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_WRONG_TYPE)}`)
}
@ -130,6 +139,9 @@ export class ChannelConfigurationElement extends LivechatElement {
if (validationErrorTypes.includes(ValidationErrorType.NotInRange)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_NOT_IN_RANGE)}`)
}
if (validationErrorTypes.includes(ValidationErrorType.TooLong)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_TOO_LONG)}`)
}
return html`<div id=${feedbackId} class="invalid-feedback">${errorMessages}</div>`
} else {

View File

@ -128,6 +128,36 @@ export function tplChannelConfiguration (el: ChannelConfigurationElement): Templ
<form livechat-configuration-channel-options role="form" @submit=${el.saveConfig} @change=${el.resetValidation}>
<livechat-configuration-section-header
.label=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_TERMS_LABEL)}
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_TERMS_DESC, true)}
.helpPage=${'documentation/user/streamers/channel'}>
</livechat-configuration-section-header>
<div class="form-group">
<textarea
name="terms"
id="peertube-livechat-terms"
.value=${el.channelConfiguration?.configuration.terms ?? ''}
maxlength=${el.termsMaxLength()}
class=${classMap(
Object.assign(
{ 'form-control': true },
el.getInputValidationClass('terms')
)
)}
@change=${(event: Event) => {
if (event?.target && el.channelConfiguration) {
let value: string | undefined = (event.target as HTMLTextAreaElement).value
if (value === '') { value = undefined }
el.channelConfiguration.configuration.terms = value
}
el.requestUpdate('channelConfiguration')
}
}
></textarea>
${el.renderFeedback('peertube-livechat-terms-feedback', 'terms')}
</div>
<livechat-configuration-section-header
.label=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_MUTE_ANONYMOUS_LABEL)}
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_MUTE_ANONYMOUS_DESC, true)}

View File

@ -11,6 +11,7 @@ import type {
import { ValidationError, ValidationErrorType } from '../../lib/models/validation'
import { getBaseRoute } from '../../../utils/uri'
import { maxEmojisPerChannel } from 'shared/lib/emojis'
import { channelTermsMaxLength } from 'shared/lib/constants'
export class ChannelDetailsService {
public _registerClientOptions: RegisterClientOptions
@ -27,6 +28,10 @@ export class ChannelDetailsService {
validateOptions = async (channelConfigurationOptions: ChannelConfigurationOptions): Promise<boolean> => {
const propertiesError: ValidationError['properties'] = {}
if (channelConfigurationOptions.terms && channelConfigurationOptions.terms.length > channelTermsMaxLength) {
propertiesError.terms = [ValidationErrorType.TooLong]
}
const botConf = channelConfigurationOptions.bot
const slowModeDuration = channelConfigurationOptions.slowMode.duration

View File

@ -672,6 +672,7 @@ export class DynamicTableFormElement extends LivechatElement {
const validationErrorTypes: ValidationErrorType[] | undefined =
this.validation?.[`${this.validationPrefix}.${originalIndex}.${propertyName}`]
// FIXME: this code is duplicated in channel-configuration
if (validationErrorTypes !== undefined && validationErrorTypes.length !== 0) {
if (validationErrorTypes.includes(ValidationErrorType.Missing)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_MISSING)}`)
@ -688,6 +689,9 @@ export class DynamicTableFormElement extends LivechatElement {
if (validationErrorTypes.includes(ValidationErrorType.Duplicate)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_DUPLICATE)}`)
}
if (validationErrorTypes.includes(ValidationErrorType.TooLong)) {
errorMessages.push(html`${ptTr(LOC_INVALID_VALUE_TOO_LONG)}`)
}
return html`<div id="${inputId}-feedback" class="invalid-feedback">${errorMessages}</div>`
} else {

View File

@ -7,7 +7,8 @@ export enum ValidationErrorType {
WrongType,
WrongFormat,
NotInRange,
Duplicate
Duplicate,
TooLong
}
export class ValidationError extends Error {