Remove access to global state from i18n/i18n (#26750)

Этот коммит содержится в:
Harrison Healey
2024-04-22 13:32:55 -04:00
коммит произвёл GitHub
родитель f3b80f77a6
Коммит b091ef5686
8 изменённых файлов: 62 добавлений и 27 удалений

Просмотреть файл

@@ -7,6 +7,7 @@ import type {Dispatch} from 'redux';
import timezones from 'timezones.json';
import {CollapsedThreads} from '@mattermost/types/config';
import type {UserProfile} from '@mattermost/types/users';
import {savePreferences} from 'mattermost-redux/actions/preferences';
import {autoUpdateTimezone} from 'mattermost-redux/actions/timezone';
@@ -17,14 +18,19 @@ import {getCurrentTimezoneFull, getCurrentTimezoneLabel} from 'mattermost-redux/
import {getCurrentUserId, getUser} from 'mattermost-redux/selectors/entities/users';
import {getUserCurrentTimezone} from 'mattermost-redux/utils/timezone_utils';
import {getLanguages, isLanguageAvailable} from 'i18n/i18n';
import {Preferences} from 'utils/constants';
import type {GlobalState} from 'types/store';
import UserSettingsDisplay from './user_settings_display';
type OwnProps = {
user: UserProfile;
}
export function makeMapStateToProps() {
return (state: GlobalState) => {
return (state: GlobalState, props: OwnProps) => {
const config = getConfig(state);
const currentUserId = getCurrentUserId(state);
const userTimezone = getCurrentTimezoneFull(state);
@@ -33,7 +39,6 @@ export function makeMapStateToProps() {
const timezoneLabel = getCurrentTimezoneLabel(state);
const allowCustomThemes = config.AllowCustomThemes === 'true';
const enableLinkPreviews = config.EnableLinkPreviews === 'true';
const defaultClientLocale = config.DefaultClientLocale as string;
const enableThemeSelection = config.EnableThemeSelection === 'true';
const lockTeammateNameDisplay = getLicense(state).LockTeammateNameDisplay === 'true' && config.LockTeammateNameDisplay === 'true';
const configTeammateNameDisplay = config.TeammateNameDisplay as string;
@@ -45,12 +50,18 @@ export function makeMapStateToProps() {
lastActiveDisplay = false;
}
let userLocale = props.user.locale;
if (!isLanguageAvailable(state, userLocale)) {
userLocale = config.DefaultClientLocale as string;
}
return {
lockTeammateNameDisplay,
allowCustomThemes,
configTeammateNameDisplay,
enableLinkPreviews,
defaultClientLocale,
locales: getLanguages(state),
userLocale,
enableThemeSelection,
timezones,
timezoneLabel,

Просмотреть файл

@@ -7,8 +7,18 @@ import type {Dispatch} from 'redux';
import {updateMe} from 'mattermost-redux/actions/users';
import {getLanguages} from 'i18n/i18n';
import type {GlobalState} from 'types/store';
import ManageLanguages from './manage_languages';
function mapStateToProps(state: GlobalState) {
return {
locales: getLanguages(state),
};
}
function mapDispatchToProps(dispatch: Dispatch) {
return {
actions: bindActionCreators({
@@ -17,4 +27,4 @@ function mapDispatchToProps(dispatch: Dispatch) {
};
}
export default connect(null, mapDispatchToProps)(ManageLanguages);
export default connect(mapStateToProps, mapDispatchToProps)(ManageLanguages);

Просмотреть файл

@@ -5,6 +5,7 @@ import React from 'react';
import type {UserProfile} from '@mattermost/types/users';
import {getAllLanguages} from 'i18n/i18n';
import {shallowWithIntl} from 'tests/helpers/intl-test-helper';
import ManageLanguages from './manage_languages';
@@ -18,6 +19,7 @@ describe('components/user_settings/display/manage_languages/manage_languages', (
const requiredProps = {
user: user as UserProfile,
locale: 'en',
locales: getAllLanguages(),
updateSection: jest.fn(),
actions: {
updateMe: jest.fn(() => Promise.resolve({})),

Просмотреть файл

@@ -14,7 +14,7 @@ import type {ActionResult} from 'mattermost-redux/types/actions';
import ExternalLink from 'components/external_link';
import SettingItemMax from 'components/setting_item_max';
import * as I18n from 'i18n/i18n.jsx';
import type {Language} from 'i18n/i18n';
import Constants from 'utils/constants';
import {isKeyPressed} from 'utils/keyboard';
@@ -26,6 +26,7 @@ type Props = {
intl: IntlShape;
user: UserProfile;
locale: string;
locales: Record<string, Language>;
updateSection: (section: string) => void;
actions: Actions;
};
@@ -47,11 +48,10 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
reactSelectContainer: React.RefObject<HTMLDivElement>;
constructor(props: Props) {
super(props);
const locales: any = I18n.getLanguages();
const userLocale = props.locale;
const selectedOption = {
value: locales[userLocale].value,
label: locales[userLocale].name,
value: props.locales[userLocale].value,
label: props.locales[userLocale].name,
};
this.reactSelectContainer = React.createRef();
@@ -155,7 +155,8 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
};
render() {
const {intl} = this.props;
const {intl, locales} = this.props;
let serverError;
if (this.state.serverError) {
serverError = (
@@ -164,7 +165,6 @@ export class ManageLanguage extends React.PureComponent<Props, State> {
}
const options: SelectedOption[] = [];
const locales: any = I18n.getLanguages();
const languages = Object.keys(locales).
map((l) => {

Просмотреть файл

@@ -9,6 +9,7 @@ import type {UserProfile} from '@mattermost/types/users';
import configureStore from 'store';
import {getAllLanguages} from 'i18n/i18n';
import {mountWithIntl} from 'tests/helpers/intl-test-helper';
import UserSettingsDisplay from './user_settings_display';
@@ -35,7 +36,8 @@ describe('components/user_settings/display/UserSettingsDisplay', () => {
setEnforceFocus: jest.fn(),
enableLinkPreviews: true,
enableThemeSelection: false,
defaultClientLocale: 'en',
locales: getAllLanguages(),
userLocale: 'en',
canCreatePublicChannel: true,
canCreatePrivateChannel: true,
timezoneLabel: '',

Просмотреть файл

@@ -20,7 +20,8 @@ import SettingItem from 'components/setting_item';
import SettingItemMax from 'components/setting_item_max';
import ThemeSetting from 'components/user_settings/display/user_settings_theme';
import * as I18n from 'i18n/i18n.jsx';
import type {Language} from 'i18n/i18n';
import {getLanguageInfo} from 'i18n/i18n';
import Constants from 'utils/constants';
import {t} from 'utils/i18n';
import {getBrowserTimezone} from 'utils/timezone';
@@ -104,7 +105,8 @@ type Props = {
userTimezone: UserTimezone;
allowCustomThemes: boolean;
enableLinkPreviews: boolean;
defaultClientLocale: string;
locales: Record<string, Language>;
userLocale: string;
enableThemeSelection: boolean;
configTeammateNameDisplay: string;
currentUserTimezone: string;
@@ -1015,11 +1017,8 @@ export default class UserSettingsDisplay extends React.PureComponent<Props, Stat
});
let languagesSection;
let userLocale = this.props.user.locale;
if (!I18n.isLanguageAvailable(userLocale)) {
userLocale = this.props.defaultClientLocale;
}
const localeName = I18n.getLanguageInfo(userLocale).name;
const userLocale = this.props.userLocale;
const localeName = getLanguageInfo(userLocale).name;
languagesSection = (
<div>
@@ -1047,7 +1046,7 @@ export default class UserSettingsDisplay extends React.PureComponent<Props, Stat
</div>
);
if (Object.keys(I18n.getLanguages()).length === 1) {
if (Object.keys(this.props.locales).length === 1) {
languagesSection = null;
}

Просмотреть файл

@@ -1,6 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/**
* @typedef {} Language
*/
/* eslint-disable import/order */
import bg from './bg.json';
import de from './de.json';
@@ -26,8 +30,6 @@ import zhCN from './zh-CN.json';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import store from 'stores/redux_store';
// should match the values in server/public/shared/i18n/i18n.go
const languages = {
de: {
@@ -168,8 +170,12 @@ export function getAllLanguages() {
return languages;
}
export function getLanguages() {
const config = getConfig(store.getState());
/**
* @param {import('types/store').GlobalState} state
* @returns {Record<string, Language>}
*/
export function getLanguages(state) {
const config = getConfig(state);
if (!config.AvailableLocales) {
return getAllLanguages();
}
@@ -185,6 +191,11 @@ export function getLanguageInfo(locale) {
return getAllLanguages()[locale];
}
export function isLanguageAvailable(locale) {
return Boolean(getLanguages()[locale]);
/**
* @param {import('types/store').GlobalState} state
* @param {string} locale
* @returns {boolean}
*/
export function isLanguageAvailable(state, locale) {
return Boolean(getLanguages(state)[locale]);
}

Просмотреть файл

@@ -15,10 +15,10 @@ export function getCurrentLocale(state: GlobalState): string {
// If locale is provided in query parameter and the user is not logged in, we try get locale from param
const localeFromParam: string | null = (new URLSearchParams(window.location?.search)).get('locale');
const defaultLocale: string | undefined =
localeFromParam && I18n.isLanguageAvailable(localeFromParam) ? localeFromParam : getConfig(state).DefaultClientLocale;
localeFromParam && I18n.isLanguageAvailable(state, localeFromParam) ? localeFromParam : getConfig(state).DefaultClientLocale;
const currentLocale: string = getCurrentUserLocale(state, defaultLocale);
if (I18n.isLanguageAvailable(currentLocale)) {
if (I18n.isLanguageAvailable(state, currentLocale)) {
return currentLocale;
}
return General.DEFAULT_LOCALE;