From 5e323338f4ffd1bcb6422f37d61be9f51df39b59 Mon Sep 17 00:00:00 2001 From: Adam Butterworth Date: Wed, 10 Apr 2019 16:09:51 -0400 Subject: [PATCH] feat: lookup language preference in cookie (#148) * feat: lookup language preference in cookie * fix: skip unsupported languages in user settings lookups --- config/webpack.dev.config.js | 1 + config/webpack.prod.config.js | 1 + package-lock.json | 43 ++++++++++------------------------- package.json | 1 + src/config/environment.js | 1 + src/i18n/i18n-loader.js | 22 ++++++++++++++---- 6 files changed, 34 insertions(+), 35 deletions(-) diff --git a/config/webpack.dev.config.js b/config/webpack.dev.config.js index 7826df0..098ea2a 100755 --- a/config/webpack.dev.config.js +++ b/config/webpack.dev.config.js @@ -120,6 +120,7 @@ module.exports = Merge.smart(commonConfig, { ACCESS_TOKEN_COOKIE_NAME: 'edx-jwt-cookie-header-payload', USER_INFO_COOKIE_NAME: 'edx-user-info', CSRF_COOKIE_NAME: 'csrftoken', + LANGUAGE_PREFERENCE_COOKIE_NAME: 'openedx-language-preference', SITE_NAME: 'edX', MARKETING_SITE_BASE_URL: 'http://localhost:18000', SUPPORT_URL: 'http://localhost:18000/support', diff --git a/config/webpack.prod.config.js b/config/webpack.prod.config.js index dc5089c..f18040d 100755 --- a/config/webpack.prod.config.js +++ b/config/webpack.prod.config.js @@ -144,6 +144,7 @@ module.exports = Merge.smart(commonConfig, { ACCESS_TOKEN_COOKIE_NAME: null, USER_INFO_COOKIE_NAME: null, CSRF_COOKIE_NAME: 'csrftoken', + LANGUAGE_PREFERENCE_COOKIE_NAME: null, NEW_RELIC_APP_ID: null, NEW_RELIC_LICENSE_KEY: null, SITE_NAME: null, diff --git a/package-lock.json b/package-lock.json index 439019e..1acda53 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2543,7 +2543,7 @@ "integrity": "sha512-APBpZvdQrC1MJWMzk33V7FR2RhBRtnH2QPLqZzS+qia7PixwgWNlnX7UfHjhx+YWkM53GdsZKs40EBkSwADuMA==" }, "@edx/edx-bootstrap": { - "version": "git://github.com/edx/edx-bootstrap.git#6665f3fe77ced299589416e0eb05b9f1697b7c41", + "version": "git://github.com/edx/edx-bootstrap.git#71fd3272d235eb133cccefc1ce63f35a7696bf28", "from": "git://github.com/edx/edx-bootstrap.git#update-with-documentation-site", "requires": { "@fortawesome/fontawesome-svg-core": "^1.2.13", @@ -10398,8 +10398,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -10420,14 +10419,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -10442,20 +10439,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -10572,8 +10566,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -10585,7 +10578,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -10600,7 +10592,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -10608,14 +10599,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -10634,7 +10623,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -10715,8 +10703,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -10728,7 +10715,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -10814,8 +10800,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -10851,7 +10836,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -10871,7 +10855,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -10915,14 +10898,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 0631f28..6f601f1 100755 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "redux-saga": "^1.0.1", "redux-thunk": "^2.2.0", "reselect": "^4.0.0", + "universal-cookie": "^3.1.0", "webpack-rtl-plugin": "^2.0.0", "whatwg-fetch": "^2.0.3" }, diff --git a/src/config/environment.js b/src/config/environment.js index cc7a580..ec272c9 100644 --- a/src/config/environment.js +++ b/src/config/environment.js @@ -12,6 +12,7 @@ export const configuration = { ACCESS_TOKEN_COOKIE_NAME: process.env.ACCESS_TOKEN_COOKIE_NAME, USER_INFO_COOKIE_NAME: process.env.USER_INFO_COOKIE_NAME, CSRF_COOKIE_NAME: process.env.CSRF_COOKIE_NAME, + LANGUAGE_PREFERENCE_COOKIE_NAME: process.env.LANGUAGE_PREFERENCE_COOKIE_NAME, ENVIRONMENT: process.env.NODE_ENV, ACCOUNTS_API_BASE_URL: `${process.env.LMS_BASE_URL}/api/user/v1/accounts`, PREFERENCES_API_BASE_URL: `${process.env.LMS_BASE_URL}/api/user/v1/preferences`, diff --git a/src/i18n/i18n-loader.js b/src/i18n/i18n-loader.js index f8dd2f2..e860a1d 100644 --- a/src/i18n/i18n-loader.js +++ b/src/i18n/i18n-loader.js @@ -13,6 +13,7 @@ */ import { addLocaleData } from 'react-intl'; +import Cookies from 'universal-cookie'; import arLocale from 'react-intl/locale-data/ar'; import enLocale from 'react-intl/locale-data/en'; @@ -46,10 +47,6 @@ LANGUAGES.registerLocale(require('@cospired/i18n-iso-languages/langs/en.json')); LANGUAGES.registerLocale(require('@cospired/i18n-iso-languages/langs/es.json')); LANGUAGES.registerLocale(require('@cospired/i18n-iso-languages/langs/fr.json')); -// TODO (ARCH-563): this should ultimately come from the user's settings, but for now, set your -// browser language to the language you want to see -const getLocale = (localeStr = window.navigator.language) => localeStr.substr(0, 2); - const messages = { // current fallback strategy is to use the first two letters of the locale code ar: arMessages, es: es419Messages, @@ -57,6 +54,23 @@ const messages = { // current fallback strategy is to use the first two letters zh: zhcnMessages, }; +const cookies = new Cookies(); + +// Get the locale by setting priority. Skip if we don't support that language. +const getLocale = (localeStr) => { + // 1. Explicit application request + if (localeStr && messages[localeStr] !== undefined) { + return localeStr; + } + // 2. User setting in cookie + const cookieLanguagePreference = cookies.get(process.env.LANGUAGE_PREFERENCE_COOKIE_NAME); + if (cookieLanguagePreference && messages[cookieLanguagePreference] !== undefined) { + return cookieLanguagePreference; + } + // 3. Browser language (default) + return window.navigator.language.substr(0, 2); +}; + const getMessages = (locale = getLocale()) => messages[locale]; const rtlLocales = ['ar', 'he', 'fa', 'ur'];