mirror of
https://github.com/Qortal/Qortal-Hub.git
synced 2025-06-19 06:11:21 +00:00
Add language selector
This commit is contained in:
parent
a70d77c17e
commit
d627c6a142
11
i18n.js
11
i18n.js
@ -19,6 +19,15 @@ const capitalize = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const supportedLanguages = {
|
||||||
|
de: { name: 'Deutsch', flag: '🇩🇪' },
|
||||||
|
en: { name: 'English', flag: '🇬🇧' },
|
||||||
|
es: { name: 'Español', flag: '🇪🇸' },
|
||||||
|
fr: { name: 'Français', flag: '🇫🇷' },
|
||||||
|
it: { name: 'Italiano', flag: '🇮🇹' },
|
||||||
|
ru: { name: 'Русский', flag: '🇷🇺' },
|
||||||
|
};
|
||||||
|
|
||||||
i18n
|
i18n
|
||||||
.use(HttpApi)
|
.use(HttpApi)
|
||||||
.use(LanguageDetector)
|
.use(LanguageDetector)
|
||||||
@ -43,7 +52,7 @@ i18n
|
|||||||
},
|
},
|
||||||
lng: navigator.language,
|
lng: navigator.language,
|
||||||
ns: ['auth', 'core', 'group', 'tutorial'],
|
ns: ['auth', 'core', 'group', 'tutorial'],
|
||||||
supportedLngs: ['en', 'it', 'es', 'fr', 'de', 'ru'],
|
supportedLngs: Object.keys(supportedLanguages),
|
||||||
});
|
});
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
|
@ -137,6 +137,7 @@ import { GeneralNotifications } from './components/GeneralNotifications';
|
|||||||
import { PdfViewer } from './common/PdfViewer';
|
import { PdfViewer } from './common/PdfViewer';
|
||||||
import ThemeSelector from './components/Theme/ThemeSelector.tsx';
|
import ThemeSelector from './components/Theme/ThemeSelector.tsx';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import LanguageSelector from './components/Language/LanguageSelector.tsx';
|
||||||
|
|
||||||
type extStates =
|
type extStates =
|
||||||
| 'not-authenticated'
|
| 'not-authenticated'
|
||||||
@ -3704,6 +3705,7 @@ function App() {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<LanguageSelector />
|
||||||
<ThemeSelector />
|
<ThemeSelector />
|
||||||
</AppContainer>
|
</AppContainer>
|
||||||
);
|
);
|
||||||
|
@ -31,6 +31,7 @@ import { GlobalContext } from '../App';
|
|||||||
import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip';
|
import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip';
|
||||||
import ThemeSelector from '../components/Theme/ThemeSelector';
|
import ThemeSelector from '../components/Theme/ThemeSelector';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import LanguageSelector from '../components/Language/LanguageSelector';
|
||||||
|
|
||||||
const manifestData = {
|
const manifestData = {
|
||||||
version: '0.5.3',
|
version: '0.5.3',
|
||||||
@ -1097,6 +1098,7 @@ export const NotAuthenticated = ({
|
|||||||
/>
|
/>
|
||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
|
|
||||||
|
<LanguageSelector />
|
||||||
<ThemeSelector />
|
<ThemeSelector />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -15,6 +15,7 @@ import { extractComponents } from '../Chat/MessageDisplay';
|
|||||||
import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
|
import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward';
|
||||||
import { AppsPrivate } from './AppsPrivate';
|
import { AppsPrivate } from './AppsPrivate';
|
||||||
import ThemeSelector from '../Theme/ThemeSelector';
|
import ThemeSelector from '../Theme/ThemeSelector';
|
||||||
|
import LanguageSelector from '../Language/LanguageSelector';
|
||||||
|
|
||||||
export const AppsHomeDesktop = ({
|
export const AppsHomeDesktop = ({
|
||||||
setMode,
|
setMode,
|
||||||
@ -157,6 +158,7 @@ export const AppsHomeDesktop = ({
|
|||||||
/>
|
/>
|
||||||
</AppsContainer>
|
</AppsContainer>
|
||||||
|
|
||||||
|
<LanguageSelector />
|
||||||
<ThemeSelector />
|
<ThemeSelector />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -8,6 +8,7 @@ import { enabledDevModeAtom } from '../atoms/global';
|
|||||||
import { AppsIcon } from '../assets/Icons/AppsIcon';
|
import { AppsIcon } from '../assets/Icons/AppsIcon';
|
||||||
import ThemeSelector from './Theme/ThemeSelector';
|
import ThemeSelector from './Theme/ThemeSelector';
|
||||||
import { CoreSyncStatus } from './CoreSyncStatus';
|
import { CoreSyncStatus } from './CoreSyncStatus';
|
||||||
|
import LanguageSelector from './Language/LanguageSelector';
|
||||||
|
|
||||||
export const DesktopSideBar = ({
|
export const DesktopSideBar = ({
|
||||||
goToHome,
|
goToHome,
|
||||||
@ -139,6 +140,7 @@ export const DesktopSideBar = ({
|
|||||||
</ButtonBase>
|
</ButtonBase>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<LanguageSelector />
|
||||||
<ThemeSelector />
|
<ThemeSelector />
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
73
src/components/Language/LanguageSelector.tsx
Normal file
73
src/components/Language/LanguageSelector.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { supportedLanguages } from '../../../i18n';
|
||||||
|
import { Tooltip } from '@mui/material';
|
||||||
|
|
||||||
|
const LanguageSelector = () => {
|
||||||
|
const { i18n } = useTranslation();
|
||||||
|
const [showSelect, setShowSelect] = useState(false);
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const newLang = e.target.value;
|
||||||
|
i18n.changeLanguage(newLang);
|
||||||
|
setShowSelect(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentLang = i18n.language;
|
||||||
|
const { name, flag } =
|
||||||
|
supportedLanguages[currentLang] || supportedLanguages['en'];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
bottom: '5%',
|
||||||
|
display: 'flex',
|
||||||
|
gap: '12px',
|
||||||
|
left: '1.5vh',
|
||||||
|
position: 'absolute',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Tooltip
|
||||||
|
title="Pollo"
|
||||||
|
// {
|
||||||
|
// themeMode === 'dark'
|
||||||
|
// ? t('core:theme.light', {
|
||||||
|
// postProcess: 'capitalize',
|
||||||
|
// })
|
||||||
|
// : t('core:theme.light', {
|
||||||
|
// postProcess: 'capitalize',
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
>
|
||||||
|
{showSelect ? (
|
||||||
|
<select
|
||||||
|
value={currentLang}
|
||||||
|
onChange={handleChange}
|
||||||
|
onBlur={() => setShowSelect(false)}
|
||||||
|
>
|
||||||
|
{Object.entries(supportedLanguages).map(([code, { name }]) => (
|
||||||
|
<option key={code} value={code}>
|
||||||
|
{code.toUpperCase()} - {name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={() => setShowSelect(true)}
|
||||||
|
style={{
|
||||||
|
fontSize: '1.5rem',
|
||||||
|
border: 'none',
|
||||||
|
background: 'none',
|
||||||
|
cursor: 'pointer',
|
||||||
|
}}
|
||||||
|
aria-label={`Current language: ${name}`}
|
||||||
|
>
|
||||||
|
{flag}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LanguageSelector;
|
@ -14,7 +14,7 @@ const ThemeSelector = () => {
|
|||||||
bottom: '1%',
|
bottom: '1%',
|
||||||
display: 'flex',
|
display: 'flex',
|
||||||
gap: '12px',
|
gap: '12px',
|
||||||
left: '1.5vh',
|
left: '1.2vh',
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user