deps: i18next 10 -> 23, react-i18next 7 -> 14

Modernizes the whole i18n stack:
- 48 translate([], {wait:true}) / translate() HOCs -> withTranslation()
- react.wait:true -> react.useSuspense:false
- whitelist -> supportedLngs; added compatibilityJSON: 'v3' so our
  natural-language keys + v3 _plural layout keep working (custom
  separators ss/eth/dj preserved)
- backends: xhr -> i18next-http-backend (client), sync-fs ->
  i18next-fs-backend (server); dropped i18next-localstorage-cache
  (was enabled:false); languagedetector 2 -> 8
- ReSendEmail: <Interpolate> (removed in v10) -> <Trans values={{email}}/>,
  dropped the removed bare t export
- saveMissing handler signature (lngs, ns, key, fallbackValue)

Silences the per-component Translate/I18n legacy-context warnings.
Browser-verified es/en switch and <Trans> interpolation on /fires;
REST smoke byte-identical.
This commit is contained in:
vjrj 2026-07-18 06:28:41 +02:00
parent f1eae84e25
commit 12bdbe8fed
52 changed files with 226 additions and 553 deletions

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Page from '../Page/Page';
const About = props => (
@ -16,4 +16,4 @@ const About = props => (
</div>
);
export default translate([], { wait: true })(About);
export default withTranslation()(About);

View file

@ -4,7 +4,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { Bert } from 'meteor/themeteorchef:bert';
import { Meteor } from 'meteor/meteor';
import { T9n } from 'meteor-accounts-t9n';
@ -45,4 +45,4 @@ Auth.propTypes = {
Auth.defaultProps = {
};
export default translate([], { wait: true })(Auth);
export default withTranslation()(Auth);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import Page from '../Page/Page';
const Credits = props => (
@ -16,4 +16,4 @@ const Credits = props => (
</div>
);
export default translate([], { wait: true })(Credits);
export default withTranslation()(Credits);

View file

@ -3,7 +3,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Row, Col } from 'react-bootstrap';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import DistanceSlider from '/imports/ui/components/DistanceSlider/DistanceSlider';
import SelectionMap, { action } from '/imports/ui/components/SelectionMap/SelectionMap';
import Gkeys from '/imports/startup/client/Gkeys';
@ -129,4 +129,4 @@ FireSubscription.propTypes = {
disableFstBtn: PropTypes.bool.isRequired
};
export default translate([], { wait: true })(FireSubscription);
export default withTranslation()(FireSubscription);

View file

@ -5,7 +5,7 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withTracker } from 'meteor/react-meteor-data';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Row, Col, Alert, FormGroup } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
@ -259,7 +259,7 @@ Fire.propTypes = {
Fire.defaultProps = {
};
// export default translate([], { wait: true })(withTracker((props) => {
// export default withTranslation()(withTracker((props) => {
const FireContainer = withTracker(({ match }) => {
const id = match.params.id;
@ -304,4 +304,4 @@ const FireContainer = withTracker(({ match }) => {
})(Fire);
// export default FireContainer;
export default translate([], { wait: true })(FireContainer);
export default withTranslation()(FireContainer);

View file

@ -4,7 +4,7 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import FromNow from '/imports/ui/components/FromNow/FromNow';
class FireStats extends Component {
@ -57,4 +57,4 @@ FireStats.propTypes = {
FireStats.defaultProps = {
};
export default translate([], { wait: true })(FireStats);
export default withTranslation()(FireStats);

View file

@ -10,7 +10,7 @@ import { ReactiveVar } from 'meteor/reactive-var';
import { withTracker } from 'meteor/react-meteor-data';
import { Tracker } from 'meteor/tracker';
import { Helmet } from 'react-helmet-async';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { Map } from 'react-leaflet';
import Control from 'react-leaflet-control';
import LoadingBar from '/imports/ui/components/Loading/LoadingBar';
@ -386,7 +386,7 @@ FiresMap.propTypes = {
let geoInit = true;
export default translate([], { wait: true })(withTracker(() => {
export default withTranslation()(withTracker(() => {
// const firesType = match.params.type;
// const withIndustries = firesType === 'with-industries';
// console.log(`With industries: ${withIndustries}`);

View file

@ -4,7 +4,7 @@
/* eslint-env jquery */
import 'simple-line-icons/css/simple-line-icons.css';
import React, { Component } from 'react';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Helmet } from 'react-helmet-async';
import PropTypes from 'prop-types';
// import { Link } from 'react-router-dom';
@ -335,4 +335,4 @@ Index.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(Index);
export default withTranslation()(Index);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateParseShortFormat } from '/imports/api/Common/dates';
import Page from '../Page/Page';
@ -17,4 +17,4 @@ const License = props => (
</div>
);
export default translate([], { wait: true })(License);
export default withTranslation()(License);

View file

@ -7,7 +7,7 @@ import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import { testId } from '/imports/ui/components/Utils/TestUtils';
import Col from '../../components/Col/Col';
@ -126,4 +126,4 @@ Login.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(Login);
export default withTranslation()(Login);

View file

@ -1,7 +1,7 @@
import React from 'react';
import { Meteor } from 'meteor/meteor';
import Icon from '../../components/Icon/Icon';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Helmet } from 'react-helmet-async';
import './Logout.scss';
@ -30,4 +30,4 @@ class Logout extends React.Component {
Logout.propTypes = {};
export default translate([], { wait: true })(Logout);
export default withTranslation()(Logout);

View file

@ -2,7 +2,7 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import SubscriptionEditor from '../../components/SubscriptionEditor/SubscriptionEditor';
class NewSubscription extends Component {
@ -47,4 +47,4 @@ NewSubscription.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(NewSubscription);
export default withTranslation()(NewSubscription);

View file

@ -1,6 +1,6 @@
import React from 'react';
import { Alert } from 'react-bootstrap';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { Helmet } from 'react-helmet-async';
const NotFound = () => (
@ -16,4 +16,4 @@ const NotFound = () => (
</div>
);
export default translate([], { wait: true })(NotFound);
export default withTranslation()(NotFound);

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateParseShortFormat } from '/imports/api/Common/dates';
import Page from '../Page/Page';
@ -17,4 +17,4 @@ const Privacy = props => (
</div>
);
export default translate([], { wait: true })(Privacy);
export default withTranslation()(Privacy);

View file

@ -9,7 +9,7 @@ import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { testId } from '/imports/ui/components/Utils/TestUtils';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import { withTracker } from 'meteor/react-meteor-data';
import Col from '../../components/Col/Col';
@ -272,7 +272,7 @@ Profile.propTypes = {
i18n: PropTypes.object.isRequired
};
export default translate()(withTracker(() => {
export default withTranslation()(withTracker(() => {
const subscription = Meteor.subscribe('users.editProfile');
return {

View file

@ -8,7 +8,7 @@ import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import AccountPageFooter from '../../components/AccountPageFooter/AccountPageFooter';
import validate from '../../../modules/validate';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
class RecoverPassword extends React.Component {
@ -89,4 +89,4 @@ RecoverPassword.propTypes = {
history: PropTypes.object.isRequired
};
export default translate([], { wait: true })(RecoverPassword);
export default withTranslation()(RecoverPassword);

View file

@ -6,7 +6,7 @@ import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import validate from '../../../modules/validate';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
class ResetPassword extends React.Component {
@ -104,4 +104,4 @@ ResetPassword.propTypes = {
history: PropTypes.object.isRequired,
};
export default translate([], { wait: true })(ResetPassword);
export default withTranslation()(ResetPassword);

View file

@ -1,7 +1,7 @@
/* eslint-disable import/no-absolute-path */
import React from 'react';
// import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
class Sandbox extends React.Component {
componentDidMount() {
@ -21,4 +21,4 @@ Sandbox.propTypes = {
// history: PropTypes.object.isRequired
};
export default translate([], { wait: true })(Sandbox);
export default withTranslation()(Sandbox);

View file

@ -8,7 +8,7 @@ import { Link } from 'react-router-dom';
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { translate, Trans } from 'react-i18next';
import { withTranslation, Trans } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
import { Helmet } from 'react-helmet-async';
import { testId } from '/imports/ui/components/Utils/TestUtils';
@ -213,4 +213,4 @@ Signup.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(Signup);
export default withTranslation()(Signup);

View file

@ -4,7 +4,7 @@
import React, { Fragment, Component } from 'react';
import PropTypes from 'prop-types';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { withTracker } from 'meteor/react-meteor-data';
import Blaze from 'meteor/gadicc:blaze-react-component';
import { Helmet } from 'react-helmet-async';
@ -44,7 +44,7 @@ Status.propTypes = {
Status.defaultProps = {
};
// export default translate([], { wait: true })(Status);
export default translate([], { wait: true })(withTracker(props => ({
// export default withTranslation()(Status);
export default withTranslation()(withTracker(props => ({
// props.something
}))(Status));

View file

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
import { Alert } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { Bert } from 'meteor/themeteorchef:bert';
import { Helmet } from 'react-helmet-async';
import UserSubsToFiresCollection from '/imports/api/Subscriptions/Subscriptions';
@ -127,7 +127,7 @@ Subscriptions.propTypes = {
location: PropTypes.object
};
export default translate([], { wait: true })(withTracker(() => {
export default withTranslation()(withTracker(() => {
const subscription = Meteor.subscribe('mysubscriptions');
// console.log(UserSubsToFiresCollection.find().fetch());
return {

View file

@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
import { Button, ButtonGroup, Row, Col } from 'react-bootstrap';
import { Meteor } from 'meteor/meteor';
import { withTracker } from 'meteor/react-meteor-data';
import { Trans, translate } from 'react-i18next';
import { Trans, withTranslation } from 'react-i18next';
import { Map } from 'react-leaflet';
import { Helmet } from 'react-helmet-async';
import L from 'leaflet';
@ -165,7 +165,7 @@ SubscriptionsMap.propTypes = {
t: PropTypes.func.isRequired
};
export default translate([], { wait: true })(withTracker(() => {
export default withTranslation()(withTracker(() => {
const settingsSubs = Meteor.subscribe('settings');
const userSubs = SiteSettings.findOne({ name: 'subs-public-union' });
const userSubsBounds = SiteSettings.findOne({ name: 'subs-public-union-bounds' });

View file

@ -3,7 +3,7 @@
/* eslint-disable react/jsx-indent */
import React from 'react';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { dateParseShortFormat } from '/imports/api/Common/dates';
import Page from '../Page/Page';
@ -17,4 +17,4 @@ const Terms = props => (
</div>
);
export default translate([], { wait: true })(Terms);
export default withTranslation()(Terms);

View file

@ -5,7 +5,7 @@ import { Meteor } from 'meteor/meteor';
import { Helmet } from 'react-helmet-async';
import { Accounts } from 'meteor/accounts-base';
import { Bert } from 'meteor/themeteorchef:bert';
import { translate } from 'react-i18next';
import { withTranslation } from 'react-i18next';
import { T9n } from 'meteor-accounts-t9n';
class VerifyEmail extends React.Component {
@ -48,4 +48,4 @@ VerifyEmail.propTypes = {
history: PropTypes.object.isRequired
};
export default translate([], { wait: true })(VerifyEmail);
export default withTranslation()(VerifyEmail);