diff --git a/CHANGELOG.md b/CHANGELOG.md index d5d95be1..66b8cc6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## ??? +### Features + +* Builtin Prosody: anonymous users connects automatically to the chat in a readonly mode. They must choose a nickname before they can chat. + ### Minor changes and fixes * Builtin Prosody: better random avatars quality. diff --git a/conversejs/builtin.ts b/conversejs/builtin.ts index 7ea83ab2..5ee94a3b 100644 --- a/conversejs/builtin.ts +++ b/conversejs/builtin.ts @@ -82,6 +82,7 @@ interface InitConverseParams { websocketServiceUrl: string authenticationUrl: string advancedControls: boolean + autoViewerMode: boolean forceReadonly: boolean | 'noscroll' noScroll: boolean theme: string @@ -94,6 +95,7 @@ window.initConverse = async function initConverse ({ websocketServiceUrl, authenticationUrl, advancedControls, + autoViewerMode, forceReadonly, theme }: InitConverseParams) { @@ -155,7 +157,7 @@ window.initConverse = async function initConverse ({ persistent_store: 'sessionStorage', show_images_inline: false, // for security reason, and to avoid bugs when image is larger that iframe render_media: false, // for security reason, and to avoid bugs when image is larger that iframe - whitelisted_plugins: ['livechatWindowTitlePlugin'] + whitelisted_plugins: ['livechatWindowTitlePlugin', 'livechatViewerModePlugin'] } // TODO: params.clear_messages_on_reconnection = true when muc_mam will be available. @@ -229,6 +231,44 @@ window.initConverse = async function initConverse ({ } } }) + + if (autoViewerMode && !isAuthenticated) { + window.converse.plugins.add('livechatViewerModePlugin', { + dependencies: ['converse-muc', 'converse-muc-views'], + initialize: function () { + const _converse = this._converse + const getDefaultMUCNickname = _converse.getDefaultMUCNickname + if (!getDefaultMUCNickname) { + console.error('[livechatViewerModePlugin] getDefaultMUCNickname is not initialized.') + } else { + Object.assign(_converse, { + getDefaultMUCNickname: function (this: any): any { + return getDefaultMUCNickname.apply(this, arguments) ?? 'Anonymous ' + (new Date()).getTime().toString() + } + }) + } + _converse.api.settings.update({ + livechat_viewer_mode: true + }) + + function refreshViewerMode (canChat: boolean): void { + console.log('[livechatViewerModePlugin] refreshViewerMode: ' + (canChat ? 'off' : 'on')) + if (canChat) { + body?.setAttribute('livechat-viewer-mode', 'off') + } else { + body?.setAttribute('livechat-viewer-mode', 'on') + } + } + + _converse.api.listen.on('livechatViewerModeSetNickname', () => refreshViewerMode(true)) + _converse.api.listen.on('chatRoomInitialized', function (this: any, model: any): void { + const nick = model?.get ? model.get('nick') : '' + refreshViewerMode(nick && !/^Anonymous /.test(nick)) + }) + } + }) + } + window.converse.initialize(params) } catch (error) { console.error('Failed initializing converseJS', error) diff --git a/conversejs/custom/shared/styles/livechat.scss b/conversejs/custom/shared/styles/livechat.scss index 064cfb5e..931b362f 100644 --- a/conversejs/custom/shared/styles/livechat.scss +++ b/conversejs/custom/shared/styles/livechat.scss @@ -36,3 +36,28 @@ body.livechat-readonly.livechat-noscroll { display: none; } } + +// Viewer mode +.livechat-viewer-mode-nick { + display: none; +} + +body[livechat-viewer-mode="on"] { + .livechat-viewer-mode-nick { + display: initial; + + form { + display: flex !important; + flex-flow: row wrap !important; + padding-top: 0.5em !important; + padding-bottom: 0.5em !important; + border-top: var(--chatroom-separator-border-bottom) !important; + } + } + + converse-muc-bottom-panel { + >:not(.livechat-viewer-mode-nick) { + display: none; + } + } +} diff --git a/conversejs/custom/templates/muc-bottom-panel.js b/conversejs/custom/templates/muc-bottom-panel.js new file mode 100644 index 00000000..3da72668 --- /dev/null +++ b/conversejs/custom/templates/muc-bottom-panel.js @@ -0,0 +1,38 @@ +import { __ } from 'i18n' +import { _converse, api } from '@converse/headless/core' +import { html } from 'lit' +import tplMucBottomPanel from '../../src/plugins/muc-views/templates/muc-bottom-panel.js' + +async function setNickname (ev, model) { + ev.preventDefault() + const nick = ev.target.nick.value.trim() + nick && await model.setNickname(nick) + _converse.api.trigger('livechatViewerModeSetNickname') +} + +export default (o) => { + if (api.settings.get('livechat_viewer_mode')) { + const model = o.model + const i18nNickname = __('Nickname') + const i18nJoin = __('Enter groupchat') + return html` +