Channel conf UI WIP
This commit is contained in:
parent
af115e984b
commit
562073fc09
@ -58,7 +58,7 @@
|
|||||||
name="forbidden_words_{{fieldNumber}}"
|
name="forbidden_words_{{fieldNumber}}"
|
||||||
id="peertube-livechat-forbidden-words-{{fieldNumber}}"
|
id="peertube-livechat-forbidden-words-{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>{{entries}}</textarea>
|
>{{joinedEntries}}</textarea>
|
||||||
<p class="form-group-description">{{forbiddenWordsDesc2}}</p>
|
<p class="form-group-description">{{forbiddenWordsDesc2}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -121,7 +121,7 @@
|
|||||||
name="quote_{{fieldNumber}}"
|
name="quote_{{fieldNumber}}"
|
||||||
id="peertube-livechat-quote-{{fieldNumber}}"
|
id="peertube-livechat-quote-{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
>{{TODO}}</textarea>
|
>{{joinedMessages}}</textarea>
|
||||||
<p class="form-group-description">{{quoteDesc2}}</p>
|
<p class="form-group-description">{{quoteDesc2}}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@ -134,7 +134,7 @@
|
|||||||
name="quote_delay_{{fieldNumber}}"
|
name="quote_delay_{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="peertube-livechat-quote-delay-{{fieldNumber}}"
|
id="peertube-livechat-quote-delay-{{fieldNumber}}"
|
||||||
value="5"
|
value="{{delay}}"
|
||||||
/>
|
/>
|
||||||
<p class="form-group-description">{{quoteDelayDesc}}</p>
|
<p class="form-group-description">{{quoteDelayDesc}}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -159,7 +159,7 @@
|
|||||||
name="command_{{fieldNumber}}"
|
name="command_{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="peertube-livechat-command-{{fieldNumber}}"
|
id="peertube-livechat-command-{{fieldNumber}}"
|
||||||
value=""
|
value="{{command}}"
|
||||||
/>
|
/>
|
||||||
<p class="form-group-description">{{commandCmdDesc}}</p>
|
<p class="form-group-description">{{commandCmdDesc}}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -170,7 +170,7 @@
|
|||||||
name="command_message_{{fieldNumber}}"
|
name="command_message_{{fieldNumber}}"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
id="peertube-livechat-command-message-{{fieldNumber}}"
|
id="peertube-livechat-command-message-{{fieldNumber}}"
|
||||||
value=""
|
value="{{message}}"
|
||||||
/>
|
/>
|
||||||
<p class="form-group-description">{{commandMessageDesc}}</p>
|
<p class="form-group-description">{{commandMessageDesc}}</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -33,37 +33,90 @@ async function getConfigurationChannelViewData (
|
|||||||
throw new Error('Invalid channel configuration options.')
|
throw new Error('Invalid channel configuration options.')
|
||||||
}
|
}
|
||||||
|
|
||||||
const forbiddenWordsArray = []
|
const forbiddenWordsArray: Object[] = []
|
||||||
for (let i = 0; i < channelConfiguration.configuration.bot.forbiddenWords.length; i++) {
|
for (let i = 0; i < channelConfiguration.configuration.bot.forbiddenWords.length; i++) {
|
||||||
const fw = channelConfiguration.configuration.bot.forbiddenWords[i]
|
const fw = channelConfiguration.configuration.bot.forbiddenWords[i]
|
||||||
forbiddenWordsArray.push({
|
forbiddenWordsArray.push({
|
||||||
displayNumber: i + 1,
|
displayNumber: i + 1,
|
||||||
fieldNumber: i,
|
fieldNumber: i,
|
||||||
displayHelp: i === 0,
|
displayHelp: i === 0,
|
||||||
entries: fw.entries.join('\n'),
|
joinedEntries: fw.entries.join('\n'),
|
||||||
regexp: !!fw.regexp,
|
regexp: !!fw.regexp,
|
||||||
applyToModerators: fw.applyToModerators,
|
applyToModerators: fw.applyToModerators,
|
||||||
reason: fw.reason
|
reason: fw.reason
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// Ensuring we have at least N blocks:
|
||||||
|
while (forbiddenWordsArray.length < 3) {
|
||||||
|
const i = forbiddenWordsArray.length
|
||||||
|
// default value
|
||||||
|
forbiddenWordsArray.push({
|
||||||
|
displayNumber: i + 1,
|
||||||
|
fieldNumber: i,
|
||||||
|
displayHelp: i === 0,
|
||||||
|
joinedEntries: '',
|
||||||
|
regexp: false,
|
||||||
|
applyToModerators: false,
|
||||||
|
reason: ''
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const quotesArray: Object[] = []
|
||||||
|
for (let i = 0; i < channelConfiguration.configuration.bot.quotes.length; i++) {
|
||||||
|
const qs = channelConfiguration.configuration.bot.quotes[i]
|
||||||
|
quotesArray.push({
|
||||||
|
displayNumber: i + 1,
|
||||||
|
fieldNumber: i,
|
||||||
|
displayHelp: i === 0,
|
||||||
|
joinedMessages: qs.messages.join('\n'),
|
||||||
|
delay: Math.round(qs.delay / 60) // converting to minutes
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Ensuring we have at least N blocks:
|
||||||
|
while (quotesArray.length < 1) {
|
||||||
|
const i = quotesArray.length
|
||||||
|
// default value
|
||||||
|
quotesArray.push({
|
||||||
|
displayNumber: i + 1,
|
||||||
|
fieldNumber: i,
|
||||||
|
displayHelp: i === 0,
|
||||||
|
joinedMessages: '',
|
||||||
|
delay: 5
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
const cmdsArray: Object[] = []
|
||||||
|
for (let i = 0; i < channelConfiguration.configuration.bot.commands.length; i++) {
|
||||||
|
const cs = channelConfiguration.configuration.bot.commands[i]
|
||||||
|
cmdsArray.push({
|
||||||
|
displayNumber: i + 1,
|
||||||
|
fieldNumber: i,
|
||||||
|
displayHelp: i === 0,
|
||||||
|
message: cs.message,
|
||||||
|
command: cs.command
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Ensuring we have at least N blocks:
|
||||||
|
while (cmdsArray.length < 3) {
|
||||||
|
const i = cmdsArray.length
|
||||||
|
// default value
|
||||||
|
cmdsArray.push({
|
||||||
|
displayNumber: i + 1,
|
||||||
|
fieldNumber: i,
|
||||||
|
displayHelp: i === 0,
|
||||||
|
message: '',
|
||||||
|
command: ''
|
||||||
|
})
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
channelConfiguration,
|
channelConfiguration,
|
||||||
forbiddenWordsArray,
|
forbiddenWordsArray,
|
||||||
quotesArray: [0].map(count => {
|
quotesArray,
|
||||||
return {
|
cmdsArray
|
||||||
displayNumber: count + 1,
|
|
||||||
fieldNumber: count,
|
|
||||||
displayHelp: count === 0
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
cmdsArray: [0, 1, 2].map(count => {
|
|
||||||
return {
|
|
||||||
displayNumber: count + 1,
|
|
||||||
fieldNumber: count,
|
|
||||||
displayHelp: count === 0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +163,9 @@ async function vivifyConfigurationChannel (
|
|||||||
// TODO: handle form errors.
|
// TODO: handle form errors.
|
||||||
|
|
||||||
for (let i = 0; data.has('forbidden_words_' + i.toString()); i++) {
|
for (let i = 0; data.has('forbidden_words_' + i.toString()); i++) {
|
||||||
const entries = (data.get('forbidden_words_' + i.toString())?.toString() ?? '').split(/\r?\n|\r|\n/g)
|
const entries = (data.get('forbidden_words_' + i.toString())?.toString() ?? '')
|
||||||
|
.split(/\r?\n|\r|\n/g)
|
||||||
|
.filter(s => !/^\s*$/.test(s)) // filtering empty lines
|
||||||
const regexp = data.get('forbidden_words_regexp_' + i.toString())
|
const regexp = data.get('forbidden_words_regexp_' + i.toString())
|
||||||
const applyToModerators = data.get('forbidden_words_applytomoderators_' + i.toString())
|
const applyToModerators = data.get('forbidden_words_applytomoderators_' + i.toString())
|
||||||
const reason = data.get('forbidden_words_reason_' + i.toString())?.toString()
|
const reason = data.get('forbidden_words_reason_' + i.toString())?.toString()
|
||||||
@ -125,7 +180,31 @@ async function vivifyConfigurationChannel (
|
|||||||
channelConfigurationOptions.bot.forbiddenWords.push(fw)
|
channelConfigurationOptions.bot.forbiddenWords.push(fw)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: quotes and commands.
|
for (let i = 0; data.has('quote_' + i.toString()); i++) {
|
||||||
|
const messages = (data.get('quote_' + i.toString())?.toString() ?? '')
|
||||||
|
.split(/\r?\n|\r|\n/g)
|
||||||
|
.filter(s => !/^\s*$/.test(s)) // filtering empty lines
|
||||||
|
let delay = parseInt(data.get('quote_delay_' + i.toString())?.toString() ?? '')
|
||||||
|
if (!delay || isNaN(delay) || delay < 1) {
|
||||||
|
delay = 5
|
||||||
|
}
|
||||||
|
delay = delay * 60 // converting to seconds
|
||||||
|
const q: ChannelConfigurationOptions['bot']['quotes'][0] = {
|
||||||
|
messages,
|
||||||
|
delay
|
||||||
|
}
|
||||||
|
channelConfigurationOptions.bot.quotes.push(q)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; data.has('command_' + i.toString()); i++) {
|
||||||
|
const command = (data.get('command_' + i.toString())?.toString() ?? '')
|
||||||
|
const message = (data.get('command_message_' + i.toString())?.toString() ?? '')
|
||||||
|
const c: ChannelConfigurationOptions['bot']['commands'][0] = {
|
||||||
|
command,
|
||||||
|
message
|
||||||
|
}
|
||||||
|
channelConfigurationOptions.bot.commands.push(c)
|
||||||
|
}
|
||||||
|
|
||||||
const headers: any = clientOptions.peertubeHelpers.getAuthHeader() ?? {}
|
const headers: any = clientOptions.peertubeHelpers.getAuthHeader() ?? {}
|
||||||
headers['content-type'] = 'application/json;charset=UTF-8'
|
headers['content-type'] = 'application/json;charset=UTF-8'
|
||||||
|
@ -103,6 +103,21 @@ class BotConfiguration {
|
|||||||
return singleton
|
return singleton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current room conf content.
|
||||||
|
* @param roomJIDParam room JID (local or full)
|
||||||
|
* @returns the room conf, or null if does not exist
|
||||||
|
*/
|
||||||
|
public async getRoom (roomJIDParam: string): Promise<ChannelCommonRoomConf | null> {
|
||||||
|
const roomJID = this._canonicJID(roomJIDParam)
|
||||||
|
if (!roomJID) {
|
||||||
|
this.logger.error('Invalid room JID')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const conf = await this._getRoomConf(roomJID)
|
||||||
|
return conf
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the bot configuration for a given room.
|
* Update the bot configuration for a given room.
|
||||||
* @param roomJIDParam Room full or local JID
|
* @param roomJIDParam Room full or local JID
|
||||||
|
@ -166,9 +166,9 @@ function _readQuotes (botData: any): ChannelConfigurationOptions['bot']['quotes'
|
|||||||
throw new Error('Invalid quotes data')
|
throw new Error('Invalid quotes data')
|
||||||
}
|
}
|
||||||
const result: ChannelConfigurationOptions['bot']['quotes'] = []
|
const result: ChannelConfigurationOptions['bot']['quotes'] = []
|
||||||
for (const fw of botData.quotes) {
|
for (const qs of botData.quotes) {
|
||||||
const messages = _readStringArray(fw, 'message')
|
const messages = _readStringArray(qs, 'messages')
|
||||||
const delay = _readInteger(fw, 'delay', 1, 6000)
|
const delay = _readInteger(qs, 'delay', 1, 6000)
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
messages,
|
messages,
|
||||||
@ -183,9 +183,9 @@ function _readCommands (botData: any): ChannelConfigurationOptions['bot']['comma
|
|||||||
throw new Error('Invalid commands data')
|
throw new Error('Invalid commands data')
|
||||||
}
|
}
|
||||||
const result: ChannelConfigurationOptions['bot']['commands'] = []
|
const result: ChannelConfigurationOptions['bot']['commands'] = []
|
||||||
for (const fw of botData.commands) {
|
for (const cs of botData.commands) {
|
||||||
const message = _readSimpleInput(fw, 'message')
|
const message = _readSimpleInput(cs, 'message')
|
||||||
const command = _readSimpleInput(fw, 'command')
|
const command = _readSimpleInput(cs, 'command')
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
message,
|
message,
|
||||||
|
@ -39,39 +39,9 @@ function getDefaultChannelConfigurationOptions (_options: RegisterServerOptions)
|
|||||||
bot: {
|
bot: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
nickname: 'Sepia',
|
nickname: 'Sepia',
|
||||||
// Note: we are instanciating several data for forbiddenWords, quotes and commands.
|
forbiddenWords: [],
|
||||||
// This will be used by the frontend to instanciates requires fields
|
quotes: [],
|
||||||
forbiddenWords: [
|
commands: []
|
||||||
{
|
|
||||||
entries: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
entries: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
entries: []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
quotes: [
|
|
||||||
{
|
|
||||||
messages: [],
|
|
||||||
delay: 5 * 60 // seconds to minutes
|
|
||||||
}
|
|
||||||
],
|
|
||||||
commands: [
|
|
||||||
{
|
|
||||||
command: '',
|
|
||||||
message: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
command: '',
|
|
||||||
message: ''
|
|
||||||
},
|
|
||||||
{
|
|
||||||
command: '',
|
|
||||||
message: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,22 +79,47 @@ async function storeChannelConfigurationOptions (
|
|||||||
* Converts the channel configuration to the bot room configuration object (minus the room JID and domain)
|
* Converts the channel configuration to the bot room configuration object (minus the room JID and domain)
|
||||||
* @param options server options
|
* @param options server options
|
||||||
* @param channelConfigurationOptions The channel configuration
|
* @param channelConfigurationOptions The channel configuration
|
||||||
|
* @param previousRoomConf the previous saved room conf, if available. Used to merge handlers.
|
||||||
* @returns Partial bot room configuration
|
* @returns Partial bot room configuration
|
||||||
*/
|
*/
|
||||||
function channelConfigurationOptionsToBotRoomConf (
|
function channelConfigurationOptionsToBotRoomConf (
|
||||||
options: RegisterServerOptions,
|
options: RegisterServerOptions,
|
||||||
channelConfigurationOptions: ChannelConfigurationOptions
|
channelConfigurationOptions: ChannelConfigurationOptions,
|
||||||
|
previousRoomConf: ChannelCommonRoomConf | null
|
||||||
): ChannelCommonRoomConf {
|
): ChannelCommonRoomConf {
|
||||||
// Note concerning handlers:
|
// Note concerning handlers:
|
||||||
// If we want the bot to correctly enable/disable the handlers,
|
// If we want the bot to correctly enable/disable the handlers,
|
||||||
// we must always define all handlers, even if not used.
|
// we must always define all handlers, even if not used.
|
||||||
|
// That's why we are gathering handlers ids in handlersId, and disabling missing handlers at the end of this function.
|
||||||
|
const handlersIds: Map<string, true> = new Map<string, true>()
|
||||||
const handlers: ConfigHandlers = []
|
const handlers: ConfigHandlers = []
|
||||||
channelConfigurationOptions.bot.forbiddenWords.forEach((v, i) => {
|
channelConfigurationOptions.bot.forbiddenWords.forEach((v, i) => {
|
||||||
handlers.push(_getForbiddenWordsHandler(
|
const id = 'forbidden_words_' + i.toString()
|
||||||
'forbidden_words_' + i.toString(),
|
handlersIds.set(id, true)
|
||||||
channelConfigurationOptions.bot.forbiddenWords[i]
|
handlers.push(_getForbiddenWordsHandler(id, v))
|
||||||
))
|
|
||||||
})
|
})
|
||||||
|
channelConfigurationOptions.bot.quotes.forEach((v, i) => {
|
||||||
|
const id = 'quote_' + i.toString()
|
||||||
|
handlersIds.set(id, true)
|
||||||
|
handlers.push(_getQuotesHandler(id, v))
|
||||||
|
})
|
||||||
|
channelConfigurationOptions.bot.commands.forEach((v, i) => {
|
||||||
|
const id = 'command_' + i.toString()
|
||||||
|
handlersIds.set(id, true)
|
||||||
|
handlers.push(_getCommandsHandler(id, v))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Disabling missing handlers:
|
||||||
|
if (previousRoomConf) {
|
||||||
|
for (const handler of previousRoomConf.handlers) {
|
||||||
|
if (!handlersIds.has(handler.id)) {
|
||||||
|
// cloning to avoid issues...
|
||||||
|
const disabledHandler = JSON.parse(JSON.stringify(handler))
|
||||||
|
disabledHandler.enabled = false
|
||||||
|
handlers.push(disabledHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const roomConf: ChannelCommonRoomConf = {
|
const roomConf: ChannelCommonRoomConf = {
|
||||||
enabled: channelConfigurationOptions.bot.enabled,
|
enabled: channelConfigurationOptions.bot.enabled,
|
||||||
@ -192,6 +187,52 @@ function _getForbiddenWordsHandler (
|
|||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _getQuotesHandler (
|
||||||
|
id: string,
|
||||||
|
quotes: ChannelConfigurationOptions['bot']['quotes'][0]
|
||||||
|
): ConfigHandler {
|
||||||
|
const handler: ConfigHandler = {
|
||||||
|
type: 'quotes_random',
|
||||||
|
id,
|
||||||
|
enabled: false,
|
||||||
|
options: {
|
||||||
|
quotes: [],
|
||||||
|
delay: 5 * 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (quotes.messages.length === 0) {
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.enabled = true
|
||||||
|
handler.options.quotes = quotes.messages
|
||||||
|
handler.options.delay = quotes.delay
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getCommandsHandler (
|
||||||
|
id: string,
|
||||||
|
command: ChannelConfigurationOptions['bot']['commands'][0]
|
||||||
|
): ConfigHandler {
|
||||||
|
const handler: ConfigHandler = {
|
||||||
|
type: 'command_say',
|
||||||
|
id,
|
||||||
|
enabled: false,
|
||||||
|
options: {
|
||||||
|
quotes: [],
|
||||||
|
command: 'undefined' // This is arbitrary, and does not matter as enabled=false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!command.message || command.message === '') {
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.enabled = true
|
||||||
|
handler.options.command = command.command
|
||||||
|
handler.options.quotes = [command.message]
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
const stringToWordRegexpSpecials = [
|
const stringToWordRegexpSpecials = [
|
||||||
// order matters for these
|
// order matters for these
|
||||||
'-', '[', ']',
|
'-', '[', ']',
|
||||||
|
@ -334,12 +334,13 @@ class RoomChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger.info(`Room ${roomJID} has associated channel options, writing it`)
|
this.logger.info(`Room ${roomJID} has associated channel options, writing it`)
|
||||||
|
const previousRoomConf = await BotConfiguration.singleton().getRoom(roomJID)
|
||||||
const botConf: RoomConf = Object.assign(
|
const botConf: RoomConf = Object.assign(
|
||||||
{
|
{
|
||||||
local: roomJID,
|
local: roomJID,
|
||||||
domain: this.mucDomain
|
domain: this.mucDomain
|
||||||
},
|
},
|
||||||
channelConfigurationOptionsToBotRoomConf(this.options, channelConfigurationOptions)
|
channelConfigurationOptionsToBotRoomConf(this.options, channelConfigurationOptions, previousRoomConf)
|
||||||
)
|
)
|
||||||
|
|
||||||
await BotConfiguration.singleton().updateRoom(roomJID, botConf)
|
await BotConfiguration.singleton().updateRoom(roomJID, botConf)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user