From 656128a86a9920f84cba8e2aa8644ff7ea2e87fe Mon Sep 17 00:00:00 2001
From: styiannis <1515939+styiannis@users.noreply.github.com>
Date: Sat, 17 Jul 2021 20:46:03 +0300
Subject: [PATCH] added languages menu options
---
.../page-layout/PageHeader/HeaderRight.jsx | 77 +++++++++++++++----
.../PageHeader/LanguageOptions.scss | 39 ++++++++++
.../PageHeader/LanguageOptions.tsx | 65 ++++++++++++++++
.../page-layout/PageHeader/PageHeader.scss | 1 -
.../static/js/utils/contexts/HeaderContext.js | 34 +++++---
5 files changed, 189 insertions(+), 27 deletions(-)
create mode 100644 frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.scss
create mode 100644 frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.tsx
diff --git a/frontend/src/static/js/components/page-layout/PageHeader/HeaderRight.jsx b/frontend/src/static/js/components/page-layout/PageHeader/HeaderRight.jsx
index 8fe9fb6..ad1b6e7 100644
--- a/frontend/src/static/js/components/page-layout/PageHeader/HeaderRight.jsx
+++ b/frontend/src/static/js/components/page-layout/PageHeader/HeaderRight.jsx
@@ -13,8 +13,37 @@ import {
UserThumbnail,
} from '../../_shared';
import { HeaderThemeSwitcher } from './HeaderThemeSwitcher';
+import { LanguageOptions } from './LanguageOptions';
-function headerPopupPages(user, popupNavItems, hasHeaderThemeSwitcher) {
+const OpenThemeSwitcher = () => {
+ const { t } = useTranslation();
+ return (
+
+
+
+ arrow_back
+
+
+ {t('Switch theme')}
+
+ );
+};
+
+const OpenLanguageOptions = () => {
+ const { t } = useTranslation();
+ return (
+
+
+
+ arrow_back
+
+
+ {t('Language')}
+
+ );
+};
+
+function headerPopupPages(user, popupNavItems, hasHeaderThemeSwitcher, hasTranslations) {
const pages = {
main: null,
};
@@ -65,14 +94,7 @@ function headerPopupPages(user, popupNavItems, hasHeaderThemeSwitcher) {
pages['switch-theme'] = (
-
-
-
- arrow_back
-
-
- Switch theme
-
+
@@ -81,15 +103,29 @@ function headerPopupPages(user, popupNavItems, hasHeaderThemeSwitcher) {
);
}
+ if (hasTranslations) {
+ pages['language'] = (
+
+ );
+ }
+
return pages;
}
function UploadMediaButton({ user, links }) {
+ const { t } = useTranslation();
return !user.is.anonymous && user.can.addMedia ? (
-
+
- Upload media
+ {t('Upload media')}
) : null;
@@ -106,9 +142,9 @@ function LoginButton({ user, link, hasHeaderThemeSwitcher }) {
className={
'button-link sign-in' + (hasHeaderThemeSwitcher ? ' hidden-only-in-small' : ' hidden-only-in-extra-small')
}
- title="{t('Sign in')}"
+ title="{t('SIGN IN')}"
>
- {t('Sign in')}
+ {t('SIGN IN')}
) : null;
@@ -125,9 +161,9 @@ function RegisterButton({ user, link, hasHeaderThemeSwitcher }) {
'button-link register-link' +
(hasHeaderThemeSwitcher ? ' hidden-only-in-small' : ' hidden-only-in-extra-small')
}
- title="{t('Register')}"
+ title="{t('REGISTER')}"
>
- {t('Register')}
+ {t('REGISTER')}
) : null;
@@ -157,7 +193,9 @@ export function HeaderRight(props) {
@@ -173,7 +211,12 @@ export function HeaderRight(props) {
diff --git a/frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.scss b/frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.scss
new file mode 100644
index 0000000..07e87b3
--- /dev/null
+++ b/frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.scss
@@ -0,0 +1,39 @@
+@import '../../../../css/includes/_variables.scss';
+@import '../../../../css/includes/_variables_dimensions.scss';
+
+.language-options {
+ position: relative;
+ width: 100%;
+ padding: 12px 0;
+}
+
+.language-option {
+ display: block;
+
+ button {
+ display: block;
+ width: 100%;
+ padding: 0 24px 0 64px;
+ line-height: 40px;
+ text-align: inherit;
+ color: inherit;
+ border: 0;
+ background: 0;
+
+ .material-icons {
+ margin-right: 16px;
+ color: var(--header-popup-menu-icon-color);
+ }
+
+ &:focus,
+ &:hover {
+ background-color: var(--in-popup-nav-menu-item-hover-bg-color);
+ }
+ }
+
+ &.selected-language {
+ button {
+ padding-left: 24px;
+ }
+ }
+}
diff --git a/frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.tsx b/frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.tsx
new file mode 100644
index 0000000..82b8f4e
--- /dev/null
+++ b/frontend/src/static/js/components/page-layout/PageHeader/LanguageOptions.tsx
@@ -0,0 +1,65 @@
+import React, { useContext, useEffect, useState } from 'react';
+import { useTranslation } from 'react-i18next';
+import { BrowserCache } from '../../../utils/classes';
+import { SiteContext } from '../../../utils/contexts';
+import { enabled as langEnabled, labels as langLabels } from '../../../utils/languages';
+import { MaterialIcon } from '../../_shared';
+
+import './LanguageOptions.scss';
+
+interface LanguageOptionProps {
+ code: string;
+ label: string;
+ active: boolean;
+}
+
+export const LanguageOption: React.FC = ({ code, label, active }) => {
+ const { i18n } = useTranslation();
+ const onClick = () => i18n.changeLanguage(code);
+ return (
+
+
+
+ );
+};
+
+export const LanguageOptions: React.FC = () => {
+ const site = useContext(SiteContext);
+ const [browserCache, setBrowserCache] = useState(null);
+
+ const { i18n } = useTranslation();
+ const [languages, setLanguages] = useState([]);
+ const [current, setCurrent] = useState(i18n.language);
+
+ useEffect(() => {
+ // @ts-ignore
+ setBrowserCache(new BrowserCache('MediaCMS[' + site.id + '][language]', 86400));
+ }, [site.id]);
+
+ useEffect(() => {
+ setCurrent(i18n.language);
+ if (browserCache) {
+ // @ts-ignore
+ browserCache.set('code', i18n.language);
+ }
+ }, [i18n.language]);
+
+ useEffect(() => {
+ const lang: string[] = [];
+ for (let k in langEnabled) {
+ lang.push(langEnabled[k]);
+ }
+ setLanguages(lang);
+ }, []);
+
+ return (
+
+ {languages.map((code) => (
+
+ ))}
+
+ );
+};
diff --git a/frontend/src/static/js/components/page-layout/PageHeader/PageHeader.scss b/frontend/src/static/js/components/page-layout/PageHeader/PageHeader.scss
index 7d00ee1..21dc53a 100755
--- a/frontend/src/static/js/components/page-layout/PageHeader/PageHeader.scss
+++ b/frontend/src/static/js/components/page-layout/PageHeader/PageHeader.scss
@@ -196,7 +196,6 @@ $__button-link-horizontal-padding: 16;
font-weight: 500;
line-height: 1;
display: block;
- text-transform: uppercase;
}
.signin-icon-link {
diff --git a/frontend/src/static/js/utils/contexts/HeaderContext.js b/frontend/src/static/js/utils/contexts/HeaderContext.js
index 376609d..4f9c0a4 100644
--- a/frontend/src/static/js/utils/contexts/HeaderContext.js
+++ b/frontend/src/static/js/utils/contexts/HeaderContext.js
@@ -1,4 +1,5 @@
import React, { createContext } from 'react';
+import i18next from 'i18next';
import { config as mediacmsConfig } from '../settings/config.js';
const config = mediacmsConfig(window.MediaCMS);
@@ -8,6 +9,7 @@ const theme = config.theme;
const user = config.member;
const hasThemeSwitcher = theme.switch.enabled && 'header' === theme.switch.position;
+const hasTranslations = true;
function popupTopNavItems() {
const items = [];
@@ -17,7 +19,7 @@ function popupTopNavItems() {
items.push({
link: links.user.addMedia,
icon: 'video_call',
- text: 'Upload media',
+ text: i18next.t('Upload media'),
itemAttr: {
className: 'visible-only-in-small',
},
@@ -27,7 +29,7 @@ function popupTopNavItems() {
items.push({
link: user.pages.media,
icon: 'video_library',
- text: 'My media',
+ text: i18next.t('My media'),
});
}
}
@@ -35,7 +37,7 @@ function popupTopNavItems() {
items.push({
link: links.signout,
icon: 'exit_to_app',
- text: 'Sign out',
+ text: i18next.t('Sign out'),
});
}
@@ -50,7 +52,7 @@ function popupMiddleNavItems() {
itemType: 'open-subpage',
icon: 'brightness_4',
iconPos: 'left',
- text: 'Switch theme',
+ text: i18next.t('Switch theme'),
buttonAttr: {
className: 'change-page',
'data-page-id': 'switch-theme',
@@ -58,6 +60,19 @@ function popupMiddleNavItems() {
});
}
+ if (hasTranslations) {
+ items.push({
+ itemType: 'open-subpage',
+ icon: 'language',
+ iconPos: 'left',
+ text: i18next.t('Language'),
+ buttonAttr: {
+ className: 'change-page',
+ 'data-page-id': 'language',
+ },
+ });
+ }
+
if (user.is.anonymous) {
if (user.can.login) {
items.push({
@@ -77,7 +92,7 @@ function popupMiddleNavItems() {
itemType: 'link',
icon: 'person_add',
iconPos: 'left',
- text: 'Register',
+ text: i18next.t('Register'),
link: links.register,
linkAttr: {
className: hasThemeSwitcher ? 'visible-only-in-small' : 'visible-only-in-extra-small',
@@ -88,14 +103,14 @@ function popupMiddleNavItems() {
items.push({
link: links.user.editProfile,
icon: 'brush',
- text: 'Edit profile',
+ text: i18next.t('Edit profile'),
});
if (user.can.changePassword) {
items.push({
link: links.changePassword,
icon: 'lock',
- text: 'Change password',
+ text: i18next.t('Change password'),
});
}
}
@@ -110,7 +125,7 @@ function popupBottomNavItems() {
items.push({
link: links.admin,
icon: 'admin_panel_settings',
- text: 'MediaCMS administration',
+ text: `MediaCMS ${i18next.t('administration')}`,
});
}
@@ -119,6 +134,7 @@ function popupBottomNavItems() {
export const HeaderContext = createContext({
hasThemeSwitcher,
+ hasTranslations,
popupNavItems: {
top: popupTopNavItems(),
middle: popupMiddleNavItems(),
@@ -126,4 +142,4 @@ export const HeaderContext = createContext({
},
});
-export const HeaderConsumer = HeaderContext.Consumer;
\ No newline at end of file
+export const HeaderConsumer = HeaderContext.Consumer;