added attempt at dynamic listing

This commit is contained in:
Mehdi Benadel 2024-04-05 20:46:14 +02:00
parent 3632bb7cec
commit 9ff4abfce4
4 changed files with 174 additions and 74 deletions

View File

@ -63,78 +63,104 @@
</div> </div>
</div> </div>
{{#forbiddenWordsArray}}{{! iterating on forbiddenWordsArray to display N fields }} <div class="row mt-5" livechat-configuration-channel-options-bot-enabled>
<div class="row mt-5" livechat-configuration-channel-options-bot-enabled> <div class="col-12 col-lg-4 col-xl-3">
<div class="col-12 col-lg-4 col-xl-3"> <h2>{{forbiddenWords}} #{{displayNumber}}</h2>
<h2>{{forbiddenWords}} #{{displayNumber}}</h2> {{#displayHelp}}
{{#displayHelp}} <p>{{forbiddenWordsDesc}} {{moreInfo}}</p>
<p>{{forbiddenWordsDesc}} {{moreInfo}}</p> {{{helpButtonForbiddenWords}}}
{{{helpButtonForbiddenWords}}} {{/displayHelp}}
{{/displayHelp}} </div>
</div> <table class="col-12 col-lg-4 col-xl-3 forbidden_words_table">
<div class="col-12 col-lg-8 col-xl-9"> <thead>
<div class="form-group"> <tr>
<label for="peertube-livechat-forbidden-words-{{fieldNumber}}">{{forbiddenWords}}</label> <th scope="col">{{forbiddenWords}} <span class="form-group-description">{{forbiddenWordsDesc2}}</th>
{{! warning: don't add extra line break in textarea! }} <th scope="col">{{forbiddenWordsRegexp}} <span class="form-group-description">{{forbiddenWordsRegexpDesc}}</span></th>
<textarea <th scope="col">{{forbiddenWordsApplyToModerators}} <span class="form-group-description">{{forbiddenWordsApplyToModeratorsDesc}}</span></th>
name="forbidden_words_{{fieldNumber}}" <th scope="col">{{forbiddenWordsLabel}} <span class="form-group-description">{{forbiddenWordsLabelDesc}}</th>
id="peertube-livechat-forbidden-words-{{fieldNumber}}" <th scope="col">{{forbiddenWordsReason}} <span class="form-group-description">{{forbiddenWordsReasonDesc}}</th>
class="form-control" <th scope="col">{{forbiddenWordsComments}} <span class="form-group-description">{{forbiddenWordsCommentsDesc}}</th>
>{{joinedEntries}}</textarea> <th scope="col">Remove <span class="form-group-description">Remove Row</th>
<p class="form-group-description">{{forbiddenWordsDesc2}}</p> </tr>
</div> </thead>
<div class="form-group"> {{#forbiddenWordsArray}}{{! iterating on forbiddenWordsArray to display N fields }}
<label> <tbody>
<input <tr class="button.peertube-livechat-forbidden-words-row-{{fieldNumber}}">
type="checkbox" <td>
name="forbidden_words_regexp_{{fieldNumber}}" <label for="peertube-livechat-forbidden-words-{{fieldNumber}}">{{forbiddenWords}}</label>
value="1" {{! warning: don't add extra line break in textarea! }}
{{#regexp}} <textarea
checked="checked" name="forbidden_words_{{fieldNumber}}"
{{/regexp}} id="peertube-livechat-forbidden-words-{{fieldNumber}}"
/> class="form-control"
{{forbiddenWordsRegexp}} >{{joinedEntries}}</textarea>
</label> <p class="form-group-description">{{forbiddenWordsDesc2}}</p>
<p class="form-group-description">{{forbiddenWordsRegexpDesc}}</p> </td>
</div> <label>
<div class="form-group"> <input
<label> type="checkbox"
<input name="forbidden_words_regexp_{{fieldNumber}}"
type="checkbox" value="1"
name="forbidden_words_applytomoderators_{{fieldNumber}}" {{#regexp}}
value="1" checked="checked"
{{#applyToModerators}} {{/regexp}}
checked="checked" />
{{/applyToModerators}} {{forbiddenWordsRegexp}}
/> </label>
{{forbiddenWordsApplyToModerators}} <p class="form-group-description">{{forbiddenWordsRegexpDesc}}</p>
</label> <td>
<p class="form-group-description">{{forbiddenWordsApplyToModeratorsDesc}}</p> <label>
</div> <input
<div class="form-group"> type="checkbox"
<label for="peertube-livechat-forbidden-words-reason-{{fieldNumber}}">{{forbiddenWordsReason}}</label> name="forbidden_words_applytomoderators_{{fieldNumber}}"
<input value="1"
type="text" {{#applyToModerators}}
name="forbidden_words_reason_{{fieldNumber}}" checked="checked"
class="form-control" {{/applyToModerators}}
id="peertube-livechat-forbidden-words-reason-{{fieldNumber}}" />
value="{{reason}}" {{forbiddenWordsApplyToModerators}}
/> </label>
<p class="form-group-description">{{forbiddenWordsReasonDesc}}</p> <p class="form-group-description">{{forbiddenWordsApplyToModeratorsDesc}}</p>
</div> </td>
<div class="form-group"> <label for="peertube-livechat-forbidden-words-label-{{fieldNumber}}">{{forbiddenWordsLabel}}</label>
<label for="peertube-livechat-forbidden-words-comments-{{fieldNumber}}">{{forbiddenWordsComments}}</label> <input
{{! warning: don't add extra line break in textarea! }} type="text"
<textarea name="forbidden_words_label_{{fieldNumber}}"
name="forbidden_words_comments_{{fieldNumber}}" class="form-control"
id="peertube-livechat-forbidden-words-comments-{{fieldNumber}}" id="peertube-livechat-forbidden-words-label-{{fieldNumber}}"
class="form-control" value="{{label}}"
>{{comments}}</textarea> />
<p class="form-group-description">{{forbiddenWordsCommentsDesc}}</p> <p class="form-group-description">{{forbiddenWordsLabelDesc}}</p>
</div> <td>
</div> <label for="peertube-livechat-forbidden-words-reason-{{fieldNumber}}">{{forbiddenWordsReason}}</label>
<input
type="text"
name="forbidden_words_reason_{{fieldNumber}}"
class="form-control"
id="peertube-livechat-forbidden-words-reason-{{fieldNumber}}"
value="{{reason}}"
/>
<p class="form-group-description">{{forbiddenWordsReasonDesc}}</p>
</td>
<label for="peertube-livechat-forbidden-words-comments-{{fieldNumber}}">{{forbiddenWordsComments}}</label>
{{! warning: don't add extra line break in textarea! }}
<textarea
name="forbidden_words_comments_{{fieldNumber}}"
id="peertube-livechat-forbidden-words-comments-{{fieldNumber}}"
class="form-control"
>{{comments}}</textarea>
<p class="form-group-description">{{forbiddenWordsCommentsDesc}}</p>
<td>
<button type="button" class="btn btn-danger peertube-livechat-forbidden-words-{{fieldNumber}}-remove">x</button>
</td>
</tr>
{{/forbiddenWordsArray}}
<tr>
<button type="button" class="btn btn-success peertube-livechat-forbidden-words-add">+</button>
</tr>
</tbody>
</table>
</div> </div>
{{/forbiddenWordsArray}}
{{#quotesArray}}{{! iterating on quotesArray to display N fields }} {{#quotesArray}}{{! iterating on quotesArray to display N fields }}
<div class="row mt-5" livechat-configuration-channel-options-bot-enabled> <div class="row mt-5" livechat-configuration-channel-options-bot-enabled>

View File

@ -47,12 +47,13 @@ async function getConfigurationChannelViewData (
joinedEntries: fw.entries.join('\n'), joinedEntries: fw.entries.join('\n'),
regexp: !!fw.regexp, regexp: !!fw.regexp,
applyToModerators: fw.applyToModerators, applyToModerators: fw.applyToModerators,
label:fw.label,
reason: fw.reason, reason: fw.reason,
comments: fw.comments comments: fw.comments
}) })
} }
// Ensuring we have at least N blocks: // Ensuring we have at least N blocks:
while (forbiddenWordsArray.length < 3) { while (forbiddenWordsArray.length < 1) {
const i = forbiddenWordsArray.length const i = forbiddenWordsArray.length
// default value // default value
forbiddenWordsArray.push({ forbiddenWordsArray.push({
@ -62,6 +63,7 @@ async function getConfigurationChannelViewData (
joinedEntries: '', joinedEntries: '',
regexp: false, regexp: false,
applyToModerators: false, applyToModerators: false,
label:'',
reason: '', reason: '',
comments: '' comments: ''
}) })
@ -105,7 +107,7 @@ async function getConfigurationChannelViewData (
}) })
} }
// Ensuring we have at least N blocks: // Ensuring we have at least N blocks:
while (cmdsArray.length < 3) { while (cmdsArray.length < 1) {
const i = cmdsArray.length const i = cmdsArray.length
// default value // default value
cmdsArray.push({ cmdsArray.push({
@ -144,6 +146,52 @@ async function vivifyConfigurationChannel (
const enableBotCB = form.querySelector('input[name=bot]') as HTMLInputElement const enableBotCB = form.querySelector('input[name=bot]') as HTMLInputElement
const botEnabledEl = form.querySelectorAll('[livechat-configuration-channel-options-bot-enabled]') const botEnabledEl = form.querySelectorAll('[livechat-configuration-channel-options-bot-enabled]')
const dataClasses = ['forbidden-words', 'command', 'quote']
type ChannelConfigClass = (typeof dataClasses)[number]
type ChannelRowData = Record<ChannelConfigClass,{ rows: HTMLTableRowElement[], addButton: HTMLButtonElement, removeButtons: HTMLButtonElement[]}>
const populateRowData: Function = () => {
let modifiers : ChannelRowData = {};
for (let dataClass in dataClasses) {
let rows : HTMLTableRowElement[] = [];
let removeButtons : HTMLButtonElement[] = [];
for (let i = 0, row : HTMLTableRowElement; row = form.querySelector(`button.peertube-livechat-${dataClass}-${i}-row`) as HTMLTableRowElement; i++) {
rows.push(row)
}
for (let i = 0, button : HTMLButtonElement; button = form.querySelector(`button.peertube-livechat-${dataClass}-${i}-remove`) as HTMLButtonElement; i++) {
removeButtons.push(button)
}
modifiers[dataClass] = {
rows,
addButton: form.querySelector(`button.peertube-livechat-${dataClass}-add`) as HTMLButtonElement,
removeButtons
}
}
return modifiers
}
let rowDataRecords : ChannelRowData = populateRowData();
function removeRow(dataClass: ChannelConfigClass, index: number): any {
let {rows} = rowDataRecords[dataClass]
let rowToDelete = rows.splice(index,1)[0]
rowToDelete
for (let i = index, row : HTMLTableRowElement; row = form.querySelector(`button.peertube-livechat-${dataClass}-${i}-row`) as HTMLTableRowElement; i++) {
rows.push(row)
}
}
function addRow(dataClass: ChannelConfigClass): any {
throw new Error('Function not implemented.')
}
const refresh: Function = () => { const refresh: Function = () => {
botEnabledEl.forEach(el => { botEnabledEl.forEach(el => {
if (enableBotCB.checked) { if (enableBotCB.checked) {
@ -211,6 +259,16 @@ async function vivifyConfigurationChannel (
} }
} }
for (let iQt = 0; iQt < botConf.quotes.length; iQt++) {
const qt = botConf.quotes[iQt]
if (qt.messages.some(/\s+/.test)) {
const selector = '#peertube-livechat-quote-' + iQt.toString()
errorFieldSelectors.push(selector)
const message = await translate(LOC_INVALID_VALUE)
await displayError(selector, message)
}
}
for (let iCd = 0; iCd < botConf.commands.length; iCd++) { for (let iCd = 0; iCd < botConf.commands.length; iCd++) {
const cd = botConf.commands[iCd] const cd = botConf.commands[iCd]
if (/\s+/.test(cd.command)) { if (/\s+/.test(cd.command)) {
@ -256,6 +314,7 @@ async function vivifyConfigurationChannel (
.filter(s => !/^\s*$/.test(s)) // filtering empty lines .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 label = data.get('forbidden_words_label_' + i.toString())?.toString()
const reason = data.get('forbidden_words_reason_' + i.toString())?.toString() const reason = data.get('forbidden_words_reason_' + i.toString())?.toString()
const comments = data.get('forbidden_words_comments_' + i.toString())?.toString() const comments = data.get('forbidden_words_comments_' + i.toString())?.toString()
const fw: ChannelConfigurationOptions['bot']['forbiddenWords'][0] = { const fw: ChannelConfigurationOptions['bot']['forbiddenWords'][0] = {
@ -263,6 +322,9 @@ async function vivifyConfigurationChannel (
applyToModerators: !!applyToModerators, applyToModerators: !!applyToModerators,
regexp: !!regexp regexp: !!regexp
} }
if (label) {
fw.label = label
}
if (reason) { if (reason) {
fw.reason = reason fw.reason = reason
} }
@ -331,6 +393,15 @@ async function vivifyConfigurationChannel (
} }
enableBotCB.onclick = () => refresh() enableBotCB.onclick = () => refresh()
for(let [dataClass, rowData] of Object.entries(rowDataRecords)) {
rowData.addButton.onclick = () => addRow(dataClass)
for (let i = 0; i < rowData.removeButtons.length; i++) {
rowData.removeButtons[i].onclick = () => removeRow(dataClass, i)
}
}
form.onsubmit = () => { form.onsubmit = () => {
toggleSubmit(true) toggleSubmit(true)
if (!form.checkValidity()) { if (!form.checkValidity()) {

View File

@ -180,6 +180,7 @@ async function _readForbiddenWords (botData: any): Promise<ChannelConfigurationO
entries = _readStringArray(fw, 'entries') entries = _readStringArray(fw, 'entries')
} }
const applyToModerators = _readBoolean(fw, 'applyToModerators') const applyToModerators = _readBoolean(fw, 'applyToModerators')
const label = fw.label ? _readSimpleInput(fw, 'label') : undefined
const reason = fw.reason ? _readSimpleInput(fw, 'reason') : undefined const reason = fw.reason ? _readSimpleInput(fw, 'reason') : undefined
const comments = fw.comments ? _readMultiLineString(fw, 'comments') : undefined const comments = fw.comments ? _readMultiLineString(fw, 'comments') : undefined
@ -187,6 +188,7 @@ async function _readForbiddenWords (botData: any): Promise<ChannelConfigurationO
regexp, regexp,
entries, entries,
applyToModerators, applyToModerators,
label,
reason, reason,
comments comments
}) })

View File

@ -79,6 +79,7 @@ interface ChannelConfigurationOptions {
entries: string[] entries: string[]
regexp?: boolean regexp?: boolean
applyToModerators?: boolean applyToModerators?: boolean
label?: string
reason?: string reason?: string
comments?: string comments?: string
}> }>