diff --git a/CHANGELOG.md b/CHANGELOG.md index b0b861ea..0d2473ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ ### Features -* Builtin ConverseJS on external XMPP server: new placeholders for the room name: CHANNEL_ID, CHANNEL_NAME. +* Possibility to have webchat per channel (see [this request](https://github.com/JohnXLivingston/peertube-plugin-livechat/issues/58)) + * Builtin ConverseJS on external XMPP server: new placeholders for the room name: CHANNEL_ID, CHANNEL_NAME. + * External webchat tool: new placeholder CHANNEL_ID in the webchat url. ## v3.2.0 diff --git a/client/@types/peertube.d.ts b/client/@types/peertube.d.ts index a649d552..36cd1004 100644 --- a/client/@types/peertube.d.ts +++ b/client/@types/peertube.d.ts @@ -67,4 +67,13 @@ interface Video { name: string originInstanceUrl: string uuid: string + channel: Channel +} + +interface Channel { + id: number + name: string + displayName: string + url: string + host: string } diff --git a/client/videowatch-client-plugin.ts b/client/videowatch-client-plugin.ts index 37a7c549..76beddf1 100644 --- a/client/videowatch-client-plugin.ts +++ b/client/videowatch-client-plugin.ts @@ -28,7 +28,7 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { return staticBase.replace(/\/static.*$/, '/router') } - function getIframeUri (uuid: string): string | null { + function getIframeUri (video: Video): string | null { if (!settings) { logger.error('Settings are not initialized, too soon to compute the iframeUri') return null @@ -37,10 +37,17 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { const chatType: ChatType = (settings['chat-type'] ?? 'disabled') as ChatType if (chatType === 'builtin-prosody' || chatType === 'builtin-converse') { // Using the builtin converseJS - iframeUri = getBaseRoute() + '/webchat/room/' + encodeURIComponent(uuid) + iframeUri = getBaseRoute() + '/webchat/room/' + encodeURIComponent(video.uuid) } else if (chatType === 'external-uri') { iframeUri = settings['chat-uri'] || '' - iframeUri = iframeUri.replace(/{{VIDEO_UUID}}/g, encodeURIComponent(uuid)) + iframeUri = iframeUri.replace(/{{VIDEO_UUID}}/g, encodeURIComponent(video.uuid)) + if (iframeUri.includes('{{CHANNEL_ID}}')) { + if (!video.channel || !video.channel.id) { + logger.error('Missing channel info in video object.') + return null + } + iframeUri = iframeUri.replace(/{{CHANNEL_ID}}/g, encodeURIComponent(video.channel.id)) + } if (!/^https?:\/\//.test(iframeUri)) { logger.error('The webchaturi must begin with https://') return null @@ -85,7 +92,7 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { buttonContainer.append(button) } - async function insertChatDom (container: HTMLElement, uuid: string, showOpenBlank: boolean): Promise { + async function insertChatDom (container: HTMLElement, video: Video, showOpenBlank: boolean): Promise { logger.log('Adding livechat in the DOM...') const p = new Promise((resolve, reject) => { // eslint-disable-next-line @typescript-eslint/no-floating-promises @@ -98,7 +105,7 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { const labelOpenBlank = labels[1] const labelClose = labels[2] - const iframeUri = getIframeUri(uuid) + const iframeUri = getIframeUri(video) if (!iframeUri) { return reject(new Error('No uri, cant display the buttons.')) } @@ -107,7 +114,7 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { buttonContainer.classList.add('peertube-plugin-livechat-buttons') container.append(buttonContainer) - displayButton(buttonContainer, 'open', labelOpen, () => openChat(uuid), 'talking.svg') + displayButton(buttonContainer, 'open', labelOpen, () => openChat(video), 'talking.svg') if (showOpenBlank) { displayButton(buttonContainer, 'openblank', labelOpenBlank, () => { closeChat() @@ -122,14 +129,14 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { return p } - function openChat (uuid: string): void | boolean { - if (!uuid) { - logger.log('No current uuid.') + function openChat (video: Video): void | boolean { + if (!video) { + logger.log('No video.') return false } - logger.info('Trying to load the chat for video ' + uuid + '.') - const iframeUri = getIframeUri(uuid) + logger.info('Trying to load the chat for video ' + video.uuid + '.') + const iframeUri = getIframeUri(video) if (!iframeUri) { logger.error('Incorrect iframe uri') return false @@ -202,9 +209,9 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { return } - insertChatDom(container as HTMLElement, video.uuid, !!settings['chat-open-blank']).then(() => { + insertChatDom(container as HTMLElement, video, !!settings['chat-open-blank']).then(() => { if (settings['chat-auto-display']) { - openChat(video.uuid) + openChat(video) } else if (container) { container.setAttribute('peertube-plugin-livechat-state', 'closed') } diff --git a/documentation/conversejs.md b/documentation/conversejs.md index f93ef613..70d7e72c 100644 --- a/documentation/conversejs.md +++ b/documentation/conversejs.md @@ -30,7 +30,7 @@ You can have a single room for all webchats, or you can use any of there placeho - ```{{CHANNEL_ID}}``` to insert the channel numerical ID and have a custom room for each channel. - ```{{CHANNEL_NAME}}``` to insert the channel name (see the Peertube's documentation for possible characters) and have a custom room for each channel. -You can mix several placeholder. +You can mix several placeholders. Example: ```room_{{VIDEO_UUID}}@room.peertube.im.your_domain``` diff --git a/documentation/external.md b/documentation/external.md index 883ccd4d..3cf89ff8 100644 --- a/documentation/external.md +++ b/documentation/external.md @@ -14,10 +14,16 @@ Speficy here the url for you chat application. You can add the string {{VIDEO_UUID}} in the url, it will be replaced by the video UUID. -It is possible to use a single chat for all your videos if you omit this parameter. +You can also use {{CHANNEL_ID}} to add the channel id, so you can group webchats per user channel. + +It is possible to use a single chat for all your videos if you omit these parameters. Example: ```https://peertube.im.your_domain?room={{VIDEO_UUID}}``` +or +```https://peertube.im.your_domain?room={{CHANNEL_ID}}``` + +NB: when using CHANNEL_ID with remote videos, you can have unexpected results. You should consider disabling webchat for remote videos. ### Chat behaviour diff --git a/server/lib/settings.ts b/server/lib/settings.ts index fdc24320..94c4615c 100644 --- a/server/lib/settings.ts +++ b/server/lib/settings.ts @@ -165,9 +165,12 @@ You must at least have a BOSH or a Websocket uri.`, default: '', descriptionHTML: `Put here your webchat url. An iframe will be created pointing to this url. -The placeholder {{VIDEO_UUID}} will be replace by the video UUID if present. -Example : https://my_domain/conversejs.html?room=video_{{VIDEO_UUID}}.
-If this field is empty, it will use the builtin ConverseJS webchat.`, +You can use following placeholders to inject video metadata in the url: +
    +
  • {{VIDEO_UUID}} to add the video UUID.
  • +
  • {{CHANNEL_ID}} to add the CHANNEL numerical ID.
  • +
+Example : https://my_domain/conversejs.html?room=video_{{VIDEO_UUID}}.`, private: false })