Log in with external Peertube account (#348):
* For anonymous users: new "log in using an external account" dialog, with the "remote Peertube account" options * ConverseJS: using global vars for custom localized string (injected using Webpack)
This commit is contained in:
		| @ -14,6 +14,8 @@ TODO: https://github.com/JohnXLivingston/peertube-plugin-livechat/issues/48 | ||||
| * #143: User colors: implementing [XEP-0392](https://xmpp.org/extensions/xep-0392.html) to have random colors on users nicknames | ||||
| * #330: Chat does no more use an iframe to display the chat besides the videos. | ||||
| * #330: Fullscreen chat: now uses a custom page (in other words: when opening the chat in a new tab, you will have the Peertube menu). | ||||
| * For anonymous users: new "log in using an external account" dialog, with following options: | ||||
|   * remote Peertube account | ||||
|  | ||||
| ### Minor changes and fixes | ||||
|  | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| const fs = require('node:fs') | ||||
| const path = require('node:path') | ||||
| const YAML = require('yaml') | ||||
| const locKeys = require('./loc.keys.js') | ||||
|  | ||||
| /** | ||||
|  * This script will patch ConverseJS .po files, to add custom strings. | ||||
| @ -11,9 +12,7 @@ const livechatDir = path.resolve(__dirname, '..', 'languages') | ||||
| const converseDir = path.resolve(__dirname, '..', 'build', 'conversejs', 'src', 'i18n') | ||||
|  | ||||
| // Labels to import: | ||||
| const labels = loadLabels([ | ||||
|   'slow_mode_info' | ||||
| ]) | ||||
| const labels = loadLabels(locKeys) | ||||
|  | ||||
| function loadLabels (keys) { | ||||
|   const labels = {} | ||||
|  | ||||
| @ -79,6 +79,7 @@ rm -rf "$converse_build_dir/custom/" | ||||
| echo "Adding the custom files..." | ||||
| cp -r "$src_dir/custom/" "$converse_build_dir/custom/" | ||||
| mv "$converse_build_dir/custom/webpack.livechat.js" "$converse_build_dir/" | ||||
| cp "$src_dir/loc.keys.js" "$converse_build_dir/" | ||||
|  | ||||
| echo "Patching i18n files to add custom labels..." | ||||
| /bin/env node conversejs/build-conversejs-patch-i18n.js | ||||
|  | ||||
							
								
								
									
										117
									
								
								conversejs/custom/livechat-external-login-content.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								conversejs/custom/livechat-external-login-content.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | ||||
| import { api } from '@converse/headless/core.js' | ||||
| import { CustomElement } from 'shared/components/element.js' | ||||
| import { tplExternalLoginModal } from 'templates/livechat-external-login-modal.js' | ||||
| import { __ } from 'i18n' | ||||
|  | ||||
| export default class LivechatExternalLoginContentElement extends CustomElement { | ||||
|   static get properties () { | ||||
|     return { | ||||
|       remote_peertube_state: { type: String, attribute: false }, | ||||
|       remote_peertube_alert_message: { type: String, attribute: false }, | ||||
|       remote_peertube_try_anyway_url: { type: String, attribute: false } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   constructor () { | ||||
|     super() | ||||
|     this.remote_peertube_state = 'init' | ||||
|   } | ||||
|  | ||||
|   render () { | ||||
|     return tplExternalLoginModal(this, { | ||||
|       remote_peertube_state: this.remote_peertube_state, | ||||
|       remote_peertube_alert_message: this.remote_peertube_alert_message, | ||||
|       remote_peertube_try_anyway_url: this.remote_peertube_try_anyway_url | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   onKeyUp (_ev) { | ||||
|     if (this.remote_peertube_state !== 'init') { | ||||
|       this.remote_peertube_state = 'init' | ||||
|       this.remote_peertube_alert_message = '' | ||||
|       this.clearAlert() | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   async openRemotePeertube (ev) { | ||||
|     ev.preventDefault() | ||||
|     this.clearAlert() | ||||
|  | ||||
|     const remotePeertubeUrl = ev.target.peertube_url.value.trim() | ||||
|     if (!remotePeertubeUrl) { return } | ||||
|  | ||||
|     this.remote_peertube_state = 'loading' | ||||
|  | ||||
|     try { | ||||
|       // Calling Peertube API to check if livechat plugin is available. | ||||
|       // In the meantime, this will also check that the URL exists, and is a Peertube instance | ||||
|       // (or something with similar API result... as the user typed the url, we assume there is no security risk here). | ||||
|       const configApiUrl = new URL('/api/v1/config', remotePeertubeUrl) | ||||
|       const config = await (await fetch(configApiUrl.toString())).json() | ||||
|       if (!config || typeof config !== 'object') { | ||||
|         throw new Error('Invalid config API result') | ||||
|       } | ||||
|       if (!('plugin' in config) || !('registered' in config.plugin) || !Array.isArray(config.plugin.registered)) { | ||||
|         throw new Error('No registered plugin in config API result') | ||||
|       } | ||||
|       if (!config.plugin.registered.find(p => p.npmName === 'peertube-plugin-livechat')) { | ||||
|         console.error('Plugin livechat not available on remote instance') | ||||
|         this.remote_peertube_state = 'error' | ||||
|         // eslint-disable-next-line no-undef | ||||
|         this.remote_peertube_alert_message = __(LOC_login_remote_peertube_no_livechat) | ||||
|         return | ||||
|       } | ||||
|       // Note: we do not check if the livechat plugin disables federation (neither on current or remote instance). | ||||
|       // We assume this is not a standard use case, and we don't want to add to much use cases. | ||||
|  | ||||
|       // Now we must search the current video on the remote instance, to be sure it federates, and to get the url. | ||||
|       // Note: url search can be disabled on remote instance for non logged in users... | ||||
|       // As we are not authenticated on remote here, there are chances that the search wont return anything. | ||||
|       // As a fallback, we will launch another search with the video UUID. | ||||
|       // And if no result neither, we will just propose to open using the lazy-load page. | ||||
|       const videoUrl = api.settings.get('livechat_peertube_video_original_url') | ||||
|       const videoUUID = api.settings.get('livechat_peertube_video_uuid') | ||||
|       for (const search of [videoUrl, videoUUID]) { | ||||
|         if (!search) { continue } | ||||
|         // searching first on federation network, then on vidiverse (this could be disabled) | ||||
|         for (const searchTarget of ['local', 'search-index']) { | ||||
|           const searchAPIUrl = new URL('/api/v1/search/videos', remotePeertubeUrl) | ||||
|           searchAPIUrl.searchParams.append('start', '0') | ||||
|           searchAPIUrl.searchParams.append('count', 1) | ||||
|           searchAPIUrl.searchParams.append('search', search) | ||||
|           searchAPIUrl.searchParams.append('searchTarget', searchTarget) | ||||
|           const videos = await (await fetch(searchAPIUrl.toString())).json() | ||||
|           if (videos && Array.isArray(videos.data) && videos.data.length > 0 && videos.data[0].uuid) { | ||||
|             console.log('Video found, opening on remote instance') | ||||
|             this.remote_peertube_state = 'ok' | ||||
|             window.location.href = new URL( | ||||
|               '/videos/watch/' + encodeURIComponent(videos.data[0].uuid), remotePeertubeUrl | ||||
|             ).toString() | ||||
|             return | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|  | ||||
|       console.error('Video not found on remote instance') | ||||
|       this.remote_peertube_state = 'error' | ||||
|       // eslint-disable-next-line no-undef | ||||
|       this.remote_peertube_alert_message = __(LOC_login_remote_peertube_video_not_found) | ||||
|       this.remote_peertube_try_anyway_url = new URL( | ||||
|         '/search/lazy-load-video;url=' + encodeURIComponent(videoUrl), | ||||
|         remotePeertubeUrl | ||||
|       ).toString() | ||||
|     } catch (err) { | ||||
|       console.error(err) | ||||
|       this.remote_peertube_state = 'error' | ||||
|       // eslint-disable-next-line no-undef | ||||
|       this.remote_peertube_alert_message = __(LOC_login_remote_peertube_url_invalid) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   clearAlert () { | ||||
|     this.remote_peertube_alert_message = '' | ||||
|     this.remote_peertube_try_anyway_url = '' | ||||
|   } | ||||
| } | ||||
|  | ||||
| api.elements.define('converse-livechat-external-login-content', LivechatExternalLoginContentElement) | ||||
							
								
								
									
										20
									
								
								conversejs/custom/shared/modals/livechat-external-login.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								conversejs/custom/shared/modals/livechat-external-login.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| import { __ } from 'i18n' | ||||
| import BaseModal from 'plugins/modal/modal.js' | ||||
| import { api } from '@converse/headless/core' | ||||
| import { html } from 'lit' | ||||
| import 'livechat-external-login-content.js' | ||||
|  | ||||
| class ExternalLoginModal extends BaseModal { | ||||
|   remotePeertubeError = '' | ||||
|  | ||||
|   renderModal () { | ||||
|     return html`<converse-livechat-external-login-content></converse-livechat-external-login-content>` | ||||
|   } | ||||
|  | ||||
|   getModalTitle () { | ||||
|     // eslint-disable-next-line no-undef | ||||
|     return __(LOC_login_using_external_account) | ||||
|   } | ||||
| } | ||||
|  | ||||
| api.elements.define('converse-livechat-external-login', ExternalLoginModal) | ||||
| @ -43,30 +43,39 @@ body.livechat-readonly.livechat-noscroll { | ||||
| } | ||||
|  | ||||
| // Viewer mode | ||||
| .livechat-viewer-mode-nick { | ||||
| .livechat-viewer-mode-content { | ||||
|   display: none; | ||||
| } | ||||
|  | ||||
| body[livechat-viewer-mode="on"] { | ||||
|   .livechat-viewer-mode-nick { | ||||
|     display: initial; | ||||
|   form { | ||||
|     display: flex !important; | ||||
|     flex-flow: row wrap !important; | ||||
|     padding-bottom: 0.5em !important; | ||||
|     border-top: 1px solid var(--chatroom-head-bg-color) !important; | ||||
|     gap: 10px; | ||||
|     align-items: baseline; | ||||
|  | ||||
|     form { | ||||
|       display: flex !important; | ||||
|       flex-flow: row wrap !important; | ||||
|       padding-bottom: 0.5em !important; | ||||
|       border-top: var(--chatroom-separator-border-bottom) !important; | ||||
|       gap: 10px; | ||||
|       align-items: baseline; | ||||
|  | ||||
|       label { | ||||
|         color: var(--text-color); // fix converseJs css that breaks this label color. | ||||
|       } | ||||
|     label { | ||||
|       color: var(--text-color); // fix converseJs css that breaks this label color. | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   hr { | ||||
|     margin: 0; | ||||
|     background-color: var(--chatroom-head-bg-color); | ||||
|   } | ||||
|  | ||||
|   .livechat-viewer-mode-external-login { | ||||
|     padding: 2em; | ||||
|   } | ||||
| } | ||||
|  | ||||
| body[livechat-viewer-mode="on"] { | ||||
|   .livechat-viewer-mode-content { | ||||
|     display: initial; | ||||
|   } | ||||
|  | ||||
|   converse-muc-bottom-panel { | ||||
|     >:not(.livechat-viewer-mode-nick) { | ||||
|     >:not(.livechat-viewer-mode-content) { | ||||
|       display: none; | ||||
|     } | ||||
|   } | ||||
|  | ||||
							
								
								
									
										56
									
								
								conversejs/custom/templates/livechat-external-login-modal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								conversejs/custom/templates/livechat-external-login-modal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,56 @@ | ||||
| import { __ } from 'i18n' | ||||
| import { html } from 'lit' | ||||
|  | ||||
| export const tplExternalLoginModal = (el, o) => { | ||||
|   // eslint-disable-next-line no-undef | ||||
|   const i18nRemotePeertube = __(LOC_login_remote_peertube) | ||||
|   // eslint-disable-next-line no-undef | ||||
|   const i18nRemotePeertubeUrl = __(LOC_login_remote_peertube_url) | ||||
|   const i18nRemotePeertubeOpen = __('OK') | ||||
|   return html`<div class="modal-body livechat-external-login-modal"> | ||||
|     <form class="converse-form chatroom-form" @submit=${(ev) => el.openRemotePeertube(ev)}> | ||||
|       <label> | ||||
|         ${i18nRemotePeertube} | ||||
|         <input | ||||
|           type="url" | ||||
|           placeholder="${i18nRemotePeertubeUrl}" | ||||
|           class="form-control ${o.remote_peertube_alert_message ? 'is-invalid' : ''}" | ||||
|           name="peertube_url" | ||||
|           ?disabled=${o.remote_peertube_state === 'loading'} | ||||
|         /> | ||||
|       </label> | ||||
|       <input | ||||
|         type="submit" | ||||
|         class="btn btn-primary" | ||||
|         value="${i18nRemotePeertubeOpen}" | ||||
|         @keyup=${el.onKeyUp} | ||||
|         ?disabled=${o.remote_peertube_state === 'loading'} | ||||
|       /> | ||||
|       ${ | ||||
|         o.remote_peertube_state !== 'loading' | ||||
|           ? '' | ||||
|           : html`<small class="form-text text-muted">${ | ||||
|             // eslint-disable-next-line no-undef | ||||
|             __(LOC_login_remote_peertube_searching) | ||||
|           }</small>` | ||||
|       } | ||||
|       ${!o.remote_peertube_alert_message | ||||
|         ? '' | ||||
|         : html`<div class="invalid-feedback d-block">${o.remote_peertube_alert_message}</div>` | ||||
|       } | ||||
|       ${!o.remote_peertube_try_anyway_url | ||||
|         ? '' | ||||
|         : html`<div class="form-text"> | ||||
|           ${ | ||||
|             // eslint-disable-next-line no-undef | ||||
|             __(LOC_login_remote_peertube_video_not_found_try_anyway) | ||||
|           } | ||||
|           <button class="btn btn-primary" onclick="window.location.href='${o.remote_peertube_try_anyway_url}'">${ | ||||
|             // eslint-disable-next-line no-undef | ||||
|             __(LOC_login_remote_peertube_video_not_found_try_anyway_button) | ||||
|           }</button> | ||||
|         </div>` | ||||
|       } | ||||
|     </fieldset> | ||||
|   </form></div>` | ||||
| } | ||||
| @ -3,6 +3,7 @@ import { _converse, api } from '@converse/headless/core' | ||||
| import { html } from 'lit' | ||||
| import tplMucBottomPanel from '../../src/plugins/muc-views/templates/muc-bottom-panel.js' | ||||
| import { CustomElement } from 'shared/components/element.js' | ||||
| import 'shared/modals/livechat-external-login.js' | ||||
|  | ||||
| async function setNickname (ev, model) { | ||||
|   ev.preventDefault() | ||||
| @ -54,7 +55,8 @@ class SlowMode extends CustomElement { | ||||
|     return html`<div class="livechat-slow-mode-info-box"> | ||||
|       <converse-icon class="fa fa-info-circle" size="1.2em"></converse-icon> | ||||
|       ${__( | ||||
|         'Slow mode is enabled, users can send a message every %1$s seconds.', | ||||
|         // eslint-disable-next-line no-undef | ||||
|         LOC_slow_mode_info, | ||||
|         this.model.config.get('slow_mode_duration') | ||||
|       )} | ||||
|       <i class="livechat-hide-slow-mode-info-box" @click=${this.closeSlowModeInfoBox}> | ||||
| @ -82,14 +84,15 @@ export default (o) => { | ||||
|     const i18nNickname = __('Nickname') | ||||
|     const i18nJoin = __('Enter groupchat') | ||||
|     const i18nHeading = __('Choose a nickname to enter') | ||||
|     // eslint-disable-next-line no-undef | ||||
|     const i18nExternalLogin = __(LOC_login_using_external_account) | ||||
|     return html` | ||||
|     <div class="livechat-viewer-mode-nick chatroom-form-container" | ||||
|             @submit=${ev => setNickname(ev, model)}> | ||||
|         <form class="converse-form chatroom-form"> | ||||
|     <div class="livechat-viewer-mode-content chatroom-form-container"> | ||||
|         <form class="converse-form chatroom-form" @submit=${ev => setNickname(ev, model)}> | ||||
|             <label>${i18nHeading}</label> | ||||
|             <fieldset class="form-group"> | ||||
|               <input type="text" | ||||
|                   required="required" | ||||
|                   required | ||||
|                   name="nick" | ||||
|                   value="" | ||||
|                   class="form-control" | ||||
| @ -99,6 +102,21 @@ export default (o) => { | ||||
|                 <input type="submit" class="btn btn-primary" name="join" value="${i18nJoin}"/> | ||||
|             </fieldset> | ||||
|         </form> | ||||
|         ${ | ||||
|           // If we open a room with forcetype, there is no current video... So just disabling external login | ||||
|           // (in such case, we should be logged in as admin/moderator...) | ||||
|           !api.settings.get('livechat_peertube_video_original_url') | ||||
|             ? '' | ||||
|             : html` | ||||
|               <hr> | ||||
|               <div class="livechat-viewer-mode-external-login"> | ||||
|                 <button class="btn btn-primary" @click=${ev => { | ||||
|                   ev.preventDefault() | ||||
|                   api.modal.show('converse-livechat-external-login') | ||||
|                 }}>${i18nExternalLogin}</button> | ||||
|               </div> | ||||
|             ` | ||||
|         } | ||||
|     </div> | ||||
|     ${tplSlowMode(o)} | ||||
|     ${tplMucBottomPanel(o)}` | ||||
|  | ||||
| @ -1,18 +1,54 @@ | ||||
| const prod = require('./webpack/webpack.build.js') | ||||
| const { merge } = require('webpack-merge') | ||||
| const webpack = require('webpack') | ||||
| const path = require('path') | ||||
| const fs = require('fs') | ||||
| const locKeys = require('./loc.keys.js') | ||||
|  | ||||
| function loadLocs () { | ||||
|   // Loading english strings, so we can inject them as constants. | ||||
|   const refFile = path.resolve(__dirname, '..', '..', 'dist', 'languages', 'en.reference.json') | ||||
|   if (!fs.existsSync(refFile)) { | ||||
|     throw new Error('Missing english reference file, please run "npm run build:languages" before building ConverseJS') | ||||
|   } | ||||
|   const english = require(refFile) | ||||
|  | ||||
|   const r = {} | ||||
|   for (const key of locKeys) { | ||||
|     if (!(key in english) || (typeof english[key] !== 'string')) { | ||||
|       throw new Error('Missing english string key=' + key) | ||||
|     } | ||||
|     r['LOC_' + key] = JSON.stringify(english[key]) | ||||
|   } | ||||
|   return r | ||||
| } | ||||
|  | ||||
| module.exports = merge(prod, { | ||||
|   entry: path.resolve(__dirname, 'custom/entry.js'), | ||||
|   output: { | ||||
|     filename: 'converse.min.js' | ||||
|   }, | ||||
|   plugins: [ | ||||
|     new webpack.DefinePlugin(loadLocs()) | ||||
|   ], | ||||
|   resolve: { | ||||
|     extensions: ['.js'], | ||||
|     alias: { | ||||
|       './templates/muc-bottom-panel.js': path.resolve('custom/templates/muc-bottom-panel.js'), | ||||
|       '../../templates/background_logo.js$': path.resolve(__dirname, 'custom/templates/background_logo.js'), | ||||
|       'shared/styles/index.scss$': path.resolve(__dirname, 'custom/shared/styles/livechat.scss') | ||||
|       'shared/styles/index.scss$': path.resolve(__dirname, 'custom/shared/styles/livechat.scss'), | ||||
|       'shared/modals/livechat-external-login.js': path.resolve( | ||||
|         __dirname, | ||||
|         'custom/shared/modals/livechat-external-login.js' | ||||
|       ), | ||||
|       'templates/livechat-external-login-modal.js': path.resolve( | ||||
|         __dirname, | ||||
|         'custom/templates/livechat-external-login-modal.js' | ||||
|       ), | ||||
|       'livechat-external-login-content.js': path.resolve( | ||||
|         __dirname, | ||||
|         'custom/livechat-external-login-content.js' | ||||
|       ) | ||||
|     } | ||||
|   } | ||||
| }) | ||||
|  | ||||
| @ -8,7 +8,10 @@ import type { AuthentInfos } from './auth' | ||||
|  * @returns default parameters to provide to ConverseJS. | ||||
|  */ | ||||
| function defaultConverseParams ( | ||||
|   { forceReadonly, theme, assetsPath, room, forceDefaultHideMucParticipants, autofocus }: InitConverseJSParams | ||||
|   { | ||||
|     forceReadonly, theme, assetsPath, room, forceDefaultHideMucParticipants, autofocus, | ||||
|     peertubeVideoOriginalUrl, peertubeVideoUUID | ||||
|   }: InitConverseJSParams | ||||
| ): any { | ||||
|   const mucShowInfoMessages = forceReadonly | ||||
|     ? [ | ||||
| @ -87,7 +90,10 @@ function defaultConverseParams ( | ||||
|     colorize_username: true, | ||||
|  | ||||
|     // This is a specific settings, that is used in ConverseJS customization, to force avatars loading in readonly mode. | ||||
|     livechat_load_all_vcards: !!forceReadonly | ||||
|     livechat_load_all_vcards: !!forceReadonly, | ||||
|  | ||||
|     livechat_peertube_video_original_url: peertubeVideoOriginalUrl, | ||||
|     livechat_peertube_video_uuid: peertubeVideoUUID | ||||
|   } | ||||
|  | ||||
|   // TODO: params.clear_messages_on_reconnection = true when muc_mam will be available. | ||||
|  | ||||
| @ -6,7 +6,9 @@ export const livechatViewerModePlugin = { | ||||
|     const _converse = this._converse | ||||
|  | ||||
|     _converse.api.settings.extend({ | ||||
|       livechat_enable_viewer_mode: false | ||||
|       livechat_enable_viewer_mode: false, | ||||
|       livechat_peertube_video_original_url: undefined, | ||||
|       livechat_peertube_video_uuid: undefined | ||||
|     }) | ||||
|  | ||||
|     const originalGetDefaultMUCNickname = _converse.getDefaultMUCNickname | ||||
|  | ||||
							
								
								
									
										19
									
								
								conversejs/loc.keys.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								conversejs/loc.keys.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| /** Localization keys to inject in ConverseJS: | ||||
|  *  these keys are used to: | ||||
|  *  - inject needed localization strings in ConverseJS language files | ||||
|  *  - defined global variable using Webpack, to retrieve the english key to pass to the ConverseJS localization function | ||||
| */ | ||||
| const locKeys = [ | ||||
|   'slow_mode_info', | ||||
|   'login_using_external_account', | ||||
|   'login_remote_peertube', | ||||
|   'login_remote_peertube_searching', | ||||
|   'login_remote_peertube_url', | ||||
|   'login_remote_peertube_url_invalid', | ||||
|   'login_remote_peertube_no_livechat', | ||||
|   'login_remote_peertube_video_not_found', | ||||
|   'login_remote_peertube_video_not_found_try_anyway', | ||||
|   'login_remote_peertube_video_not_found_try_anyway_button' | ||||
| ] | ||||
|  | ||||
| module.exports = locKeys | ||||
| @ -392,3 +392,13 @@ invalid_value: "Invalid value." | ||||
| slow_mode_info: "Slow mode is enabled, users can send a message every %1$s seconds." | ||||
|  | ||||
| chatroom_not_accessible: "This chatroom does not exist, or is not accessible to you." | ||||
|  | ||||
| login_using_external_account: "Log in using an external account" | ||||
| login_remote_peertube: "Log in using an account on another Peertube instance:" | ||||
| login_remote_peertube_url: "Your Peertube instance URL" | ||||
| login_remote_peertube_searching: "Searching the video on the Peertube instance..." | ||||
| login_remote_peertube_url_invalid: "Invalid Peertube URL." | ||||
| login_remote_peertube_no_livechat: "The livechat plugin is not installed on this Peertube instance." | ||||
| login_remote_peertube_video_not_found: "This video is not available on this Peertube instance." | ||||
| login_remote_peertube_video_not_found_try_anyway: "In some cases, the video can still be retrieved if you connect to the remote instance." | ||||
| login_remote_peertube_video_not_found_try_anyway_button: "Try anyway to open the video on the Peertube instance" | ||||
|  | ||||
| @ -77,6 +77,8 @@ async function getConverseJSParams ( | ||||
|   } = connectionInfos | ||||
|  | ||||
|   return { | ||||
|     peertubeVideoOriginalUrl: roomInfos.video?.url, | ||||
|     peertubeVideoUUID: roomInfos.video?.uuid, | ||||
|     staticBaseUrl, | ||||
|     assetsPath: staticBaseUrl + 'conversejs/', | ||||
|     isRemoteChat: !!(roomInfos.video?.remote), | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| type ConverseJSTheme = 'peertube' | 'default' | 'concord' | ||||
|  | ||||
| interface InitConverseJSParams { | ||||
|   peertubeVideoOriginalUrl?: string | ||||
|   peertubeVideoUUID?: string | ||||
|   isRemoteChat: boolean | ||||
|   localAnonymousJID: string | null | ||||
|   remoteAnonymousJID: string | null | ||||
|  | ||||
		Reference in New Issue
	
	Block a user