peertube-plugin-livechat/client/common/configuration/elements/channel-configuration.ts

353 lines
14 KiB
TypeScript
Raw Normal View History

2024-05-23 15:17:28 +00:00
// SPDX-FileCopyrightText: 2024 Mehdi Benadel <https://mehdibenadel.com>
//
// SPDX-License-Identifier: AGPL-3.0-only
import type { RegisterClientOptions } from '@peertube/peertube-types/client'
2024-05-23 14:56:11 +00:00
import type { ChannelConfiguration } from 'shared/lib/types'
2024-05-23 15:09:58 +00:00
import { html } from 'lit'
import { customElement, property, state } from 'lit/decorators.js'
2024-05-23 14:56:11 +00:00
import { ptTr } from '../../lib/directives/translation'
import { Task } from '@lit/task'
import { ChannelDetailsService } from '../services/channel-details'
import { provide } from '@lit/context'
2024-05-23 14:56:11 +00:00
import { channelConfigurationContext, channelDetailsServiceContext } from '../contexts/channel'
import { registerClientOptionsContext } from '../../lib/contexts/peertube'
2024-05-23 15:09:58 +00:00
import { LivechatElement } from '../../lib/elements/livechat'
2024-05-23 13:52:12 +00:00
@customElement('livechat-channel-configuration')
2024-05-23 15:09:58 +00:00
export class ChannelConfigurationElement extends LivechatElement {
@provide({ context: registerClientOptionsContext })
@property({ attribute: false })
2024-05-24 12:08:48 +00:00
public registerClientOptions?: RegisterClientOptions
@property({ attribute: false })
2024-05-24 12:08:48 +00:00
public channelId?: number
@provide({ context: channelConfigurationContext })
@state()
2024-05-24 12:08:48 +00:00
public _channelConfiguration?: ChannelConfiguration
@provide({ context: channelDetailsServiceContext })
2024-05-24 12:08:48 +00:00
private _channelDetailsService?: ChannelDetailsService
@state()
public _formStatus: boolean | any = undefined
2024-05-23 20:52:39 +00:00
private readonly _asyncTaskRender = new Task(this, {
task: async ([registerClientOptions]) => {
if (registerClientOptions) {
this._channelDetailsService = new ChannelDetailsService(registerClientOptions)
this._channelConfiguration = await this._channelDetailsService.fetchConfiguration(this.channelId ?? 0)
}
},
args: () => [this.registerClientOptions]
2024-05-23 20:52:39 +00:00
})
2024-05-24 12:08:48 +00:00
private readonly _saveConfig = (event?: Event): void => {
event?.preventDefault()
2024-05-23 13:52:12 +00:00
if (this._channelDetailsService && this._channelConfiguration) {
2024-05-23 20:52:39 +00:00
this._channelDetailsService.saveOptions(this._channelConfiguration.channel.id,
this._channelConfiguration.configuration)
.then(() => {
2024-05-23 13:52:12 +00:00
this._formStatus = { success: true }
2024-05-24 12:08:48 +00:00
this.registerClientOptions
?.peertubeHelpers.notifier.info('Livechat configuration has been properly updated.')
2024-05-23 13:52:12 +00:00
this.requestUpdate('_formStatus')
})
2024-05-24 12:08:48 +00:00
.catch((error: Error) => {
console.error(`An error occurred. ${error.name}: ${error.message}`)
this.registerClientOptions
?.peertubeHelpers.notifier.error(
`An error occurred. ${(error.name && error.message) ? `${error.name}: ${error.message}` : ''}`)
2024-05-23 13:52:12 +00:00
this.requestUpdate('_formStatus')
2024-05-23 20:52:39 +00:00
})
}
}
2024-05-23 20:52:39 +00:00
protected override render = (): unknown => {
const tableHeaderList = {
forbiddenWords: {
entries: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_DESC2)
},
regex: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_REGEXP_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_REGEXP_DESC)
},
applyToModerators: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_APPLYTOMODERATORS_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_APPLYTOMODERATORS_DESC)
},
label: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL_DESC)
},
reason: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_REASON_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_REASON_DESC)
},
comments: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_COMMENTS_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_COMMENTS_DESC)
}
},
quotes: {
messages: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_QUOTE_LABEL2),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_QUOTE_DESC2)
},
delay: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_QUOTE_DELAY_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_QUOTE_DELAY_DESC)
}
},
commands: {
command: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_COMMAND_CMD_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_COMMAND_CMD_DESC)
},
message: {
colName: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_COMMAND_MESSAGE_LABEL),
description: ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_COMMAND_MESSAGE_DESC)
}
}
}
2024-05-23 20:52:39 +00:00
const tableSchema = {
forbiddenWords: {
entries: {
inputType: 'textarea',
default: [''],
2024-05-23 20:52:39 +00:00
separator: '\n'
},
regex: {
inputType: 'checkbox',
2024-05-23 20:52:39 +00:00
default: false
},
applyToModerators: {
inputType: 'checkbox',
default: false
},
label: {
inputType: 'text',
default: ''
},
reason: {
inputType: 'text',
default: '',
datalist: []
},
comments: {
inputType: 'textarea',
default: ''
2024-05-23 20:52:39 +00:00
}
},
quotes: {
messages: {
inputType: 'textarea',
default: [''],
2024-05-23 20:52:39 +00:00
separator: '\n'
},
delay: {
inputType: 'number',
2024-05-23 20:52:39 +00:00
default: 10
}
},
commands: {
command: {
inputType: 'text',
2024-05-23 20:52:39 +00:00
default: ''
},
message: {
inputType: 'text',
2024-05-23 20:52:39 +00:00
default: ''
}
}
}
return this._asyncTaskRender.render({
complete: () => html`
2024-05-23 20:52:39 +00:00
<div class="margin-content peertube-plugin-livechat-configuration
peertube-plugin-livechat-configuration-channel">
<h1>
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_TITLE)}:
<span class="peertube-plugin-livechat-configuration-channel-info">
<span>${this._channelConfiguration?.channel.displayName}</span>
<span>${this._channelConfiguration?.channel.name}</span>
</span>
2024-05-23 13:52:12 +00:00
<livechat-help-button .page="documentation/user/streamers/channel">
</livechat-help-button>
</h1>
<p>${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_DESC)}</p>
<form livechat-configuration-channel-options role="form" @submit=${this._saveConfig}>
<div class="row mt-3">
2024-05-23 13:52:12 +00:00
<div class="row mt-5">
<div class="col-12 col-lg-4 col-xl-3">
<livechat-configuration-row
.title=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_SLOW_MODE_LABEL)}
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_SLOW_MODE_DESC, true)}
2024-05-23 20:52:39 +00:00
.helpPage=${'documentation/user/streamers/slow_mode'}>
2024-05-23 13:52:12 +00:00
</livechat-configuration-row>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="form-group">
<label>
<input
type="number"
name="slow_mode_duration"
class="form-control"
min="0"
max="1000"
id="peertube-livechat-slow-mode-duration"
@input=${(event: InputEvent) => {
2024-05-23 20:52:39 +00:00
if (event?.target && this._channelConfiguration) {
this._channelConfiguration.configuration.slowMode.duration =
Number((event.target as HTMLInputElement).value)
}
2024-05-23 13:52:12 +00:00
this.requestUpdate('_channelConfiguration')
}
}
2024-05-23 13:52:12 +00:00
value="${this._channelConfiguration?.configuration.slowMode.duration}"
/>
</label>
</div>
</div>
2024-05-23 13:52:12 +00:00
</div>
<div class="row mt-5">
<div class="col-12 col-lg-4 col-xl-3">
<livechat-configuration-row
.title=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_BOT_OPTIONS_TITLE)}
.description=${''}
2024-05-23 20:52:39 +00:00
.helpPage=${'documentation/user/streamers/channel'}>
2024-05-23 13:52:12 +00:00
</livechat-configuration-row>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<div class="form-group">
<label>
<input
type="checkbox"
name="bot"
id="peertube-livechat-bot"
@input=${(event: InputEvent) => {
2024-05-23 20:52:39 +00:00
if (event?.target && this._channelConfiguration) {
this._channelConfiguration.configuration.bot.enabled =
(event.target as HTMLInputElement).checked
}
2024-05-23 13:52:12 +00:00
this.requestUpdate('_channelConfiguration')
}
}
.value=${this._channelConfiguration?.configuration.bot.enabled}
?checked=${this._channelConfiguration?.configuration.bot.enabled}
/>
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_ENABLE_BOT_LABEL)}
</label>
</div>
2024-05-23 20:52:39 +00:00
${this._channelConfiguration?.configuration.bot.enabled
? html`<div class="form-group">
<labelfor="peertube-livechat-bot-nickname">
${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_BOT_NICKNAME)}
</label>
<input
2024-05-23 13:52:12 +00:00
type="text"
name="bot_nickname"
class="form-control"
id="peertube-livechat-bot-nickname"
@input=${(event: InputEvent) => {
2024-05-23 20:52:39 +00:00
if (event?.target && this._channelConfiguration) {
this._channelConfiguration.configuration.bot.nickname =
(event.target as HTMLInputElement).value
}
this.requestUpdate('_channelConfiguration')
}
}
2024-05-23 13:52:12 +00:00
value="${this._channelConfiguration?.configuration.bot.nickname}"
/>
2024-05-23 13:52:12 +00:00
</div>`
: ''
}
2024-05-23 13:52:12 +00:00
</div>
</div>
2024-05-23 20:52:39 +00:00
${this._channelConfiguration?.configuration.bot.enabled
? html`<div class="row mt-5">
2024-05-23 13:52:12 +00:00
<div class="col-12 col-lg-4 col-xl-3">
<livechat-configuration-row
.title=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_LABEL)}
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_FORBIDDEN_WORDS_DESC)}
2024-05-23 20:52:39 +00:00
.helpPage=${'documentation/user/streamers/bot/forbidden_words'}>
2024-05-23 13:52:12 +00:00
</livechat-configuration-row>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<livechat-dynamic-table-form
.header=${tableHeaderList.forbiddenWords}
.schema=${tableSchema.forbiddenWords}
.rows=${this._channelConfiguration?.configuration.bot.forbiddenWords}
@update=${(e: CustomEvent) => {
if (this._channelConfiguration) {
this._channelConfiguration.configuration.bot.forbiddenWords = e.detail
this.requestUpdate('_channelConfiguration')
}
}
}
2024-05-23 13:52:12 +00:00
.formName=${'forbidden-words'}>
</livechat-dynamic-table-form>
</div>
</div>
<div class="row mt-5">
<div class="col-12 col-lg-4 col-xl-3">
<livechat-configuration-row
.title=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_QUOTE_LABEL)}
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_QUOTE_DESC)}
2024-05-23 20:52:39 +00:00
.helpPage=${'documentation/user/streamers/bot/quotes'}>
2024-05-23 13:52:12 +00:00
</livechat-configuration-row>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<livechat-dynamic-table-form
.header=${tableHeaderList.quotes}
.schema=${tableSchema.quotes}
.rows=${this._channelConfiguration?.configuration.bot.quotes}
@update=${(e: CustomEvent) => {
2024-05-23 13:52:12 +00:00
if (this._channelConfiguration) {
this._channelConfiguration.configuration.bot.quotes = e.detail
this.requestUpdate('_channelConfiguration')
}
}
}
.formName=${'quote'}>
2024-05-23 13:52:12 +00:00
</livechat-dynamic-table-form>
</div>
</div>
<div class="row mt-5">
<div class="col-12 col-lg-4 col-xl-3">
<livechat-configuration-row
.title=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_COMMAND_LABEL)}
.description=${ptTr(LOC_LIVECHAT_CONFIGURATION_CHANNEL_COMMAND_DESC)}
2024-05-23 20:52:39 +00:00
.helpPage=${'documentation/user/streamers/bot/commands'}>
2024-05-23 13:52:12 +00:00
</livechat-configuration-row>
</div>
<div class="col-12 col-lg-8 col-xl-9">
<livechat-dynamic-table-form
.header=${tableHeaderList.commands}
.schema=${tableSchema.commands}
.rows=${this._channelConfiguration?.configuration.bot.commands}
@update=${(e: CustomEvent) => {
2024-05-23 13:52:12 +00:00
if (this._channelConfiguration) {
this._channelConfiguration.configuration.bot.commands = e.detail
this.requestUpdate('_channelConfiguration')
}
}
}
.formName=${'command'}>
2024-05-23 13:52:12 +00:00
</livechat-dynamic-table-form>
</div>
</div>`
: ''
}
<div class="form-group mt-5">
<input type="submit" class="peertube-button-link orange-button" value=${ptTr(LOC_SAVE)} />
</div>
</form>
</div>`
})
}
}