From e8ceedd689b6a7298abe25aa613849447d7c3d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sat, 26 Jun 2021 15:07:45 +0200 Subject: [PATCH] Localizable about pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/about.js | 10 ++-- app/soapbox/actions/soapbox.js | 1 + app/soapbox/features/about/index.js | 64 +++++++++++++++++++++-- app/soapbox/features/preferences/index.js | 2 +- app/soapbox/locales/pl.json | 1 + app/styles/about.scss | 4 ++ 6 files changed, 71 insertions(+), 11 deletions(-) diff --git a/app/soapbox/actions/about.js b/app/soapbox/actions/about.js index a515bdfbb..3752d10da 100644 --- a/app/soapbox/actions/about.js +++ b/app/soapbox/actions/about.js @@ -4,14 +4,14 @@ export const FETCH_ABOUT_PAGE_REQUEST = 'FETCH_ABOUT_PAGE_REQUEST'; export const FETCH_ABOUT_PAGE_SUCCESS = 'FETCH_ABOUT_PAGE_SUCCESS'; export const FETCH_ABOUT_PAGE_FAIL = 'FETCH_ABOUT_PAGE_FAIL'; -export function fetchAboutPage(slug = 'index') { +export function fetchAboutPage(slug = 'index', locale) { return (dispatch, getState) => { - dispatch({ type: FETCH_ABOUT_PAGE_REQUEST, slug }); - return api(getState).get(`/instance/about/${slug}.html`).then(response => { - dispatch({ type: FETCH_ABOUT_PAGE_SUCCESS, slug, html: response.data }); + dispatch({ type: FETCH_ABOUT_PAGE_REQUEST, slug, locale }); + return api(getState).get(`/instance/about/${slug}${locale ? `.${locale}` : ''}.html`).then(response => { + dispatch({ type: FETCH_ABOUT_PAGE_SUCCESS, slug, locale, html: response.data }); return response.data; }).catch(error => { - dispatch({ type: FETCH_ABOUT_PAGE_FAIL, slug, error }); + dispatch({ type: FETCH_ABOUT_PAGE_FAIL, slug, locale, error }); throw error; }); }; diff --git a/app/soapbox/actions/soapbox.js b/app/soapbox/actions/soapbox.js index d7a42e19c..015ab0049 100644 --- a/app/soapbox/actions/soapbox.js +++ b/app/soapbox/actions/soapbox.js @@ -47,6 +47,7 @@ export const defaultConfig = ImmutableMap({ cryptoDonatePanel: ImmutableMap({ limit: 1, }), + aboutPages: ImmutableMap(), }); export function getSoapboxConfig(state) { diff --git a/app/soapbox/features/about/index.js b/app/soapbox/features/about/index.js index df7b41aa2..0ff88bf26 100644 --- a/app/soapbox/features/about/index.js +++ b/app/soapbox/features/about/index.js @@ -1,18 +1,33 @@ import React from 'react'; import { connect } from 'react-redux'; +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { fetchAboutPage } from 'soapbox/actions/about'; +import { getSettings } from 'soapbox/actions/settings'; +import { getSoapboxConfig } from 'soapbox/actions/soapbox'; +import { languages } from '../preferences'; +const mapStateToProps = state => ({ + locale: getSettings(state).get('locale'), + aboutPages: getSoapboxConfig(state).get('aboutPages'), +}); + +@connect(mapStateToProps) +@injectIntl class AboutPage extends ImmutablePureComponent { state = { pageHtml: '', + locale: this.props.locale, } loadPageHtml = () => { - const { dispatch, match } = this.props; + const { dispatch, match, aboutPages } = this.props; + const { locale } = this.state; const { slug } = match.params; - dispatch(fetchAboutPage(slug)).then(html => { + const page = aboutPages.get(slug || 'about'); + const fetchLocale = page && locale !== page.get('default') && page.get('locales').includes(locale); + dispatch(fetchAboutPage(slug, fetchLocale && locale)).then(html => { this.setState({ pageHtml: html }); }).catch(error => { // TODO: Better error handling. 404 page? @@ -20,17 +35,55 @@ class AboutPage extends ImmutablePureComponent { }); } + setLocale = (locale) => () => { + this.setState({ locale }); + }; + componentDidMount() { this.loadPageHtml(); } componentDidUpdate(prevProps, prevState) { - const { slug } = this.props.match.params; + const { locale, match, aboutPages } = this.props; + const { locale: prevLocale, aboutPages: prevAboutPages } = prevProps; + const { locale: stateLocale } = this.props; + const { locale: prevStateLocale } = prevState; + const { slug } = match.params; const { slug: prevSlug } = prevProps.match.params; - if (slug !== prevSlug) this.loadPageHtml(); + if (locale !== prevLocale) this.setState({ locale }); + if (slug !== prevSlug || stateLocale !== prevStateLocale || (!prevAboutPages.get(slug || 'about') && aboutPages.get(slug || 'about'))) + this.loadPageHtml(); } render() { + const { match, aboutPages } = this.props; + const { slug } = match.params; + + const page = aboutPages.get(slug || 'about'); + const defaultLocale = page && page.get('default'); + const alsoAvailable = page && ( +
+ + {' '} + +
+ ); + return (
@@ -38,6 +91,7 @@ class AboutPage extends ImmutablePureComponent { className='rich-formatting' dangerouslySetInnerHTML={{ __html: this.state.pageHtml }} /> + {alsoAvailable}
); @@ -45,4 +99,4 @@ class AboutPage extends ImmutablePureComponent { } -export default connect()(AboutPage); +export default AboutPage; diff --git a/app/soapbox/features/preferences/index.js b/app/soapbox/features/preferences/index.js index 7d188afc6..5bed02edf 100644 --- a/app/soapbox/features/preferences/index.js +++ b/app/soapbox/features/preferences/index.js @@ -15,7 +15,7 @@ import { } from 'soapbox/features/forms'; import SettingsCheckbox from 'soapbox/components/settings_checkbox'; -const languages = { +export const languages = { en: 'English', ar: 'العربية', ast: 'Asturianu', diff --git a/app/soapbox/locales/pl.json b/app/soapbox/locales/pl.json index 532770f18..9703f3dd8 100644 --- a/app/soapbox/locales/pl.json +++ b/app/soapbox/locales/pl.json @@ -1,4 +1,5 @@ { + "about.also_available": "Strona dostępna w językach:", "accordion.collapse": "Zwiń", "accordion.expand": "Rozwiń", "account.add_or_remove_from_list": "Dodaj lub usuń z list", diff --git a/app/styles/about.scss b/app/styles/about.scss index a1b20544b..39ce9cd54 100644 --- a/app/styles/about.scss +++ b/app/styles/about.scss @@ -359,6 +359,10 @@ $fluid-breakpoint: $maximum-width + 20px; } } +.also-available { + margin-top: 0; +} + .public-layout { position: relative; background-color: var(--brand-color);