Terms&Conditions (#18) WIP:

* Converse module to display terms.
* Prosody module to send terms.
This commit is contained in:
John Livingston
2024-06-25 09:59:46 +02:00
parent 45a63eaecd
commit b110456029
11 changed files with 324 additions and 6 deletions

View File

@ -0,0 +1,62 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import { CustomElement } from 'shared/components/element.js'
import { api } from '@converse/headless/core'
import { html } from 'lit'
import { __ } from 'i18n'
import '../styles/muc-terms.scss'
export default class MUCTermsView extends CustomElement {
static get properties () {
return {
model: { type: Object, attribute: true },
termstype: { type: String, attribute: true }
}
}
async initialize () {
if (!this.model) {
return
}
this.listenTo(this.model, 'change:x_livechat_terms_' + this.termstype, () => this.requestUpdate())
}
render () {
const terms = this.model?.get('x_livechat_terms_' + this.termstype)
return html`
${terms && terms.body && !this._hideInfoBox(terms.body)
? html`
<div>
<converse-rich-text text=${terms.body} render_styling></converse-rich-text>
<i class="livechat-hide-terms-info-box" @click=${this.closeInfoBox} title=${__('Close')}>
<converse-icon class="fa fa-times" size="1em"></converse-icon>
</i>
</div>`
: ''
}`
}
closeInfoBox (ev) {
ev.preventDefault()
const terms = this.model?.get('x_livechat_terms_' + this.termstype)
if (terms) {
localStorage?.setItem('x_livechat_terms_' + this.termstype + '_hidden', terms.body)
}
this.requestUpdate()
}
_hideInfoBox (body) {
// When hiding the infobox, we store in localStorage the current body, so we will show it again if message change.
// Note: for termstype=global we don't store the MUC server, so if user join chat from different instances,
// it will show terms again
// Note: same for termstype=muc, we don't store the MUC JID, so if user changes channel,
// it will probably show terms again
const lsHideInfoBox = localStorage?.getItem('x_livechat_terms_' + this.termstype + '_hidden')
return lsHideInfoBox === body
}
}
api.elements.define('livechat-converse-muc-terms', MUCTermsView)

View File

@ -0,0 +1,48 @@
// SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
//
// SPDX-License-Identifier: AGPL-3.0-only
import { converse, api } from '../../../src/headless/core.js'
import './components/muc-terms.js'
const { sizzle } = converse.env
converse.plugins.add('livechat-converse-terms', {
dependencies: ['converse-muc'],
initialize () {
api.listen.on('parseMUCMessage', (stanza, attrs) => {
const livechatTerms = sizzle('x-livechat-terms', stanza)
if (!livechatTerms.length) {
return attrs
}
return Object.assign(
attrs,
{
x_livechat_terms: livechatTerms[0].getAttribute('type')
}
)
})
},
overrides: {
ChatRoom: {
onMessage: function onMessage (attrs) {
if (!attrs.x_livechat_terms) {
return this.__super__.onMessage(attrs)
}
// We received a x-livechat-terms message, we don't forward it to standard onMessage,
// but we just update the room attribute.
const type = attrs.x_livechat_terms
if (type !== 'global' && type !== 'muc') {
console.error('Invalid x-livechat-terms type: ', type)
return
}
// console.info('Received a x-livechat-terms message', attrs)
const options = {}
options['x_livechat_terms_' + type] = attrs
this.set(options)
// this will be displayed by the livechat-converse-muc-terms custom element,
// which is inserted in the DOM by the muc.js template overload.
}
}
}
})

View File

@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
.conversejs {
livechat-converse-muc-terms {
background-color: var(--peertube-main-background);
color: var(--peertube-main-foreground);
div {
align-items: center;
border: 1px solid var(--peertube-menu-background);
display: flex;
flex-flow: row;
justify-content: space-between;
margin: 5px;
padding: 5px;
converse-rich-text {
flex-grow: 2;
max-height: 5em;
overflow-y: scroll;
white-space: pre-wrap;
}
.livechat-hide-terms-info-box {
cursor: pointer;
font-size: var(--font-size-small);
flex-shrink: 2;
}
}
}
}
.livechat-readonly .conversejs {
livechat-converse-muc-terms {
display: none !important;
}
}