diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cf2eb1e..0f4ffd65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Minor changes and fixes +* Anonymous chat user: remember the chosen nickname in sessionStorage, to avoid entering it again too often. +* Fix: if an anonymous chat user enter spaces in the nickname choice, it will allows them to keep the random nickname. * Translation updates: German, French. * New Swedish translations. diff --git a/conversejs/builtin.ts b/conversejs/builtin.ts index d9fcf0fe..5308e21a 100644 --- a/conversejs/builtin.ts +++ b/conversejs/builtin.ts @@ -9,7 +9,7 @@ import { remoteRoomAuthenticatedParams } from './lib/converse-params' import { getLocalAuthentInfos } from './lib/auth' -import { randomNick } from './lib/nick' +import { randomNick, getPreviousAnonymousNick, setPreviousAnonymousNick } from './lib/nick' declare global { interface Window { @@ -110,6 +110,7 @@ window.initConverse = async function initConverse (initConverseParams: InitConve }) if (autoViewerMode && !isAuthenticated && !isRemoteWithNicknameSet) { + const previousNickname = getPreviousAnonymousNick() converse.plugins.add('livechatViewerModePlugin', { dependencies: ['converse-muc', 'converse-muc-views'], initialize: function () { @@ -120,13 +121,10 @@ window.initConverse = async function initConverse (initConverseParams: InitConve } else { Object.assign(_converse, { getDefaultMUCNickname: function (this: any): any { - return getDefaultMUCNickname.apply(this, arguments) ?? randomNick('Anonymous') + return getDefaultMUCNickname.apply(this, arguments) ?? previousNickname ?? randomNick('Anonymous') } }) } - _converse.api.settings.update({ - livechat_viewer_mode: true - }) function refreshViewerMode (canChat: boolean): void { console.log('[livechatViewerModePlugin] refreshViewerMode: ' + (canChat ? 'off' : 'on')) @@ -137,9 +135,32 @@ window.initConverse = async function initConverse (initConverseParams: InitConve } } + if (previousNickname === null) { + _converse.api.settings.update({ + livechat_viewer_mode: true + }) + } + _converse.api.listen.on('livechatViewerModeSetNickname', () => refreshViewerMode(true)) + + _converse.ChatRoomOccupants.prototype.on('change:nick', (data: any, nick: string) => { + try { + // On nick change, if the user is_me, storing the new nickname + if (nick && data?.attributes?.is_me === true) { + console.log('Nickname change, storing to previousAnonymousNick') + setPreviousAnonymousNick(nick) + } + } catch (err) { + console.error('Error on nick change handling...', err) + } + }) + _converse.api.listen.on('chatRoomInitialized', function (this: any, model: any): void { - const nick = model?.get ? model.get('nick') : '' + // When room is initialized, if user has chosen a nickname, set viewermode to off. + // Note: when previousNickname is set, model.get('nick') has not the nick yet... + // It will only come after receiving a presence stanza. + // So we use previousNickname before trying to read the model. + const nick = previousNickname ?? (model?.get ? model.get('nick') : '') refreshViewerMode(nick && !/^Anonymous /.test(nick)) }) } diff --git a/conversejs/custom/templates/muc-bottom-panel.js b/conversejs/custom/templates/muc-bottom-panel.js index 3da72668..a0101c4f 100644 --- a/conversejs/custom/templates/muc-bottom-panel.js +++ b/conversejs/custom/templates/muc-bottom-panel.js @@ -6,8 +6,13 @@ import tplMucBottomPanel from '../../src/plugins/muc-views/templates/muc-bottom- async function setNickname (ev, model) { ev.preventDefault() const nick = ev.target.nick.value.trim() - nick && await model.setNickname(nick) - _converse.api.trigger('livechatViewerModeSetNickname') + if (!nick) { + return + } + await model.setNickname(nick) + _converse.api.trigger('livechatViewerModeSetNickname', model, nick, { + synchronous: true + }) } export default (o) => { diff --git a/conversejs/lib/nick.ts b/conversejs/lib/nick.ts index 1b8d8178..d8e3b9f3 100644 --- a/conversejs/lib/nick.ts +++ b/conversejs/lib/nick.ts @@ -1,9 +1,41 @@ +/** + * Generates a random nickname. + * @param base Nickname prefix + * @returns A nickname like "Given Base 12345" + */ function randomNick (base: string): string { // using a 6 digit random number to generate a nickname with low colision risk const n = 100000 + Math.floor(Math.random() * 900000) return base + ' ' + n.toString() } -export { - randomNick +/** + * Get the previous anonymous nickname (stored in sessionStorage). + * @returns previous nickname or null + */ +function getPreviousAnonymousNick (): string | null { + try { + return sessionStorage.getItem('livechat-previous-anonymous-nickname') + } catch (err) { + console.error(err) + return null + } +} + +/** + * Stores the chosen nickname in sessionStorage. + */ +function setPreviousAnonymousNick (nick: string): void { + try { + console.log('Storing anonymous nickname', nick) + sessionStorage.setItem('livechat-previous-anonymous-nickname', nick) + } catch (err) { + console.error(err) + } +} + +export { + randomNick, + getPreviousAnonymousNick, + setPreviousAnonymousNick }