kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Localizable about pages
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>actually-fix-tabs-bar
rodzic
ecbad41bd9
commit
e8ceedd689
|
@ -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_SUCCESS = 'FETCH_ABOUT_PAGE_SUCCESS';
|
||||||
export const FETCH_ABOUT_PAGE_FAIL = 'FETCH_ABOUT_PAGE_FAIL';
|
export const FETCH_ABOUT_PAGE_FAIL = 'FETCH_ABOUT_PAGE_FAIL';
|
||||||
|
|
||||||
export function fetchAboutPage(slug = 'index') {
|
export function fetchAboutPage(slug = 'index', locale) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch({ type: FETCH_ABOUT_PAGE_REQUEST, slug });
|
dispatch({ type: FETCH_ABOUT_PAGE_REQUEST, slug, locale });
|
||||||
return api(getState).get(`/instance/about/${slug}.html`).then(response => {
|
return api(getState).get(`/instance/about/${slug}${locale ? `.${locale}` : ''}.html`).then(response => {
|
||||||
dispatch({ type: FETCH_ABOUT_PAGE_SUCCESS, slug, html: response.data });
|
dispatch({ type: FETCH_ABOUT_PAGE_SUCCESS, slug, locale, html: response.data });
|
||||||
return response.data;
|
return response.data;
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
dispatch({ type: FETCH_ABOUT_PAGE_FAIL, slug, error });
|
dispatch({ type: FETCH_ABOUT_PAGE_FAIL, slug, locale, error });
|
||||||
throw error;
|
throw error;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,6 +47,7 @@ export const defaultConfig = ImmutableMap({
|
||||||
cryptoDonatePanel: ImmutableMap({
|
cryptoDonatePanel: ImmutableMap({
|
||||||
limit: 1,
|
limit: 1,
|
||||||
}),
|
}),
|
||||||
|
aboutPages: ImmutableMap(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export function getSoapboxConfig(state) {
|
export function getSoapboxConfig(state) {
|
||||||
|
|
|
@ -1,18 +1,33 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { fetchAboutPage } from 'soapbox/actions/about';
|
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 {
|
class AboutPage extends ImmutablePureComponent {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
pageHtml: '',
|
pageHtml: '',
|
||||||
|
locale: this.props.locale,
|
||||||
}
|
}
|
||||||
|
|
||||||
loadPageHtml = () => {
|
loadPageHtml = () => {
|
||||||
const { dispatch, match } = this.props;
|
const { dispatch, match, aboutPages } = this.props;
|
||||||
|
const { locale } = this.state;
|
||||||
const { slug } = match.params;
|
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 });
|
this.setState({ pageHtml: html });
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
// TODO: Better error handling. 404 page?
|
// TODO: Better error handling. 404 page?
|
||||||
|
@ -20,17 +35,55 @@ class AboutPage extends ImmutablePureComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setLocale = (locale) => () => {
|
||||||
|
this.setState({ locale });
|
||||||
|
};
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.loadPageHtml();
|
this.loadPageHtml();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps, prevState) {
|
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;
|
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() {
|
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 && (
|
||||||
|
<div className='rich-formatting also-available'>
|
||||||
|
<FormattedMessage id='about.also_available' defaultMessage='Available in:' />
|
||||||
|
{' '}
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href='#' className='sidebar-menu-profile__name' onClick={this.setLocale(defaultLocale)}>
|
||||||
|
{languages[defaultLocale] || defaultLocale}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{
|
||||||
|
page.get('locales').map(locale => (
|
||||||
|
<li key={locale}>
|
||||||
|
<a href='#' className='sidebar-menu-profile__name' onClick={this.setLocale(locale)}>
|
||||||
|
{languages[locale] || locale}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='content'>
|
<div className='content'>
|
||||||
<div className='about-page'>
|
<div className='about-page'>
|
||||||
|
@ -38,6 +91,7 @@ class AboutPage extends ImmutablePureComponent {
|
||||||
className='rich-formatting'
|
className='rich-formatting'
|
||||||
dangerouslySetInnerHTML={{ __html: this.state.pageHtml }}
|
dangerouslySetInnerHTML={{ __html: this.state.pageHtml }}
|
||||||
/>
|
/>
|
||||||
|
{alsoAvailable}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -45,4 +99,4 @@ class AboutPage extends ImmutablePureComponent {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect()(AboutPage);
|
export default AboutPage;
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
} from 'soapbox/features/forms';
|
} from 'soapbox/features/forms';
|
||||||
import SettingsCheckbox from 'soapbox/components/settings_checkbox';
|
import SettingsCheckbox from 'soapbox/components/settings_checkbox';
|
||||||
|
|
||||||
const languages = {
|
export const languages = {
|
||||||
en: 'English',
|
en: 'English',
|
||||||
ar: 'العربية',
|
ar: 'العربية',
|
||||||
ast: 'Asturianu',
|
ast: 'Asturianu',
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"about.also_available": "Strona dostępna w językach:",
|
||||||
"accordion.collapse": "Zwiń",
|
"accordion.collapse": "Zwiń",
|
||||||
"accordion.expand": "Rozwiń",
|
"accordion.expand": "Rozwiń",
|
||||||
"account.add_or_remove_from_list": "Dodaj lub usuń z list",
|
"account.add_or_remove_from_list": "Dodaj lub usuń z list",
|
||||||
|
|
|
@ -359,6 +359,10 @@ $fluid-breakpoint: $maximum-width + 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.also-available {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.public-layout {
|
.public-layout {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--brand-color);
|
background-color: var(--brand-color);
|
||||||
|
|
Ładowanie…
Reference in New Issue