Merge branch 'main' into weblate-peertube-livechat-peertube-plugin-livechat
This commit is contained in:
commit
fdff085b37
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## ??? (Not Released Yet)
|
||||||
|
|
||||||
|
### Minor changes and fixes
|
||||||
|
|
||||||
|
* Fix #329: auto focus message field after anonymous user has entered nickname.
|
||||||
|
* Fix #392: add draggable items touch screen handling
|
||||||
|
* Fix #506: hide offline users by default in occupant list
|
||||||
|
* Fix #547: add button to go to the end of the chat
|
||||||
|
* Fix #503: set custom emojis max height to text height + bigger when posted alone
|
||||||
|
* Fix: Converse bottom panel messages not visible on new Peertube v7 theme (for example for muted users)
|
||||||
|
* Fix #75: New short video urls makes it difficult to use the settings «Activate chat for these videos».
|
||||||
|
|
||||||
## 12.0.4
|
## 12.0.4
|
||||||
|
|
||||||
### Minor changes and fixes
|
### Minor changes and fixes
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
SPDX-FileCopyrightText: 2025 Mehdi Benadel <https://mehdibenadel.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
// SPDX-FileCopyrightText: 2025 Nicolas Chesnais <https://autre.space>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
@ -11,6 +12,7 @@ import './styles/draggables.scss'
|
|||||||
*/
|
*/
|
||||||
export class DraggablesCustomElement extends CustomElement {
|
export class DraggablesCustomElement extends CustomElement {
|
||||||
currentDragged = null
|
currentDragged = null
|
||||||
|
droppableEl = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The tag name for draggable elements.
|
* The tag name for draggable elements.
|
||||||
@ -37,6 +39,9 @@ export class DraggablesCustomElement extends CustomElement {
|
|||||||
this._handleDragLeaveBinded = this._handleDragLeave.bind(this)
|
this._handleDragLeaveBinded = this._handleDragLeave.bind(this)
|
||||||
this._handleDragEndBinded = this._handleDragEnd.bind(this)
|
this._handleDragEndBinded = this._handleDragEnd.bind(this)
|
||||||
this._handleDropBinded = this._handleDrop.bind(this)
|
this._handleDropBinded = this._handleDrop.bind(this)
|
||||||
|
this._handleTouchStartBinded = this._handleTouchStart.bind(this)
|
||||||
|
this._handleTouchMoveBinded = this._handleTouchMove.bind(this)
|
||||||
|
this._handleTouchEndBinded = this._handleTouchEnd.bind(this)
|
||||||
|
|
||||||
return super.initialize()
|
return super.initialize()
|
||||||
}
|
}
|
||||||
@ -44,21 +49,29 @@ export class DraggablesCustomElement extends CustomElement {
|
|||||||
connectedCallback () {
|
connectedCallback () {
|
||||||
super.connectedCallback()
|
super.connectedCallback()
|
||||||
this.currentDragged = null
|
this.currentDragged = null
|
||||||
|
this.droppableEl = null
|
||||||
this.addEventListener('dragstart', this._handleDragStartBinded)
|
this.addEventListener('dragstart', this._handleDragStartBinded)
|
||||||
this.addEventListener('dragover', this._handleDragOverBinded)
|
this.addEventListener('dragover', this._handleDragOverBinded)
|
||||||
this.addEventListener('dragleave', this._handleDragLeaveBinded)
|
this.addEventListener('dragleave', this._handleDragLeaveBinded)
|
||||||
this.addEventListener('dragend', this._handleDragEndBinded)
|
this.addEventListener('dragend', this._handleDragEndBinded)
|
||||||
this.addEventListener('drop', this._handleDropBinded)
|
this.addEventListener('drop', this._handleDropBinded)
|
||||||
|
this.addEventListener('touchstart', this._handleTouchStartBinded)
|
||||||
|
this.addEventListener('touchmove', this._handleTouchMoveBinded)
|
||||||
|
this.addEventListener('touchend', this._handleTouchEndBinded)
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback () {
|
disconnectedCallback () {
|
||||||
super.disconnectedCallback()
|
super.disconnectedCallback()
|
||||||
this.currentDragged = null
|
this.currentDragged = null
|
||||||
|
this.droppableEl = null
|
||||||
this.removeEventListener('dragstart', this._handleDragStartBinded)
|
this.removeEventListener('dragstart', this._handleDragStartBinded)
|
||||||
this.removeEventListener('dragover', this._handleDragOverBinded)
|
this.removeEventListener('dragover', this._handleDragOverBinded)
|
||||||
this.removeEventListener('dragleave', this._handleDragLeaveBinded)
|
this.removeEventListener('dragleave', this._handleDragLeaveBinded)
|
||||||
this.removeEventListener('dragend', this._handleDragEndBinded)
|
this.removeEventListener('dragend', this._handleDragEndBinded)
|
||||||
this.removeEventListener('drop', this._handleDropBinded)
|
this.removeEventListener('drop', this._handleDropBinded)
|
||||||
|
this.removeEventListener('touchstart', this._handleTouchStartBinded)
|
||||||
|
this.removeEventListener('touchmove', this._handleTouchMoveBinded)
|
||||||
|
this.removeEventListener('touchend', this._handleTouchEndBinded)
|
||||||
}
|
}
|
||||||
|
|
||||||
_isADraggableEl (target) {
|
_isADraggableEl (target) {
|
||||||
@ -69,8 +82,7 @@ export class DraggablesCustomElement extends CustomElement {
|
|||||||
return target.closest?.(this.droppableTagNames.join(','))
|
return target.closest?.(this.droppableTagNames.join(','))
|
||||||
}
|
}
|
||||||
|
|
||||||
_isOnTopHalf (ev, el) {
|
_isOnTopHalf (y, el) {
|
||||||
const y = ev.clientY
|
|
||||||
const bounding = el.getBoundingClientRect()
|
const bounding = el.getBoundingClientRect()
|
||||||
return (y <= bounding.y + (bounding.height / 2))
|
return (y <= bounding.y + (bounding.height / 2))
|
||||||
}
|
}
|
||||||
@ -81,13 +93,39 @@ export class DraggablesCustomElement extends CustomElement {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_setCurrentDragged (draggedEl) {
|
||||||
|
console.log('[livechat drag&drop] Starting to drag a ' + this.draggableTagName + '...')
|
||||||
|
this.currentDragged = draggedEl
|
||||||
|
this._resetDropOver()
|
||||||
|
}
|
||||||
|
|
||||||
|
_setDroppableClasses (droppableEl, y) {
|
||||||
|
// Are we on the top or bottom part of the droppableEl?
|
||||||
|
let topHalf = false
|
||||||
|
if (!this.droppableAlwaysBottomTagNames.includes(droppableEl.nodeName.toLowerCase())) {
|
||||||
|
topHalf = this._isOnTopHalf(y, droppableEl)
|
||||||
|
}
|
||||||
|
droppableEl.classList.add(topHalf ? 'livechat-drag-top-half' : 'livechat-drag-bottom-half')
|
||||||
|
droppableEl.classList.remove(topHalf ? 'livechat-drag-bottom-half' : 'livechat-drag-top-half')
|
||||||
|
}
|
||||||
|
|
||||||
|
_tryToDrop (droppedOnEl) {
|
||||||
|
if (!droppedOnEl) return
|
||||||
|
|
||||||
|
console.log('[livechat drag&drop] ' + this.draggableTagName + ' dropped...')
|
||||||
|
try {
|
||||||
|
this._dropDone(this.currentDragged, droppedOnEl, droppedOnEl.classList.contains('livechat-drag-top-half'))
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
this._resetDropOver()
|
||||||
|
}
|
||||||
|
|
||||||
_handleDragStart (ev) {
|
_handleDragStart (ev) {
|
||||||
// The draggable=true is on a child bode
|
// The draggable=true is on a child bode
|
||||||
const possibleEl = ev.target.parentElement
|
const possibleEl = ev.target.parentElement
|
||||||
if (!this._isADraggableEl(possibleEl)) { return }
|
if (!this._isADraggableEl(possibleEl)) { return }
|
||||||
console.log('[livechat drag&drop] Starting to drag a ' + this.draggableTagName + '...')
|
this._setCurrentDragged(possibleEl)
|
||||||
this.currentDragged = possibleEl
|
|
||||||
this._resetDropOver()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleDragOver (ev) {
|
_handleDragOver (ev) {
|
||||||
@ -97,14 +135,7 @@ export class DraggablesCustomElement extends CustomElement {
|
|||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event says we should preventDefault
|
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event says we should preventDefault
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
|
this._setDroppableClasses(droppableEl, ev.clientY)
|
||||||
// Are we on the top or bottom part of the droppableEl?
|
|
||||||
let topHalf = false
|
|
||||||
if (!this.droppableAlwaysBottomTagNames.includes(droppableEl.nodeName.toLowerCase())) {
|
|
||||||
topHalf = this._isOnTopHalf(ev, droppableEl)
|
|
||||||
}
|
|
||||||
droppableEl.classList.add(topHalf ? 'livechat-drag-top-half' : 'livechat-drag-bottom-half')
|
|
||||||
droppableEl.classList.remove(topHalf ? 'livechat-drag-bottom-half' : 'livechat-drag-top-half')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_handleDragLeave (ev) {
|
_handleDragLeave (ev) {
|
||||||
@ -124,16 +155,33 @@ export class DraggablesCustomElement extends CustomElement {
|
|||||||
|
|
||||||
let droppedOnEl = document.querySelector('.livechat-drag-bottom-half, .livechat-drag-top-half')
|
let droppedOnEl = document.querySelector('.livechat-drag-bottom-half, .livechat-drag-top-half')
|
||||||
droppedOnEl = this._getParentDroppableEl(droppedOnEl)
|
droppedOnEl = this._getParentDroppableEl(droppedOnEl)
|
||||||
if (!droppedOnEl) { return }
|
this._tryToDrop(droppedOnEl)
|
||||||
|
}
|
||||||
|
|
||||||
console.log('[livechat drag&drop] ' + this.draggableTagName + ' dropped...')
|
_handleTouchStart (ev) {
|
||||||
|
const possibleEl = this._getParentDroppableEl(ev.target)
|
||||||
|
if (!possibleEl) return
|
||||||
|
this._setCurrentDragged(possibleEl)
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
_handleTouchMove (ev) {
|
||||||
this._dropDone(this.currentDragged, droppedOnEl, droppedOnEl.classList.contains('livechat-drag-top-half'))
|
if (!this.currentDragged) return
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
const { clientX, clientY } = ev.touches[0]
|
||||||
}
|
const droppableEl = this._getParentDroppableEl(document.elementFromPoint(clientX, clientY))
|
||||||
|
if (!droppableEl || droppableEl === this.droppableEl) return
|
||||||
|
|
||||||
|
this.droppableEl = droppableEl
|
||||||
this._resetDropOver()
|
this._resetDropOver()
|
||||||
|
this._setDroppableClasses(droppableEl, clientY)
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleTouchEnd (_ev) {
|
||||||
|
if (!this.currentDragged || !this.droppableEl) return
|
||||||
|
|
||||||
|
this._tryToDrop(this.droppableEl)
|
||||||
|
this.currentDragged = null
|
||||||
|
this.droppableEl = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
* SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
* SPDX-FileCopyrightText: 2025 Nicolas Chesnais <https://autre.space>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
@ -16,4 +17,8 @@
|
|||||||
.livechat-drag-top-half > .draggables-line {
|
.livechat-drag-top-half > .draggables-line {
|
||||||
border-top: 4px solid blue;
|
border-top: 4px solid blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[draggable="true"] {
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
* SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
* SPDX-FileCopyrightText: 2025 Nicolas Chesnais <https://autre.space>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
@ -149,11 +150,17 @@
|
|||||||
background-color: var(--peertube-grey-background) !important;
|
background-color: var(--peertube-grey-background) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Changing size for emojis, to have bigger custom emojis
|
// Resize custom emojis to text height
|
||||||
img.emoji {
|
img.emoji {
|
||||||
width: unset !important;
|
width: unset !important;
|
||||||
height: unset !important;
|
height: unset !important;
|
||||||
max-height: 3em !important; // and no max-width
|
max-height: 1.5em !important; // and no max-width
|
||||||
|
vertical-align: -0.45em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trick to enlarge a single custom emoji with no text in message
|
||||||
|
&[text^=":"][text$=":"] img.emoji:only-child {
|
||||||
|
max-height: 2.5em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
// underline links in chat messages
|
// underline links in chat messages
|
||||||
|
@ -227,6 +227,21 @@ body.converse-embedded {
|
|||||||
|
|
||||||
.occupants {
|
.occupants {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
// Put occupants filters items on a single line
|
||||||
|
converse-list-filter form > div {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.filter-by {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let search input take the whole width when displayed
|
||||||
|
.btn-group:has(+ select.hidden) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,3 +279,13 @@ body.converse-embedded {
|
|||||||
justify-content: normal !important;
|
justify-content: normal !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* stylelint-disable-next-line no-duplicate-selectors */
|
||||||
|
.conversejs {
|
||||||
|
converse-muc {
|
||||||
|
.muc-bottom-panel, converse-muc-bottom-panel {
|
||||||
|
// Fixing a color (Converse use a hardcoded "white", which does not work with Peertube v7 new theme)
|
||||||
|
color: var(--peertube-menu-foreground) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
// SPDX-FileCopyrightText: 2025 Nicolas Chesnais <https://autre.space>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ import tplMucBottomPanel from '../../src/plugins/muc-views/templates/muc-bottom-
|
|||||||
import { CustomElement } from 'shared/components/element.js'
|
import { CustomElement } from 'shared/components/element.js'
|
||||||
import 'shared/modals/livechat-external-login.js'
|
import 'shared/modals/livechat-external-login.js'
|
||||||
|
|
||||||
async function setNickname (ev, model) {
|
async function setNicknameAndFocus (ev, model) {
|
||||||
ev.preventDefault()
|
ev.preventDefault()
|
||||||
const nick = ev.target.nick.value.trim()
|
const nick = ev.target.nick.value.trim()
|
||||||
if (!nick) {
|
if (!nick) {
|
||||||
@ -22,6 +23,7 @@ async function setNickname (ev, model) {
|
|||||||
_converse.api.trigger('livechatViewerModeSetNickname', model, nick, {
|
_converse.api.trigger('livechatViewerModeSetNickname', model, nick, {
|
||||||
synchronous: true
|
synchronous: true
|
||||||
})
|
})
|
||||||
|
document.querySelector('.chat-textarea')?.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
class SlowMode extends CustomElement {
|
class SlowMode extends CustomElement {
|
||||||
@ -100,6 +102,54 @@ const tplEmojiOnly = (o) => {
|
|||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class BackToLastMsg extends CustomElement {
|
||||||
|
static get properties () {
|
||||||
|
return {
|
||||||
|
jid: { type: String }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
show = false
|
||||||
|
|
||||||
|
async connectedCallback () {
|
||||||
|
super.connectedCallback()
|
||||||
|
this.model = _converse.chatboxes.get(this.jid)
|
||||||
|
await this.model.initialized
|
||||||
|
|
||||||
|
let scrolled = this.model.ui.get('scrolled')
|
||||||
|
let hasUnreadMsg = this.model.get('num_unread_general') > 0
|
||||||
|
this.listenTo(this.model.ui, 'change:scrolled', () => {
|
||||||
|
scrolled = this.model.ui.get('scrolled')
|
||||||
|
this.show = scrolled && !hasUnreadMsg
|
||||||
|
this.requestUpdate()
|
||||||
|
})
|
||||||
|
this.listenTo(this.model, 'change:num_unread_general', () => {
|
||||||
|
hasUnreadMsg = this.model.get('num_unread_general') > 0
|
||||||
|
// Do not show the element if there is new messages since there is another element for that
|
||||||
|
this.show = scrolled && !hasUnreadMsg
|
||||||
|
this.requestUpdate()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick (ev) {
|
||||||
|
ev?.preventDefault()
|
||||||
|
const chatContainer = document.querySelector('converse-chat-content')
|
||||||
|
chatContainer?.scrollTo({ top: chatContainer.scrollHeight })
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
return this.show
|
||||||
|
? html`<div class="livechat-back-to-last-msg new-msgs-indicator" @click=${this.onClick}>
|
||||||
|
▼ ${
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
__(LOC_back_to_last_msg)
|
||||||
|
} ▼
|
||||||
|
</div>`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
api.elements.define('livechat-back-to-last-msg', BackToLastMsg)
|
||||||
|
|
||||||
const tplViewerMode = (o) => {
|
const tplViewerMode = (o) => {
|
||||||
if (!api.settings.get('livechat_enable_viewer_mode')) {
|
if (!api.settings.get('livechat_enable_viewer_mode')) {
|
||||||
return html``
|
return html``
|
||||||
@ -112,7 +162,7 @@ const tplViewerMode = (o) => {
|
|||||||
const i18nExternalLogin = __(LOC_login_using_external_account)
|
const i18nExternalLogin = __(LOC_login_using_external_account)
|
||||||
return html`
|
return html`
|
||||||
<div class="livechat-viewer-mode-content chatroom-form-container">
|
<div class="livechat-viewer-mode-content chatroom-form-container">
|
||||||
<form class="converse-form chatroom-form" @submit=${ev => setNickname(ev, model)}>
|
<form class="converse-form chatroom-form" @submit=${ev => setNicknameAndFocus(ev, model)}>
|
||||||
<label>${i18nHeading}</label>
|
<label>${i18nHeading}</label>
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<input type="text"
|
<input type="text"
|
||||||
@ -163,6 +213,7 @@ export default (o) => {
|
|||||||
${tplViewerMode(o)}
|
${tplViewerMode(o)}
|
||||||
${tplSlowMode(o)}
|
${tplSlowMode(o)}
|
||||||
${tplEmojiOnly(o)}
|
${tplEmojiOnly(o)}
|
||||||
|
<livechat-back-to-last-msg jid=${o.model.get('jid')}></livechat-back-to-last-msg>
|
||||||
${
|
${
|
||||||
mutedAnonymousMessage
|
mutedAnonymousMessage
|
||||||
? html`<span class="muc-bottom-panel muc-bottom-panel--muted">${mutedAnonymousMessage}</span>`
|
? html`<span class="muc-bottom-panel muc-bottom-panel--muted">${mutedAnonymousMessage}</span>`
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
// SPDX-FileCopyrightText: 2025 Nicolas Chesnais <https://autre.space>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
@ -53,6 +54,11 @@ function getToolbarButtons (this: any, toolbarEl: any, buttons: any[]): any {
|
|||||||
toolbarEl.model.save({
|
toolbarEl.model.save({
|
||||||
hidden_occupants: !toolbarEl.model.get('hidden_occupants')
|
hidden_occupants: !toolbarEl.model.get('hidden_occupants')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Hide offline occupants by default
|
||||||
|
const sideBarEl = document.querySelector('converse-muc-sidebar') as unknown as any
|
||||||
|
sideBarEl?.model.set('filter_visible', true)
|
||||||
|
sideBarEl?.filter.set('type', 'state')
|
||||||
}}>
|
}}>
|
||||||
${icon}
|
${icon}
|
||||||
</button>`
|
</button>`
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
// SPDX-FileCopyrightText: 2025 Nicolas Chesnais <https://autre.space>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
@ -68,7 +69,8 @@ const locKeys = [
|
|||||||
'announcements_message_type_standard',
|
'announcements_message_type_standard',
|
||||||
'announcements_message_type_announcement',
|
'announcements_message_type_announcement',
|
||||||
'announcements_message_type_highlight',
|
'announcements_message_type_highlight',
|
||||||
'announcements_message_type_warning'
|
'announcements_message_type_warning',
|
||||||
|
'back_to_last_msg'
|
||||||
]
|
]
|
||||||
|
|
||||||
module.exports = locKeys
|
module.exports = locKeys
|
||||||
|
@ -149,7 +149,7 @@ all_non_lives_description: "If checked, the chat will be enabled for all video t
|
|||||||
|
|
||||||
videos_list_label: "Activate chat for these videos"
|
videos_list_label: "Activate chat for these videos"
|
||||||
videos_list_description: |
|
videos_list_description: |
|
||||||
Videos UUIDs for which we want a web chat.
|
Videos UUIDs for which we want a web chat (short UUID or UUIDv4).
|
||||||
Can be non-live videos. One per line. <br />
|
Can be non-live videos. One per line. <br />
|
||||||
You can add comments: everything after the # character will be stripped off, and empty lines ignored.<br />
|
You can add comments: everything after the # character will be stripped off, and empty lines ignored.<br />
|
||||||
Don't add private videos, the UUIDs will be sent to the frontend.
|
Don't add private videos, the UUIDs will be sent to the frontend.
|
||||||
@ -682,3 +682,4 @@ converse_theme_warning_description: |
|
|||||||
It is strongly recommanded to keep the "Peertube theme", in combinaison with the "Automatic color detection" feature.
|
It is strongly recommanded to keep the "Peertube theme", in combinaison with the "Automatic color detection" feature.
|
||||||
Otherwise some user may experience issues depending on the Peertube theme they use.
|
Otherwise some user may experience issues depending on the Peertube theme they use.
|
||||||
</span>
|
</span>
|
||||||
|
back_to_last_msg: Go back to last message
|
||||||
|
@ -152,7 +152,7 @@ prosody_muc_expiration_description: "Aquí puede elegir cuánto tiempo el servid
|
|||||||
durante 1 <b>año</b>. Puede reemplazar 1 por cualquier valor entero.</li>\n \
|
durante 1 <b>año</b>. Puede reemplazar 1 por cualquier valor entero.</li>\n \
|
||||||
\ <li><b>nunca</b>: el contenido nunca caducará y se mantendrá para siempre.</li>\n\
|
\ <li><b>nunca</b>: el contenido nunca caducará y se mantendrá para siempre.</li>\n\
|
||||||
</ul>\n"
|
</ul>\n"
|
||||||
videos_list_description: "UUIDs de los videos para los cuales se desea un chat web.\n
|
videos_list_description: "UUIDs de los videos para los cuales se desea un chat web (corto UUID o UUIDv4).\n
|
||||||
Pueden ser videos no en vivo. Una por línea. <br />\nPuede agregar comentarios:
|
Pueden ser videos no en vivo. Una por línea. <br />\nPuede agregar comentarios:
|
||||||
todo lo que este detras del caracter # no sera interpretado y las líneas vacías
|
todo lo que este detras del caracter # no sera interpretado y las líneas vacías
|
||||||
ignoradas. <br />\nNo agregue videos privados, los UUID se enviarán al frontend.\n"
|
ignoradas. <br />\nNo agregue videos privados, los UUID se enviarán al frontend.\n"
|
||||||
|
@ -111,7 +111,7 @@ all_non_lives_description: "Si coché, il y aura un tchat pour toutes les vidéo
|
|||||||
|
|
||||||
videos_list_label: "Activer le tchat pour ces vidéos"
|
videos_list_label: "Activer le tchat pour ces vidéos"
|
||||||
videos_list_description: |
|
videos_list_description: |
|
||||||
Mettez ici les UUIDs des vidéos pour lesquelles vous voulez forcer l'activation du tchat.
|
Mettez ici les UUIDs des vidéos pour lesquelles vous voulez forcer l'activation du tchat (UUID court ou UUIDv4).
|
||||||
Cela peut être des directs, ou non. Un UUID par ligne. <br />
|
Cela peut être des directs, ou non. Un UUID par ligne. <br />
|
||||||
Vous pouvez ajouter des commentaires : tout ce qui se trouve après le caractère # sera retiré, et les lignes vides ignorées. <br />
|
Vous pouvez ajouter des commentaires : tout ce qui se trouve après le caractère # sera retiré, et les lignes vides ignorées. <br />
|
||||||
N'ajoutez pas de vidéos privées, les UUIDs fuiteraient.
|
N'ajoutez pas de vidéos privées, les UUIDs fuiteraient.
|
||||||
@ -664,3 +664,4 @@ converse_theme_warning_description: "<span class=\"peertube-plugin-livechat-warn
|
|||||||
la fonctionnalité «Détection automatique des couleurs».\n Sinon certain⋅es utilisateur⋅rices
|
la fonctionnalité «Détection automatique des couleurs».\n Sinon certain⋅es utilisateur⋅rices
|
||||||
pourraient rencontrer des problèmes selon le thème qu'iels utilisent pour Peertube.\n\
|
pourraient rencontrer des problèmes selon le thème qu'iels utilisent pour Peertube.\n\
|
||||||
</span>\n"
|
</span>\n"
|
||||||
|
back_to_last_msg: Retourner au dernier message
|
||||||
|
72
package-lock.json
generated
72
package-lock.json
generated
@ -17,6 +17,7 @@
|
|||||||
"http-proxy": "^1.18.1",
|
"http-proxy": "^1.18.1",
|
||||||
"log-rotate": "^0.2.8",
|
"log-rotate": "^0.2.8",
|
||||||
"openid-client": "^5.7.1",
|
"openid-client": "^5.7.1",
|
||||||
|
"short-uuid": "^5.2.0",
|
||||||
"validate-color": "^2.2.4",
|
"validate-color": "^2.2.4",
|
||||||
"xmppjs-chat-bot": "^0.5.0"
|
"xmppjs-chat-bot": "^0.5.0"
|
||||||
},
|
},
|
||||||
@ -3250,6 +3251,20 @@
|
|||||||
"node": "14 || >=16.14"
|
"node": "14 || >=16.14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@peertube/peertube-types/node_modules/short-uuid": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-4.2.2.tgz",
|
||||||
|
"integrity": "sha512-IE7hDSGV2U/VZoCsjctKX6l5t5ak2jE0+aeGJi3KtvjIUNuZVmHVYUjNBhmo369FIWGDtaieRaO8A83Lvwfpqw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"any-base": "^1.1.0",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rtsao/scc": {
|
"node_modules/@rtsao/scc": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
|
||||||
@ -5138,8 +5153,7 @@
|
|||||||
"node_modules/any-base": {
|
"node_modules/any-base": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
|
||||||
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==",
|
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/anymatch": {
|
"node_modules/anymatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
@ -11637,16 +11651,29 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/short-uuid": {
|
"node_modules/short-uuid": {
|
||||||
"version": "4.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-5.2.0.tgz",
|
||||||
"integrity": "sha512-r3cxuPPZSuF0QkKsK9bBR7u+7cwuCRzWzgjPh07F5N2iIUNgblnMHepBY16xgj5t1lG9iOP9k/TEafY1qhRzaw==",
|
"integrity": "sha512-296/Nzi4DmANh93iYBwT4NoYRJuHnKEzefrkSagQbTH/A6NTaB68hSPDjm5IlbI5dx9FXdmtqPcj6N5H+CPm6w==",
|
||||||
"dev": true,
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"any-base": "^1.1.0",
|
"any-base": "^1.1.0",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^9.0.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/short-uuid/node_modules/uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/bin/uuid"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/side-channel": {
|
"node_modules/side-channel": {
|
||||||
@ -15504,6 +15531,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-9.1.2.tgz",
|
||||||
"integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==",
|
"integrity": "sha512-ERJq3FOzJTxBbFjZ7iDs+NiK4VI9Wz+RdrrAB8dio1oV+YvdPzUEE4QNiT2VD51DkIbCYRUUzCRkssXCHqSnKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
|
},
|
||||||
|
"short-uuid": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-4.2.2.tgz",
|
||||||
|
"integrity": "sha512-IE7hDSGV2U/VZoCsjctKX6l5t5ak2jE0+aeGJi3KtvjIUNuZVmHVYUjNBhmo369FIWGDtaieRaO8A83Lvwfpqw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"any-base": "^1.1.0",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -16987,8 +17024,7 @@
|
|||||||
"any-base": {
|
"any-base": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz",
|
||||||
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==",
|
"integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"anymatch": {
|
"anymatch": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
@ -21663,13 +21699,19 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"short-uuid": {
|
"short-uuid": {
|
||||||
"version": "4.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/short-uuid/-/short-uuid-5.2.0.tgz",
|
||||||
"integrity": "sha512-r3cxuPPZSuF0QkKsK9bBR7u+7cwuCRzWzgjPh07F5N2iIUNgblnMHepBY16xgj5t1lG9iOP9k/TEafY1qhRzaw==",
|
"integrity": "sha512-296/Nzi4DmANh93iYBwT4NoYRJuHnKEzefrkSagQbTH/A6NTaB68hSPDjm5IlbI5dx9FXdmtqPcj6N5H+CPm6w==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"any-base": "^1.1.0",
|
"any-base": "^1.1.0",
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^9.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": {
|
||||||
|
"version": "9.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||||
|
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"side-channel": {
|
"side-channel": {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
SPDX-FileCopyrightText: 2025 Mehdi Benadel <https://mehdibenadel.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
"http-proxy": "^1.18.1",
|
"http-proxy": "^1.18.1",
|
||||||
"log-rotate": "^0.2.8",
|
"log-rotate": "^0.2.8",
|
||||||
"openid-client": "^5.7.1",
|
"openid-client": "^5.7.1",
|
||||||
|
"short-uuid": "^5.2.0",
|
||||||
"validate-color": "^2.2.4",
|
"validate-color": "^2.2.4",
|
||||||
"xmppjs-chat-bot": "^0.5.0"
|
"xmppjs-chat-bot": "^0.5.0"
|
||||||
},
|
},
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
SPDX-FileCopyrightText: 2025 Mehdi Benadel <https://mehdibenadel.com>
|
||||||
|
|
||||||
SPDX-License-Identifier: AGPL-3.0-only
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"extends": "@tsconfig/node16/tsconfig.json",
|
"extends": "@tsconfig/node16/tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noImplicitOverride": true,
|
"noImplicitOverride": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"removeComments": true,
|
"removeComments": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
@ -1,16 +1,35 @@
|
|||||||
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
|
||||||
|
// SPDX-FileCopyrightText: 2025 Mehdi Benadel <https://mehdibenadel.com>
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
const short = require('short-uuid')
|
||||||
|
|
||||||
|
const translator = short()
|
||||||
|
|
||||||
|
function shortToUUID (shortUUID: string): string {
|
||||||
|
if (!shortUUID) return shortUUID
|
||||||
|
|
||||||
|
return translator.toUUID(shortUUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
function isShortUUID (value: string): boolean {
|
||||||
|
if (!value) return false
|
||||||
|
|
||||||
|
return value.length === translator.maxLength
|
||||||
|
}
|
||||||
|
|
||||||
function parseConfigUUIDs (s: string): string[] {
|
function parseConfigUUIDs (s: string): string[] {
|
||||||
if (!s) {
|
if (!s) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
let a = s.split('\n')
|
let a = s.split('\n')
|
||||||
a = a.map(line => {
|
a = a.map(line => {
|
||||||
return line.replace(/#.*$/, '')
|
line = line.replace(/#.*$/, '')
|
||||||
.replace(/^\s+/, '')
|
.replace(/^\s+/, '')
|
||||||
.replace(/\s+$/, '')
|
.replace(/\s+$/, '')
|
||||||
|
|
||||||
|
return isShortUUID(line) ? shortToUUID(line) : line
|
||||||
})
|
})
|
||||||
return a.filter(line => line !== '')
|
return a.filter(line => line !== '')
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user