From 1ac1f7ca92b7a15fbcc8c33b82bfce7fa79b8f89 Mon Sep 17 00:00:00 2001 From: Vittorio Palmisano Date: Tue, 27 Apr 2021 19:57:36 +0200 Subject: [PATCH] using eslint settings from mediasoup-client --- app/.eslintrc.json | 113 +++----- app/.prettierrc | 2 +- app/src/config.ts | 499 ++++++++++++++++++++++++++++++++ app/src/translations/locales.ts | 276 +++++++++--------- 4 files changed, 676 insertions(+), 214 deletions(-) create mode 100644 app/src/config.ts diff --git a/app/.eslintrc.json b/app/.eslintrc.json index c4590994..c2bb6eaf 100644 --- a/app/.eslintrc.json +++ b/app/.eslintrc.json @@ -6,91 +6,48 @@ }, "overrides": [ { - "files":["**/*.{ts,tsx}"], - "plugins": ["prettier", "@typescript-eslint"], - "extends": ["airbnb-typescript", "react-app", "prettier"], + "files": ["**/*.{ts,tsx}"], + "plugins": ["@typescript-eslint"], + "extends":[ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended" + ], "parser": "@typescript-eslint/parser", "parserOptions": { - "project": "./tsconfig.json" + "project": "./tsconfig.json" }, "settings": { - "import/resolver": { - "typescript": { - "alwaysTryTypes": true - } - } + "import/resolver": { + "typescript": { + "alwaysTryTypes": true + } + } }, "rules": { - "object-curly-spacing": ["warn", "always"], - "no-unused-vars": [ - "warn", - { - "vars": "all", - "args": "none" - } - ], - "@typescript-eslint/semi": [ - "off" - ], - "@typescript-eslint/no-unused-vars": [ - "warn", - { - "vars": "all", - "args": "none" - } - ], - "max-len": [ - "warn", - { - "code": 100, - "ignoreStrings": true, - "ignoreTemplateLiterals": true, - "ignoreComments": true - } - ], - "prefer-destructuring": [ - "error", - { - "VariableDeclarator": { - "array": false, - "object": true - }, - "AssignmentExpression": { - "array": false, - "object": false - } - }, { - "enforceForRenamedProperties": false - } - ], + "no-unused-vars" : 0, + "@typescript-eslint/ban-types" : 0, + "@typescript-eslint/ban-ts-comment" : 0, + "@typescript-eslint/ban-ts-ignore" : 0, + "@typescript-eslint/explicit-module-boundary-types" : 0, + "@typescript-eslint/member-delimiter-style" : [ 2, - "no-plusplus": [ - "error", - { - "allowForLoopAfterthoughts": true - } - ], - "react/jsx-key": "error", - "import/no-extraneous-dependencies": [ - "error", - { - "devDependencies": [ - "**/*.test.js", - "**/*.test.jsx", - "**/*.test.ts", - "**/*.test.tsx", - "src/tests/**/*" - ] - } - ], - "react/jsx-props-no-spreading": "off", - "import/prefer-default-export": "off", - "react/jsx-boolean-value": "off", - "react/prop-types": "off", - "react/no-unescaped-entities": "off", - "react/jsx-one-expression-per-line": "off", - "react/jsx-wrap-multilines": "off", - "react/destructuring-assignment": "off" + { + "multiline" : { "delimiter": "semi", "requireLast": true }, + "singleline" : { "delimiter": "semi", "requireLast": false } + } + ], + "@typescript-eslint/no-explicit-any" : 0, + "@typescript-eslint/no-unused-vars" : [ 2, + { + "vars" : "all", + "args" : "after-used", + "ignoreRestSiblings" : false + } + ], + "@typescript-eslint/no-use-before-define" : [ 2, { "functions": false } ], + "@typescript-eslint/no-empty-function" : 0, + "@typescript-eslint/no-non-null-assertion" : 0 } } ], diff --git a/app/.prettierrc b/app/.prettierrc index bcbc4f22..41222071 100644 --- a/app/.prettierrc +++ b/app/.prettierrc @@ -3,5 +3,5 @@ "printWidth": 100, "semi": false, "singleQuote": true, - "tabWidth": 2 + "tabWidth": 4 } \ No newline at end of file diff --git a/app/src/config.ts b/app/src/config.ts new file mode 100644 index 00000000..c6269b2d --- /dev/null +++ b/app/src/config.ts @@ -0,0 +1,499 @@ +import convict from 'convict'; +import * as convictFormatWithValidator from 'convict-format-with-validator'; + +convict.addFormat(convictFormatWithValidator.ipaddress); + +const config = convict({ + loginEnabled : + { + doc: 'The login is enabled.', + format: Boolean, + default: false + }, + developmentPort : + { + doc: 'The development server listening port.', + format: Number, + default: 3443 + }, + productionPort : + { + doc: 'The production server listening port.', + format: Number, + default: 443 + }, + serverHostname : + { + doc: 'If the server component runs on a different host than the app you can specify the host name.', + format: '*', + default: null + }, + /** + * Supported browsers version in bowser satisfy format. + * See more: + * https://www.npmjs.com/package/bowser#filtering-browsers + * Otherwise you got a unsupported browser page + */ + supportedBrowsers : + { + doc: 'Supported browsers version in bowser satisfy format.', + format: Object, + default: + { + 'windows' : { + 'internet explorer' : '>12', + 'microsoft edge' : '>18' + }, + 'safari' : '>12', + 'firefox' : '>=60', + 'chrome' : '>=74', + 'chromium' : '>=74', + 'opera' : '>=62', + 'samsung internet for android' : '>=11.1.1.52' + } + }, + /** + * Network priorities + * DSCP bits set by browser according this priority values. + * ("high" means actually: EF for audio, and AF41 for Video in chrome) + * https://en.wikipedia.org/wiki/Differentiated_services + */ + networkPriorities : + { + doc: 'Network priorities.', + format: Object, + default : + { + audio : 'high', + mainVideo : 'high', + additionalVideos : 'medium', + screenShare : 'medium' + } + }, + // The aspect ratio of the videos as shown on the screen. + // This is changeable in client settings. + // This value must match one of the defined values in + // viewAspectRatios EXACTLY (e.g. 1.333) + viewAspectRatio : + { + doc: 'The aspect ratio of the videos as shown on the screen.', + format: Number, + default: 1.777 + }, + viewAspectRatios : + { + doc : 'The selectable aspect ratios in the settings.', + format : Array, + default : + [ + { + value : 1.333, // 4 / 3 + label : '4 : 3' + }, + { + value : 1.777, // 16 / 9 + label : '16 : 9' + } + ], + }, + // The aspect ratio of the video from the camera + // this is not changeable in settings, only config + videoAspectRatio : + { + doc: 'The aspect ratio of the video from the camera.', + format: Number, + default: 1.777 + }, + defaultResolution : + { + doc: 'The default video camera capture resolution.', + format: String, + default: 'medium' + }, + defaultFrameRate : + { + doc: 'The default video camera capture framerate.', + format: Number, + default: 15 + }, + defaultScreenResolution : + { + doc: 'The default screen sharing resolution.', + format: String, + default: 'veryhigh' + }, + defaultScreenSharingFrameRate : + { + doc: 'The default screen sharing framerate.', + format: Number, + default: 5 + }, + simulcast : + { + doc: 'Enable or disable simulcast for webcam video.', + format: Boolean, + default: true + }, + simulcastSharing : + { + doc: 'Enable or disable simulcast for screen sharing video.', + format: Boolean, + default: false + }, + simulcastProfiles : + { + doc: 'Define different encodings for various resolutions of the video.', + format: Object, + default: + { + 3840 : + [ + { scaleResolutionDownBy: 4, maxBitRate: 1500000 }, + { scaleResolutionDownBy: 2, maxBitRate: 4000000 }, + { scaleResolutionDownBy: 1, maxBitRate: 10000000 } + ], + 1920 : + [ + { scaleResolutionDownBy: 4, maxBitRate: 750000 }, + { scaleResolutionDownBy: 2, maxBitRate: 1500000 }, + { scaleResolutionDownBy: 1, maxBitRate: 4000000 } + ], + 1280 : + [ + { scaleResolutionDownBy: 4, maxBitRate: 250000 }, + { scaleResolutionDownBy: 2, maxBitRate: 900000 }, + { scaleResolutionDownBy: 1, maxBitRate: 3000000 } + ], + 640 : + [ + { scaleResolutionDownBy: 2, maxBitRate: 250000 }, + { scaleResolutionDownBy: 1, maxBitRate: 900000 } + ], + 320 : + [ + { scaleResolutionDownBy: 1, maxBitRate: 250000 } + ] + } + }, + // The adaptive spatial layer selection scaling factor (in the range [0.5, 1.0]) + // example: + // with level width=640px, the minimum width required to trigger the + // level change will be: 640 * 0.75 = 480px + adaptiveScalingFactor : + { + doc: 'The adaptive spatial layer selection scaling factor.', + format: (value: number) => value >= 0.5 && value <= 1.0, + default: 0.75 + }, + /** + * White listing browsers that support audio output device selection. + * It is not yet fully implemented in Firefox. + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=1498512 + */ + audioOutputSupportedBrowsers : + { + doc: 'White listing browsers that support audio output device selection.', + format: Array, + default: [ + 'chrome', + 'opera' + ] + }, + requestTimeout : + { + doc: 'The Socket.io request timeout.', + format: Number, + default: 20000 + }, + requestRetries : + { + doc: 'The Socket.io request maximum retries.', + format: Number, + default: 3 + }, + transportOptions : + { + doc: '', + format: Object, + default: { + tcp : true + } + }, + // defaults for audio setting on new clients / can be customized and overruled from client side + defaultAudio : + { + doc: 'Defaults audio settings.', + format: Object, + default : + { + autoGainControl : true, // default : true + echoCancellation : true, // default : true + noiseSuppression : true, // default : true + // Automatically unmute speaking above noisThereshold + voiceActivatedUnmute : false, // default : false + // This is only for voiceActivatedUnmute and audio-indicator + noiseThreshold : -60 // default -60 + } + }, + // Audio options for now only centrally from config file: + centralAudioOptions : + { + doc: 'Defaults audio settings.', + format: Object, + default : + { + // will not eat that much bandwith thanks to opus + sampleRate : 48000, // default : 48000 and don't go higher + // usually mics are mono so this saves bandwidth + channelCount : 1, // default : 1 + volume : 1.0, // default : 1.0 + sampleSize : 16, // default : 16 + // usually mics are mono so this saves bandwidth + opusStereo : false, // default : false + opusDtx : true, // default : true / will save bandwidth + opusFec : true, // default : true / forward error correction + opusPtime : '20', // default : 20 / minimum packet time (3, 5, 10, 20, 40, 60, 120) + opusMaxPlaybackRate : 48000 // default : 48000 and don't go higher + } + }, + /** + * Set max number participants in one room that join + * unmuted. Next participant will join automatically muted + * Default value is 4 + * + * Set it to 0 to auto mute all, + * Set it to negative (-1) to never automatically auto mute + * but use it with caution + * full mesh audio strongly decrease room capacity! + */ + autoMuteThreshold : + { + doc: 'Set max number participants in one room that join unmuted.', + format: Number, + default: 4 + }, + background : + { + doc: 'The page background image URL', + format: String, + default: 'images/background.jpg' + }, + defaultLayout : + { + doc: 'The default layout', + format: [ 'democratic', 'filmstrip' ], + default: 'democratic' + }, + buttonControlBar : + { + doc: 'If true, will show media control buttons in separate control bar, not in the ME container.', + format: Boolean, + default: false + }, + drawerOverlayed : + { + doc: 'If false, will push videos away to make room for side drawer. If true, will overlay side drawer over videos.', + format: Boolean, + default: true + }, + notificationPosition : + { + doc: 'The position of notifications.', + format: [ 'left', 'right' ], + default: 'right' + }, + /** + * Set the notificationSounds. Valid keys are: + * 'parkedPeer', 'parkedPeers', 'raisedHand', 'chatMessage', + * 'sendFile', 'newPeer' and 'default'. + * + * Not defining a key is equivalent to using the default notification sound. + * Setting 'play' to null disables the sound notification. + */ + notificationSounds : + { + doc: 'Set the notifications sounds.', + format: Object, + default : + { + chatMessage : { + play : '/sounds/notify-chat.mp3' + }, + raisedHand : { + play : '/sounds/notify-hand.mp3' + }, + default : { + delay : 5000, // minimum delay between alert sounds [ms] + play : '/sounds/notify.mp3' + } + } + }, + hideTimeout : + { + doc: 'Timeout for autohiding topbar and button control bar.', + format: Number, + default: 3000 + }, + lastN : + { + doc: 'The max number of participant that will be visible in as speaker.', + format: Number, + default: 4 + }, + mobileLastN : + { + doc: 'The max number of participant that will be visible in as speaker for mobile users.', + format: Number, + default: 1 + }, + maxLastN : + { + doc: 'The highest number of lastN the user can select manually in the user interface.', + format: Number, + default: 5 + }, + lockLastN : + { + doc: 'If truthy, users can NOT change number of speakers visible.', + format: Boolean, + default: false + }, + // Show logo if "logo" is not null, else show title + // Set logo file name using logo.* pattern like "logo.png" to not track it by git + logo : + { + doc: 'If not null, it shows the logo loaded from URL, else it shows the title.', + format: String, + default: 'images/logo.edumeet.svg' + }, + title : + { + doc: 'The title to show if the logo is not specified.', + format: String, + default: 'edumeet' + }, + supportUrl : + { + doc: 'Service & Support URL if not set then not displayed on the about modals.', + format: String, + default: 'https://support.example.com' + }, + // Privacy and data protection URL or path by default privacy/privacy.html + // that is a placeholder for your policies + // + // but an external url could be also used here + privacyUrl : + { + doc: 'Privacy and data protection URL or path by default privacy/privacy.html.', + format: String, + default: 'privacy/privacy.html' + }, + // UI theme elements + theme : + { + palette : + { + primary : + { + main : { default: '#313131' } + } + }, + overrides : + { + MuiAppBar : + { + colorPrimary : + { + backgroundColor : { default: '#313131' } + } + }, + MuiButton : + { + containedPrimary : + { + backgroundColor : { default: '#5F9B2D' }, + '&:hover' : + { + backgroundColor : { default: '#5F9B2D' } + } + }, + containedSecondary : + { + backgroundColor : { default: '#f50057' }, + '&:hover' : + { + backgroundColor : { default: '#f50057' } + } + } + + }, + + /* + MuiIconButton : + { + colorPrimary : + { + backgroundColor : '#5F9B2D', + '&:hover' : + { + backgroundColor : '#5F9B2D' + } + }, + colorSecondary : + { + backgroundColor : '#f50057', + '&:hover' : + { + backgroundColor : '#f50057' + } + } + + }, + */ + + MuiFab : + { + primary : + { + backgroundColor : { default: '#5F9B2D' }, + '&:hover' : + { + backgroundColor : { default: '#5F9B2D' } + } + }, + secondary : + { + backgroundColor : { default: '#f50057' }, + '&:hover' : + { + backgroundColor : { default: '#f50057' } + } + } + + }, + MuiBadge : + { + colorPrimary : + { + backgroundColor : { default: '#5F9B2D' }, + '&:hover' : + { + backgroundColor : { default: '#518029' } + } + } + } + }, + typography : + { + useNextVariants : { default: true } + } + } +}); + +// Load config from window object +config.load((window as any).config); + +// Perform validation +config.validate({ allowed: 'strict' }); + +export default config; diff --git a/app/src/translations/locales.ts b/app/src/translations/locales.ts index fd055b09..ac3b2e29 100644 --- a/app/src/translations/locales.ts +++ b/app/src/translations/locales.ts @@ -2,151 +2,157 @@ /* eslint-disable import/no-dynamic-require */ const list = [ - { - name: 'English', - file: 'en', - locale: ['en', 'en-en'], - }, - { - name: 'Czech', - file: 'cs', - locale: ['cs', 'cs-cs'], - }, - { - name: 'Chinese (Simplified)', - file: 'cn', - locale: ['zn', 'zn-zn', 'zn-cn'], - }, // hans - { - name: 'Chinese (Traditional)', - file: 'tw', - locale: ['zn-tw', 'zn-hk', 'zn-sg'], - }, // hant - { - name: 'Croatian', - file: 'hr', - locale: ['hr', 'hr-hr'], - }, - { - name: 'Danish', - file: 'dk', - locale: ['dk', 'dk-dk'], - }, - { - name: 'French', - file: 'fr', - locale: ['fr', 'fr-fr'], - }, - { - name: 'German', - file: 'de', - locale: ['de', 'de-de'], - }, - { - name: 'Greek', - file: 'el', - locale: ['el', 'el-el'], - }, - { - name: 'Hindi', - file: 'hi', - locale: ['hi', 'hi-hi'], - }, - { - name: 'Hungarian', - file: 'hu', - locale: ['hu', 'hu-hu'], - }, - { - name: 'Italian', - file: 'it', - locale: ['it', 'it-it'], - }, - { - name: 'Kazakh', - file: 'kk', - locale: ['kk', 'kk-kz '], - }, - { - name: 'Latvian', - file: 'lv', - locale: ['lv', 'lv-lv'], - }, - { - name: 'Norwegian', - file: 'nb', - locale: ['nb', 'nb-no'], - }, - { - name: 'Polish', - file: 'pl', - locale: ['pl', 'pl-pl'], - }, - { - name: 'Portuguese', - file: 'pt', - locale: ['pt', 'pt-pt'], - }, - { - name: 'Romanian', - file: 'ro', - locale: ['ro', 'ro-ro'], - }, - { - name: 'Russian', - file: 'ru', - locale: ['ru', 'ru-ru'], - }, - { - name: 'Spanish', - file: 'es', - locale: ['es', 'es-es'], - }, - { - name: 'Turkish', - file: 'tr', - locale: ['tr', 'tr-tr'], - }, - { - name: 'Ukrainian', - file: 'uk', - locale: ['uk', 'uk-uk'], - }, -] + { + name : 'English', + file : 'en', + locale : [ 'en', 'en-en' ] + }, + { + name : 'Czech', + file : 'cs', + locale : [ 'cs', 'cs-cs' ] + }, + { + name : 'Chinese (Simplified)', + file : 'cn', + locale : [ 'zn', 'zn-zn', 'zn-cn' ] + }, // hans + { + name : 'Chinese (Traditional)', + file : 'tw', + locale : [ 'zn-tw', 'zn-hk', 'zn-sg' ] + }, // hant + { + name : 'Croatian', + file : 'hr', + locale : [ 'hr', 'hr-hr' ] + }, + { + name : 'Danish', + file : 'dk', + locale : [ 'dk', 'dk-dk' ] + }, + { + name : 'French', + file : 'fr', + locale : [ 'fr', 'fr-fr' ] + }, + { + name : 'German', + file : 'de', + locale : [ 'de', 'de-de' ] + }, + { + name : 'Greek', + file : 'el', + locale : [ 'el', 'el-el' ] + }, + { + name : 'Hindi', + file : 'hi', + locale : [ 'hi', 'hi-hi' ] + }, + { + name : 'Hungarian', + file : 'hu', + locale : [ 'hu', 'hu-hu' ] + }, + { + name : 'Italian', + file : 'it', + locale : [ 'it', 'it-it' ] + }, + { + name : 'Kazakh', + file : 'kk', + locale : [ 'kk', 'kk-kz ' ] + }, + { + name : 'Latvian', + file : 'lv', + locale : [ 'lv', 'lv-lv' ] + }, + { + name : 'Norwegian', + file : 'nb', + locale : [ 'nb', 'nb-no' ] + }, + { + name : 'Polish', + file : 'pl', + locale : [ 'pl', 'pl-pl' ] + }, + { + name : 'Portuguese', + file : 'pt', + locale : [ 'pt', 'pt-pt' ] + }, + { + name : 'Romanian', + file : 'ro', + locale : [ 'ro', 'ro-ro' ] + }, + { + name : 'Russian', + file : 'ru', + locale : [ 'ru', 'ru-ru' ] + }, + { + name : 'Spanish', + file : 'es', + locale : [ 'es', 'es-es' ] + }, + { + name : 'Turkish', + file : 'tr', + locale : [ 'tr', 'tr-tr' ] + }, + { + name : 'Ukrainian', + file : 'uk', + locale : [ 'uk', 'uk-uk' ] + } +]; -export const detect = () => { - const localeFull = (navigator.language || (navigator as any).browserLanguage).toLowerCase() +export const detect = () => +{ + const localeFull = (navigator.language || + (navigator as any).browserLanguage).toLowerCase(); - // const localeCountry = localeFull.split(/[-_]/)[0]; + // const localeCountry = localeFull.split(/[-_]/)[0]; - // const localeRegion = localeFull.split(/[-_]/)[1] || null; + // const localeRegion = localeFull.split(/[-_]/)[1] || null; - return localeFull -} + return localeFull; +}; -export const getList = () => list +export const getList = () => list; export interface ILocale { - name: string - file: string - locale: string[] - messages: any + name: string; + file: string; + locale: string[]; + messages: any; } -export const loadOne = (locale: string): ILocale => { - let res: any = {} +export const loadOne = (locale: string): ILocale => +{ + let res: any = {}; - try { - res = list.filter( - (item) => item.locale.includes(locale) || item.locale.includes(locale.split(/[-_]/)[0]) - )[0] + try + { + res = list.filter( + (item) => item.locale.includes(locale) || item.locale.includes(locale.split(/[-_]/)[0]) + )[0]; - res.messages = require(`./${res.file}`) - } catch { - res = list.filter((item) => item.locale.includes('en'))[0] + res.messages = require(`./${res.file}`); + } + catch + { + res = list.filter((item) => item.locale.includes('en'))[0]; - res.messages = require(`./${res.file}`) - } + res.messages = require(`./${res.file}`); + } - return res -} + return res; +};