This commit is contained in:
@@ -1,91 +1,92 @@
|
|||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { Globe } from 'lucide-react';
|
import { Globe } from 'lucide-react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import cls from 'classnames';
|
import cls from 'classnames';
|
||||||
|
|
||||||
import { api } from '~renderer/utils/api';
|
import { api } from '~renderer/utils/api';
|
||||||
import { useLocale } from '~renderer/i18n';
|
import { useLocale } from '~renderer/i18n';
|
||||||
import { type Lang } from '~renderer/i18n/translations';
|
import { type Lang } from '~renderer/i18n/translations';
|
||||||
|
|
||||||
const LOCALES: { value: Lang; code: string; label: string }[] = [
|
const LOCALES: { value: Lang; code: string; label: string }[] = [
|
||||||
{ value: 'enUS', code: 'En', label: 'English' },
|
{ value: 'enUS', code: 'En', label: 'English' },
|
||||||
{ value: 'deDE', code: 'De', label: 'Deutsch' },
|
{ value: 'deDE', code: 'De', label: 'Deutsch' },
|
||||||
{ value: 'zhCN', code: 'Zh', label: '中文' },
|
{ value: 'zhCN', code: 'Zh', label: '中文' },
|
||||||
{ value: 'esES', code: 'Es', label: 'Español' },
|
{ value: 'esES', code: 'Es', label: 'Español' },
|
||||||
{ value: 'ptBR', code: 'Pt', label: 'Português' },
|
{ value: 'ptBR', code: 'Pt', label: 'Português' },
|
||||||
{ value: 'ruRU', code: 'Ru', label: 'Русский' }
|
{ value: 'ruRU', code: 'Ru', label: 'Русский' },
|
||||||
];
|
{ value: 'trTR', code: 'Tr', label: 'Türkçe' }
|
||||||
|
];
|
||||||
const LanguageDropdown = () => {
|
|
||||||
const { lang, setLang, t } = useLocale();
|
const LanguageDropdown = () => {
|
||||||
const setPref = api.preferences.set.useMutation();
|
const { lang, setLang, t } = useLocale();
|
||||||
const code = LOCALES.find(l => l.value === lang)?.code ?? 'En';
|
const setPref = api.preferences.set.useMutation();
|
||||||
|
const code = LOCALES.find(l => l.value === lang)?.code ?? 'En';
|
||||||
const [open, setOpen] = useState(false);
|
|
||||||
const [pos, setPos] = useState<{ top: number; right: number }>();
|
const [open, setOpen] = useState(false);
|
||||||
const btnRef = useRef<HTMLButtonElement>(null);
|
const [pos, setPos] = useState<{ top: number; right: number }>();
|
||||||
|
const btnRef = useRef<HTMLButtonElement>(null);
|
||||||
const toggle = () => {
|
|
||||||
const r = btnRef.current?.getBoundingClientRect();
|
const toggle = () => {
|
||||||
if (r) setPos({ top: r.bottom + 4, right: window.innerWidth - r.right });
|
const r = btnRef.current?.getBoundingClientRect();
|
||||||
setOpen(o => !o);
|
if (r) setPos({ top: r.bottom + 4, right: window.innerWidth - r.right });
|
||||||
};
|
setOpen(o => !o);
|
||||||
|
};
|
||||||
useEffect(() => {
|
|
||||||
if (!open) return;
|
useEffect(() => {
|
||||||
const close = () => setOpen(false);
|
if (!open) return;
|
||||||
window.addEventListener('click', close);
|
const close = () => setOpen(false);
|
||||||
return () => window.removeEventListener('click', close);
|
window.addEventListener('click', close);
|
||||||
}, [open]);
|
return () => window.removeEventListener('click', close);
|
||||||
|
}, [open]);
|
||||||
const pick = (v: Lang) => {
|
|
||||||
setLang(v);
|
const pick = (v: Lang) => {
|
||||||
setPref.mutate({ locale: v });
|
setLang(v);
|
||||||
setOpen(false);
|
setPref.mutate({ locale: v });
|
||||||
};
|
setOpen(false);
|
||||||
|
};
|
||||||
return (
|
|
||||||
<>
|
return (
|
||||||
<button
|
<>
|
||||||
ref={btnRef}
|
<button
|
||||||
type="button"
|
ref={btnRef}
|
||||||
title={t('topbar.language')}
|
type="button"
|
||||||
onClick={e => {
|
title={t('topbar.language')}
|
||||||
e.stopPropagation();
|
onClick={e => {
|
||||||
toggle();
|
e.stopPropagation();
|
||||||
}}
|
toggle();
|
||||||
className="bg-transparent flex cursor-pointer items-center border-0 px-1 text-[12px] tracking-wide hocus:text-orange"
|
}}
|
||||||
>
|
className="bg-transparent flex cursor-pointer items-center border-0 px-1 text-[12px] tracking-wide hocus:text-orange"
|
||||||
<Globe size={14} />
|
>
|
||||||
{code}
|
<Globe size={14} />
|
||||||
</button>
|
{code}
|
||||||
{open &&
|
</button>
|
||||||
pos &&
|
{open &&
|
||||||
createPortal(
|
pos &&
|
||||||
<div
|
createPortal(
|
||||||
onClick={e => e.stopPropagation()}
|
<div
|
||||||
style={{ top: pos.top, right: pos.right }}
|
onClick={e => e.stopPropagation()}
|
||||||
className="fixed z-50 flex flex-col border border-blueGray/30 bg-darkGray py-1 shadow-[0_8px_20px_rgba(0,0,0,0.5)]"
|
style={{ top: pos.top, right: pos.right }}
|
||||||
>
|
className="fixed z-50 flex flex-col border border-blueGray/30 bg-darkGray py-1 shadow-[0_8px_20px_rgba(0,0,0,0.5)]"
|
||||||
{LOCALES.map(l => (
|
>
|
||||||
<button
|
{LOCALES.map(l => (
|
||||||
key={l.value}
|
<button
|
||||||
type="button"
|
key={l.value}
|
||||||
title={l.label}
|
type="button"
|
||||||
onClick={() => pick(l.value)}
|
title={l.label}
|
||||||
className={cls(
|
onClick={() => pick(l.value)}
|
||||||
'bg-transparent cursor-pointer border-0 px-3 py-1 text-center text-[12px] hocus:bg-orange/20',
|
className={cls(
|
||||||
l.value === lang ? 'text-warmGreen' : 'text-white'
|
'bg-transparent cursor-pointer border-0 px-3 py-1 text-center text-[12px] hocus:bg-orange/20',
|
||||||
)}
|
l.value === lang ? 'text-warmGreen' : 'text-white'
|
||||||
>
|
)}
|
||||||
{l.code}
|
>
|
||||||
</button>
|
{l.code}
|
||||||
))}
|
</button>
|
||||||
</div>,
|
))}
|
||||||
document.body
|
</div>,
|
||||||
)}
|
document.body
|
||||||
</>
|
)}
|
||||||
);
|
</>
|
||||||
};
|
);
|
||||||
|
};
|
||||||
export default LanguageDropdown;
|
|
||||||
|
export default LanguageDropdown;
|
||||||
|
|||||||
+1545
-1326
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user