Add full language UI translations and modal wrapping
This commit is contained in:
153
src/App.vue
153
src/App.vue
@@ -22,8 +22,37 @@ const installDismissed = ref(false);
|
||||
const isCoarsePointer = ref(false);
|
||||
const isStandalone = ref(false);
|
||||
const themePreference = ref('system');
|
||||
const isLangOpen = ref(false);
|
||||
const langMenuRef = ref(null);
|
||||
let displayModeMedia = null;
|
||||
let prefersColorSchemeMedia = null;
|
||||
const languageFlags = {
|
||||
en: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#b22234"/><rect y="2" width="24" height="2" fill="#fff"/><rect y="6" width="24" height="2" fill="#fff"/><rect y="10" width="24" height="2" fill="#fff"/><rect y="14" width="24" height="2" fill="#fff"/><rect width="10" height="8" fill="#3c3b6e"/></svg>',
|
||||
zh: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#de2910"/><circle cx="6" cy="5" r="2" fill="#ffde00"/></svg>',
|
||||
hi: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#ffffff"/><rect width="24" height="5.33" fill="#ff9933"/><rect y="10.67" width="24" height="5.33" fill="#128807"/><circle cx="12" cy="8" r="2" fill="#000080"/></svg>',
|
||||
es: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#aa151b"/><rect y="4" width="24" height="8" fill="#f1bf00"/></svg>',
|
||||
fr: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="8" height="16" fill="#0055a4"/><rect x="8" width="8" height="16" fill="#ffffff"/><rect x="16" width="8" height="16" fill="#ef4135"/></svg>',
|
||||
ar: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#006c35"/><rect y="11" width="24" height="3" fill="#ffffff"/></svg>',
|
||||
bn: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#006a4e"/><circle cx="11" cy="8" r="4" fill="#f42a41"/></svg>',
|
||||
ru: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#ffffff"/><rect y="5.33" width="24" height="5.33" fill="#0039a6"/><rect y="10.67" width="24" height="5.33" fill="#d52b1e"/></svg>',
|
||||
pt: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="9" height="16" fill="#006600"/><rect x="9" width="15" height="16" fill="#ff0000"/><circle cx="9.5" cy="8" r="2.5" fill="#ffcc00"/></svg>',
|
||||
ur: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#01411c"/><rect width="6" height="16" fill="#ffffff"/><circle cx="15" cy="8" r="3" fill="#ffffff"/></svg>',
|
||||
pl: '<svg viewBox="0 0 24 16" xmlns="http://www.w3.org/2000/svg"><rect width="24" height="16" fill="#ffffff"/><rect y="8" width="24" height="8" fill="#dc143c"/></svg>'
|
||||
};
|
||||
|
||||
const languages = computed(() => [
|
||||
{ code: 'en', label: t('language.en') },
|
||||
{ code: 'zh', label: t('language.zh') },
|
||||
{ code: 'hi', label: t('language.hi') },
|
||||
{ code: 'es', label: t('language.es') },
|
||||
{ code: 'fr', label: t('language.fr') },
|
||||
{ code: 'ar', label: t('language.ar') },
|
||||
{ code: 'bn', label: t('language.bn') },
|
||||
{ code: 'ru', label: t('language.ru') },
|
||||
{ code: 'pt', label: t('language.pt') },
|
||||
{ code: 'ur', label: t('language.ur') },
|
||||
{ code: 'pl', label: t('language.pl') }
|
||||
]);
|
||||
|
||||
const installLabel = computed(() => {
|
||||
return isCoarsePointer.value ? t('pwa.installMobile') : t('pwa.installDesktop');
|
||||
@@ -85,6 +114,18 @@ const handleSystemThemeChange = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const selectLanguage = (value) => {
|
||||
setLocale(value);
|
||||
isLangOpen.value = false;
|
||||
};
|
||||
|
||||
const handleOutsideClick = (event) => {
|
||||
if (!langMenuRef.value) return;
|
||||
if (!langMenuRef.value.contains(event.target)) {
|
||||
isLangOpen.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (!store.loadState()) {
|
||||
store.initGame(); // Inicjalizacja domyślnej gry jeśli brak zapisu
|
||||
@@ -111,6 +152,7 @@ onMounted(() => {
|
||||
} else if (displayModeMedia?.addListener) {
|
||||
displayModeMedia.addListener(updateStandalone);
|
||||
}
|
||||
document.addEventListener('click', handleOutsideClick);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -128,6 +170,7 @@ onUnmounted(() => {
|
||||
} else if (displayModeMedia?.removeListener) {
|
||||
displayModeMedia.removeListener(updateStandalone);
|
||||
}
|
||||
document.removeEventListener('click', handleOutsideClick);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -138,9 +181,29 @@ onUnmounted(() => {
|
||||
<header class="game-header">
|
||||
<h1>{{ t('app.title') }}</h1>
|
||||
<div class="header-toggles">
|
||||
<div class="lang-toggle">
|
||||
<button class="lang-btn" :class="{ active: locale === 'pl' }" @click="setLocale('pl')">PL</button>
|
||||
<button class="lang-btn" :class="{ active: locale === 'en' }" @click="setLocale('en')">EN</button>
|
||||
<div class="lang-dropdown" ref="langMenuRef">
|
||||
<button
|
||||
class="lang-trigger"
|
||||
type="button"
|
||||
:aria-label="t('language.label')"
|
||||
:aria-expanded="isLangOpen"
|
||||
@click="isLangOpen = !isLangOpen"
|
||||
>
|
||||
<span class="lang-flag" v-html="languageFlags[locale]"></span>
|
||||
</button>
|
||||
<div v-if="isLangOpen" class="lang-menu">
|
||||
<button
|
||||
v-for="lang in languages"
|
||||
:key="lang.code"
|
||||
class="lang-option"
|
||||
:class="{ active: locale === lang.code }"
|
||||
type="button"
|
||||
@click="selectLanguage(lang.code)"
|
||||
>
|
||||
<span class="lang-flag" v-html="languageFlags[lang.code]"></span>
|
||||
<span class="lang-name">{{ lang.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="theme-toggle">
|
||||
<span class="theme-label">{{ t('theme.label') }}</span>
|
||||
@@ -242,35 +305,87 @@ h1 {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.lang-toggle {
|
||||
.lang-dropdown {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
gap: 8px;
|
||||
padding: 6px 10px;
|
||||
border-radius: 999px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.lang-trigger {
|
||||
background: var(--toggle-bg);
|
||||
border: 1px solid var(--toggle-border);
|
||||
box-shadow: var(--toggle-shadow);
|
||||
}
|
||||
|
||||
.lang-btn {
|
||||
background: transparent;
|
||||
border: 1px solid var(--toggle-btn-border);
|
||||
color: var(--text-strong);
|
||||
padding: 4px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 1px;
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.lang-btn.active {
|
||||
.lang-trigger:hover {
|
||||
border-color: var(--toggle-hover-border);
|
||||
}
|
||||
|
||||
.lang-menu {
|
||||
position: absolute;
|
||||
top: calc(100% + 8px);
|
||||
right: 0;
|
||||
min-width: 170px;
|
||||
background: var(--toggle-bg);
|
||||
border: 1px solid var(--toggle-border);
|
||||
box-shadow: var(--toggle-shadow);
|
||||
border-radius: 16px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
z-index: 10;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.lang-option {
|
||||
background: transparent;
|
||||
border: 1px solid var(--toggle-btn-border);
|
||||
color: var(--text-strong);
|
||||
padding: 6px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 0.85rem;
|
||||
letter-spacing: 0.5px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.lang-option:hover {
|
||||
border-color: var(--toggle-hover-border);
|
||||
}
|
||||
|
||||
.lang-option.active {
|
||||
border-color: var(--primary-accent);
|
||||
box-shadow: var(--toggle-active-shadow);
|
||||
}
|
||||
|
||||
.lang-btn:hover {
|
||||
border-color: var(--toggle-hover-border);
|
||||
.lang-flag {
|
||||
width: 24px;
|
||||
height: 16px;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
.lang-flag svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.lang-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.theme-toggle {
|
||||
|
||||
@@ -337,6 +337,7 @@ onUnmounted(() => {
|
||||
animation: slideUp 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
position: relative;
|
||||
z-index: 1001;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
h2 {
|
||||
@@ -344,12 +345,14 @@ h2 {
|
||||
color: var(--primary-accent);
|
||||
margin: 0 0 10px 0;
|
||||
text-shadow: 0 0 20px var(--primary-accent);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
p {
|
||||
color: var(--text-secondary);
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 30px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.stats {
|
||||
@@ -380,6 +383,7 @@ p {
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
color: var(--text-muted);
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.share-buttons {
|
||||
@@ -409,6 +413,13 @@ p {
|
||||
align-self: center;
|
||||
padding: 8px 18px;
|
||||
font-size: 0.85rem;
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.actions .btn-neon {
|
||||
max-width: 100%;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { ref, computed } from 'vue';
|
||||
|
||||
const supportedLocales = ['pl', 'en', 'zh', 'hi', 'es', 'fr', 'ar', 'bn', 'ru', 'pt', 'ur'];
|
||||
|
||||
const detectLocale = () => {
|
||||
if (typeof navigator === 'undefined') return 'en';
|
||||
const browserLocale = (navigator.languages && navigator.languages[0]) || navigator.language || 'en';
|
||||
const short = browserLocale.toLowerCase().split('-')[0];
|
||||
return short === 'pl' ? 'pl' : 'en';
|
||||
return supportedLocales.includes(short) ? short : 'en';
|
||||
};
|
||||
|
||||
const messages = {
|
||||
@@ -49,6 +51,18 @@ const messages = {
|
||||
'pwa.installTitle': 'Zainstaluj aplikację i graj offline',
|
||||
'pwa.installMobile': 'Dodaj do ekranu głównego',
|
||||
'pwa.installDesktop': 'Zainstaluj na komputerze',
|
||||
'language.label': 'Wybór języka',
|
||||
'language.pl': 'Polski',
|
||||
'language.en': 'Angielski',
|
||||
'language.zh': 'Mandaryński',
|
||||
'language.hi': 'Hindi',
|
||||
'language.es': 'Hiszpański',
|
||||
'language.fr': 'Francuski',
|
||||
'language.ar': 'Arabski',
|
||||
'language.bn': 'Bengalski',
|
||||
'language.ru': 'Rosyjski',
|
||||
'language.pt': 'Portugalski',
|
||||
'language.ur': 'Urdu',
|
||||
'theme.label': 'Motyw',
|
||||
'theme.system': 'System',
|
||||
'theme.light': 'Jasny',
|
||||
@@ -95,10 +109,544 @@ const messages = {
|
||||
'pwa.installTitle': 'Install the app and play offline',
|
||||
'pwa.installMobile': 'Add to home screen',
|
||||
'pwa.installDesktop': 'Install on desktop',
|
||||
'language.label': 'Language selection',
|
||||
'language.pl': 'Polish',
|
||||
'language.en': 'English',
|
||||
'language.zh': 'Mandarin',
|
||||
'language.hi': 'Hindi',
|
||||
'language.es': 'Spanish',
|
||||
'language.fr': 'French',
|
||||
'language.ar': 'Arabic',
|
||||
'language.bn': 'Bengali',
|
||||
'language.ru': 'Russian',
|
||||
'language.pt': 'Portuguese',
|
||||
'language.ur': 'Urdu',
|
||||
'theme.label': 'Theme',
|
||||
'theme.system': 'System',
|
||||
'theme.light': 'Light',
|
||||
'theme.dark': 'Dark'
|
||||
},
|
||||
zh: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': '简单 5X5',
|
||||
'level.medium': '中等 10X10',
|
||||
'level.hard': '困难 15X15',
|
||||
'level.custom': '自定义',
|
||||
'level.guide': '指南 ❓',
|
||||
'actions.reset': '重置',
|
||||
'actions.random': '新随机',
|
||||
'actions.undo': '撤销',
|
||||
'status.time': '时间',
|
||||
'status.moves': '步数',
|
||||
'status.progress': '进度',
|
||||
'fixed.time': '时间:',
|
||||
'fixed.progress': '进度:',
|
||||
'fixed.hide': '隐藏',
|
||||
'fixed.show': '显示',
|
||||
'guide.play': '开始',
|
||||
'guide.pause': '暂停',
|
||||
'guide.step': '步骤',
|
||||
'guide.speed': '速度',
|
||||
'guide.waiting': '等待...',
|
||||
'guide.solved': '已解!',
|
||||
'custom.title': '自定义游戏',
|
||||
'custom.prompt': '输入网格大小 (5 - 80):',
|
||||
'custom.cancel': '取消',
|
||||
'custom.start': '开始',
|
||||
'custom.sizeError': '尺寸必须在 5 到 80 之间!',
|
||||
'win.title': '恭喜!',
|
||||
'win.message': '你解开了谜题!',
|
||||
'win.time': '时间:',
|
||||
'win.playAgain': '再玩一次',
|
||||
'win.shareTitle': '分享你的结果',
|
||||
'win.shareText': '我在 {time} 内解开了 {size}x{size} 的数织!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': '下载截图',
|
||||
'pwa.installTitle': '安装应用并离线游玩',
|
||||
'pwa.installMobile': '添加到主屏幕',
|
||||
'pwa.installDesktop': '安装到桌面',
|
||||
'language.label': '语言选择',
|
||||
'language.pl': '波兰语',
|
||||
'language.en': '英语',
|
||||
'language.zh': '中文',
|
||||
'language.hi': '印地语',
|
||||
'language.es': '西班牙语',
|
||||
'language.fr': '法语',
|
||||
'language.ar': '阿拉伯语',
|
||||
'language.bn': '孟加拉语',
|
||||
'language.ru': '俄语',
|
||||
'language.pt': '葡萄牙语',
|
||||
'language.ur': '乌尔都语',
|
||||
'theme.label': '主题',
|
||||
'theme.system': '系统',
|
||||
'theme.light': '浅色',
|
||||
'theme.dark': '深色'
|
||||
},
|
||||
hi: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'आसान 5X5',
|
||||
'level.medium': 'मध्यम 10X10',
|
||||
'level.hard': 'कठिन 15X15',
|
||||
'level.custom': 'कस्टम',
|
||||
'level.guide': 'गाइड ❓',
|
||||
'actions.reset': 'रीसेट',
|
||||
'actions.random': 'नई रैंडम',
|
||||
'actions.undo': 'वापस',
|
||||
'status.time': 'समय',
|
||||
'status.moves': 'चालें',
|
||||
'status.progress': 'प्रगति',
|
||||
'fixed.time': 'समय:',
|
||||
'fixed.progress': 'प्रगति:',
|
||||
'fixed.hide': 'छिपाएं',
|
||||
'fixed.show': 'दिखाएं',
|
||||
'guide.play': 'शुरू',
|
||||
'guide.pause': 'रोकें',
|
||||
'guide.step': 'कदम',
|
||||
'guide.speed': 'गति',
|
||||
'guide.waiting': 'प्रतीक्षा...',
|
||||
'guide.solved': 'हल हो गया!',
|
||||
'custom.title': 'कस्टम गेम',
|
||||
'custom.prompt': 'ग्रिड आकार दर्ज करें (5 - 80):',
|
||||
'custom.cancel': 'रद्द करें',
|
||||
'custom.start': 'शुरू',
|
||||
'custom.sizeError': 'आकार 5 और 80 के बीच होना चाहिए!',
|
||||
'win.title': 'बधाई!',
|
||||
'win.message': 'आपने पहेली हल कर ली!',
|
||||
'win.time': 'समय:',
|
||||
'win.playAgain': 'फिर से खेलें',
|
||||
'win.shareTitle': 'अपना परिणाम साझा करें',
|
||||
'win.shareText': 'मैंने {time} में {size}x{size} नॉनोग्राम हल किया!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'स्क्रीनशॉट डाउनलोड करें',
|
||||
'pwa.installTitle': 'ऐप इंस्टॉल करें और ऑफलाइन खेलें',
|
||||
'pwa.installMobile': 'होम स्क्रीन पर जोड़ें',
|
||||
'pwa.installDesktop': 'डेस्कटॉप पर इंस्टॉल करें',
|
||||
'language.label': 'भाषा चयन',
|
||||
'language.pl': 'पोलिश',
|
||||
'language.en': 'अंग्रेज़ी',
|
||||
'language.zh': 'चीनी',
|
||||
'language.hi': 'हिंदी',
|
||||
'language.es': 'स्पेनिश',
|
||||
'language.fr': 'फ़्रेंच',
|
||||
'language.ar': 'अरबी',
|
||||
'language.bn': 'बंगाली',
|
||||
'language.ru': 'रूसी',
|
||||
'language.pt': 'पुर्तगाली',
|
||||
'language.ur': 'उर्दू',
|
||||
'theme.label': 'थीम',
|
||||
'theme.system': 'सिस्टम',
|
||||
'theme.light': 'हल्का',
|
||||
'theme.dark': 'गहरा'
|
||||
},
|
||||
es: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'FÁCIL 5X5',
|
||||
'level.medium': 'MEDIO 10X10',
|
||||
'level.hard': 'DIFÍCIL 15X15',
|
||||
'level.custom': 'PERSONALIZADO',
|
||||
'level.guide': 'GUÍA ❓',
|
||||
'actions.reset': 'REINICIAR',
|
||||
'actions.random': 'NUEVO ALEATORIO',
|
||||
'actions.undo': 'DESHACER',
|
||||
'status.time': 'TIEMPO',
|
||||
'status.moves': 'MOVIMIENTOS',
|
||||
'status.progress': 'PROGRESO',
|
||||
'fixed.time': 'Tiempo:',
|
||||
'fixed.progress': 'Progreso:',
|
||||
'fixed.hide': 'Ocultar',
|
||||
'fixed.show': 'Mostrar',
|
||||
'guide.play': 'INICIAR',
|
||||
'guide.pause': 'PAUSA',
|
||||
'guide.step': 'PASO',
|
||||
'guide.speed': 'VELOCIDAD',
|
||||
'guide.waiting': 'Esperando...',
|
||||
'guide.solved': '¡Resuelto!',
|
||||
'custom.title': 'JUEGO PERSONALIZADO',
|
||||
'custom.prompt': 'Introduce el tamaño de la cuadrícula (5 - 80):',
|
||||
'custom.cancel': 'Cancelar',
|
||||
'custom.start': 'Empezar',
|
||||
'custom.sizeError': '¡El tamaño debe estar entre 5 y 80!',
|
||||
'win.title': '¡FELICIDADES!',
|
||||
'win.message': '¡Has resuelto el rompecabezas!',
|
||||
'win.time': 'Tiempo:',
|
||||
'win.playAgain': 'Jugar de nuevo',
|
||||
'win.shareTitle': 'Comparte tu resultado',
|
||||
'win.shareText': '¡Resolví un nonograma de {size}x{size} en {time}!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'Descargar captura',
|
||||
'pwa.installTitle': 'Instala la app y juega sin conexión',
|
||||
'pwa.installMobile': 'Agregar a la pantalla de inicio',
|
||||
'pwa.installDesktop': 'Instalar en el escritorio',
|
||||
'language.label': 'Selección de idioma',
|
||||
'language.pl': 'Polaco',
|
||||
'language.en': 'Inglés',
|
||||
'language.zh': 'Chino',
|
||||
'language.hi': 'Hindi',
|
||||
'language.es': 'Español',
|
||||
'language.fr': 'Francés',
|
||||
'language.ar': 'Árabe',
|
||||
'language.bn': 'Bengalí',
|
||||
'language.ru': 'Ruso',
|
||||
'language.pt': 'Portugués',
|
||||
'language.ur': 'Urdu',
|
||||
'theme.label': 'Tema',
|
||||
'theme.system': 'Sistema',
|
||||
'theme.light': 'Claro',
|
||||
'theme.dark': 'Oscuro'
|
||||
},
|
||||
fr: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'FACILE 5X5',
|
||||
'level.medium': 'MOYEN 10X10',
|
||||
'level.hard': 'DIFFICILE 15X15',
|
||||
'level.custom': 'PERSONNALISÉ',
|
||||
'level.guide': 'GUIDE ❓',
|
||||
'actions.reset': 'RÉINITIALISER',
|
||||
'actions.random': 'NOUVEAU ALÉATOIRE',
|
||||
'actions.undo': 'ANNULER',
|
||||
'status.time': 'TEMPS',
|
||||
'status.moves': 'COUPS',
|
||||
'status.progress': 'PROGRÈS',
|
||||
'fixed.time': 'Temps:',
|
||||
'fixed.progress': 'Progrès:',
|
||||
'fixed.hide': 'Masquer',
|
||||
'fixed.show': 'Afficher',
|
||||
'guide.play': 'LANCER',
|
||||
'guide.pause': 'PAUSE',
|
||||
'guide.step': 'ÉTAPE',
|
||||
'guide.speed': 'VITESSE',
|
||||
'guide.waiting': 'En attente...',
|
||||
'guide.solved': 'Résolu !',
|
||||
'custom.title': 'JEU PERSONNALISÉ',
|
||||
'custom.prompt': 'Entrez la taille de la grille (5 - 80) :',
|
||||
'custom.cancel': 'Annuler',
|
||||
'custom.start': 'Démarrer',
|
||||
'custom.sizeError': 'La taille doit être entre 5 et 80 !',
|
||||
'win.title': 'FÉLICITATIONS !',
|
||||
'win.message': 'Vous avez résolu le puzzle !',
|
||||
'win.time': 'Temps:',
|
||||
'win.playAgain': 'Rejouer',
|
||||
'win.shareTitle': 'Partagez votre résultat',
|
||||
'win.shareText': 'J’ai résolu un nonogramme {size}x{size} en {time} !',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'Télécharger la capture',
|
||||
'pwa.installTitle': 'Installez l’app et jouez hors ligne',
|
||||
'pwa.installMobile': 'Ajouter à l’écran d’accueil',
|
||||
'pwa.installDesktop': 'Installer sur le bureau',
|
||||
'language.label': 'Choix de la langue',
|
||||
'language.pl': 'Polonais',
|
||||
'language.en': 'Anglais',
|
||||
'language.zh': 'Chinois',
|
||||
'language.hi': 'Hindi',
|
||||
'language.es': 'Espagnol',
|
||||
'language.fr': 'Français',
|
||||
'language.ar': 'Arabe',
|
||||
'language.bn': 'Bengali',
|
||||
'language.ru': 'Russe',
|
||||
'language.pt': 'Portugais',
|
||||
'language.ur': 'Ourdou',
|
||||
'theme.label': 'Thème',
|
||||
'theme.system': 'Système',
|
||||
'theme.light': 'Clair',
|
||||
'theme.dark': 'Sombre'
|
||||
},
|
||||
ar: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'سهل 5X5',
|
||||
'level.medium': 'متوسط 10X10',
|
||||
'level.hard': 'صعب 15X15',
|
||||
'level.custom': 'مخصص',
|
||||
'level.guide': 'دليل ❓',
|
||||
'actions.reset': 'إعادة ضبط',
|
||||
'actions.random': 'عشوائي جديد',
|
||||
'actions.undo': 'تراجع',
|
||||
'status.time': 'الوقت',
|
||||
'status.moves': 'الحركات',
|
||||
'status.progress': 'التقدم',
|
||||
'fixed.time': 'الوقت:',
|
||||
'fixed.progress': 'التقدم:',
|
||||
'fixed.hide': 'إخفاء',
|
||||
'fixed.show': 'إظهار',
|
||||
'guide.play': 'ابدأ',
|
||||
'guide.pause': 'إيقاف مؤقت',
|
||||
'guide.step': 'خطوة',
|
||||
'guide.speed': 'السرعة',
|
||||
'guide.waiting': 'جارٍ الانتظار...',
|
||||
'guide.solved': 'تم الحل!',
|
||||
'custom.title': 'لعبة مخصصة',
|
||||
'custom.prompt': 'أدخل حجم الشبكة (5 - 80):',
|
||||
'custom.cancel': 'إلغاء',
|
||||
'custom.start': 'ابدأ',
|
||||
'custom.sizeError': 'يجب أن يكون الحجم بين 5 و80!',
|
||||
'win.title': 'تهانينا!',
|
||||
'win.message': 'لقد حللت اللغز!',
|
||||
'win.time': 'الوقت:',
|
||||
'win.playAgain': 'العب مرة أخرى',
|
||||
'win.shareTitle': 'شارك نتيجتك',
|
||||
'win.shareText': 'حللت نونوغرام {size}x{size} في {time}!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'تحميل لقطة الشاشة',
|
||||
'pwa.installTitle': 'ثبّت التطبيق والعب دون اتصال',
|
||||
'pwa.installMobile': 'أضف إلى الشاشة الرئيسية',
|
||||
'pwa.installDesktop': 'التثبيت على سطح المكتب',
|
||||
'language.label': 'اختيار اللغة',
|
||||
'language.pl': 'البولندية',
|
||||
'language.en': 'الإنجليزية',
|
||||
'language.zh': 'الصينية',
|
||||
'language.hi': 'الهندية',
|
||||
'language.es': 'الإسبانية',
|
||||
'language.fr': 'الفرنسية',
|
||||
'language.ar': 'العربية',
|
||||
'language.bn': 'البنغالية',
|
||||
'language.ru': 'الروسية',
|
||||
'language.pt': 'البرتغالية',
|
||||
'language.ur': 'الأردية',
|
||||
'theme.label': 'السمة',
|
||||
'theme.system': 'النظام',
|
||||
'theme.light': 'فاتح',
|
||||
'theme.dark': 'داكن'
|
||||
},
|
||||
bn: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'সহজ 5X5',
|
||||
'level.medium': 'মাঝারি 10X10',
|
||||
'level.hard': 'কঠিন 15X15',
|
||||
'level.custom': 'কাস্টম',
|
||||
'level.guide': 'গাইড ❓',
|
||||
'actions.reset': 'রিসেট',
|
||||
'actions.random': 'নতুন র্যান্ডম',
|
||||
'actions.undo': 'পূর্বাবস্থায়',
|
||||
'status.time': 'সময়',
|
||||
'status.moves': 'চাল',
|
||||
'status.progress': 'অগ্রগতি',
|
||||
'fixed.time': 'সময়:',
|
||||
'fixed.progress': 'অগ্রগতি:',
|
||||
'fixed.hide': 'লুকান',
|
||||
'fixed.show': 'দেখান',
|
||||
'guide.play': 'শুরু',
|
||||
'guide.pause': 'বিরতি',
|
||||
'guide.step': 'ধাপ',
|
||||
'guide.speed': 'গতি',
|
||||
'guide.waiting': 'অপেক্ষা...',
|
||||
'guide.solved': 'সমাধান হয়েছে!',
|
||||
'custom.title': 'কাস্টম গেম',
|
||||
'custom.prompt': 'গ্রিডের আকার দিন (5 - 80):',
|
||||
'custom.cancel': 'বাতিল',
|
||||
'custom.start': 'শুরু',
|
||||
'custom.sizeError': 'আকার 5 থেকে 80 এর মধ্যে হতে হবে!',
|
||||
'win.title': 'অভিনন্দন!',
|
||||
'win.message': 'আপনি ধাঁধা সমাধান করেছেন!',
|
||||
'win.time': 'সময়:',
|
||||
'win.playAgain': 'আবার খেলুন',
|
||||
'win.shareTitle': 'আপনার ফলাফল শেয়ার করুন',
|
||||
'win.shareText': 'আমি {time} সময়ে {size}x{size} ননোগ্রাম সমাধান করেছি!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'স্ক্রিনশট ডাউনলোড করুন',
|
||||
'pwa.installTitle': 'অ্যাপটি ইনস্টল করে অফলাইনে খেলুন',
|
||||
'pwa.installMobile': 'হোম স্ক্রিনে যোগ করুন',
|
||||
'pwa.installDesktop': 'ডেস্কটপে ইনস্টল করুন',
|
||||
'language.label': 'ভাষা নির্বাচন',
|
||||
'language.pl': 'পোলিশ',
|
||||
'language.en': 'ইংরেজি',
|
||||
'language.zh': 'চীনা',
|
||||
'language.hi': 'হিন্দি',
|
||||
'language.es': 'স্প্যানিশ',
|
||||
'language.fr': 'ফরাসি',
|
||||
'language.ar': 'আরবি',
|
||||
'language.bn': 'বাংলা',
|
||||
'language.ru': 'রুশ',
|
||||
'language.pt': 'পর্তুগিজ',
|
||||
'language.ur': 'উর্দু',
|
||||
'theme.label': 'থিম',
|
||||
'theme.system': 'সিস্টেম',
|
||||
'theme.light': 'হালকা',
|
||||
'theme.dark': 'গাঢ়'
|
||||
},
|
||||
ru: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'ЛЕГКО 5X5',
|
||||
'level.medium': 'СРЕДНЕ 10X10',
|
||||
'level.hard': 'ТЯЖЕЛО 15X15',
|
||||
'level.custom': 'СВОЯ',
|
||||
'level.guide': 'ПОДСКАЗКА ❓',
|
||||
'actions.reset': 'СБРОС',
|
||||
'actions.random': 'НОВАЯ СЛУЧАЙНАЯ',
|
||||
'actions.undo': 'ОТМЕНА',
|
||||
'status.time': 'ВРЕМЯ',
|
||||
'status.moves': 'ХОДЫ',
|
||||
'status.progress': 'ПРОГРЕСС',
|
||||
'fixed.time': 'Время:',
|
||||
'fixed.progress': 'Прогресс:',
|
||||
'fixed.hide': 'Скрыть',
|
||||
'fixed.show': 'Показать',
|
||||
'guide.play': 'СТАРТ',
|
||||
'guide.pause': 'ПАУЗА',
|
||||
'guide.step': 'ШАГ',
|
||||
'guide.speed': 'СКОРОСТЬ',
|
||||
'guide.waiting': 'Ожидание...',
|
||||
'guide.solved': 'Решено!',
|
||||
'custom.title': 'СВОЯ ИГРА',
|
||||
'custom.prompt': 'Введите размер сетки (5 - 80):',
|
||||
'custom.cancel': 'Отмена',
|
||||
'custom.start': 'Старт',
|
||||
'custom.sizeError': 'Размер должен быть от 5 до 80!',
|
||||
'win.title': 'ПОЗДРАВЛЯЕМ!',
|
||||
'win.message': 'Вы решили головоломку!',
|
||||
'win.time': 'Время:',
|
||||
'win.playAgain': 'Сыграть снова',
|
||||
'win.shareTitle': 'Поделитесь результатом',
|
||||
'win.shareText': 'Я решил(а) нонограмму {size}x{size} за {time}!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'Скачать снимок',
|
||||
'pwa.installTitle': 'Установите приложение и играйте офлайн',
|
||||
'pwa.installMobile': 'Добавить на главный экран',
|
||||
'pwa.installDesktop': 'Установить на компьютер',
|
||||
'language.label': 'Выбор языка',
|
||||
'language.pl': 'Польский',
|
||||
'language.en': 'Английский',
|
||||
'language.zh': 'Китайский',
|
||||
'language.hi': 'Хинди',
|
||||
'language.es': 'Испанский',
|
||||
'language.fr': 'Французский',
|
||||
'language.ar': 'Арабский',
|
||||
'language.bn': 'Бенгальский',
|
||||
'language.ru': 'Русский',
|
||||
'language.pt': 'Португальский',
|
||||
'language.ur': 'Урду',
|
||||
'theme.label': 'Тема',
|
||||
'theme.system': 'Система',
|
||||
'theme.light': 'Светлая',
|
||||
'theme.dark': 'Тёмная'
|
||||
},
|
||||
pt: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'FÁCIL 5X5',
|
||||
'level.medium': 'MÉDIO 10X10',
|
||||
'level.hard': 'DIFÍCIL 15X15',
|
||||
'level.custom': 'PERSONALIZADO',
|
||||
'level.guide': 'GUIA ❓',
|
||||
'actions.reset': 'REINICIAR',
|
||||
'actions.random': 'NOVO ALEATÓRIO',
|
||||
'actions.undo': 'DESFAZER',
|
||||
'status.time': 'TEMPO',
|
||||
'status.moves': 'MOVIMENTOS',
|
||||
'status.progress': 'PROGRESSO',
|
||||
'fixed.time': 'Tempo:',
|
||||
'fixed.progress': 'Progresso:',
|
||||
'fixed.hide': 'Ocultar',
|
||||
'fixed.show': 'Mostrar',
|
||||
'guide.play': 'INICIAR',
|
||||
'guide.pause': 'PAUSAR',
|
||||
'guide.step': 'PASSO',
|
||||
'guide.speed': 'VELOCIDADE',
|
||||
'guide.waiting': 'Aguardando...',
|
||||
'guide.solved': 'Resolvido!',
|
||||
'custom.title': 'JOGO PERSONALIZADO',
|
||||
'custom.prompt': 'Digite o tamanho da grade (5 - 80):',
|
||||
'custom.cancel': 'Cancelar',
|
||||
'custom.start': 'Iniciar',
|
||||
'custom.sizeError': 'O tamanho deve estar entre 5 e 80!',
|
||||
'win.title': 'PARABÉNS!',
|
||||
'win.message': 'Você resolveu o puzzle!',
|
||||
'win.time': 'Tempo:',
|
||||
'win.playAgain': 'Jogar novamente',
|
||||
'win.shareTitle': 'Compartilhe seu resultado',
|
||||
'win.shareText': 'Resolvi um nonograma {size}x{size} em {time}!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'Baixar captura',
|
||||
'pwa.installTitle': 'Instale o app e jogue offline',
|
||||
'pwa.installMobile': 'Adicionar à tela inicial',
|
||||
'pwa.installDesktop': 'Instalar no desktop',
|
||||
'language.label': 'Seleção de idioma',
|
||||
'language.pl': 'Polonês',
|
||||
'language.en': 'Inglês',
|
||||
'language.zh': 'Chinês',
|
||||
'language.hi': 'Hindi',
|
||||
'language.es': 'Espanhol',
|
||||
'language.fr': 'Francês',
|
||||
'language.ar': 'Árabe',
|
||||
'language.bn': 'Bengali',
|
||||
'language.ru': 'Russo',
|
||||
'language.pt': 'Português',
|
||||
'language.ur': 'Urdu',
|
||||
'theme.label': 'Tema',
|
||||
'theme.system': 'Sistema',
|
||||
'theme.light': 'Claro',
|
||||
'theme.dark': 'Escuro'
|
||||
},
|
||||
ur: {
|
||||
'app.title': 'Nonograms',
|
||||
'level.easy': 'آسان 5X5',
|
||||
'level.medium': 'درمیانہ 10X10',
|
||||
'level.hard': 'مشکل 15X15',
|
||||
'level.custom': 'حسب ضرورت',
|
||||
'level.guide': 'رہنمائی ❓',
|
||||
'actions.reset': 'ری سیٹ',
|
||||
'actions.random': 'نیا رینڈم',
|
||||
'actions.undo': 'واپس',
|
||||
'status.time': 'وقت',
|
||||
'status.moves': 'چالیں',
|
||||
'status.progress': 'پیش رفت',
|
||||
'fixed.time': 'وقت:',
|
||||
'fixed.progress': 'پیش رفت:',
|
||||
'fixed.hide': 'چھپائیں',
|
||||
'fixed.show': 'دکھائیں',
|
||||
'guide.play': 'شروع',
|
||||
'guide.pause': 'توقف',
|
||||
'guide.step': 'قدم',
|
||||
'guide.speed': 'رفتار',
|
||||
'guide.waiting': 'انتظار...',
|
||||
'guide.solved': 'حل ہوگیا!',
|
||||
'custom.title': 'حسب ضرورت کھیل',
|
||||
'custom.prompt': 'گرڈ کا سائز درج کریں (5 - 80):',
|
||||
'custom.cancel': 'منسوخ',
|
||||
'custom.start': 'شروع',
|
||||
'custom.sizeError': 'سائز 5 اور 80 کے درمیان ہونا چاہیے!',
|
||||
'win.title': 'مبارک ہو!',
|
||||
'win.message': 'آپ نے پہیلی حل کر لی!',
|
||||
'win.time': 'وقت:',
|
||||
'win.playAgain': 'دوبارہ کھیلیں',
|
||||
'win.shareTitle': 'اپنا نتیجہ شیئر کریں',
|
||||
'win.shareText': 'میں نے {time} میں {size}x{size} نونوگرام حل کیا!',
|
||||
'win.shareX': 'X',
|
||||
'win.shareFacebook': 'Facebook',
|
||||
'win.shareWhatsapp': 'WhatsApp',
|
||||
'win.shareDownload': 'اسکرین شاٹ ڈاؤن لوڈ کریں',
|
||||
'pwa.installTitle': 'ایپ انسٹال کریں اور آف لائن کھیلیں',
|
||||
'pwa.installMobile': 'ہوم اسکرین پر شامل کریں',
|
||||
'pwa.installDesktop': 'ڈیسک ٹاپ پر انسٹال کریں',
|
||||
'language.label': 'زبان کا انتخاب',
|
||||
'language.pl': 'پولش',
|
||||
'language.en': 'انگریزی',
|
||||
'language.zh': 'چینی',
|
||||
'language.hi': 'ہندی',
|
||||
'language.es': 'ہسپانوی',
|
||||
'language.fr': 'فرانسیسی',
|
||||
'language.ar': 'عربی',
|
||||
'language.bn': 'بنگالی',
|
||||
'language.ru': 'روسی',
|
||||
'language.pt': 'پرتگالی',
|
||||
'language.ur': 'اردو',
|
||||
'theme.label': 'تھیم',
|
||||
'theme.system': 'سسٹم',
|
||||
'theme.light': 'ہلکا',
|
||||
'theme.dark': 'گہرا'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -118,7 +666,7 @@ const t = (key, params) => {
|
||||
};
|
||||
|
||||
const setLocale = (value) => {
|
||||
locale.value = messages[value] ? value : 'en';
|
||||
locale.value = supportedLocales.includes(value) ? value : 'en';
|
||||
if (typeof document !== 'undefined') {
|
||||
document.documentElement.lang = locale.value;
|
||||
document.title = t('app.title');
|
||||
|
||||
Reference in New Issue
Block a user