diff --git a/client/videowatch-client-plugin.js b/client/videowatch-client-plugin.js index b0e9e07c..1dae9d80 100644 --- a/client/videowatch-client-plugin.js +++ b/client/videowatch-client-plugin.js @@ -27,7 +27,10 @@ function register ({ registerHook, peertubeHelpers }) { function getBaseRoute () { // FIXME: should be provided by PeertubeHelpers (does not exists for now) - return '/plugins/livechat/router' + // We are guessing the route with the correct plugin version with this trick: + const staticBase = peertubeHelpers.getBaseStaticRoute() + // we can't use '/plugins/livechat/router', because the loaded html page needs correct relative paths. + return staticBase.replace(/\/static.*$/, '/router') } function getIframeUri (uuid) { @@ -38,7 +41,7 @@ function register ({ registerHook, peertubeHelpers }) { let iframeUri = '' if (!settings['chat-use-builtin']) { iframeUri = settings['chat-uri'] || '' - iframeUri = iframeUri.replace('{{VIDEO_UUID}}', uuid) + iframeUri = iframeUri.replace(/{{VIDEO_UUID}}/g, uuid) if (!/^https?:\/\//.test(iframeUri)) { logger.error('The webchaturi must begin with https://') return null diff --git a/conversejs/conversejs.js b/conversejs/conversejs.js new file mode 100644 index 00000000..060ecd1c --- /dev/null +++ b/conversejs/conversejs.js @@ -0,0 +1,41 @@ +require('converse.js') + +window.initConverse = function initConverse ({ + baseStaticUrl, + room, + boshServiceUrl +}) { + window.converse.initialize({ + assets_path: baseStaticUrl, + + authentication: 'anonymous', + auto_login: true, + auto_join_rooms: [ + room + ], + bosh_service_url: boshServiceUrl, + jid: 'peertube.im.your_domain', + notify_all_room_messages: [ + room + ], + singleton: true, + auto_focus: false, + hide_muc_participants: false, + keepalive: true, + play_sounds: false, + muc_mention_autocomplete_min_chars: 3, + muc_mention_autocomplete_filter: 'contains', + modtools_disable_assign: true, + muc_disable_slash_commands: [ + 'admin', 'ban', 'clear', 'deop', 'destroy', 'kick', + 'member', 'modtools', 'mute', 'op', 'owner', 'register', + 'revoke', 'subject', 'topic', 'voice' + ], + muc_instant_rooms: true, + show_client_info: false, + allow_adhoc_commands: false, + allow_contact_requests: false, + show_controlbox_by_default: false, + view_mode: 'fullscreen' + }) +} diff --git a/conversejs/index.html b/conversejs/index.html new file mode 100644 index 00000000..4dbaccbd --- /dev/null +++ b/conversejs/index.html @@ -0,0 +1,26 @@ + + + + Converse + + + + + + + + +
+ + + diff --git a/main.js b/main.js index 8580de49..340d1c53 100644 --- a/main.js +++ b/main.js @@ -1,7 +1,10 @@ +const path = require('path') +const fs = require('fs').promises + async function register ({ _registerHook, registerSetting, - _settingsManager, + settingsManager, _storageManager, _videoCategoryManager, _videoLicenceManager, @@ -53,11 +56,20 @@ async function register ({ descriptionHTML: 'If checked, use a builtin ConverseJS iframe.
' + 'You still have to configure an external XMPP service. Please see the documentation.' }) + registerSetting({ + name: 'chat-room-server', + label: 'Builtin webchat: XMPP room service server', + type: 'input', + default: '', + descriptionHTML: 'When using the built-in converseJS webchat:
' + + 'Your XMPP room server. Example : room.peertube.im.your_domain.', + private: true + }) registerSetting({ name: 'chat-bosh-uri', label: 'Builtin webchat: BOSH uri', type: 'input', - default: true, + default: '', descriptionHTML: 'When using the built-in converseJS webchat:
' + 'URI of the external BOSH server. Please make sure it accept cross origin request from your domain.', private: true @@ -86,10 +98,23 @@ async function register ({ private: false }) + const converseJSIndex = await fs.readFile(path.resolve(__dirname, './conversejs/index.html')) + const router = getRouter() router.get('/ping', (req, res) => res.json({ message: 'pong' })) router.get('/webchat', async (req, res, next) => { try { + const settings = await settingsManager.getSettings([ + 'chat-use-builtin', 'chat-room-server', 'chat-bosh-uri' + ]) + + if (!settings['chat-use-builtin']) { + throw new Error('Builtin chat disabled.') + } + if (!settings['chat-room-server']) { + throw new Error('Missing chat-room-server settings.') + } + // FIXME: with Peertube 3.0.1 the following method is not available... // When loadByIdOrUUID is available, change the entry point to // be /webchat/:videoId @@ -109,7 +134,16 @@ async function register ({ if (!video) { throw new Error('Video not found') } - res.send('ok') + + let page = '' + converseJSIndex + // FIXME: Peertube should provide the static folder path. For now: + const staticRelative = '../static/conversejs' + page = page.replace(/{{BASE_STATIC_URL}}/g, staticRelative) + page = page.replace(/{{ROOM}}/g, 'public_' + video.uuid + '@' + settings['chat-room-server']) + page = page.replace(/{{BOSH_SERVICE_URL}}/g, settings['chat-bosh-uri']) + + res.status(200) + res.send(page) } catch (error) { return next(error) } diff --git a/package-lock.json b/package-lock.json index 3c9789fa..2069d423 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "peertube-plugin-livechat", - "version": "0.0.5", + "version": "0.0.8", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -995,6 +995,12 @@ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, + "converse.js": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/converse.js/-/converse.js-7.0.4.tgz", + "integrity": "sha512-U07RJB71nG88IRlfhlcxOlJAnH4pVNH1H8jF39OANxZbqSikOX3qJO3e3fV0Tem0I9oNgDqkRW60pI22zjeP0w==", + "dev": true + }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", diff --git a/package.json b/package.json index 2bb0fe89..d17c5e1f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "peertube-plugin-livechat", "description": "PeerTube plugin livechat", - "version": "0.0.8", + "version": "0.1.0", "author": "John Livingston", "bugs": "https://github.com/JohnXLivingston/peertube-plugin-livechat/issues", "clientScripts": [ @@ -23,6 +23,7 @@ ], "devDependencies": { "@purtuga/esm-webpack-plugin": "^1.1.1", + "converse.js": "^7.0.4", "eslint": "^7.20.0", "eslint-config-standard": "^16.0.2", "eslint-plugin-import": "^2.22.1", @@ -45,7 +46,9 @@ "build": "webpack --mode=production", "lint": "npx eslint --ext .js ." }, - "staticDirs": {}, + "staticDirs": { + "conversejs": "dist/conversejs" + }, "translations": { "fr-FR": "./languages/fr.json" } diff --git a/webpack.config.js b/webpack.config.js index 7e8b981d..5f210fb0 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -18,4 +18,12 @@ let config = clientFiles.map(f => ({ plugins: [ new EsmWebpackPlugin() ] })) +config.push({ + entry: "./conversejs/conversejs.js", + output: { + path: path.resolve(__dirname, "./dist/conversejs"), + filename: "./conversejs.js" + } +}) + module.exports = config