mirror of
https://github.com/Radiquum/radiquum.github.io.git
synced 2025-05-21 19:59:35 +05:00
feat: Add website Translation based on user browser language
This commit is contained in:
parent
a8dea5ee51
commit
742fb28189
4 changed files with 244 additions and 192 deletions
68
static/i18n/i18n.js
Normal file
68
static/i18n/i18n.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
const linkRegexFull =
|
||||
/\|% LINK='[.,#?=&a-zA-Z_:_\/]*' %\|[.,a-zA-Zа-яА-Я-!_ ]*\|% ENDLINK %\|/gim;
|
||||
const linkRegexFullNonGlobal =
|
||||
/\|% LINK='[.,#?=&a-zA-Z_:_\/]*' %\|[.,a-zA-Zа-яА-Я-!_ ]*\|% ENDLINK %\|/im;
|
||||
function parseLink(string) {
|
||||
const links = [...string.match(linkRegexFull)];
|
||||
const linkRegexStart = /\|% LINK='[.,#?=&a-zA-Z_:_\/]*' %\|/;
|
||||
for (let i = 0; i < links.length; i++) {
|
||||
let tmp = links[i];
|
||||
const href = tmp
|
||||
.match(linkRegexStart)[0]
|
||||
.replace("|%", "")
|
||||
.replace("%|", "")
|
||||
.split("=")[1]
|
||||
.trim();
|
||||
let lnk = "";
|
||||
lnk = tmp.replace(
|
||||
linkRegexStart,
|
||||
`<a class="text-bg-pink hover:underline" href=${href} ${href.startsWith("http") ? "target='_blank' referrerpolicy='origin'" : ""}>`
|
||||
);
|
||||
lnk = lnk.replace("|% ENDLINK %|", `</a>`);
|
||||
string = string.replace(linkRegexFullNonGlobal, lnk);
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
const i18nTags = document.querySelectorAll("[data-i18n]");
|
||||
const i18nStyles = document.querySelectorAll("[data-i18n-style]");
|
||||
function changeLanguage(lang) {
|
||||
let strings = {};
|
||||
let styles = {};
|
||||
if (lang == "ru") {
|
||||
strings = i18n_ru;
|
||||
styles = i18n_ru_style;
|
||||
}
|
||||
|
||||
for (let i = 0; i < i18nTags.length; i++) {
|
||||
const element = i18nTags[i];
|
||||
const id = element.getAttribute("data-i18n");
|
||||
if (!strings[id]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (linkRegexFull.test(strings[id])) {
|
||||
element.innerHTML = parseLink(strings[id]);
|
||||
} else {
|
||||
element.innerHTML = strings[id];
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < i18nStyles.length; i++) {
|
||||
const element = i18nStyles[i];
|
||||
const id = element.getAttribute("data-i18n-style");
|
||||
if (!styles[id]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
element.style.cssText = styles[id];
|
||||
}
|
||||
}
|
||||
|
||||
function detectAndChangeLanguage() {
|
||||
const userLang = window.navigator.language;
|
||||
if (userLang.startsWith("ru")) {
|
||||
changeLanguage("ru");
|
||||
}
|
||||
}
|
||||
|
||||
detectAndChangeLanguage();
|
69
static/i18n/strings/ru.js
Normal file
69
static/i18n/strings/ru.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
const i18n_ru = {
|
||||
NAME: "КЕНТАЙ РАДИКУУМ",
|
||||
PRONOUNCE: "Он",
|
||||
SPECIES: "Красная Панда / Протоген",
|
||||
|
||||
// QUICK_BIO
|
||||
QUICK_BIO_FURRY: "Фурри",
|
||||
QUICK_BIO_CODER: "Программист",
|
||||
QUICK_BIO_PHOTOGRAPHER: "Фотограф",
|
||||
QUICK_BIO_ENTHUSIAST: "Селф-Хостинг Энтузиаст",
|
||||
QUICK_BIO_LASTFM: "Сейчас слушает: ",
|
||||
|
||||
// BUTTONS
|
||||
BTN_ABOUT_ME: "ОБО МНЕ",
|
||||
BTN_OR: "или",
|
||||
BTN_LINKS: "ССЫЛКИ",
|
||||
|
||||
// ABOUT ME
|
||||
CARD_TITLE: "ОБО МНЕ",
|
||||
CARD_TECH_ENTHUSIAST_TITLE: "Технический энтузиаст",
|
||||
CARD_TECH_ENTHUSIAST_DESC:
|
||||
"Мне нравится развиваться в области технологий, я увлечен разработкой программного обеспечения. Я люблю копаться в коде и изучать новое программное обеспечение, хотя железки меня тоже привлекают.",
|
||||
CARD_PHOTOGRAPHER_TITLE: "Фотограф",
|
||||
CARD_PHOTOGRAPHER_DESC:
|
||||
"Я также увлекаюсь |% LINK='https://wah.su/photos' %|фотографией|% ENDLINK %| и с удовольствием делюсь своим прогрессом.",
|
||||
CARD_SELFHOSTER_TITLE: "Самостоятельный хостинг",
|
||||
CARD_SELFHOSTER_DESC:
|
||||
"Я очень увлечен самостоятельным хостингом через мой проект |% LINK='https://home.wah.su' %|wah.su|% ENDLINK %|, который помогает мне погрузиться в управление серверами и хостинговыми платформами.",
|
||||
CARD_MUSIC_TITLE: "Музыка",
|
||||
CARD_MUSIC_DESC:
|
||||
"Я слушаю много разной музыки, но в основном слушаю EDM / Happy Hardcore / Tech / Rock / Alternative. От таких исполнителей как: S3RL, Camellia, t+pazolite, BTMH, Saint Motel и других...",
|
||||
CARD_SKILLS_TITLE: "Навыки",
|
||||
CARD_SKILLS_FRONTEND: "Разработка фронт-енд",
|
||||
CARD_SKILLS_BACKEND: "Разработка бэк-енд",
|
||||
CARD_SKILLS_API: "API",
|
||||
CARD_SKILLS_COLLAB: "Совместная работа",
|
||||
CARD_SKILLS_DEPLOY: "Развёртывание",
|
||||
CARD_READPANDA_TITLE: "Поклонник красных панд",
|
||||
CARD_READPANDA_DESC:
|
||||
"Я очень люблю красных панд и не могу насмотреться на них! Я собираю стикеры с красными пандами и делюсь ими в Telegram-канале |% LINK='https://t.me/red_panda_stickers' %|Red Panda Stickers|% ENDLINK %|. Кроме того, я собрал |% LINK='https://wahs.wah.su' %|коллекцию|% ENDLINK %| из более чем 3000 фотографий и видео с красными пандами.",
|
||||
CARD_CONTACT_TITLE: "Связаться",
|
||||
CARD_CONTACT_DESC:
|
||||
"Не стесняйтесь связаться со мной в любое время! Способы связаться со мной через мессенджеры доступны в разделе |% LINK='#links' %|ссылок!|% ENDLINK %|.",
|
||||
LNK_TITLE: "ССЫЛКИ",
|
||||
LNK_PHOTO_HEADER: "ФОТОГРАФИИ",
|
||||
LNK_PHOTO_PIXEY: "Смотри фото как в инстаграме",
|
||||
LNK_PHOTO_INSTAFOPS: "Более фурри фото",
|
||||
LNK_PHOTO_IMMICH: "Смотри фото как в Гугл Фото",
|
||||
LNK_ARTS_HEADER: "АРТЫ",
|
||||
LNK_SOCIALS_HEADER: "СОЦ. СЕТИ",
|
||||
LNK_PROJECTS_HEADER: "ПРОЕКТЫ",
|
||||
LNK_PROJECTS_ANIX:
|
||||
"Неофициальный клиент для android приложения Anixart сделанный с помощью Next.js",
|
||||
LNK_PROJECTS_TGP: "Телеграм бот для использования ТГ как гугл фото",
|
||||
LNK_PROJECTS_WG: "Генератор слов вдохновлённый @tsoding",
|
||||
LNK_PROJECTS_FADL: "Форк оригинального проекта для добавления новых функций",
|
||||
LNK_PROJECTS_GITHUB: "Посмотреть мои другие репозитории",
|
||||
LNK_PROJECTS_WAHSU: "Мой проект по селф-хосту",
|
||||
LNK_CONTACT_HEADER: "СВЯЗАТЬСЯ",
|
||||
LNK_FRIEND_HEADER: "ДРУЗЬЯ И КОЛЛЕКЦИИ",
|
||||
LNK_COLLECTION_RPS: "ТГК для стикеров с красными пандами",
|
||||
LNK_COLLECTION_RPI: "3000+ Фото и видео с красными пандами",
|
||||
LNK_FRIEND_BLEP: "ВК Группа классного фотографа",
|
||||
LNK_FRIEND_ITC: "GitHub профиль другого фурри-кодера",
|
||||
};
|
||||
|
||||
const i18n_ru_style = {
|
||||
CARD_SKILLS_STYLE: "--sm--mt:54px; --lg--mt:40px;",
|
||||
};
|
|
@ -698,22 +698,6 @@ video {
|
|||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.-ml-4 {
|
||||
margin-left: -1rem;
|
||||
}
|
||||
|
||||
.-mt-8 {
|
||||
margin-top: -2rem;
|
||||
}
|
||||
|
||||
.-mt-6 {
|
||||
margin-top: -1.5rem;
|
||||
}
|
||||
|
||||
.-ml-2 {
|
||||
margin-left: -0.5rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
|
@ -762,11 +746,6 @@ video {
|
|||
height: 100%;
|
||||
}
|
||||
|
||||
.h-fit {
|
||||
height: -moz-fit-content;
|
||||
height: fit-content;
|
||||
}
|
||||
|
||||
.max-h-\[182px\] {
|
||||
max-height: 182px;
|
||||
}
|
||||
|
@ -825,21 +804,6 @@ video {
|
|||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.translate-y-full {
|
||||
--tw-translate-y: 100%;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.translate-y-\[50\%\] {
|
||||
--tw-translate-y: 50%;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
.translate-y-\[80\%\] {
|
||||
--tw-translate-y: 80%;
|
||||
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%, 100% {
|
||||
transform: translateY(-25%);
|
||||
|
@ -1021,6 +985,11 @@ video {
|
|||
background-color: rgb(245 245 245 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-\[\#ffeb3c\] {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 235 60 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-bg-black {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(18 27 44 / var(--tw-bg-opacity));
|
||||
|
@ -1076,14 +1045,8 @@ video {
|
|||
background-color: rgb(234 179 8 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-\[\#ffeb3c\] {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(255 235 60 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-slate-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(100 116 139 / var(--tw-bg-opacity));
|
||||
.bg-opacity-20 {
|
||||
--tw-bg-opacity: 0.2;
|
||||
}
|
||||
|
||||
.bg-opacity-40 {
|
||||
|
@ -1094,14 +1057,6 @@ video {
|
|||
--tw-bg-opacity: 0.5;
|
||||
}
|
||||
|
||||
.bg-opacity-10 {
|
||||
--tw-bg-opacity: 0.1;
|
||||
}
|
||||
|
||||
.bg-opacity-20 {
|
||||
--tw-bg-opacity: 0.2;
|
||||
}
|
||||
|
||||
.object-contain {
|
||||
-o-object-fit: contain;
|
||||
object-fit: contain;
|
||||
|
@ -1166,10 +1121,6 @@ video {
|
|||
text-align: right;
|
||||
}
|
||||
|
||||
.align-text-bottom {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.text-2xl {
|
||||
font-size: 1.5rem;
|
||||
line-height: 2rem;
|
||||
|
@ -1200,11 +1151,6 @@ video {
|
|||
line-height: 1.75rem;
|
||||
}
|
||||
|
||||
.text-6xl {
|
||||
font-size: 3.75rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
@ -1236,72 +1182,19 @@ video {
|
|||
color: rgb(255 255 255 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-gray-500 {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(107 114 128 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.underline {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.mix-blend-multiply {
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
.mix-blend-exclusion {
|
||||
mix-blend-mode: exclusion;
|
||||
}
|
||||
|
||||
.shadow {
|
||||
--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.shadow-md {
|
||||
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.shadow-inner {
|
||||
--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
||||
--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);
|
||||
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
||||
}
|
||||
|
||||
.shadow-black {
|
||||
--tw-shadow-color: #000;
|
||||
--tw-shadow: var(--tw-shadow-colored);
|
||||
}
|
||||
|
||||
.brightness-50 {
|
||||
--tw-brightness: brightness(.5);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.invert {
|
||||
--tw-invert: invert(100%);
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.filter {
|
||||
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
||||
}
|
||||
|
||||
.backdrop-blur-lg {
|
||||
--tw-backdrop-blur: blur(16px);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||
}
|
||||
|
||||
.backdrop-invert {
|
||||
--tw-backdrop-invert: invert(100%);
|
||||
-webkit-backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||
backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
|
||||
}
|
||||
|
||||
.transition-\[border-color\] {
|
||||
transition-property: border-color;
|
||||
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
|
@ -1422,8 +1315,8 @@ body {
|
|||
top: -6rem;
|
||||
}
|
||||
|
||||
.sm\:-mt-\[86px\] {
|
||||
margin-top: -86px;
|
||||
.sm\:-mt-\[var\(--sm--mt\)\] {
|
||||
margin-top: calc(var(--sm--mt) * -1);
|
||||
}
|
||||
|
||||
.sm\:mt-0 {
|
||||
|
@ -1553,8 +1446,8 @@ body {
|
|||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.lg\:-mt-\[60px\] {
|
||||
margin-top: -60px;
|
||||
.lg\:-mt-\[var\(--lg--mt\)\] {
|
||||
margin-top: calc(var(--lg--mt) * -1);
|
||||
}
|
||||
|
||||
.lg\:mt-28 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue