diff --git a/client/common-client-plugin.ts b/client/common-client-plugin.ts index 6babffee..522ee580 100644 --- a/client/common-client-plugin.ts +++ b/client/common-client-plugin.ts @@ -1,6 +1,4 @@ -'use strict' - function register ({ registerHook }: RegisterOptions): void { registerHook({ target: 'action:router.navigation-end', diff --git a/client/tsconfig.json b/client/tsconfig.json index 89e45dbc..21014bdc 100644 --- a/client/tsconfig.json +++ b/client/tsconfig.json @@ -13,8 +13,13 @@ "strictBindCallApply": true, // should already be true because of strict:true "noUnusedLocals": true, "outDir": "../dist/client", - "paths": {} + "paths": { + "shared/*": ["../shared/*"] + } }, - "include": ["./**/*"], + "include": [ + "./**/*", + "../shared/**/*" + ], "exclude": [] } diff --git a/client/videowatch-client-plugin.ts b/client/videowatch-client-plugin.ts index caa51d20..9160c63f 100644 --- a/client/videowatch-client-plugin.ts +++ b/client/videowatch-client-plugin.ts @@ -1,4 +1,4 @@ -'use strict' +import { parseConfigUUIDs } from 'shared/lib/config' interface VideoCache {[key: string]: Video} @@ -14,19 +14,6 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { let lastUUID: string | null = null let settings: any = {} - function parseUUIDs (s: string): string[] { - if (!s) { - return [] - } - let a = s.split('\n') - a = a.map(line => { - return line.replace(/#.*$/, '') - .replace(/^\s+/, '') - .replace(/\s+$/, '') - }) - return a.filter(line => line !== '') - } - function getBaseRoute (): string { // FIXME: should be provided by PeertubeHelpers (does not exists for now) // We are guessing the route with the correct plugin version with this trick: @@ -195,12 +182,11 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { container.setAttribute('peertube-plugin-livechat-state', 'initializing') videoWrapper.append(container) - // eslint-disable-next-line @typescript-eslint/no-floating-promises peertubeHelpers.getSettings().then((s: any) => { settings = s const liveOn = !!settings['chat-all-lives'] const nonLiveOn = !!settings['chat-all-non-lives'] - const uuids = parseUUIDs(settings['chat-videos-list']) + const uuids = parseConfigUUIDs(settings['chat-videos-list']) if (!uuids.length && !liveOn && !nonLiveOn) { logger.log('Feature not activated.') return @@ -241,6 +227,8 @@ function register ({ registerHook, peertubeHelpers }: RegisterOptions): void { container.setAttribute('peertube-plugin-livechat-state', 'closed') } }) + }, () => { + logger.error('Cant get settings') }) } diff --git a/server/lib/routers/api.ts b/server/lib/routers/api.ts index 2b7ed81e..820a6db1 100644 --- a/server/lib/routers/api.ts +++ b/server/lib/routers/api.ts @@ -1,4 +1,5 @@ import type { Router, Request, Response, NextFunction } from 'express' +import { videoHasWebchat } from '../../../shared/lib/video' // See here for description: https://modules.prosody.im/mod_muc_http_defaults.html interface RoomDefaults { @@ -38,9 +39,23 @@ async function initApiRouter (options: RegisterServerOptions): Promise { if (!video) { throw new Error('Video not found') } - // FIXME: check settings (chat enabled for this video) + // check settings (chat enabled for this video?) + const settings = await options.settingsManager.getSettings([ + 'chat-only-locals', + 'chat-all-lives', + 'chat-all-non-lives', + 'chat-videos-list' + ]) + if (!videoHasWebchat({ + 'chat-only-locals': settings['chat-only-locals'] as boolean, + 'chat-all-lives': settings['chat-all-lives'] as boolean, + 'chat-all-non-lives': settings['chat-all-non-lives'] as boolean, + 'chat-videos-list': settings['chat-videos-list'] as string + }, video)) { + throw new Error('Chat is not activated for this video') + } - // TODO: check if room is legit and fill informations + // TODO: fill missing informations const roomDefaults: RoomDefaults = { config: { name: video.name, diff --git a/server/tsconfig.json b/server/tsconfig.json index 4a3ff98c..5872a594 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -15,9 +15,12 @@ "sourceMap": true, "baseUrl": "./", - "outDir": "../dist/server", + "outDir": "../dist/", "paths": {} }, - "include": ["./**/*"], + "include": [ + "./**/*", + "../shared/**/*" + ], "exclude": [] } diff --git a/shared/.eslintrc.json b/shared/.eslintrc.json new file mode 100644 index 00000000..d6e49863 --- /dev/null +++ b/shared/.eslintrc.json @@ -0,0 +1,41 @@ +{ + "root": true, + "env": { + "browser": true, + "es6": true + }, + "extends": [ + "standard-with-typescript" + ], + "globals": {}, + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": 2018, + "project": [ + "./server/tsconfig.json", + "./client/tsconfig.json" + ] + }, + "plugins": [ + "@typescript-eslint" + ], + "ignorePatterns": [], + "rules": { + "@typescript-eslint/no-unused-vars": [2, {"argsIgnorePattern": "^_"}], + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/strict-boolean-expressions": "off", + "@typescript-eslint/return-await": [2, "in-try-catch"], // FIXME: correct? + "@typescript-eslint/no-invalid-void-type": "off", + "@typescript-eslint/triple-slash-reference": "off", + "max-len": [ + "error", + { + "code": 120, + "comments": 120 + } + ], + "no-unused-vars": "off" + } +} diff --git a/shared/lib/config.ts b/shared/lib/config.ts new file mode 100644 index 00000000..0b0cea36 --- /dev/null +++ b/shared/lib/config.ts @@ -0,0 +1,16 @@ +function parseConfigUUIDs (s: string): string[] { + if (!s) { + return [] + } + let a = s.split('\n') + a = a.map(line => { + return line.replace(/#.*$/, '') + .replace(/^\s+/, '') + .replace(/\s+$/, '') + }) + return a.filter(line => line !== '') +} + +export { + parseConfigUUIDs +} diff --git a/shared/lib/video.ts b/shared/lib/video.ts new file mode 100644 index 00000000..3a29fa99 --- /dev/null +++ b/shared/lib/video.ts @@ -0,0 +1,52 @@ +import { parseConfigUUIDs } from './config' + +interface SharedSettings { + 'chat-only-locals': boolean + 'chat-all-lives': boolean + 'chat-all-non-lives': boolean + 'chat-videos-list': string +} + +interface SharedVideoBase { + uuid: string + isLive: boolean +} + +interface SharedVideoFrontend extends SharedVideoBase { + isLocal: boolean +} + +interface SharedVideoBackend extends SharedVideoBase { + remote: boolean +} + +type SharedVideo = SharedVideoBackend | SharedVideoFrontend + +function videoHasWebchat (settings: SharedSettings, video: SharedVideo): boolean { + if (settings['chat-only-locals']) { + if ('isLocal' in video) { + if (!video.isLocal) return false + } else { + if (video.remote) return false + } + } + + if (settings['chat-all-lives']) { + if (video.isLive) return true + } + + if (settings['chat-all-non-lives']) { + if (!video.isLive) return true + } + + const uuids = parseConfigUUIDs(settings['chat-videos-list']) + if (uuids.includes(video.uuid)) { + return true + } + + return false +} + +export { + videoHasWebchat +} diff --git a/webpack.config.js b/webpack.config.js index eceb5aea..a07c45e7 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -22,6 +22,9 @@ let config = clientFiles.map(f => ({ ] }, resolve: { + alias: { + 'shared': path.resolve(__dirname, 'shared/') + }, extensions: [ '.tsx', '.ts', '.js' ], }, output: {