Compare commits
20 Commits
b043e1e9c4
...
nctv-avata
Author | SHA1 | Date | |
---|---|---|---|
21ecdf77c6 | |||
cfe2ac0607 | |||
74566a895a | |||
587334a3e1 | |||
30cce2ec03 | |||
24f48788ab | |||
bed00aa4c5 | |||
fd16c95b8f | |||
39f6e4c637 | |||
f8c34213cb | |||
eb889711f5 | |||
8dd6ed7888 | |||
0cc38ac575 | |||
cde9b3f74a | |||
75245c0858 | |||
be59329581 | |||
6d103af5c9 | |||
e57d39c8ab | |||
9526a19aab | |||
db1993f97e |
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,10 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## 11.0.0 (Not Released Yet)
|
||||
## 10.3.3
|
||||
|
||||
### New features
|
||||
### Minor changes and fixes
|
||||
|
||||
* Updating ConverseJS, to use upstream (v11 WIP). This comes with many improvments and new features.
|
||||
* Fix #481: Moderation bot was not able to connect when remote chat was disabled.
|
||||
* Some cleaning in code generating Prosody configuration file.
|
||||
|
||||
## 10.3.2
|
||||
|
||||
### Minor changes and fixes
|
||||
|
||||
* Fix #477: ended polls never disappear when archiving is disabled (and no more than 20 new messages).
|
||||
|
||||
## 10.3.1
|
||||
|
||||
|
BIN
assets/images/avatars/nctv/hat_01.png
Normal file
BIN
assets/images/avatars/nctv/hat_01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 350 B |
BIN
assets/images/avatars/nctv/nigbot.png
Normal file
BIN
assets/images/avatars/nctv/nigbot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
@ -4,7 +4,7 @@
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
#peertube-plugin-livechat-container {
|
||||
#peertube-plugin-livechat-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
@ -28,7 +28,7 @@
|
||||
height: 100%;
|
||||
|
||||
converse-muc {
|
||||
min-height: max(58vh, 400px);
|
||||
min-height: max(59vh, 400px);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,6 +58,9 @@ const avatarPartsDef = {
|
||||
fur: 10,
|
||||
eyes: 15,
|
||||
mouth: 10
|
||||
},
|
||||
'nctv': {
|
||||
body: null,
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,6 +172,23 @@ async function generateAvatars (part) {
|
||||
}
|
||||
}
|
||||
|
||||
const generateNigbotAvatar = async () => {
|
||||
console.log('Starting generating nigbot avatar');
|
||||
|
||||
const inputDir = './assets/images/avatars/nctv/';
|
||||
const outputDir = './dist/server/avatars/nctv/';
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
|
||||
const buff = await sharp(path.join(inputDir, 'nigbot.png')).toBuffer();
|
||||
await sharp(buff)
|
||||
.resize(60, 60)
|
||||
.png({ palette: true })
|
||||
.toFile(path.join(outputDir, '1.png'));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
async function generateBotsAvatars () {
|
||||
{
|
||||
// Moderation bot avatar: choosing some parts, and turning it so it is facing left.
|
||||
@ -294,6 +314,21 @@ async function generateBotsAvatars () {
|
||||
})
|
||||
.toFile(path.join(botOutputDir, '1.png'))
|
||||
}
|
||||
|
||||
{
|
||||
// Nigbot avatar for users
|
||||
const inputDir = './assets/images/avatars/nctv'
|
||||
const botOutputDir = './dist/server/bot_avatars/nctv/'
|
||||
fs.mkdirSync(botOutputDir, { recursive: true })
|
||||
const buff = await sharp(path.join(inputDir, 'nigbot.png'))
|
||||
.toBuffer()
|
||||
|
||||
await sharp(buff)
|
||||
// .resize(60, 60)
|
||||
.png()
|
||||
.toFile(path.join(botOutputDir, '1.png'))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (isMainThread) {
|
||||
@ -337,6 +372,9 @@ if (isMainThread) {
|
||||
throw err
|
||||
}
|
||||
)
|
||||
} else if (part === 'nctv') {
|
||||
generateNigbotAvatar();
|
||||
parentPort.postMessage('done');
|
||||
} else {
|
||||
generateAvatars(part).then(
|
||||
() => {
|
||||
|
@ -15,21 +15,32 @@ set -x
|
||||
|
||||
# Set CONVERSE_VERSION and CONVERSE_REPO to select which repo and tag/commit/branch use.
|
||||
# Defaults values:
|
||||
CONVERSE_VERSION="v11.0.0"
|
||||
CONVERSE_VERSION="v10.1.6"
|
||||
CONVERSE_REPO="https://github.com/conversejs/converse.js.git"
|
||||
# You can eventually set CONVERSE_COMMIT to a specific commit ID, if you want to apply some patches.
|
||||
# 2024-07-15: using Converse upstream (v11 WIP).
|
||||
CONVERSE_COMMIT="46313ad92c1a861bcb50b9653859cfa9a960ae4a"
|
||||
# 2024-07-15, FIXME: the following commit includes a quick fix for Converse/#3443, waiting for upstream to be fixed.
|
||||
CONVERSE_COMMIT="7d65ef8d30a1f3949dbc590b6d27a9d786bf819f"
|
||||
CONVERSE_COMMIT=""
|
||||
|
||||
# It is possible to use another repository, if we want some customization that are not upstream (yet):
|
||||
# CONVERSE_VERSION="livechat"
|
||||
# # CONVERSE_COMMIT="4402fcc3fc60f6c9334f86528c33a0b463371d12"
|
||||
# 2014-01-16: we are using a custom version, to wait for some PR to be apply upstream.
|
||||
# This version includes following changes:
|
||||
# - #converse.js/3300: Adding the maxWait option for `debouncedPruneHistory`
|
||||
# - #converse.js/3302: debounce MUC sidebar rendering
|
||||
# - Fix: refresh the MUC sidebar when participants collection is sorted
|
||||
# - Fix: MUC occupant list does not sort itself on nicknames or roles changes
|
||||
# - Fix inconsistency between browsers on textarea outlines
|
||||
# - Fix: room information not correctly refreshed when modifications are made by other users
|
||||
# This version already includes following changes that will not be merged in ConverseJS upstream:
|
||||
# - Don't load vCards for all room occupants when the right menu is closed
|
||||
# - Changing the default avatar, for something very light (to mitigate blinking effect when vCards are loaded)
|
||||
# - Custom settings livechat_load_all_vcards for the readonly mode
|
||||
# - Adding "users" icon in the menu toggle button
|
||||
# - Removing unecessary plugins: headless/pubsub, minimize, notifications, profile, omemo, push, roomlist, dragresize.
|
||||
# - Destroy room: remove the challenge, and the new JID
|
||||
# - New config option [colorize_username](https://conversejs.org/docs/html/configuration.html#colorize_username)
|
||||
# - New loadEmojis hook, to customize emojis at runtime.
|
||||
# - Fix custom emojis path when assets_path is not the default path.
|
||||
CONVERSE_VERSION="livechat-10.1.0"
|
||||
# CONVERSE_COMMIT="4402fcc3fc60f6c9334f86528c33a0b463371d12"
|
||||
CONVERSE_REPO="https://github.com/JohnXLivingston/converse.js"
|
||||
# 2024-07-15, fix MUC save.
|
||||
CONVERSE_COMMIT="58c682b9ba09038beb961e9d8f804c270408ea69"
|
||||
CONVERSE_COMMIT="bbee0e4e8d2dc43636385cf4cca34f3604f59520"
|
||||
|
||||
rootdir="$(pwd)"
|
||||
src_dir="$rootdir/conversejs"
|
||||
|
@ -8,11 +8,12 @@
|
||||
* @description This files will override the original ConverseJS index.js file.
|
||||
*/
|
||||
|
||||
import '@converse/headless'
|
||||
import './i18n/index.js'
|
||||
import 'shared/registry.js'
|
||||
import { CustomElement } from 'shared/components/element'
|
||||
import { VIEW_PLUGINS } from './shared/constants.js'
|
||||
import { _converse, converse } from '@converse/headless'
|
||||
import { _converse, converse } from '@converse/headless/core'
|
||||
|
||||
import 'shared/styles/index.scss'
|
||||
|
||||
@ -49,9 +50,6 @@ import '../custom/plugins/terms/index.js'
|
||||
import '../custom/plugins/poll/index.js'
|
||||
/* END: Removable components */
|
||||
|
||||
// Running some specific livechat patches:
|
||||
import '../custom/livechat-patch-vcard.js'
|
||||
|
||||
import { CORE_PLUGINS } from './headless/shared/constants.js'
|
||||
import { ROOM_FEATURES } from './headless/plugins/muc/constants.js'
|
||||
// We must add our custom plugins to CORE_PLUGINS (so it is white listed):
|
||||
@ -63,7 +61,7 @@ CORE_PLUGINS.push('livechat-converse-poll')
|
||||
// (see headless/plugins/muc, getDiscoInfoFeatures, which loops on this const)
|
||||
ROOM_FEATURES.push('x_peertubelivechat_mute_anonymous')
|
||||
|
||||
_converse.exports.CustomElement = CustomElement
|
||||
_converse.CustomElement = CustomElement
|
||||
|
||||
const initialize = converse.initialize
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { api } from '@converse/headless/index.js'
|
||||
import { api } from '@converse/headless/core.js'
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { tplExternalLoginModal } from 'templates/livechat-external-login-modal.js'
|
||||
import { __ } from 'i18n'
|
||||
|
@ -1,61 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
// Here we are patching the vCard plugin, to add some specific optimizations.
|
||||
|
||||
import { _converse, api } from '@converse/headless/index.js'
|
||||
import {
|
||||
onOccupantAvatarChanged,
|
||||
setVCardOnModel,
|
||||
setVCardOnOccupant
|
||||
} from '@converse/headless/plugins/vcard/utils.js'
|
||||
|
||||
const pluginDefinition = _converse.pluggable.plugins['converse-vcard']
|
||||
const originalInitialize = pluginDefinition.initialize
|
||||
|
||||
pluginDefinition.initialize = function initialize () {
|
||||
const previousListeners = _converse._events.chatRoomInitialized ?? []
|
||||
originalInitialize.apply(this)
|
||||
|
||||
_converse.api.settings.extend({
|
||||
livechat_load_all_vcards: false
|
||||
})
|
||||
|
||||
// Now we must detect the new chatRoomInitialized listener, and remove it:
|
||||
const listenersToRemove = []
|
||||
for (const def of _converse._events.chatRoomInitialized ?? []) {
|
||||
if (def.callback && !previousListeners.includes(def.callback)) {
|
||||
listenersToRemove.push(def.callback)
|
||||
}
|
||||
}
|
||||
for (const callback of listenersToRemove) {
|
||||
console.debug('Livechat patching vcard: we must remove this listener', callback)
|
||||
api.listen.not('chatRoomInitialized', callback)
|
||||
}
|
||||
|
||||
// Adding the new listener:
|
||||
api.listen.on('chatRoomInitialized', (m) => {
|
||||
console.debug('Patched version of the vcard chatRoomInitialized event.')
|
||||
setVCardOnModel(m)
|
||||
|
||||
// loadAll: when in readonly mode (ie: OBS integration), always load all avatars.
|
||||
const loadAll = api.settings.get('livechat_load_all_vcards') === true
|
||||
let hiddenOccupants = m.get('hidden_occupants')
|
||||
if (hiddenOccupants !== true || loadAll) {
|
||||
m.occupants.forEach(setVCardOnOccupant)
|
||||
}
|
||||
m.listenTo(m.occupants, 'add', (occupant) => {
|
||||
if (hiddenOccupants !== true || loadAll) {
|
||||
setVCardOnOccupant(occupant)
|
||||
}
|
||||
})
|
||||
m.on('change:hidden_occupants', () => {
|
||||
hiddenOccupants = m.get('hidden_occupants')
|
||||
if (hiddenOccupants !== true || loadAll) {
|
||||
m.occupants.forEach(setVCardOnOccupant)
|
||||
}
|
||||
})
|
||||
m.listenTo(m.occupants, 'change:image_hash', o => onOccupantAvatarChanged(o))
|
||||
})
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
import { XMLNS_POLL } from '../constants.js'
|
||||
import { tplPollForm } from '../templates/poll-form.js'
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { converse, api, parsers } from '@converse/headless'
|
||||
import { converse, api } from '@converse/headless/core'
|
||||
import { webForm2xForm } from '@converse/headless/utils/form'
|
||||
import { __ } from 'i18n'
|
||||
import '../styles/poll-form.scss'
|
||||
@ -18,6 +18,7 @@ export default class MUCPollFormView extends CustomElement {
|
||||
return {
|
||||
model: { type: Object, attribute: true },
|
||||
modal: { type: Object, attribute: true },
|
||||
form_fields: { type: Object, attribute: false },
|
||||
alert_message: { type: Object, attribute: false },
|
||||
title: { type: String, attribute: false },
|
||||
instructions: { type: String, attribute: false }
|
||||
@ -26,8 +27,6 @@ export default class MUCPollFormView extends CustomElement {
|
||||
|
||||
_fieldTranslationMap = new Map()
|
||||
|
||||
xform = undefined
|
||||
|
||||
async initialize () {
|
||||
this.alert_message = undefined
|
||||
if (!this.model) {
|
||||
@ -37,18 +36,20 @@ export default class MUCPollFormView extends CustomElement {
|
||||
try {
|
||||
this._initFieldTranslations()
|
||||
const stanza = await this._fetchPollForm()
|
||||
const xform = parsers.parseXForm(stanza)
|
||||
const query = stanza.querySelector('query')
|
||||
const xform = sizzle(`x[xmlns="${Strophe.NS.XFORM}"]`, query)[0]
|
||||
if (!xform) {
|
||||
throw Error('Missing xform in stanza')
|
||||
}
|
||||
|
||||
xform.fields?.map(f => this._translateField(f))
|
||||
this.xform = xform
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
this.title = __(LOC_poll_title) // xform.querySelector('title')?.textContent ?? ''
|
||||
// eslint-disable-next-line no-undef
|
||||
this.instructions = __(LOC_poll_instructions) // xform.querySelector('instructions')?.textContent ?? ''
|
||||
this.form_fields = Array.from(xform.querySelectorAll('field')).map(field => {
|
||||
this._translateField(field)
|
||||
return u.xForm2TemplateResult(field, stanza)
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
this.alert_message = __('Error')
|
||||
@ -85,10 +86,10 @@ export default class MUCPollFormView extends CustomElement {
|
||||
}
|
||||
|
||||
_translateField (field) {
|
||||
const v = field.var
|
||||
const v = field.getAttribute('var')
|
||||
const label = this._fieldTranslationMap.get(v)
|
||||
if (label) {
|
||||
field.label = label
|
||||
field.setAttribute('label', label)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import { tplPoll } from '../templates/poll.js'
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { converse, _converse, api } from '@converse/headless'
|
||||
import { converse, _converse, api } from '@converse/headless/core'
|
||||
import '../styles/poll.scss'
|
||||
|
||||
export default class MUCPollView extends CustomElement {
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { _converse, converse } from '../../../src/headless/index.js'
|
||||
import { _converse, converse } from '../../../src/headless/core.js'
|
||||
import { getHeadingButtons } from './utils.js'
|
||||
import { POLL_MESSAGE_TAG, POLL_QUESTION_TAG, POLL_CHOICE_TAG } from './constants.js'
|
||||
import { __ } from 'i18n'
|
||||
@ -12,6 +12,8 @@ import './components/poll-form-view.js'
|
||||
|
||||
const { sizzle } = converse.env
|
||||
|
||||
const delayedTimeout = 2 // for delayed poll message, how long must the be considered as valid.
|
||||
|
||||
converse.plugins.add('livechat-converse-poll', {
|
||||
dependencies: ['converse-muc', 'converse-disco'],
|
||||
|
||||
@ -97,6 +99,23 @@ converse.plugins.add('livechat-converse-poll', {
|
||||
if (attrs.is_archived) {
|
||||
return this.__super__.onMessage(attrs)
|
||||
}
|
||||
if (attrs.is_delayed) {
|
||||
// When archiving is disabled, the "history" mechanism is still available:
|
||||
// Last X (20 by default) messages will be kept, and sent to users.
|
||||
// The only thing that differentiates such messages is that they are delayed.
|
||||
// We can't just ignore all delayed messages, because if one day we enable SMACKS
|
||||
// (to handle deconnections on poor network), there could be some legitimate delayed messages.
|
||||
// So we will only ignore the poll if it was sent more than X minutes ago.
|
||||
console.debug('Got a delayed poll message, checking if old or not')
|
||||
const d = new Date()
|
||||
d.setMinutes(d.getMinutes() - delayedTimeout)
|
||||
if (attrs.time < d.toISOString()) {
|
||||
console.debug(
|
||||
`Poll message was delayed fore more than ${delayedTimeout} minutes (${attrs.time} < ${d.toISOString()}).`
|
||||
)
|
||||
return this.__super__.onMessage(attrs)
|
||||
}
|
||||
}
|
||||
|
||||
console.info('Got a poll message, setting it as the current_poll')
|
||||
// this will be displayed by the livechat-converse-muc-poll custom element,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import { __ } from 'i18n'
|
||||
import BaseModal from 'plugins/modal/modal.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { modal_close_button as ModalCloseButton } from 'plugins/modal/templates/buttons.js'
|
||||
import { html } from 'lit'
|
||||
|
||||
|
@ -5,10 +5,6 @@
|
||||
import { converseLocalizedHelpUrl } from '../../../shared/lib/help'
|
||||
import { html } from 'lit'
|
||||
import { __ } from 'i18n'
|
||||
import { converse } from '@converse/headless'
|
||||
|
||||
const u = converse.env.utils
|
||||
|
||||
export function tplPollForm (el) {
|
||||
const i18nOk = __('Ok')
|
||||
// eslint-disable-next-line no-undef
|
||||
@ -17,18 +13,10 @@ export function tplPollForm (el) {
|
||||
page: 'documentation/user/streamers/polls'
|
||||
})
|
||||
|
||||
let formFieldTemplates
|
||||
if (el.xform) {
|
||||
const fields = el.xform.fields
|
||||
formFieldTemplates = fields.map(field => {
|
||||
return u.xFormField2TemplateResult(field)
|
||||
})
|
||||
}
|
||||
|
||||
return html`
|
||||
${el.alert_message ? html`<div class="error">${el.alert_message}</div>` : ''}
|
||||
${
|
||||
formFieldTemplates
|
||||
el.form_fields
|
||||
? html`
|
||||
<form class="converse-form" @submit=${ev => el.formSubmit(ev)}>
|
||||
<p class="title">
|
||||
@ -42,7 +30,7 @@ export function tplPollForm (el) {
|
||||
<p class="form-help instructions">${el.instructions}</p>
|
||||
<div class="form-errors hidden"></div>
|
||||
|
||||
${formFieldTemplates}
|
||||
${el.form_fields}
|
||||
|
||||
<fieldset class="buttons form-group">
|
||||
<input type="submit" class="btn btn-primary" value="${i18nOk}" />
|
||||
|
@ -63,7 +63,7 @@ function _tplChoice (el, currentPoll, choice, canVote) {
|
||||
<div class="livechat-progress-bar">
|
||||
<div
|
||||
role="progressbar"
|
||||
style=${'width: ' + percent + '%;'}
|
||||
style="width: ${percent}%;"
|
||||
aria-valuenow="${percent}" aria-valuemin="0" aria-valuemax="100"
|
||||
></div>
|
||||
<p>
|
||||
|
@ -3,12 +3,12 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { XMLNS_POLL } from './constants.js'
|
||||
import { _converse, api } from '../../../src/headless/index.js'
|
||||
import { _converse, api } from '../../../src/headless/core.js'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
export function getHeadingButtons (view, buttons) {
|
||||
const muc = view.model
|
||||
if (muc.get('type') !== _converse.constants.CHATROOMS_TYPE) {
|
||||
if (muc.get('type') !== _converse.CHATROOMS_TYPE) {
|
||||
// only on MUC.
|
||||
return buttons
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { _converse, converse, api } from '../../../src/headless/index.js'
|
||||
import { _converse, converse, api } from '../../../src/headless/core.js'
|
||||
|
||||
/**
|
||||
* This plugin computes the available width of converse-root, and adds classes
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { tplMUCTaskApp } from '../templates/muc-task-app.js'
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import tplMucTaskList from '../templates/muc-task-list'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import tplMucTaskLists from '../templates/muc-task-lists'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { tplMucTask } from '../templates/muc-task'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { _converse, converse } from '../../../src/headless/index.js'
|
||||
import { _converse, converse } from '../../../src/headless/core.js'
|
||||
import { ChatRoomTaskLists } from './task-lists.js'
|
||||
import { ChatRoomTaskList } from './task-list.js'
|
||||
import { ChatRoomTasks } from './tasks.js'
|
||||
@ -18,14 +18,9 @@ converse.plugins.add('livechat-converse-tasks', {
|
||||
dependencies: ['converse-muc', 'converse-disco', 'converse-pubsub'],
|
||||
|
||||
initialize () {
|
||||
Object.assign(
|
||||
_converse.exports,
|
||||
{
|
||||
ChatRoomTaskLists,
|
||||
ChatRoomTaskList,
|
||||
ChatRoomTasks
|
||||
}
|
||||
)
|
||||
_converse.ChatRoomTaskLists = ChatRoomTaskLists
|
||||
_converse.ChatRoomTaskList = ChatRoomTaskList
|
||||
_converse.ChatRoomTasks = ChatRoomTasks
|
||||
|
||||
_converse.api.settings.extend({
|
||||
livechat_task_app_enabled: false,
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import BaseModal from 'plugins/modal/modal.js'
|
||||
import tplPickTaskList from './templates/pick-task-list.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
export default class PickTaskListModal extends BaseModal {
|
||||
|
@ -7,7 +7,7 @@ import { Model } from '@converse/skeletor/src/model.js'
|
||||
/**
|
||||
* A chat room task list.
|
||||
* @class
|
||||
* @namespace _converse.exports.ChatRoomTaskList
|
||||
* @namespace _converse.ChatRoomTaskList
|
||||
* @memberof _converse
|
||||
*/
|
||||
class ChatRoomTaskList extends Model {
|
||||
|
@ -7,9 +7,9 @@ import { ChatRoomTaskList } from './task-list'
|
||||
import { initStorage } from '@converse/headless/utils/storage.js'
|
||||
|
||||
/**
|
||||
* A list of {@link _converse.exports.ChatRoomTaskList} instances, representing task lists associated to a MUC.
|
||||
* A list of {@link _converse.ChatRoomTaskList} instances, representing task lists associated to a MUC.
|
||||
* @class
|
||||
* @namespace _converse.exports.ChatRoomTaskLists
|
||||
* @namespace _converse.ChatRoomTaskLists
|
||||
* @memberOf _converse
|
||||
*/
|
||||
class ChatRoomTaskLists extends Collection {
|
||||
|
@ -7,7 +7,7 @@ import { Model } from '@converse/skeletor/src/model.js'
|
||||
/**
|
||||
* A chat room task.
|
||||
* @class
|
||||
* @namespace _converse.exports.ChatRoomTask
|
||||
* @namespace _converse.ChatRoomTask
|
||||
* @memberof _converse
|
||||
*/
|
||||
class ChatRoomTask extends Model {
|
||||
|
@ -7,9 +7,9 @@ import { ChatRoomTask } from './task'
|
||||
import { initStorage } from '@converse/headless/utils/storage.js'
|
||||
|
||||
/**
|
||||
* A list of {@link _converse.exports.ChatRoomTask} instances, representing all tasks associated to a MUC.
|
||||
* A list of {@link _converse.ChatRoomTask} instances, representing all tasks associated to a MUC.
|
||||
* @class
|
||||
* @namespace _converse.exports.ChatRoomTasks
|
||||
* @namespace _converse.ChatRoomTasks
|
||||
* @memberOf _converse
|
||||
*/
|
||||
class ChatRoomTasks extends Collection {
|
||||
|
@ -4,12 +4,12 @@
|
||||
|
||||
import { XMLNS_TASKLIST, XMLNS_TASK } from './constants.js'
|
||||
import { PubSubManager } from '../../shared/lib/pubsub-manager.js'
|
||||
import { converse, _converse, api } from '../../../src/headless/index.js'
|
||||
import { converse, _converse, api } from '../../../src/headless/core.js'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
export function getHeadingButtons (view, buttons) {
|
||||
const muc = view.model
|
||||
if (muc.get('type') !== _converse.constants.CHATROOMS_TYPE) {
|
||||
if (muc.get('type') !== _converse.CHATROOMS_TYPE) {
|
||||
// only on MUC.
|
||||
return buttons
|
||||
}
|
||||
@ -74,8 +74,8 @@ function _initChatRoomTaskLists (mucModel) {
|
||||
return
|
||||
}
|
||||
|
||||
mucModel.tasklists = new _converse.exports.ChatRoomTaskLists(undefined, { chatroom: mucModel })
|
||||
mucModel.tasks = new _converse.exports.ChatRoomTasks(undefined, { chatroom: mucModel })
|
||||
mucModel.tasklists = new _converse.ChatRoomTaskLists(undefined, { chatroom: mucModel })
|
||||
mucModel.tasks = new _converse.ChatRoomTasks(undefined, { chatroom: mucModel })
|
||||
|
||||
mucModel.taskManager = new PubSubManager(
|
||||
mucModel.get('jid'),
|
||||
@ -127,7 +127,7 @@ function _destroyChatRoomTaskLists (mucModel) {
|
||||
}
|
||||
|
||||
export function initOrDestroyChatRoomTaskLists (mucModel) {
|
||||
if (mucModel.get('type') !== _converse.constants.CHATROOMS_TYPE) {
|
||||
if (mucModel.get('type') !== _converse.CHATROOMS_TYPE) {
|
||||
// only on MUC.
|
||||
return _destroyChatRoomTaskLists(mucModel)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { html } from 'lit'
|
||||
import { __ } from 'i18n'
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { converse, api } from '../../../src/headless/index.js'
|
||||
import { converse, api } from '../../../src/headless/core.js'
|
||||
import './components/muc-terms.js'
|
||||
|
||||
const { sizzle } = converse.env
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
/* eslint-disable max-len */
|
||||
import { html } from 'lit'
|
||||
import tplIcons from '../../../src/shared/components/templates/icons.js'
|
||||
import tplIcons from '../../../src/shared/templates/icons.js'
|
||||
|
||||
export default () => {
|
||||
// Here we are adding some additonal icons to ConverseJS defaults
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { converse, _converse, api } from '../../../src/headless/index.js'
|
||||
import { converse, _converse, api } from '../../../src/headless/core.js'
|
||||
const { $build, Strophe, $iq, sizzle } = converse.env
|
||||
|
||||
/**
|
||||
@ -50,7 +50,7 @@ export class PubSubManager {
|
||||
async start () {
|
||||
// FIXME: handle errors. Find a way to display to user that this failed.
|
||||
|
||||
this.stanzaHandler = api.connection.get().addHandler(
|
||||
this.stanzaHandler = _converse.connection.addHandler(
|
||||
(message) => {
|
||||
try {
|
||||
this._handleMessage(message)
|
||||
@ -79,7 +79,7 @@ export class PubSubManager {
|
||||
// Note: no need to unsubscribe from the pubsub node, the backend will do when users leave the room.
|
||||
|
||||
if (this.stanzaHandler) {
|
||||
api.connection.get().deleteHandler(this.stanzaHandler)
|
||||
_converse.connection.deleteHandler(this.stanzaHandler)
|
||||
this.stanzaHandler = undefined
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import { __ } from 'i18n'
|
||||
import BaseModal from 'plugins/modal/modal.js'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { html } from 'lit'
|
||||
import 'livechat-external-login-content.js'
|
||||
|
||||
|
@ -52,16 +52,15 @@
|
||||
|
||||
.emoji-picker__header {
|
||||
color: var(--peertube-main-background);
|
||||
background-color: var(--peertube-main-background);
|
||||
background-color: var(--peertube-main-foreground);
|
||||
|
||||
ul {
|
||||
.emoji-category {
|
||||
color: var(--peertube-main-background);
|
||||
background-color: #2d2d2d;
|
||||
border-bottom: 1px solid var(--peertube-main-foreground);
|
||||
background-color: var(--peertube-main-foreground);
|
||||
|
||||
a {
|
||||
color: white;
|
||||
color: currentcolor;
|
||||
}
|
||||
|
||||
&.picked {
|
||||
@ -135,19 +134,17 @@
|
||||
|
||||
// Changing size for emojis, to have bigger custom emojis
|
||||
img.emoji {
|
||||
width: 3.5rem !important;
|
||||
height: 3.5rem !important;
|
||||
// max-height: 4.25em !important; // and no max-width
|
||||
width: unset !important;
|
||||
height: unset !important;
|
||||
max-height: 3em !important; // and no max-width
|
||||
}
|
||||
|
||||
// underline links in chat messages
|
||||
a[href] {
|
||||
text-decoration: none !important;
|
||||
color: #f57200 !important;
|
||||
text-decoration: underline;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline !important;
|
||||
color: #D16100 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,12 +188,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* NCTV custom */
|
||||
|
||||
.emoji-category__heading {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
// Bigger occupants sidebar when width is not big enough.
|
||||
@media screen and (max-width: 576px) {
|
||||
.chatroom .box-flyout .chatroom-body .occupants {
|
||||
|
@ -64,8 +64,8 @@ body.converse-embedded converse-root.theme-peertube {
|
||||
--message-avatar-height: 36px;
|
||||
--chat-background-color: var(--peertube-main-background);
|
||||
--chat-textarea-color: var(--peertube-input-foreground);
|
||||
--chat-textarea-background-color: var(--peertube-main-background);
|
||||
--chat-textarea-height: 38px;
|
||||
--chat-textarea-background-color: var(--peertube-input-background);
|
||||
--chat-textarea-height: 60px;
|
||||
--send-button-height: 27px;
|
||||
--send-button-margin: 3px;
|
||||
--inline-action-margin: 0.75em;
|
||||
@ -140,8 +140,8 @@ body.converse-embedded converse-root.theme-peertube {
|
||||
--fullpage-chatbox-button-size: 24px;
|
||||
--font-size-tiny: 10px;
|
||||
--font-size-small: 12px;
|
||||
--font-size: 16px;
|
||||
--font-size-large: 18px;
|
||||
--font-size: 14px;
|
||||
--font-size-large: 16px;
|
||||
--font-size-huge: 20px;
|
||||
--message-font-size: var(--font-size);
|
||||
--separator-text-color: var(--peertube-grey-foreground);
|
||||
|
@ -171,9 +171,7 @@ body.converse-embedded {
|
||||
#peertube-plugin-livechat-container {
|
||||
converse-muc-message-form {
|
||||
// For an unknown reason, message field in truncated... so adding a bottom margin.
|
||||
max-height: unset !important;
|
||||
margin-bottom: 0.5rem !important;
|
||||
margin-top: 0.4rem !important;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { html } from 'lit'
|
||||
import { api } from '@converse/headless/index.js'
|
||||
import { api } from '@converse/headless/core.js'
|
||||
|
||||
export default () => html`
|
||||
<div class="inner-content converse-brand row">
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { _converse, api } from '@converse/headless'
|
||||
import { _converse, api } from '@converse/headless/core'
|
||||
import { __ } from 'i18n'
|
||||
import { html } from 'lit'
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { __ } from 'i18n'
|
||||
import { _converse, api } from '@converse/headless'
|
||||
import { _converse, api } from '@converse/headless/core'
|
||||
import { html } from 'lit'
|
||||
import tplMucBottomPanel from '../../src/plugins/muc-views/templates/muc-bottom-panel.js'
|
||||
import { CustomElement } from 'shared/components/element.js'
|
||||
@ -79,7 +79,7 @@ class SlowMode extends CustomElement {
|
||||
api.elements.define('livechat-slow-mode', SlowMode)
|
||||
|
||||
const tplSlowMode = (o) => {
|
||||
if (!o.can_post) { return html`` }
|
||||
if (!o.can_edit) { return html`` }
|
||||
return html`<livechat-slow-mode jid=${o.model.get('jid')}>`
|
||||
}
|
||||
|
||||
@ -128,9 +128,17 @@ const tplViewerMode = (o) => {
|
||||
}
|
||||
|
||||
export default (o) => {
|
||||
// ConverseJS 10.x does not handle properly the visitor role in unmoderated rooms.
|
||||
// See https://github.com/conversejs/converse.js/issues/3428 for more info.
|
||||
// So we will do a dirty hack here to fix this case.
|
||||
// Note: ConverseJS 11.x has changed the code, and could be fixed more cleanly (or will be fixed if #3428 is fixed).
|
||||
if (o.can_edit && o.model.getOwnRole() === 'visitor') {
|
||||
o.can_edit = false
|
||||
}
|
||||
|
||||
let mutedAnonymousMessage
|
||||
if (
|
||||
!o.can_post &&
|
||||
!o.can_edit &&
|
||||
o.model.features?.get?.('x_peertubelivechat_mute_anonymous') &&
|
||||
_converse.api.settings.get('livechat_specific_is_anonymous') === true
|
||||
) {
|
||||
|
@ -2,7 +2,7 @@
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import tplMUCChatarea from '../../src/plugins/muc-views/templates/muc-chatarea.js'
|
||||
import { html } from 'lit'
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { html } from 'lit'
|
||||
import { api } from '@converse/headless'
|
||||
import { api } from '@converse/headless/core'
|
||||
import { until } from 'lit/directives/until.js'
|
||||
import { repeat } from 'lit/directives/repeat.js'
|
||||
import { unsafeHTML } from 'lit/directives/unsafe-html.js'
|
||||
|
@ -44,7 +44,7 @@ module.exports = merge(prod, {
|
||||
'../../templates/background_logo.js$': path.resolve(__dirname, 'custom/templates/background_logo.js'),
|
||||
'./templates/muc-chatarea.js': path.resolve('custom/templates/muc-chatarea.js'),
|
||||
|
||||
'./templates/icons.js': path.resolve(__dirname, 'custom/shared/components/font-awesome.js'),
|
||||
'../templates/icons.js': path.resolve(__dirname, 'custom/shared/components/font-awesome.js'),
|
||||
|
||||
'shared/styles/index.scss$': path.resolve(__dirname, 'custom/shared/styles/livechat.scss'),
|
||||
|
||||
|
@ -97,7 +97,6 @@ function defaultConverseParams (
|
||||
pruning_behavior: 'unscrolled',
|
||||
colorize_username: true,
|
||||
send_chat_markers: [],
|
||||
reuse_scram_keys: false, // for now we don't use this.
|
||||
|
||||
// This is a specific settings, that is used in ConverseJS customization, to force avatars loading in readonly mode.
|
||||
livechat_load_all_vcards: !!forceReadonly,
|
||||
|
@ -16,7 +16,7 @@ export const livechatMiniMucHeadPlugin = {
|
||||
})
|
||||
|
||||
_converse.api.listen.on('getHeadingButtons', (view: any, buttons: any[]) => {
|
||||
if (view.model.get('type') !== _converse.constants.CHATROOMS_TYPE) {
|
||||
if (view.model.get('type') !== _converse.CHATROOMS_TYPE) {
|
||||
// only on MUC.
|
||||
return buttons
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ export const livechatSpecificsPlugin = {
|
||||
})
|
||||
|
||||
_converse.api.listen.on('getHeadingButtons', (view: any, buttons: any[]) => {
|
||||
if (view.model.get('type') !== _converse.constants.CHATROOMS_TYPE) {
|
||||
if (view.model.get('type') !== _converse.CHATROOMS_TYPE) {
|
||||
// only on MUC.
|
||||
return buttons
|
||||
}
|
||||
@ -53,71 +53,6 @@ export const livechatSpecificsPlugin = {
|
||||
return buttons
|
||||
})
|
||||
|
||||
_converse.api.listen.on('getToolbarButtons', (toolbarEl: any, buttons: any[]) => {
|
||||
// We will replace the toggle occupant button, to change its appearance.
|
||||
// First, we must find it. We search from the end, because usually it is the last one.
|
||||
let toggleOccupantButton: any
|
||||
for (const button of buttons.reverse()) {
|
||||
if (button.strings?.find((s: string) => s.includes('toggle_occupants'))) { // searching the classname
|
||||
console.debug('[livechatSpecificsPlugin] found the toggle occupants button', button)
|
||||
toggleOccupantButton = button
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!toggleOccupantButton) {
|
||||
console.debug('[livechatSpecificsPlugin] Did not found the toggle occupants button')
|
||||
return buttons
|
||||
}
|
||||
|
||||
buttons = buttons.filter(b => b !== toggleOccupantButton)
|
||||
// Replacing by the new button...
|
||||
// Note: we don't need to test conditions, we know the button was here.
|
||||
const i18nHideOccupants = _converse.__('Hide participants')
|
||||
const i18nShowOccupants = _converse.__('Show participants')
|
||||
const html = window.converse.env.html
|
||||
const icon = toolbarEl.hidden_occupants
|
||||
? html`<converse-icon
|
||||
color="var(--muc-toolbar-btn-color)"
|
||||
class="fa fa-angle-double-left"
|
||||
size="1em">
|
||||
</converse-icon>
|
||||
<converse-icon
|
||||
color="var(--muc-toolbar-btn-color)"
|
||||
class="fa users"
|
||||
size="1em">
|
||||
</converse-icon>`
|
||||
: html`<converse-icon
|
||||
color="var(--muc-toolbar-btn-color)"
|
||||
class="fa users"
|
||||
size="1em">
|
||||
</converse-icon>
|
||||
<converse-icon
|
||||
color="var(--muc-toolbar-btn-color)"
|
||||
class="fa fa-angle-double-right"
|
||||
size="1em">
|
||||
</converse-icon>`
|
||||
buttons.push(html`
|
||||
<button class="toggle_occupants right"
|
||||
title="${toolbarEl.hidden_occupants ? i18nShowOccupants : i18nHideOccupants}"
|
||||
@click=${toolbarEl.toggleOccupants}>
|
||||
${icon}
|
||||
</button>`
|
||||
)
|
||||
return buttons
|
||||
})
|
||||
|
||||
// Overriding the MUCHeading custom element, to customize the destroyMUC function:
|
||||
const MUCHeading = _converse.api.elements.registry['converse-muc-heading']
|
||||
if (MUCHeading) {
|
||||
class MUCHeadingOverloaded extends MUCHeading {
|
||||
async destroy (ev: Event): Promise<void> {
|
||||
ev.preventDefault()
|
||||
await destroyMUC(_converse, this.model) // here we call a custom version of destroyMUC
|
||||
}
|
||||
}
|
||||
_converse.api.elements.define('converse-muc-heading', MUCHeadingOverloaded)
|
||||
}
|
||||
|
||||
_converse.api.listen.on('chatRoomViewInitialized', function (this: any, _model: any): void {
|
||||
// Remove the spinner if present...
|
||||
document.getElementById('livechat-loading-spinner')?.remove()
|
||||
@ -182,7 +117,7 @@ export const livechatSpecificsPlugin = {
|
||||
},
|
||||
overrides: {
|
||||
ChatRoom: {
|
||||
getActionInfoMessage: function getActionInfoMessage (this: any, code: string, nick: string, actor: any): any {
|
||||
getActionInfoMessage: function (this: any, code: string, nick: string, actor: any): any {
|
||||
if (code === '303') {
|
||||
// When there is numerous anonymous users joining at the same time,
|
||||
// they can all change their nicknames at the same time, generating a log of action messages.
|
||||
@ -195,12 +130,6 @@ export const livechatSpecificsPlugin = {
|
||||
}
|
||||
}
|
||||
return this.__super__.getActionInfoMessage(code, nick, actor)
|
||||
},
|
||||
canPostMessages: function canPostMessages (this: any) {
|
||||
// ConverseJS does not handle properly the visitor role in unmoderated rooms.
|
||||
// See https://github.com/conversejs/converse.js/issues/3428 for more info.
|
||||
// FIXME: if #3428 is fixed, remove this override.
|
||||
return this.isEntered() && this.getOwnRole() !== 'visitor'
|
||||
}
|
||||
},
|
||||
ChatRoomMessage: {
|
||||
@ -254,26 +183,3 @@ function getOpenPromise (): any {
|
||||
)
|
||||
return promise
|
||||
}
|
||||
|
||||
async function destroyMUC (_converse: any, model: any): Promise<void> {
|
||||
const __ = _converse.__
|
||||
const messages = [__('Are you sure you want to destroy this groupchat?')]
|
||||
// Note: challenge and newjid make no sens for peertube-plugin-livechat,
|
||||
// we remove them comparing to the original function.
|
||||
let fields = [
|
||||
{
|
||||
name: 'reason',
|
||||
label: __('Optional reason for destroying this groupchat'),
|
||||
placeholder: __('Reason'),
|
||||
value: undefined
|
||||
}
|
||||
]
|
||||
try {
|
||||
fields = await _converse.api.confirm(__('Confirm'), messages, fields)
|
||||
const reason = fields.filter(f => f.name === 'reason').pop()?.value
|
||||
const newjid = undefined
|
||||
return model.sendDestroyIQ(reason, newjid).then(() => model.close())
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
@ -17,11 +17,11 @@ export const livechatViewerModePlugin = {
|
||||
livechat_external_auth_reconnect_mode: undefined
|
||||
})
|
||||
|
||||
const originalGetDefaultMUCNickname = _converse.exports.getDefaultMUCNickname
|
||||
const originalGetDefaultMUCNickname = _converse.getDefaultMUCNickname
|
||||
if (!originalGetDefaultMUCNickname) {
|
||||
console.error('[livechatViewerModePlugin] getDefaultMUCNickname is not initialized.')
|
||||
} else {
|
||||
Object.assign(_converse.exports, {
|
||||
Object.assign(_converse, {
|
||||
getDefaultMUCNickname: function (this: any): any {
|
||||
if (!_converse.api.settings.get('livechat_enable_viewer_mode')) {
|
||||
return originalGetDefaultMUCNickname.apply(this, arguments)
|
||||
|
@ -175,6 +175,7 @@ avatar_set_description: |
|
||||
Please refer to the documentation:
|
||||
<a href="https://livingston.frama.io/peertube-plugin-livechat/documentation/admin/settings/" target="_blank">Settings</a>.
|
||||
avatar_set_option_sepia: "Sepia (Peertube mascot)"
|
||||
avatar_set_option_nctv: "NCTV Branded"
|
||||
avatar_set_option_cat: "Cats"
|
||||
avatar_set_option_bird: "Birds"
|
||||
avatar_set_option_fenec: "Fenecs (Mobilizon mascot)"
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "peertube-plugin-livechat",
|
||||
"version": "10.3.1",
|
||||
"version": "10.3.3",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "peertube-plugin-livechat",
|
||||
"version": "10.3.1",
|
||||
"version": "10.3.3",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@xmpp/jid": "^0.13.1",
|
||||
|
14
package.json
14
package.json
@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "peertube-plugin-livechat",
|
||||
"description": "NCTV fork of the peertube-plugin-livechat plugin, containing styling and other shit. This will be maintained with upstream.",
|
||||
"version": "10.3.1",
|
||||
"description": "PeerTube plugin livechat: create chat rooms for your Peertube lives! Comes with many features: federation, moderation tools, chat bot, chat persistence, OBS integration, ...",
|
||||
"version": "10.3.3",
|
||||
"license": "AGPL-3.0",
|
||||
"author": {
|
||||
"name": "Matty Boombalatty",
|
||||
"url": "https://gitea.nicecrew.digital/matty"
|
||||
"name": "John Livingston",
|
||||
"url": "https://github.com/JohnXLivingston"
|
||||
},
|
||||
"bugs": "https://gitea.nicecrew.digital/matty/peertube-plugin-livechat/issues",
|
||||
"bugs": "https://github.com/JohnXLivingston/peertube-plugin-livechat/issues",
|
||||
"clientScripts": [
|
||||
{
|
||||
"script": "dist/client/common-client-plugin.js",
|
||||
@ -82,8 +82,8 @@
|
||||
"engines": {
|
||||
"npm": ">=7"
|
||||
},
|
||||
"homepage": "https://gitea.nicecrew.digital/matty/peertube-plugin-livechat",
|
||||
"repository": "https://gitea.nicecrew.digital/matty/peertube-plugin-livechat",
|
||||
"homepage": "https://livingston.frama.io/peertube-plugin-livechat/",
|
||||
"repository": "github:JohnXLivingston/peertube-plugin-livechat",
|
||||
"keywords": [
|
||||
"peertube",
|
||||
"plugin"
|
||||
|
@ -102,7 +102,7 @@ async function getProsodyFilePaths (options: RegisterServerOptions): Promise<Pro
|
||||
}
|
||||
|
||||
let avatarSet: AvatarSet = (settings['avatar-set'] ?? 'sepia') as AvatarSet
|
||||
if (!['sepia', 'cat', 'bird', 'fenec', 'abstract', 'legacy'].includes(avatarSet)) {
|
||||
if (!['sepia', 'cat', 'bird', 'fenec', 'abstract', 'legacy', 'nctv'].includes(avatarSet)) {
|
||||
logger.error('Invalid avatar-set setting, using sepia as default')
|
||||
avatarSet = 'sepia'
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ abstract class ProsodyConfigBlock {
|
||||
this.entries.set(name, value)
|
||||
}
|
||||
|
||||
add (name: string, value: ConfigEntryValue): void {
|
||||
add (name: string, value: ConfigEntryValue, allowDuplicate?: boolean): void {
|
||||
if (!this.entries.has(name)) {
|
||||
this.entries.set(name, [])
|
||||
}
|
||||
@ -101,6 +101,9 @@ abstract class ProsodyConfigBlock {
|
||||
if (!Array.isArray(entry)) {
|
||||
entry = [entry]
|
||||
}
|
||||
if (!allowDuplicate && entry.includes(value)) {
|
||||
return
|
||||
}
|
||||
entry.push(value)
|
||||
this.entries.set(name, entry)
|
||||
}
|
||||
@ -239,7 +242,7 @@ class ProsodyConfigContent {
|
||||
this.muc.set('muc_room_default_history_length', 20)
|
||||
|
||||
this.muc.add('modules_enabled', 'muc_slow_mode')
|
||||
this.muc.add('slow_mode_duration_form_position', 120)
|
||||
this.muc.set('slow_mode_duration_form_position', 120)
|
||||
|
||||
this.muc.add('modules_enabled', 'pubsub_peertubelivechat')
|
||||
this.muc.add('modules_enabled', 'muc_peertubelivechat_roles')
|
||||
@ -251,7 +254,7 @@ class ProsodyConfigContent {
|
||||
}
|
||||
|
||||
this.muc.add('modules_enabled', 'muc_moderation_delay')
|
||||
this.muc.add('moderation_delay_form_position', 118)
|
||||
this.muc.set('moderation_delay_form_position', 118)
|
||||
}
|
||||
|
||||
useAnonymous (autoBanIP: boolean): void {
|
||||
@ -445,7 +448,7 @@ class ProsodyConfigContent {
|
||||
|
||||
useMucHttpDefault (url: string): void {
|
||||
this.muc.add('modules_enabled', 'muc_http_defaults')
|
||||
this.muc.add('muc_create_api_url', url)
|
||||
this.muc.set('muc_create_api_url', url)
|
||||
|
||||
// restrict_room_creation: we can override the 'local' value.
|
||||
// Indeed, when muc_http_default is used, room creation will be managed by api.
|
||||
@ -517,7 +520,7 @@ class ProsodyConfigContent {
|
||||
*/
|
||||
useBotsVirtualHost (botAvatarPath: string, botAvatarFiles: string[]): void {
|
||||
this.bot = new ProsodyConfigVirtualHost('bot.' + this.prosodyDomain)
|
||||
this.bot.set('modules_enabled', ['ping'])
|
||||
this.bot.set('modules_enabled', ['ping', 'tls'])
|
||||
this.bot.set('authentication', 'peertubelivechat_bot')
|
||||
|
||||
// For now, just using random_vcard_peertubelivechat to set bot avatar
|
||||
|
@ -13,7 +13,7 @@ import { LivechatProsodyAuth } from './prosody/auth'
|
||||
import { loc } from './loc'
|
||||
const escapeHTML = require('escape-html')
|
||||
|
||||
type AvatarSet = 'sepia' | 'cat' | 'bird' | 'fenec' | 'abstract' | 'legacy'
|
||||
type AvatarSet = 'sepia' | 'cat' | 'bird' | 'fenec' | 'abstract' | 'legacy' | 'nctv'
|
||||
|
||||
async function initSettings (options: RegisterServerOptions): Promise<void> {
|
||||
const { peertubeHelpers, settingsManager } = options
|
||||
@ -506,6 +506,7 @@ function initThemingSettings ({ registerSetting }: RegisterServerOptions): void
|
||||
private: true,
|
||||
options: [
|
||||
{ value: 'sepia', label: loc('avatar_set_option_sepia') },
|
||||
{ value: 'nctv', label: loc('avatar_set_option_nctv') },
|
||||
{ value: 'cat', label: loc('avatar_set_option_cat') },
|
||||
{ value: 'bird', label: loc('avatar_set_option_bird') },
|
||||
{ value: 'fenec', label: loc('avatar_set_option_fenec') },
|
||||
|
@ -5,7 +5,7 @@
|
||||
// Note: API request body size is limited to 100Kb (expressjs body-parser defaut limit, and Peertube nginx config).
|
||||
// So we must be sure to never send more than 100Kb. The front end sends new emojis by batch, but maxSize must remain
|
||||
// as little as possible, so that we never reach 100Kb in JSON/base64 format.
|
||||
export const maxSize: number = 30 * 1024
|
||||
export const maxSize: number = 800 * 1024
|
||||
export const allowedExtensions = ['png', 'jpg', 'jpeg', 'gif']
|
||||
export const inputFileAccept = ['image/jpg', 'image/png', 'image/gif']
|
||||
export const allowedMimeTypes = ['image/jpg', 'image/png', 'image/gif']
|
||||
|
@ -28,6 +28,7 @@ These files are used to generate multiple avatars (see the `build-avatars.js` sc
|
||||
* `assets/images/avatars/bird` contains new birds avatar set, based on the work of David Revoy (see copyright informations)
|
||||
* `assets/images/avatars/fenec` contains new fenecs avatar set, based on the work of David Revoy (see copyright informations)
|
||||
* `assets/images/avatars/abstract` contains new abstract avatar set, based on the work of David Revoy (see copyright informations)
|
||||
* `assets/images/avatars/nctv` contains NCTV avatar, based on the work of The Almighty Kek
|
||||
|
||||
### assets/styles
|
||||
|
||||
|
@ -8,11 +8,9 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"POT-Creation-Date: 2024-07-10 16:54+0200\n"
|
||||
"PO-Revision-Date: 2024-07-12 09:10+0000\n"
|
||||
"Last-Translator: Victor Hampel <v.hampel@users.noreply.weblate.framasoft.org>"
|
||||
"\n"
|
||||
"Language-Team: German <https://weblate.framasoft.org/projects/"
|
||||
"peertube-livechat/peertube-plugin-livechat-documentation/de/>\n"
|
||||
"PO-Revision-Date: 2024-07-05 19:12+0000\n"
|
||||
"Last-Translator: Victor Hampel <v.hampel@users.noreply.weblate.framasoft.org>\n"
|
||||
"Language-Team: German <https://weblate.framasoft.org/projects/peertube-livechat/peertube-plugin-livechat-documentation/de/>\n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@ -3274,30 +3272,25 @@ msgstr "Um den Wert für einen bereits bestehenden Raum zu ändern, öffnen Sie
|
||||
#: support/documentation/content/en/documentation/user/streamers/moderation_delay.md
|
||||
msgid "Currently, this feature has one known bug: users that join the chat will get all messages, even messages that are still pending for other participants. However, messages sent after they joined will be delayed correctly."
|
||||
msgstr ""
|
||||
"Derzeit gibt es bei dieser Funktion einen bekannten Fehler: Benutzer, die "
|
||||
"dem Chat beitreten, erhalten alle Nachrichten, auch solche, die noch für "
|
||||
"andere Teilnehmer ausstehen. Allerdings werden Nachrichten, die nach dem "
|
||||
"Beitritt gesendet werden, korrekt verzögert."
|
||||
|
||||
#. type: Title ##
|
||||
#: support/documentation/content/en/documentation/user/streamers/moderation_delay.md
|
||||
#, no-wrap
|
||||
#, fuzzy, no-wrap
|
||||
#| msgid "Share the chat"
|
||||
msgid "In the chat"
|
||||
msgstr "Im Chat"
|
||||
msgstr "Teilen Sie den Chat"
|
||||
|
||||
#. type: Plain text
|
||||
#: support/documentation/content/en/documentation/user/streamers/moderation_delay.md
|
||||
msgid "As a moderator, you will see the remaining time (in seconds) before the message is broadcasted, just besides the message datetime."
|
||||
msgstr ""
|
||||
"Als Moderator sehen Sie neben dem Datum der Nachricht auch die verbleibende "
|
||||
"Zeit (in Sekunden), bevor die Nachricht veröffentlicht wird."
|
||||
|
||||
#. type: Plain text
|
||||
#: support/documentation/content/en/documentation/user/streamers/moderation_delay.md
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
msgid ""
|
||||
msgstr ""
|
||||
""
|
||||
msgstr ""
|
||||
|
||||
#. type: Yaml Front Matter Hash Value: description
|
||||
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
|
||||
@ -3344,11 +3337,10 @@ msgstr "Über das [Chat Dropdown Menü](/peertube-plugin-livechat/de/documentati
|
||||
|
||||
#. type: Plain text
|
||||
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
|
||||
#, fuzzy
|
||||
#| msgid "The video owner will be owner of the chat room. This means he can configure the room, delete it, promote other users as admins, ..."
|
||||
msgid "The video owner will be owner of the chat room. This means they can configure the room, delete it, promote other users as admins, ..."
|
||||
msgstr ""
|
||||
"Der Videobesitzer ist der Besitzer des Chatraums. Das bedeutet, er kann den "
|
||||
"Raum konfigurieren, löschen, andere Benutzer als Administratoren befördern, "
|
||||
"..."
|
||||
msgstr "Der Videobesitzer ist der Besitzer des Chatraums. Das bedeutet, er kann den Raum konfigurieren, löschen, andere Benutzer als Administratoren befördern, ..."
|
||||
|
||||
#. type: Plain text
|
||||
#: build/documentation/pot_in/documentation/user/streamers/moderation.md
|
||||
|
Reference in New Issue
Block a user