|
@@ -0,0 +1,78 @@
|
|
|
|
+import * as Sentry from '@sentry/react';
|
|
|
|
+import * as moment from 'moment';
|
|
|
|
+import * as qs from 'query-string';
|
|
|
|
+
|
|
|
|
+import {DEFAULT_LOCALE_DATA, setLocale} from 'app/locale';
|
|
|
|
+import {Config} from 'app/types';
|
|
|
|
+
|
|
|
|
+// zh-cn => zh_CN
|
|
|
|
+function convertToDjangoLocaleFormat(language: string) {
|
|
|
|
+ const [left, right] = language.split('-');
|
|
|
|
+ return left + (right ? '_' + right.toUpperCase() : '');
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+async function getTranslations(language: string) {
|
|
|
|
+ language = convertToDjangoLocaleFormat(language);
|
|
|
|
+
|
|
|
|
+ // No need to load the english locale
|
|
|
|
+ if (language === 'en') {
|
|
|
|
+ return DEFAULT_LOCALE_DATA;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ return await import(`sentry-locale/${language}/LC_MESSAGES/django.po`);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ Sentry.withScope(scope => {
|
|
|
|
+ scope.setLevel(Sentry.Severity.Warning);
|
|
|
|
+ scope.setFingerprint(['sentry-locale-not-found']);
|
|
|
|
+ scope.setExtra('locale', language);
|
|
|
|
+ Sentry.captureException(e);
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ // Default locale if not found
|
|
|
|
+ return DEFAULT_LOCALE_DATA;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Initialize locale
|
|
|
|
+ *
|
|
|
|
+ * This *needs* to be initialized as early as possible (e.g. before `app/locale` is used),
|
|
|
|
+ * otherwise the rest of the application will fail to load.
|
|
|
|
+ *
|
|
|
|
+ * Priority:
|
|
|
|
+ *
|
|
|
|
+ * - URL params (`?lang=en`)
|
|
|
|
+ * - User configuration options
|
|
|
|
+ * - "en" as default
|
|
|
|
+ */
|
|
|
|
+export async function initializeLocale(config: Config) {
|
|
|
|
+ let queryString: qs.ParsedQuery = {};
|
|
|
|
+
|
|
|
|
+ // Parse query string for `lang`
|
|
|
|
+ try {
|
|
|
|
+ queryString = qs.parse(window.location.search) || {};
|
|
|
|
+ } catch {
|
|
|
|
+ // ignore if this fails to parse
|
|
|
|
+ // this can happen if we have an invalid query string
|
|
|
|
+ // e.g. unencoded "%"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const queryStringLang = Array.isArray(queryString.lang)
|
|
|
|
+ ? queryString.lang[0]
|
|
|
|
+ : queryString.lang;
|
|
|
|
+ const languageCode = queryStringLang || config.languageCode || 'en';
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ const translations = await getTranslations(languageCode);
|
|
|
|
+ setLocale(translations);
|
|
|
|
+
|
|
|
|
+ // No need to import english
|
|
|
|
+ if (languageCode !== 'en') {
|
|
|
|
+ await import(`moment/locale/${languageCode}`);
|
|
|
|
+ moment.locale(languageCode);
|
|
|
|
+ }
|
|
|
|
+ } catch (err) {
|
|
|
|
+ Sentry.captureException(err);
|
|
|
|
+ }
|
|
|
|
+}
|