diff --git a/Dockerfile.onbuild b/Dockerfile.onbuild index 3e837aad6..85becf461 100644 --- a/Dockerfile.onbuild +++ b/Dockerfile.onbuild @@ -7,6 +7,7 @@ ONBUILD ARG TALK_REPLY_COMMENTS_LOAD_DEPTH=3 ONBUILD ARG TALK_THREADING_LEVEL=3 ONBUILD ARG TALK_DEFAULT_STREAM_TAB=all ONBUILD ARG TALK_DEFAULT_LANG=en +ONBUILD ARG TALK_WHITELISTED_LANGUAGES ONBUILD ARG TALK_PLUGINS_JSON ONBUILD ARG TALK_WEBPACK_SOURCE_MAP @@ -20,4 +21,4 @@ ONBUILD COPY . /usr/src/app ONBUILD RUN cli plugins reconcile && \ yarn && \ yarn build && \ - yarn cache clean \ No newline at end of file + yarn cache clean diff --git a/client/coral-admin/src/routes/Moderation/components/Comment.css b/client/coral-admin/src/routes/Moderation/components/Comment.css index 0f8f91a97..dd5f0637c 100644 --- a/client/coral-admin/src/routes/Moderation/components/Comment.css +++ b/client/coral-admin/src/routes/Moderation/components/Comment.css @@ -1,5 +1,4 @@ @custom-media --big-viewport (min-width: 780px); - .root { border-bottom: 1px solid #e0e0e0; font-size: 18px; @@ -13,7 +12,6 @@ margin-top: 13px; min-height: 0; outline: 0; - /* Fix rendering issues in Safari by promoting this into its own layer. @@ -21,7 +19,6 @@ https://www.pivotaltracker.com/story/show/151142211 */ transform: translateZ(0); - &:last-child { border-bottom: none; } @@ -39,7 +36,6 @@ display: flex; align-items: center; justify-content: space-between; - } .author { @@ -74,7 +70,7 @@ max-width: 500px; font-weight: 300; font-size: 16px; - word-break: break-all; + overflow-wrap: break-word; } .created { @@ -95,7 +91,6 @@ font-weight: 500; line-height: 1.2; max-width: 500px; - a { display: inline-block; color: #063b9a; @@ -103,17 +98,15 @@ font-weight: 500; letter-spacing: .5px; margin-left: 10px; - font-size: 13px; margin-left: 5px; padding-bottom: 0px; border-bottom: solid 1px; line-height: 16px; - &:hover { opacity: .9; cursor: pointer; - } + } } } @@ -138,12 +131,10 @@ cursor: pointer; font-weight: normal; white-space: nowrap; - &:hover { text-decoration: underline; opacity: .9; } - i { font-size: 12px; position: relative; @@ -172,7 +163,6 @@ align-items: center; justify-content: flex-end; margin-right: 14px; - i { margin-right: 5px; } @@ -181,7 +171,6 @@ @media (--big-viewport) { .root { margin-bottom: 30px; - &:last-child { border-bottom: 1px solid #e0e0e0; } @@ -190,7 +179,6 @@ .commentContent { display: flex; - blockquote { font-size: inherit; line-height: inherit; diff --git a/client/coral-framework/services/i18n.js b/client/coral-framework/services/i18n.js index 02258a585..42a0b2030 100644 --- a/client/coral-framework/services/i18n.js +++ b/client/coral-framework/services/i18n.js @@ -39,7 +39,20 @@ import pt_BR from '../../../locales/pt_BR.yml'; import zh_CN from '../../../locales/zh_CN.yml'; import zh_TW from '../../../locales/zh_TW.yml'; -export const defaultLocale = process.env.TALK_DEFAULT_LANG.replace(/-/g, '_'); +// the list of languages that are whitelisted. If false, all languages that are +// supported by Talk will be enabled. +const whitelistedLanguages = + process.env.TALK_WHITELISTED_LANGUAGES && + process.env.TALK_WHITELISTED_LANGUAGES.split(',').map(l => l.trim()); + +// The default language. If the whitelisted languages is specified and the +// default language is not in that list, then the first language in the +// whitelisted list will be used as the default. +export const defaultLocale = whitelistedLanguages + ? !whitelistedLanguages.includes(process.env.TALK_DEFAULT_LANG) + ? whitelistedLanguages[0] + : process.env.TALK_DEFAULT_LANG + : process.env.TALK_DEFAULT_LANG; export const translations = { ...ar, @@ -64,10 +77,14 @@ let TIMEAGO_INSTANCE; // to the default language. const detectLanguage = () => first( - negotiateLanguages(navigator.languages, supportedLocales, { - defaultLocale, - strategy: 'lookup', - }) + negotiateLanguages( + navigator.languages, + whitelistedLanguages || supportedLocales, + { + defaultLocale, + strategy: 'lookup', + } + ) ); export function setupTranslations() { diff --git a/config.js b/config.js index 77ed4ab2b..4ce755f93 100644 --- a/config.js +++ b/config.js @@ -36,6 +36,13 @@ const CONFIG = { // rendered text. DEFAULT_LANG: process.env.TALK_DEFAULT_LANG || 'en', + // WHITELISTED_LANGUAGES is a comma separated list of language/locales that + // should be supported. If the default language is not included in the + // whitelist list, the first entry will be used as the default. + WHITELISTED_LANGUAGES: + process.env.TALK_WHITELISTED_LANGUAGES && + process.env.TALK_WHITELISTED_LANGUAGES.split(',').map(l => l.trim()), + // When TRUE, it ensures that database indexes created in core will not add // indexes. CREATE_MONGO_INDEXES: process.env.DISABLE_CREATE_MONGO_INDEXES !== 'TRUE', @@ -317,6 +324,17 @@ CONFIG.JWT_COOKIE_NAMES = uniq( ]) ); +//------------------------------------------------------------------------------ +// Locale validation +//------------------------------------------------------------------------------ + +if ( + CONFIG.WHITELISTED_LANGUAGES && + !CONFIG.WHITELISTED_LANGUAGES.includes(CONFIG.DEFAULT_LANG) +) { + CONFIG.DEFAULT_LANG = CONFIG.WHITELISTED_LANGUAGES[0]; +} + //------------------------------------------------------------------------------ // External database url's //------------------------------------------------------------------------------ diff --git a/docs/source/02-02-advanced-configuration.md b/docs/source/02-02-advanced-configuration.md index c4f86dbb8..13ad2c35a 100644 --- a/docs/source/02-02-advanced-configuration.md +++ b/docs/source/02-02-advanced-configuration.md @@ -31,6 +31,21 @@ image you can specify it with `--build-arg TALK_DEFAULT_LANG=en`. Specify the default translation language. (Default `en`) +## TALK_WHITELISTED_LANGUAGES + +This is a **Build Variable** and must be consumed during build. If using the +[Docker-onbuild](/talk/installation-from-docker/#onbuild) +image you can specify it with `--build-arg TALK_WHITELISTED_LANGUAGES=en`. + +Specify the comma separated whitelisted languages that you want the Talk +application to serve. This will override the available set of languages that +Talk will allow to be served. + +If the [TALK_DEFAULT_LANG](#talk-default-lang) is not included in this list of +whitelisted languages, then the first whitelisted language will become the +default language. If this parameter is empty, then all languages supported by +Talk will be whitelisted. (Default '') + ## TALK_DEFAULT_STREAM_TAB This is a **Build Variable** and must be consumed during build. If using the diff --git a/services/i18n.js b/services/i18n.js index 52c34a4ed..0a99f1aa0 100644 --- a/services/i18n.js +++ b/services/i18n.js @@ -8,7 +8,7 @@ const { const { first, get, has, merge, isUndefined } = require('lodash'); const yaml = require('yamljs'); const plugins = require('./plugins'); -const { DEFAULT_LANG } = require('../config'); +const { DEFAULT_LANG, WHITELISTED_LANGUAGES } = require('../config'); const resolve = (...paths) => path.resolve(path.join(__dirname, '..', 'locales', ...paths)); @@ -105,10 +105,14 @@ const i18n = { // negotiate the language. const lang = first( - negotiateLanguages(acceptsLanguages, supportedLocales, { - defaultLocale: DEFAULT_LANG, - strategy: 'lookup', - }) + negotiateLanguages( + acceptsLanguages, + WHITELISTED_LANGUAGES || supportedLocales, + { + defaultLocale: DEFAULT_LANG, + strategy: 'lookup', + } + ) ); debug(`decided language as '${lang}'`); diff --git a/webpack.config.js b/webpack.config.js index c6b3a770f..6914499bf 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -169,6 +169,7 @@ const config = { TALK_REPLY_COMMENTS_LOAD_DEPTH: '3', TALK_DEFAULT_STREAM_TAB: 'all', TALK_DEFAULT_LANG: 'en', + TALK_WHITELISTED_LANGUAGES: '', }), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),