diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 8b3a726..d222122 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -1,20 +1,16 @@ { "@@locale": "ar", - "appTitle": "المنتحل", "subtitle": "لعبة تخمين اجتماعية", "loadingWords": "جارٍ تحميل الكلمات...", "playersRange": "3-20 لاعبًا • بدون إنترنت", - "createGame": "إنشاء لعبة", "joinGame": "الانضمام إلى لعبة", "howToPlay": "كيفية اللعب", "settings": "الإعدادات", - "gameMode": "وضع اللعب", "singleDevice": "جهاز واحد", "multiDevice": "أجهزة متعددة", - "category": "الفئة", "categoryAll": "الكل", "categoryAnimals": "حيوانات", @@ -27,11 +23,12 @@ "categoryMovies": "أفلام", "categoryMusic": "موسيقى", "categoryTechnology": "تكنولوجيا", - "playersCount": "اللاعبون ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "يوجد لاعب بهذا الاسم بالفعل", "maxPlayersReached": "الحد الأقصى 20 لاعبًا", "minPlayersRequired": "يلزم 3 لاعبين على الأقل", - "configuration": "الإعدادات", "impostors": "🎭 المنتحلون", "impostorClue": "🔍 تلميح للمنتحل", @@ -50,15 +46,15 @@ "twoMin": "2 د", "threeMin": "3 د", "fiveMin": "5 د", - "startGame": "بدء اللعبة", - "seeYourWord": "اعرف كلمتك", "eachPlayerMustSee": "يجب على كل لاعب رؤية كلمته بسرية", "roundNumber": "الجولة {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "شاهد كلمته بالفعل", @@ -67,16 +63,19 @@ "playersRemaining": "متبقٍّ {count} لاعبين", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "أنت المنتحل!", "yourWordIs": "كلمتك هي:", "clueCategory": "تلميح: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "اضغط مطولًا لرؤية كلمتك", @@ -84,11 +83,12 @@ "showingWord": "👁️ جارٍ العرض...", "holdToSee": "👆 اضغط مطولًا للعرض", "seenMyWord": "رأيت كلمتي", - "debateRound": "النقاش - الجولة {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ انتهى الوقت!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} نشطون • {impostors} منتحل(ون) مختبئون", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "تم إقصاؤه", "notes": "ملاحظات", "goToVoting": "الانتقال للتصويت", - "voting": "🗳️ التصويت", "turnToVote": "دورك للتصويت:", "votesProgress": "الأصوات: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "من تعتقد أنه المنتحل؟", @@ -120,7 +127,6 @@ "allVoted": "صوّت الجميع!", "tapToReveal": "اضغط لكشف النتيجة", "revealResult": "كشف النتيجة", - "result": "النتيجة", "revealing": "جارٍ الكشف...", "wasImpostor": "كان المنتحل! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "عرض النتيجة النهائية", "impostorGuessWord": "هل يخمّن المنتحل الكلمة؟", "nextRound": "الجولة التالية", - "impostorGuessTitle": "🎯 تخمين المنتحل", "impostorCanGuess": "يمكن للمنتحل المُقصى\nمحاولة تخمين الكلمة", "ifCorrectImpostorsWin": "إذا أصاب، يفوز المنتحلون!", @@ -140,20 +145,23 @@ "theWordWas": "الكلمة كانت: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "فاز المنتحلون!", "wrongGuess": "تخمين خاطئ!", "gameContinues": "اللعبة مستمرة...", - "gameOver": "انتهت اللعبة", "playersWin": "فاز اللاعبون!", "theSecretWordWas": "🔍 الكلمة كانت:", "categoryLabel": "الفئة: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 المنتحل كان:", @@ -162,13 +170,16 @@ "roundElimination": "الجولة {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "إعادة المباراة", "mainMenu": "القائمة الرئيسية", - "notesTitle": "📝 ملاحظات", "notesSaved": "تم حفظ الملاحظات", "whoAreYou": "من أنت؟", @@ -176,14 +187,15 @@ "notesOf": "ملاحظات {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "ملاحظات عن كل لاعب", "playerNoteHint": "ماذا قال؟ هل هو مشبوه؟", "freeNote": "ملاحظة حرة", "freeNoteHint": "ملاحظات شخصية...", - "rulesTitle": "📖 كيفية اللعب", "rulesWhatIsTitle": "🎭 ما هو المنتحل؟", "rulesWhatIsBody": "لعبة تخمين اجتماعية لـ 3-20 لاعبًا. الجميع يحصل على كلمة سرية... ما عدا المنتحل! مهمتك: اكتشف من يتظاهر.", @@ -199,20 +211,17 @@ "rulesModesBody": "• جهاز واحد: الجميع يشارك نفس الجهاز. كل لاعب يرى كلمته بالضغط المطول على الزر.\n\n• أجهزة متعددة: كل لاعب يستخدم جهازه الخاص. يتم الاتصال عبر بلوتوث/WiFi Direct بدون حاجة للإنترنت.", "rulesExampleTitle": "✏️ مثال على لعبة", "rulesExampleBody": "الكلمة السرية: \"بيتزا\"\n\n• أحمد: \"تُؤكل ساخنة\" ✓\n• فاطمة: \"تأتي في صندوق\" ✓\n• ليلى (المنتحل): \"شيء شائع جدًا\" 🤔\n• خالد: \"عليها جبنة\" ✓\n\nإجابة ليلى كانت عامة جدًا... مشبوهة!", - "joinGameTitle": "الانضمام إلى لعبة", "multiDeviceMode": "وضع الأجهزة المتعددة", "scanQrDescription": "امسح رمز QR الذي يعرضه المضيف للاتصال باللعبة عبر بلوتوث/WiFi Direct.", "comingSoon": "قريبًا", "nearbyNotAvailable": "اتصال الأجهزة المتعددة عبر Nearby Connections يتطلب أجهزة أندرويد فعلية.\n\nحاليًا، استخدم وضع \"جهاز واحد\" للعب على جهاز مشترك.", "back": "رجوع", - "yes": "نعم", "no": "لا", "cancel": "إلغاء", "accept": "قبول", "next": "التالي", - "settingsTitle": "الإعدادات", "language": "اللغة", "soundVolume": "مستوى المؤثرات الصوتية", @@ -257,5 +266,10 @@ "defaultPlayerName": "لاعب", "play": "العب", "history": "السجل", - "mainTagline": "اكتشف المنتحل قبل فوات الأوان" + "mainTagline": "اكتشف المنتحل قبل فوات الأوان", + "deviceProfile": "الملف الشخصي للجهاز", + "profileName": "الاسم", + "profileNick": "اللقب", + "save": "حفظ", + "automaticLanguage": "تلقائي" } diff --git a/lib/l10n/app_ca.arb b/lib/l10n/app_ca.arb index d00a940..f026378 100644 --- a/lib/l10n/app_ca.arb +++ b/lib/l10n/app_ca.arb @@ -1,20 +1,16 @@ { "@@locale": "ca", - "appTitle": "L'Impostor", "subtitle": "Joc de deducció social", "loadingWords": "Carregant paraules...", "playersRange": "3-20 jugadors • Sense internet", - "createGame": "Crear partida", "joinGame": "Unir-se a partida", "howToPlay": "Com jugar", "settings": "Configuració", - "gameMode": "Mode de joc", "singleDevice": "Un sol mòbil", "multiDevice": "Multimòbil", - "category": "Categoria", "categoryAll": "Totes", "categoryAnimals": "Animals", @@ -27,11 +23,12 @@ "categoryMovies": "Pel·lícules", "categoryMusic": "Música", "categoryTechnology": "Tecnologia", - "playersCount": "Jugadors ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Ja existeix un jugador amb aquest nom", "maxPlayersReached": "Màxim 20 jugadors", "minPlayersRequired": "Calen almenys 3 jugadors", - "configuration": "Configuració", "impostors": "🎭 Impostors", "impostorClue": "🔍 Pista per a l'impostor", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Iniciar partida", - "seeYourWord": "Veure la teva paraula", "eachPlayerMustSee": "Cada jugador ha de veure la seva paraula en secret", "roundNumber": "Ronda {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Ja ha vist la seva paraula", @@ -67,16 +63,19 @@ "playersRemaining": "Falten {count} jugadors", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Ets l'impostor!", "yourWordIs": "La teva paraula és:", "clueCategory": "Pista: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Mantén premut per veure la teva paraula", @@ -84,11 +83,12 @@ "showingWord": "👁️ Mostrant...", "holdToSee": "👆 Mantén premut per veure", "seenMyWord": "He vist la meva paraula", - "debateRound": "Debat - Ronda {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Temps esgotat!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} actius • {impostors} impostor(s) ocults", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Eliminat", "notes": "Notes", "goToVoting": "Anar a votació", - "voting": "🗳️ Votació", "turnToVote": "Torn de votar:", "votesProgress": "Vots: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Qui creus que és l'impostor?", @@ -120,7 +127,6 @@ "allVoted": "Tots han votat!", "tapToReveal": "Toca per revelar el resultat", "revealResult": "Revelar resultat", - "result": "Resultat", "revealing": "Revelant...", "wasImpostor": "Era IMPOSTOR! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Veure resultat final", "impostorGuessWord": "L'impostor endevina la paraula?", "nextRound": "Següent ronda", - "impostorGuessTitle": "🎯 Endevinalla de l'impostor", "impostorCanGuess": "L'impostor eliminat pot\nintentar endevinar la paraula", "ifCorrectImpostorsWin": "Si encerta, els impostors guanyen!", @@ -140,20 +145,23 @@ "theWordWas": "La paraula era: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Els impostors guanyen!", "wrongGuess": "No ha encertat!", "gameContinues": "La partida continua...", - "gameOver": "Fi de partida", "playersWin": "Els jugadors guanyen!", "theSecretWordWas": "🔍 La paraula era:", "categoryLabel": "Categoria: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 L'impostor era:", @@ -162,13 +170,16 @@ "roundElimination": "Ronda {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Revenja", "mainMenu": "Menú principal", - "notesTitle": "📝 Notes", "notesSaved": "Notes desades", "whoAreYou": "Qui ets?", @@ -176,14 +187,15 @@ "notesOf": "Notes de {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Apunts sobre cada jugador", "playerNoteHint": "Què ha dit? Sospitós?", "freeNote": "Nota lliure", "freeNoteHint": "Apunts personals...", - "rulesTitle": "📖 Com jugar", "rulesWhatIsTitle": "🎭 Què és L'Impostor?", "rulesWhatIsBody": "Un joc de deducció social per a 3-20 jugadors. Tots reben una paraula secreta... excepte l'impostor! La teva missió: descobrir qui fingeix.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Un sol mòbil: tots comparteixen el dispositiu. Cada jugador veu la seva paraula prement i mantenint un botó.\n\n• Multimòbil: cada jugador fa servir el seu propi dispositiu. Es connecten per Bluetooth/WiFi Direct sense necessitat d'internet.", "rulesExampleTitle": "✏️ Exemple de partida", "rulesExampleBody": "Paraula secreta: \"Pizza\"\n\n• Laia: \"Es menja calenta\" ✓\n• Jordi: \"Ve en una capsa\" ✓\n• Marta (impostor): \"És molt popular\" 🤔\n• Pau: \"Té formatge\" ✓\n\nLa Marta va donar una resposta molt genèrica... Sospitosa!", - "joinGameTitle": "Unir-se a partida", "multiDeviceMode": "Mode multimòbil", "scanQrDescription": "Escaneja el codi QR que mostra l'amfitrió per connectar-te a la partida via Bluetooth/WiFi Direct.", "comingSoon": "Properament", "nearbyNotAvailable": "La connexió multimòbil amb Nearby Connections requereix dispositius Android físics.\n\nDe moment, fes servir el mode \"Un sol mòbil\" per jugar en un dispositiu compartit.", "back": "Tornar", - "yes": "Sí", "no": "No", "cancel": "Cancel·lar", "accept": "Acceptar", "next": "Següent", - "settingsTitle": "Configuració", "language": "Idioma", "soundVolume": "Volum d'efectes", @@ -257,5 +266,10 @@ "defaultPlayerName": "Jugador", "play": "Jugar", "history": "Historial", - "mainTagline": "Descobreix l’impostor abans que siga massa tard" + "mainTagline": "Descobreix l’impostor abans que siga massa tard", + "deviceProfile": "Perfil del dispositiu", + "profileName": "Nom", + "profileNick": "Àlies", + "save": "Desa", + "automaticLanguage": "Automàtic" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 70fd51c..ebd85b5 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -1,20 +1,16 @@ { "@@locale": "de", - "appTitle": "Farolero", "subtitle": "Soziales Deduktionsspiel", "loadingWords": "Wörter werden geladen...", "playersRange": "3-20 Spieler • Ohne Internet", - "createGame": "Spiel erstellen", "joinGame": "Spiel beitreten", "howToPlay": "Spielanleitung", "settings": "Einstellungen", - "gameMode": "Spielmodus", "singleDevice": "Ein Gerät", "multiDevice": "Mehrere Geräte", - "category": "Kategorie", "categoryAll": "Alle", "categoryAnimals": "Tiere", @@ -27,11 +23,12 @@ "categoryMovies": "Filme", "categoryMusic": "Musik", "categoryTechnology": "Technologie", - "playersCount": "Spieler ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Ein Spieler mit diesem Namen existiert bereits", "maxPlayersReached": "Maximal 20 Spieler", "minPlayersRequired": "Mindestens 3 Spieler erforderlich", - "configuration": "Konfiguration", "impostors": "🎭 Hochstapler", "impostorClue": "🔍 Hinweis für den Hochstapler", @@ -50,15 +46,15 @@ "twoMin": "2 Min", "threeMin": "3 Min", "fiveMin": "5 Min", - "startGame": "Spiel starten", - "seeYourWord": "Dein Wort ansehen", "eachPlayerMustSee": "Jeder Spieler muss sein Wort im Geheimen ansehen", "roundNumber": "Runde {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Hat sein Wort bereits gesehen", @@ -67,16 +63,19 @@ "playersRemaining": "Noch {count} Spieler übrig", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Du bist der Hochstapler!", "yourWordIs": "Dein Wort ist:", "clueCategory": "Hinweis: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Gedrückt halten, um dein Wort zu sehen", @@ -84,11 +83,12 @@ "showingWord": "👁️ Wird angezeigt...", "holdToSee": "👆 Gedrückt halten zum Ansehen", "seenMyWord": "Ich habe mein Wort gesehen", - "debateRound": "Diskussion - Runde {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Zeit abgelaufen!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} aktiv • {impostors} versteckte(r) Hochstapler", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Ausgeschieden", "notes": "Notizen", "goToVoting": "Zur Abstimmung", - "voting": "🗳️ Abstimmung", "turnToVote": "Jetzt abstimmen:", "votesProgress": "Stimmen: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Wer ist deiner Meinung nach der Hochstapler?", @@ -120,7 +127,6 @@ "allVoted": "Alle haben abgestimmt!", "tapToReveal": "Tippen, um das Ergebnis aufzudecken", "revealResult": "Ergebnis aufdecken", - "result": "Ergebnis", "revealing": "Wird aufgedeckt...", "wasImpostor": "War ein HOCHSTAPLER! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Endergebnis anzeigen", "impostorGuessWord": "Errät der Hochstapler das Wort?", "nextRound": "Nächste Runde", - "impostorGuessTitle": "🎯 Tipp des Hochstaplers", "impostorCanGuess": "Der ausgeschiedene Hochstapler kann\nversuchen, das Wort zu erraten", "ifCorrectImpostorsWin": "Bei richtigem Tipp gewinnen die Hochstapler!", @@ -140,20 +145,23 @@ "theWordWas": "Das Wort war: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Die Hochstapler gewinnen!", "wrongGuess": "Falsch geraten!", "gameContinues": "Das Spiel geht weiter...", - "gameOver": "Spielende", "playersWin": "Die Spieler gewinnen!", "theSecretWordWas": "🔍 Das Wort war:", "categoryLabel": "Kategorie: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 Der Hochstapler war:", @@ -162,13 +170,16 @@ "roundElimination": "Runde {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Revanche", "mainMenu": "Hauptmenü", - "notesTitle": "📝 Notizen", "notesSaved": "Notizen gespeichert", "whoAreYou": "Wer bist du?", @@ -176,14 +187,15 @@ "notesOf": "Notizen von {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Notizen zu jedem Spieler", "playerNoteHint": "Was hat er/sie gesagt? Verdächtig?", "freeNote": "Freie Notiz", "freeNoteHint": "Persönliche Notizen...", - "rulesTitle": "📖 Spielanleitung", "rulesWhatIsTitle": "🎭 Was ist Der Hochstapler?", "rulesWhatIsBody": "Ein soziales Deduktionsspiel für 3-20 Spieler. Alle erhalten ein geheimes Wort... außer der Hochstapler! Deine Mission: herausfinden, wer blufft.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Ein Gerät: Alle teilen sich das Gerät. Jeder Spieler sieht sein Wort, indem er einen Button gedrückt hält.\n\n• Mehrere Geräte: Jeder Spieler nutzt sein eigenes Gerät. Die Verbindung erfolgt über Bluetooth/WiFi Direct ohne Internetzugang.", "rulesExampleTitle": "✏️ Beispielrunde", "rulesExampleBody": "Geheimes Wort: \"Pizza\"\n\n• Lisa: \"Man isst es warm\" ✓\n• Max: \"Kommt in einer Schachtel\" ✓\n• Nina (Hochstapler): \"Ist sehr beliebt\" 🤔\n• Felix: \"Hat Käse drauf\" ✓\n\nNina gab eine sehr allgemeine Antwort... Verdächtig!", - "joinGameTitle": "Spiel beitreten", "multiDeviceMode": "Mehrere-Geräte-Modus", "scanQrDescription": "Scanne den QR-Code des Hosts, um der Partie über Bluetooth/WiFi Direct beizutreten.", "comingSoon": "Demnächst", "nearbyNotAvailable": "Die Mehrgeräte-Verbindung mit Nearby Connections erfordert physische Android-Geräte.\n\nVerwende vorerst den Modus \"Ein Gerät\", um auf einem gemeinsamen Gerät zu spielen.", "back": "Zurück", - "yes": "Ja", "no": "Nein", "cancel": "Abbrechen", "accept": "Akzeptieren", "next": "Weiter", - "settingsTitle": "Einstellungen", "language": "Sprache", "soundVolume": "Effektlautstärke", @@ -257,5 +266,10 @@ "defaultPlayerName": "Spieler", "play": "Spielen", "history": "Verlauf", - "mainTagline": "Finde den Hochstapler, bevor es zu spät ist" + "mainTagline": "Finde den Hochstapler, bevor es zu spät ist", + "deviceProfile": "Geräteprofil", + "profileName": "Name", + "profileNick": "Nickname", + "save": "Speichern", + "automaticLanguage": "Automatisch" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index f8e6f15..cc42346 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -298,5 +298,10 @@ "defaultPlayerName": "Player", "play": "Play", "history": "History", - "mainTagline": "Find the impostor before it is too late" + "mainTagline": "Find the impostor before it is too late", + "deviceProfile": "Device profile", + "profileName": "Name", + "profileNick": "Nick", + "save": "Save", + "automaticLanguage": "Automatic" } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index 2f947c9..74b1532 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -308,7 +308,9 @@ "couldNotConnectToHost": "No se pudo conectar a {host}", "@couldNotConnectToHost": { "placeholders": { - "host": { "type": "String" } + "host": { + "type": "String" + } } }, "room": "Sala", @@ -323,12 +325,19 @@ "cannotStartWithReason": "No se puede iniciar: {reason}", "@cannotStartWithReason": { "placeholders": { - "reason": { "type": "String" } + "reason": { + "type": "String" + } } }, "invalidRoom": "sala inválida", "defaultPlayerName": "Jugador", "play": "Jugar", "history": "Historial", - "mainTagline": "Descubre al impostor antes de que sea tarde" + "mainTagline": "Descubre al impostor antes de que sea tarde", + "deviceProfile": "Perfil del dispositivo", + "profileName": "Nombre", + "profileNick": "Nick", + "save": "Guardar", + "automaticLanguage": "Automático" } diff --git a/lib/l10n/app_eu.arb b/lib/l10n/app_eu.arb index 6e01731..5b5b638 100644 --- a/lib/l10n/app_eu.arb +++ b/lib/l10n/app_eu.arb @@ -1,20 +1,16 @@ { "@@locale": "eu", - "appTitle": "Inpostorrea", "subtitle": "Dedukzio sozialeko jokoa", "loadingWords": "Hitzak kargatzen...", "playersRange": "3-20 jokalari • Internetik gabe", - "createGame": "Partida sortu", "joinGame": "Partidara batu", "howToPlay": "Nola jolastu", "settings": "Ezarpenak", - "gameMode": "Joko-modua", "singleDevice": "Mugikor bakarra", "multiDevice": "Mugikor anitz", - "category": "Kategoria", "categoryAll": "Denak", "categoryAnimals": "Animaliak", @@ -27,11 +23,12 @@ "categoryMovies": "Filmak", "categoryMusic": "Musika", "categoryTechnology": "Teknologia", - "playersCount": "Jokalariak ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Izen hori duen jokalari bat badago dagoeneko", "maxPlayersReached": "Gehienez 20 jokalari", "minPlayersRequired": "Gutxienez 3 jokalari behar dira", - "configuration": "Konfigurazioa", "impostors": "🎭 Inpostoreak", "impostorClue": "🔍 Inpostorearentzako pista", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Partida hasi", - "seeYourWord": "Ikusi zure hitza", "eachPlayerMustSee": "Jokalari bakoitzak bere hitza ezkutuan ikusi behar du", "roundNumber": "{round}. txanda", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Bere hitza ikusi du dagoeneko", @@ -67,16 +63,19 @@ "playersRemaining": "{count} jokalari falta dira", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Inpostorea zara!", "yourWordIs": "Zure hitza da:", "clueCategory": "Pista: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Sakatuta eduki zure hitza ikusteko", @@ -84,11 +83,12 @@ "showingWord": "👁️ Erakusten...", "holdToSee": "👆 Sakatuta eduki ikusteko", "seenMyWord": "Nire hitza ikusi dut", - "debateRound": "Eztabaida - {round}. txanda", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Denbora agortu da!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} aktibo • {impostors} inpostore ezkutu", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Kanporatua", "notes": "Oharrak", "goToVoting": "Bozkatzera joan", - "voting": "🗳️ Bozketa", "turnToVote": "Bozkatze-txanda:", "votesProgress": "Botoak: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Nor da inpostorea zure ustez?", @@ -120,7 +127,6 @@ "allVoted": "Denek bozka eman dute!", "tapToReveal": "Sakatu emaitza agertzeko", "revealResult": "Emaitza agertu", - "result": "Emaitza", "revealing": "Agertzen...", "wasImpostor": "INPOSTOREA zen! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Azken emaitza ikusi", "impostorGuessWord": "Inpostoreak hitza asmatzen du?", "nextRound": "Hurrengo txanda", - "impostorGuessTitle": "🎯 Inpostorearen asmaketa", "impostorCanGuess": "Kanporatutako inpostoreak\nhitza asmatzen saia daiteke", "ifCorrectImpostorsWin": "Asmatzen badu, inpostoreek irabazten dute!", @@ -140,20 +145,23 @@ "theWordWas": "Hitza zen: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Inpostoreek irabazi dute!", "wrongGuess": "Ez du asmatu!", "gameContinues": "Partida jarraitzen du...", - "gameOver": "Partidaren amaiera", "playersWin": "Jokalariek irabazi dute!", "theSecretWordWas": "🔍 Hitza zen:", "categoryLabel": "Kategoria: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 Inpostorea zen:", @@ -162,13 +170,16 @@ "roundElimination": "{round}. txanda: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Errebantxa", "mainMenu": "Menu nagusia", - "notesTitle": "📝 Oharrak", "notesSaved": "Oharrak gordeta", "whoAreYou": "Nor zara?", @@ -176,14 +187,15 @@ "notesOf": "{name}-(r)en oharrak", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Jokalari bakoitzari buruzko apunteak", "playerNoteHint": "Zer esan du? Susmagarria?", "freeNote": "Ohar librea", "freeNoteHint": "Apunte pertsonalak...", - "rulesTitle": "📖 Nola jolastu", "rulesWhatIsTitle": "🎭 Zer da Inpostorrea?", "rulesWhatIsBody": "3-20 jokalarientzako dedukzio sozialeko jokoa. Denek hitz sekretu bat jasotzen dute... inpostorea izan ezik! Zure misioa: nor ari den itxurak egiten aurkitzea.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Mugikor bakarra: denek gailua partekatzen dute. Jokalari bakoitzak bere hitza ikusten du botoi bat sakatuta edukiz.\n\n• Mugikor anitz: jokalari bakoitzak bere gailua erabiltzen du. Bluetooth/WiFi Direct bidez konektatzen dira internetik behartu gabe.", "rulesExampleTitle": "✏️ Partida-adibidea", "rulesExampleBody": "Hitz sekretua: \"Pizza\"\n\n• Ane: \"Beroa jaten da\" ✓\n• Mikel: \"Kutxa batean dator\" ✓\n• Irati (inpostorea): \"Oso ezaguna da\" 🤔\n• Unai: \"Gazta dauka\" ✓\n\nIratik erantzun oso generikoa eman zuen... Susmagarria!", - "joinGameTitle": "Partidara batu", "multiDeviceMode": "Mugikor anitzeko modua", "scanQrDescription": "Eskaneatu ostalariak erakusten duen QR kodea partidara Bluetooth/WiFi Direct bidez konektatzeko.", "comingSoon": "Laster", "nearbyNotAvailable": "Mugikor anitzeko konexioak Nearby Connections-ekin Android gailu fisikoak behar ditu.\n\nOraingoz, erabili \"Mugikor bakarra\" modua gailu partekatuan jolasteko.", "back": "Atzera", - "yes": "Bai", "no": "Ez", "cancel": "Ezeztatu", "accept": "Onartu", "next": "Hurrengoa", - "settingsTitle": "Ezarpenak", "language": "Hizkuntza", "soundVolume": "Efektuen bolumena", @@ -257,5 +266,10 @@ "defaultPlayerName": "Jokalaria", "play": "Jokatu", "history": "Historia", - "mainTagline": "Aurkitu iruzurtia berandu baino lehen" + "mainTagline": "Aurkitu iruzurtia berandu baino lehen", + "deviceProfile": "Gailuaren profila", + "profileName": "Izena", + "profileNick": "Ezizena", + "save": "Gorde", + "automaticLanguage": "Automatikoa" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index b583472..28c1acd 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -1,20 +1,16 @@ { "@@locale": "fr", - "appTitle": "Farolero", "subtitle": "Jeu de déduction sociale", "loadingWords": "Chargement des mots...", "playersRange": "3-20 joueurs • Sans internet", - "createGame": "Créer une partie", "joinGame": "Rejoindre une partie", "howToPlay": "Comment jouer", "settings": "Paramètres", - "gameMode": "Mode de jeu", "singleDevice": "Un seul téléphone", "multiDevice": "Multi-téléphone", - "category": "Catégorie", "categoryAll": "Toutes", "categoryAnimals": "Animaux", @@ -27,11 +23,12 @@ "categoryMovies": "Films", "categoryMusic": "Musique", "categoryTechnology": "Technologie", - "playersCount": "Joueurs ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Un joueur avec ce nom existe déjà", "maxPlayersReached": "Maximum 20 joueurs", "minPlayersRequired": "Il faut au moins 3 joueurs", - "configuration": "Configuration", "impostors": "🎭 Imposteurs", "impostorClue": "🔍 Indice pour l'imposteur", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Lancer la partie", - "seeYourWord": "Voir ton mot", "eachPlayerMustSee": "Chaque joueur doit voir son mot en secret", "roundNumber": "Manche {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "A déjà vu son mot", @@ -67,16 +63,19 @@ "playersRemaining": "Encore {count} joueurs", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Tu es l'imposteur !", "yourWordIs": "Ton mot est :", "clueCategory": "Indice : {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Maintiens appuyé pour voir ton mot", @@ -84,11 +83,12 @@ "showingWord": "👁️ Affichage...", "holdToSee": "👆 Maintiens appuyé pour voir", "seenMyWord": "J'ai vu mon mot", - "debateRound": "Débat - Manche {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Temps écoulé !", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} actifs • {impostors} imposteur(s) caché(s)", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Éliminé", "notes": "Notes", "goToVoting": "Passer au vote", - "voting": "🗳️ Vote", "turnToVote": "Au tour de voter :", "votesProgress": "Votes : {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Qui est l'imposteur selon toi ?", @@ -120,7 +127,6 @@ "allVoted": "Tout le monde a voté !", "tapToReveal": "Appuie pour révéler le résultat", "revealResult": "Révéler le résultat", - "result": "Résultat", "revealing": "Révélation...", "wasImpostor": "C'était l'IMPOSTEUR ! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Voir le résultat final", "impostorGuessWord": "L'imposteur devine-t-il le mot ?", "nextRound": "Manche suivante", - "impostorGuessTitle": "🎯 Devinette de l'imposteur", "impostorCanGuess": "L'imposteur éliminé peut\ntenter de deviner le mot", "ifCorrectImpostorsWin": "S'il trouve, les imposteurs gagnent !", @@ -140,20 +145,23 @@ "theWordWas": "Le mot était : {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Les imposteurs gagnent !", "wrongGuess": "Il n'a pas trouvé !", "gameContinues": "La partie continue...", - "gameOver": "Fin de partie", "playersWin": "Les joueurs gagnent !", "theSecretWordWas": "🔍 Le mot était :", "categoryLabel": "Catégorie : {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 L'imposteur était :", @@ -162,13 +170,16 @@ "roundElimination": "Manche {round} : {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Revanche", "mainMenu": "Menu principal", - "notesTitle": "📝 Notes", "notesSaved": "Notes sauvegardées", "whoAreYou": "Qui es-tu ?", @@ -176,14 +187,15 @@ "notesOf": "Notes de {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Notes sur chaque joueur", "playerNoteHint": "Qu'a-t-il dit ? Suspect ?", "freeNote": "Note libre", "freeNoteHint": "Notes personnelles...", - "rulesTitle": "📖 Comment jouer", "rulesWhatIsTitle": "🎭 Qu'est-ce que L'Imposteur ?", "rulesWhatIsBody": "Un jeu de déduction sociale pour 3-20 joueurs. Tout le monde reçoit un mot secret... sauf l'imposteur ! Ta mission : découvrir qui bluff.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Un seul téléphone : tout le monde partage l'appareil. Chaque joueur voit son mot en appuyant et maintenant un bouton.\n\n• Multi-téléphone : chaque joueur utilise son propre appareil. Ils se connectent par Bluetooth/WiFi Direct sans avoir besoin d'internet.", "rulesExampleTitle": "✏️ Exemple de partie", "rulesExampleBody": "Mot secret : \"Pizza\"\n\n• Marie : \"Ça se mange chaud\" ✓\n• Lucas : \"Ça arrive dans une boîte\" ✓\n• Julie (imposteur) : \"C'est très populaire\" 🤔\n• Thomas : \"Il y a du fromage\" ✓\n\nJulie a donné une réponse très générique... Suspecte !", - "joinGameTitle": "Rejoindre une partie", "multiDeviceMode": "Mode multi-téléphone", "scanQrDescription": "Scanne le code QR affiché par l'hôte pour te connecter à la partie via Bluetooth/WiFi Direct.", "comingSoon": "Prochainement", "nearbyNotAvailable": "La connexion multi-téléphone avec Nearby Connections nécessite des appareils Android physiques.\n\nPour l'instant, utilise le mode \"Un seul téléphone\" pour jouer sur un appareil partagé.", "back": "Retour", - "yes": "Oui", "no": "Non", "cancel": "Annuler", "accept": "Accepter", "next": "Suivant", - "settingsTitle": "Paramètres", "language": "Langue", "soundVolume": "Volume des effets", @@ -257,5 +266,10 @@ "defaultPlayerName": "Joueur", "play": "Jouer", "history": "Historique", - "mainTagline": "Découvre l’imposteur avant qu’il ne soit trop tard" + "mainTagline": "Découvre l’imposteur avant qu’il ne soit trop tard", + "deviceProfile": "Profil de l’appareil", + "profileName": "Nom", + "profileNick": "Pseudo", + "save": "Enregistrer", + "automaticLanguage": "Automatique" } diff --git a/lib/l10n/app_hi.arb b/lib/l10n/app_hi.arb index 8d73afe..29ce798 100644 --- a/lib/l10n/app_hi.arb +++ b/lib/l10n/app_hi.arb @@ -1,20 +1,16 @@ { "@@locale": "hi", - "appTitle": "धोखेबाज़", "subtitle": "सामाजिक अनुमान का खेल", "loadingWords": "शब्द लोड हो रहे हैं...", "playersRange": "3-20 खिलाड़ी • इंटरनेट की ज़रूरत नहीं", - "createGame": "गेम बनाएँ", "joinGame": "गेम में शामिल हों", "howToPlay": "कैसे खेलें", "settings": "सेटिंग्स", - "gameMode": "गेम मोड", "singleDevice": "एक डिवाइस", "multiDevice": "मल्टी-डिवाइस", - "category": "श्रेणी", "categoryAll": "सभी", "categoryAnimals": "जानवर", @@ -27,11 +23,12 @@ "categoryMovies": "फ़िल्में", "categoryMusic": "संगीत", "categoryTechnology": "टेक्नोलॉजी", - "playersCount": "खिलाड़ी ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "इस नाम का खिलाड़ी पहले से मौजूद है", "maxPlayersReached": "अधिकतम 20 खिलाड़ी", "minPlayersRequired": "कम से कम 3 खिलाड़ी ज़रूरी हैं", - "configuration": "कॉन्फ़िगरेशन", "impostors": "🎭 धोखेबाज़", "impostorClue": "🔍 धोखेबाज़ के लिए संकेत", @@ -50,15 +46,15 @@ "twoMin": "2 मिनट", "threeMin": "3 मिनट", "fiveMin": "5 मिनट", - "startGame": "गेम शुरू करें", - "seeYourWord": "अपना शब्द देखें", "eachPlayerMustSee": "हर खिलाड़ी को अपना शब्द गुपचुप देखना होगा", "roundNumber": "राउंड {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "अपना शब्द देख चुके हैं", @@ -67,16 +63,19 @@ "playersRemaining": "{count} खिलाड़ी बाकी हैं", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "आप धोखेबाज़ हैं!", "yourWordIs": "आपका शब्द है:", "clueCategory": "संकेत: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "अपना शब्द देखने के लिए दबाए रखें", @@ -84,11 +83,12 @@ "showingWord": "👁️ दिखा रहे हैं...", "holdToSee": "👆 देखने के लिए दबाए रखें", "seenMyWord": "मैंने अपना शब्द देख लिया", - "debateRound": "बहस - राउंड {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ समय समाप्त!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} सक्रिय • {impostors} धोखेबाज़ छिपे हुए", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "बाहर", "notes": "नोट्स", "goToVoting": "वोटिंग पर जाएँ", - "voting": "🗳️ वोटिंग", "turnToVote": "वोट करने की बारी:", "votesProgress": "वोट: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "आपको कौन धोखेबाज़ लगता है?", @@ -120,7 +127,6 @@ "allVoted": "सबने वोट कर दिया!", "tapToReveal": "नतीजा देखने के लिए टैप करें", "revealResult": "नतीजा दिखाएँ", - "result": "नतीजा", "revealing": "दिखा रहे हैं...", "wasImpostor": "धोखेबाज़ था! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "अंतिम नतीजा देखें", "impostorGuessWord": "क्या धोखेबाज़ शब्द का अनुमान लगाएगा?", "nextRound": "अगला राउंड", - "impostorGuessTitle": "🎯 धोखेबाज़ का अनुमान", "impostorCanGuess": "बाहर किया गया धोखेबाज़\nशब्द का अनुमान लगा सकता है", "ifCorrectImpostorsWin": "अगर सही अनुमान लगाया, तो धोखेबाज़ जीतते हैं!", @@ -140,20 +145,23 @@ "theWordWas": "शब्द था: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "धोखेबाज़ जीत गए!", "wrongGuess": "गलत अनुमान!", "gameContinues": "गेम जारी है...", - "gameOver": "गेम ख़त्म", "playersWin": "खिलाड़ी जीत गए!", "theSecretWordWas": "🔍 शब्द था:", "categoryLabel": "श्रेणी: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 धोखेबाज़ था:", @@ -162,13 +170,16 @@ "roundElimination": "राउंड {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "फिर से खेलें", "mainMenu": "मुख्य मेनू", - "notesTitle": "📝 नोट्स", "notesSaved": "नोट्स सहेजे गए", "whoAreYou": "आप कौन हैं?", @@ -176,14 +187,15 @@ "notesOf": "{name} के नोट्स", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "हर खिलाड़ी के बारे में नोट्स", "playerNoteHint": "उसने क्या कहा? शक है?", "freeNote": "फ्री नोट", "freeNoteHint": "निजी नोट्स...", - "rulesTitle": "📖 कैसे खेलें", "rulesWhatIsTitle": "🎭 धोखेबाज़ क्या है?", "rulesWhatIsBody": "3-20 खिलाड़ियों के लिए एक सामाजिक अनुमान का खेल। सबको एक गुप्त शब्द मिलता है... धोखेबाज़ को छोड़कर! आपका मिशन: पता लगाएँ कि कौन बहाना बना रहा है।", @@ -199,20 +211,17 @@ "rulesModesBody": "• एक डिवाइस: सभी एक ही डिवाइस शेयर करते हैं। हर खिलाड़ी बटन दबाकर अपना शब्द देखता है।\n\n• मल्टी-डिवाइस: हर खिलाड़ी अपना डिवाइस इस्तेमाल करता है। ब्लूटूथ/WiFi Direct से जुड़ते हैं, इंटरनेट की ज़रूरत नहीं।", "rulesExampleTitle": "✏️ गेम का उदाहरण", "rulesExampleBody": "गुप्त शब्द: \"पिज़्ज़ा\"\n\n• आर्यन: \"गरम खाया जाता है\" ✓\n• प्रिया: \"डिब्बे में आता है\" ✓\n• नेहा (धोखेबाज़): \"बहुत लोकप्रिय है\" 🤔\n• राहुल: \"इसमें चीज़ होता है\" ✓\n\nनेहा का जवाब बहुत सामान्य था... शक़ है!", - "joinGameTitle": "गेम में शामिल हों", "multiDeviceMode": "मल्टी-डिवाइस मोड", "scanQrDescription": "ब्लूटूथ/WiFi Direct से गेम में जुड़ने के लिए होस्ट का QR कोड स्कैन करें।", "comingSoon": "जल्द आ रहा है", "nearbyNotAvailable": "Nearby Connections से मल्टी-डिवाइस कनेक्शन के लिए असली Android डिवाइस चाहिए।\n\nअभी के लिए, शेयर किए गए डिवाइस पर खेलने के लिए \"एक डिवाइस\" मोड का उपयोग करें।", "back": "वापस", - "yes": "हाँ", "no": "नहीं", "cancel": "रद्द करें", "accept": "स्वीकार करें", "next": "अगला", - "settingsTitle": "सेटिंग्स", "language": "भाषा", "soundVolume": "साउंड इफ़ेक्ट्स की आवाज़", @@ -257,5 +266,10 @@ "defaultPlayerName": "खिलाड़ी", "play": "खेलें", "history": "इतिहास", - "mainTagline": "बहुत देर होने से पहले impostor को ढूँढें" + "mainTagline": "बहुत देर होने से पहले impostor को ढूँढें", + "deviceProfile": "डिवाइस प्रोफ़ाइल", + "profileName": "नाम", + "profileNick": "निकनेम", + "save": "सहेजें", + "automaticLanguage": "स्वचालित" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index 7d025f7..99d015e 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1,20 +1,16 @@ { "@@locale": "it", - "appTitle": "Farolero", "subtitle": "Gioco di deduzione sociale", "loadingWords": "Caricamento parole...", "playersRange": "3-20 giocatori • Senza internet", - "createGame": "Crea partita", "joinGame": "Unisciti alla partita", "howToPlay": "Come giocare", "settings": "Impostazioni", - "gameMode": "Modalità di gioco", "singleDevice": "Un solo dispositivo", "multiDevice": "Multi-dispositivo", - "category": "Categoria", "categoryAll": "Tutte", "categoryAnimals": "Animali", @@ -27,11 +23,12 @@ "categoryMovies": "Film", "categoryMusic": "Musica", "categoryTechnology": "Tecnologia", - "playersCount": "Giocatori ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Esiste già un giocatore con questo nome", "maxPlayersReached": "Massimo 20 giocatori", "minPlayersRequired": "Servono almeno 3 giocatori", - "configuration": "Configurazione", "impostors": "🎭 Impostori", "impostorClue": "🔍 Indizio per l'impostore", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Inizia partita", - "seeYourWord": "Vedi la tua parola", "eachPlayerMustSee": "Ogni giocatore deve vedere la propria parola in segreto", "roundNumber": "Round {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Ha già visto la sua parola", @@ -67,16 +63,19 @@ "playersRemaining": "Mancano {count} giocatori", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Sei l'impostore!", "yourWordIs": "La tua parola è:", "clueCategory": "Indizio: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Tieni premuto per vedere la tua parola", @@ -84,11 +83,12 @@ "showingWord": "👁️ Mostrando...", "holdToSee": "👆 Tieni premuto per vedere", "seenMyWord": "Ho visto la mia parola", - "debateRound": "Discussione - Round {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Tempo scaduto!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} attivi • {impostors} impostore/i nascosti", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Eliminato", "notes": "Note", "goToVoting": "Vai alla votazione", - "voting": "🗳️ Votazione", "turnToVote": "Turno di votare:", "votesProgress": "Voti: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Chi pensi sia l'impostore?", @@ -120,7 +127,6 @@ "allVoted": "Tutti hanno votato!", "tapToReveal": "Tocca per rivelare il risultato", "revealResult": "Rivela risultato", - "result": "Risultato", "revealing": "Rivelando...", "wasImpostor": "Era un IMPOSTORE! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Vedi risultato finale", "impostorGuessWord": "L'impostore indovina la parola?", "nextRound": "Prossimo round", - "impostorGuessTitle": "🎯 Tentativo dell'impostore", "impostorCanGuess": "L'impostore eliminato può\nprovare a indovinare la parola", "ifCorrectImpostorsWin": "Se indovina, gli impostori vincono!", @@ -140,20 +145,23 @@ "theWordWas": "La parola era: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Gli impostori vincono!", "wrongGuess": "Non ha indovinato!", "gameContinues": "La partita continua...", - "gameOver": "Fine della partita", "playersWin": "I giocatori vincono!", "theSecretWordWas": "🔍 La parola era:", "categoryLabel": "Categoria: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 L'impostore era:", @@ -162,13 +170,16 @@ "roundElimination": "Round {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Rivincita", "mainMenu": "Menu principale", - "notesTitle": "📝 Note", "notesSaved": "Note salvate", "whoAreYou": "Chi sei?", @@ -176,14 +187,15 @@ "notesOf": "Note di {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Appunti su ogni giocatore", "playerNoteHint": "Cosa ha detto? Sospetto?", "freeNote": "Nota libera", "freeNoteHint": "Appunti personali...", - "rulesTitle": "📖 Come giocare", "rulesWhatIsTitle": "🎭 Cos'è L'Impostore?", "rulesWhatIsBody": "Un gioco di deduzione sociale per 3-20 giocatori. Tutti ricevono una parola segreta... tranne l'impostore! La tua missione: scoprire chi sta fingendo.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Un solo dispositivo: tutti condividono il dispositivo. Ogni giocatore vede la propria parola tenendo premuto un pulsante.\n\n• Multi-dispositivo: ogni giocatore usa il proprio dispositivo. Si connettono tramite Bluetooth/WiFi Direct senza bisogno di internet.", "rulesExampleTitle": "✏️ Esempio di partita", "rulesExampleBody": "Parola segreta: \"Pizza\"\n\n• Marco: \"Si mangia calda\" ✓\n• Giulia: \"Arriva in una scatola\" ✓\n• Luca (impostore): \"È molto popolare\" 🤔\n• Sofia: \"Ha il formaggio\" ✓\n\nLuca ha dato una risposta molto generica... Sospetto!", - "joinGameTitle": "Unisciti alla partita", "multiDeviceMode": "Modalità multi-dispositivo", "scanQrDescription": "Scansiona il codice QR mostrato dall'host per connetterti alla partita tramite Bluetooth/WiFi Direct.", "comingSoon": "Prossimamente", "nearbyNotAvailable": "La connessione multi-dispositivo con Nearby Connections richiede dispositivi Android fisici.\n\nPer ora, usa la modalità \"Un solo dispositivo\" per giocare su un dispositivo condiviso.", "back": "Indietro", - "yes": "Sì", "no": "No", "cancel": "Annulla", "accept": "Accetta", "next": "Avanti", - "settingsTitle": "Impostazioni", "language": "Lingua", "soundVolume": "Volume effetti", @@ -257,5 +266,10 @@ "defaultPlayerName": "Giocatore", "play": "Gioca", "history": "Cronologia", - "mainTagline": "Scopri l’impostore prima che sia troppo tardi" + "mainTagline": "Scopri l’impostore prima che sia troppo tardi", + "deviceProfile": "Profilo del dispositivo", + "profileName": "Nome", + "profileNick": "Nick", + "save": "Salva", + "automaticLanguage": "Automatico" } diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index e9e4b3d..62dc607 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -1,20 +1,16 @@ { "@@locale": "ja", - "appTitle": "インポスター", "subtitle": "正体推理ゲーム", "loadingWords": "ワードを読み込み中...", "playersRange": "3-20人 • インターネット不要", - "createGame": "ゲームを作成", "joinGame": "ゲームに参加", "howToPlay": "遊び方", "settings": "設定", - "gameMode": "ゲームモード", "singleDevice": "1台で遊ぶ", "multiDevice": "複数台で遊ぶ", - "category": "カテゴリー", "categoryAll": "すべて", "categoryAnimals": "動物", @@ -27,11 +23,12 @@ "categoryMovies": "映画", "categoryMusic": "音楽", "categoryTechnology": "テクノロジー", - "playersCount": "プレイヤー ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "同じ名前のプレイヤーがすでにいます", "maxPlayersReached": "最大20人までです", "minPlayersRequired": "最低3人必要です", - "configuration": "設定", "impostors": "🎭 インポスター", "impostorClue": "🔍 インポスターへのヒント", @@ -50,15 +46,15 @@ "twoMin": "2分", "threeMin": "3分", "fiveMin": "5分", - "startGame": "ゲーム開始", - "seeYourWord": "自分のワードを見る", "eachPlayerMustSee": "各プレイヤーは秘密にワードを確認してください", "roundNumber": "ラウンド {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "ワードを確認済み", @@ -67,16 +63,19 @@ "playersRemaining": "残り {count} 人", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "あなたはインポスターです!", "yourWordIs": "あなたのワード:", "clueCategory": "ヒント: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "長押しでワードを確認", @@ -84,11 +83,12 @@ "showingWord": "👁️ 表示中...", "holdToSee": "👆 長押しで確認", "seenMyWord": "ワードを確認しました", - "debateRound": "議論 - ラウンド {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ 時間切れ!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} 人参加中 • {impostors} 人のインポスターが潜伏中", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "脱落", "notes": "メモ", "goToVoting": "投票へ進む", - "voting": "🗳️ 投票", "turnToVote": "投票の番:", "votesProgress": "投票: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "誰がインポスターだと思いますか?", @@ -120,7 +127,6 @@ "allVoted": "全員が投票しました!", "tapToReveal": "タップして結果を見る", "revealResult": "結果を発表", - "result": "結果", "revealing": "発表中...", "wasImpostor": "インポスターでした! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "最終結果を見る", "impostorGuessWord": "インポスターがワードを当てる?", "nextRound": "次のラウンドへ", - "impostorGuessTitle": "🎯 インポスターの推理", "impostorCanGuess": "脱落したインポスターは\nワードを当てることができます", "ifCorrectImpostorsWin": "正解すればインポスターの勝ちです!", @@ -140,20 +145,23 @@ "theWordWas": "ワードは: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "インポスターの勝利!", "wrongGuess": "不正解!", "gameContinues": "ゲームは続きます...", - "gameOver": "ゲーム終了", "playersWin": "プレイヤーの勝利!", "theSecretWordWas": "🔍 ワードは:", "categoryLabel": "カテゴリー: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 インポスターは:", @@ -162,13 +170,16 @@ "roundElimination": "ラウンド {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "もう一度", "mainMenu": "メインメニュー", - "notesTitle": "📝 メモ", "notesSaved": "メモを保存しました", "whoAreYou": "あなたは誰?", @@ -176,14 +187,15 @@ "notesOf": "{name}のメモ", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "各プレイヤーについてのメモ", "playerNoteHint": "何を言った?怪しい?", "freeNote": "フリーメモ", "freeNoteHint": "個人メモ...", - "rulesTitle": "📖 遊び方", "rulesWhatIsTitle": "🎭 インポスターとは?", "rulesWhatIsBody": "3〜20人で遊べる正体推理ゲームです。全員にお題のワードが配られますが…インポスターだけは知りません!あなたの使命:誰がなりすましているかを見抜くことです。", @@ -199,20 +211,17 @@ "rulesModesBody": "• 1台で遊ぶ:端末を全員で共有します。各プレイヤーはボタンを長押しして自分のワードを確認します。\n\n• 複数台で遊ぶ:各プレイヤーが自分の端末を使います。Bluetooth/WiFi Directで接続、インターネット不要。", "rulesExampleTitle": "✏️ ゲームの例", "rulesExampleBody": "お題のワード:「ピザ」\n\n• さくら:「温かいうちに食べる」 ✓\n• たくや:「箱に入って届く」 ✓\n• ゆい(インポスター):「とても人気がある」 🤔\n• けんと:「チーズがのっている」 ✓\n\nゆいの答えはあまりにも曖昧... 怪しい!", - "joinGameTitle": "ゲームに参加", "multiDeviceMode": "複数台モード", "scanQrDescription": "ホストが表示するQRコードをスキャンして、Bluetooth/WiFi Direct経由でゲームに接続します。", "comingSoon": "近日公開", "nearbyNotAvailable": "複数台接続のNearby Connectionsには、物理的なAndroid端末が必要です。\n\n現時点では「1台で遊ぶ」モードをご利用ください。", "back": "戻る", - "yes": "はい", "no": "いいえ", "cancel": "キャンセル", "accept": "OK", "next": "次へ", - "settingsTitle": "設定", "language": "言語", "soundVolume": "効果音の音量", @@ -257,5 +266,10 @@ "defaultPlayerName": "プレイヤー", "play": "プレイ", "history": "履歴", - "mainTagline": "手遅れになる前にインポスターを見つけよう" + "mainTagline": "手遅れになる前にインポスターを見つけよう", + "deviceProfile": "デバイスプロフィール", + "profileName": "名前", + "profileNick": "ニックネーム", + "save": "保存", + "automaticLanguage": "自動" } diff --git a/lib/l10n/app_ko.arb b/lib/l10n/app_ko.arb index aadc6ca..0ea8edc 100644 --- a/lib/l10n/app_ko.arb +++ b/lib/l10n/app_ko.arb @@ -1,20 +1,16 @@ { "@@locale": "ko", - "appTitle": "임포스터", "subtitle": "사회적 추리 게임", "loadingWords": "단어 불러오는 중...", "playersRange": "3-20명 • 인터넷 불필요", - "createGame": "게임 만들기", "joinGame": "게임 참가", "howToPlay": "게임 방법", "settings": "설정", - "gameMode": "게임 모드", "singleDevice": "기기 하나로", "multiDevice": "여러 기기로", - "category": "카테고리", "categoryAll": "전체", "categoryAnimals": "동물", @@ -27,11 +23,12 @@ "categoryMovies": "영화", "categoryMusic": "음악", "categoryTechnology": "기술", - "playersCount": "플레이어 ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "같은 이름의 플레이어가 이미 있습니다", "maxPlayersReached": "최대 20명까지 가능합니다", "minPlayersRequired": "최소 3명이 필요합니다", - "configuration": "설정", "impostors": "🎭 임포스터", "impostorClue": "🔍 임포스터 힌트", @@ -50,15 +46,15 @@ "twoMin": "2분", "threeMin": "3분", "fiveMin": "5분", - "startGame": "게임 시작", - "seeYourWord": "내 단어 보기", "eachPlayerMustSee": "각 플레이어는 비밀리에 자신의 단어를 확인하세요", "roundNumber": "라운드 {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "단어를 이미 확인함", @@ -67,16 +63,19 @@ "playersRemaining": "나머지 {count}명", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "당신은 임포스터입니다!", "yourWordIs": "당신의 단어:", "clueCategory": "힌트: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "길게 눌러 단어를 확인하세요", @@ -84,11 +83,12 @@ "showingWord": "👁️ 표시 중...", "holdToSee": "👆 길게 눌러 확인", "seenMyWord": "내 단어를 확인했습니다", - "debateRound": "토론 - 라운드 {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ 시간 종료!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active}명 참여 중 • {impostors}명의 임포스터 잠복 중", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "탈락", "notes": "메모", "goToVoting": "투표하러 가기", - "voting": "🗳️ 투표", "turnToVote": "투표할 차례:", "votesProgress": "투표: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "누가 임포스터라고 생각하나요?", @@ -120,7 +127,6 @@ "allVoted": "모두 투표했습니다!", "tapToReveal": "탭하여 결과 확인", "revealResult": "결과 공개", - "result": "결과", "revealing": "공개 중...", "wasImpostor": "임포스터였습니다! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "최종 결과 보기", "impostorGuessWord": "임포스터가 단어를 맞출까요?", "nextRound": "다음 라운드", - "impostorGuessTitle": "🎯 임포스터의 추측", "impostorCanGuess": "탈락한 임포스터가\n단어를 맞출 수 있습니다", "ifCorrectImpostorsWin": "정답이면 임포스터의 승리!", @@ -140,20 +145,23 @@ "theWordWas": "단어는: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "임포스터 승리!", "wrongGuess": "오답입니다!", "gameContinues": "게임이 계속됩니다...", - "gameOver": "게임 종료", "playersWin": "플레이어 승리!", "theSecretWordWas": "🔍 단어는:", "categoryLabel": "카테고리: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 임포스터는:", @@ -162,13 +170,16 @@ "roundElimination": "라운드 {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "재대결", "mainMenu": "메인 메뉴", - "notesTitle": "📝 메모", "notesSaved": "메모가 저장되었습니다", "whoAreYou": "당신은 누구인가요?", @@ -176,14 +187,15 @@ "notesOf": "{name}의 메모", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "각 플레이어에 대한 메모", "playerNoteHint": "뭐라고 했나? 수상한가?", "freeNote": "자유 메모", "freeNoteHint": "개인 메모...", - "rulesTitle": "📖 게임 방법", "rulesWhatIsTitle": "🎭 임포스터란?", "rulesWhatIsBody": "3~20명이 즐기는 사회적 추리 게임입니다. 모두가 비밀 단어를 받지만... 임포스터만 받지 못합니다! 당신의 임무: 누가 아는 척하는지 찾아내세요.", @@ -199,20 +211,17 @@ "rulesModesBody": "• 기기 하나로: 모두가 한 기기를 공유합니다. 각 플레이어가 버튼을 길게 눌러 자신의 단어를 확인합니다.\n\n• 여러 기기로: 각 플레이어가 자신의 기기를 사용합니다. Bluetooth/WiFi Direct로 연결하며 인터넷이 필요 없습니다.", "rulesExampleTitle": "✏️ 게임 예시", "rulesExampleBody": "비밀 단어: \"피자\"\n\n• 수진: \"뜨거울 때 먹어요\" ✓\n• 민수: \"상자에 들어 있어요\" ✓\n• 지은 (임포스터): \"아주 인기 있어요\" 🤔\n• 현우: \"치즈가 올려져 있어요\" ✓\n\n지은이 너무 일반적인 답변을 했네요... 수상해요!", - "joinGameTitle": "게임 참가", "multiDeviceMode": "여러 기기 모드", "scanQrDescription": "호스트가 보여주는 QR 코드를 스캔하여 Bluetooth/WiFi Direct로 게임에 접속하세요.", "comingSoon": "곧 출시", "nearbyNotAvailable": "여러 기기 연결을 위한 Nearby Connections는 실제 Android 기기가 필요합니다.\n\n현재는 \"기기 하나로\" 모드를 사용하여 하나의 기기에서 플레이하세요.", "back": "뒤로", - "yes": "예", "no": "아니오", "cancel": "취소", "accept": "확인", "next": "다음", - "settingsTitle": "설정", "language": "언어", "soundVolume": "효과음 볼륨", @@ -257,5 +266,10 @@ "defaultPlayerName": "플레이어", "play": "플레이", "history": "기록", - "mainTagline": "늦기 전에 임포스터를 찾아내세요" + "mainTagline": "늦기 전에 임포스터를 찾아내세요", + "deviceProfile": "기기 프로필", + "profileName": "이름", + "profileNick": "닉네임", + "save": "저장", + "automaticLanguage": "자동" } diff --git a/lib/l10n/app_nl.arb b/lib/l10n/app_nl.arb index dfec24b..4b90e39 100644 --- a/lib/l10n/app_nl.arb +++ b/lib/l10n/app_nl.arb @@ -1,20 +1,16 @@ { "@@locale": "nl", - "appTitle": "De Bedrieger", "subtitle": "Sociaal deductiespel", "loadingWords": "Woorden laden...", "playersRange": "3-20 spelers • Zonder internet", - "createGame": "Spel aanmaken", "joinGame": "Deelnemen aan spel", "howToPlay": "Hoe te spelen", "settings": "Instellingen", - "gameMode": "Spelmodus", "singleDevice": "Eén toestel", "multiDevice": "Meerdere toestellen", - "category": "Categorie", "categoryAll": "Alle", "categoryAnimals": "Dieren", @@ -27,11 +23,12 @@ "categoryMovies": "Films", "categoryMusic": "Muziek", "categoryTechnology": "Technologie", - "playersCount": "Spelers ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Er bestaat al een speler met die naam", "maxPlayersReached": "Maximaal 20 spelers", "minPlayersRequired": "Er zijn minstens 3 spelers nodig", - "configuration": "Configuratie", "impostors": "🎭 Bedriegers", "impostorClue": "🔍 Aanwijzing voor bedrieger", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Spel starten", - "seeYourWord": "Bekijk je woord", "eachPlayerMustSee": "Elke speler moet zijn woord in het geheim bekijken", "roundNumber": "Ronde {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Heeft zijn woord al gezien", @@ -67,16 +63,19 @@ "playersRemaining": "Nog {count} spelers", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Jij bent de bedrieger!", "yourWordIs": "Jouw woord is:", "clueCategory": "Aanwijzing: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Houd ingedrukt om je woord te zien", @@ -84,11 +83,12 @@ "showingWord": "👁️ Wordt getoond...", "holdToSee": "👆 Houd ingedrukt om te zien", "seenMyWord": "Ik heb mijn woord gezien", - "debateRound": "Debat - Ronde {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Tijd is om!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} actief • {impostors} verborgen bedrieger(s)", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Geëlimineerd", "notes": "Notities", "goToVoting": "Naar stemming", - "voting": "🗳️ Stemming", "turnToVote": "Beurt om te stemmen:", "votesProgress": "Stemmen: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Wie is volgens jou de bedrieger?", @@ -120,7 +127,6 @@ "allVoted": "Iedereen heeft gestemd!", "tapToReveal": "Tik om het resultaat te onthullen", "revealResult": "Resultaat onthullen", - "result": "Resultaat", "revealing": "Onthullen...", "wasImpostor": "Was de BEDRIEGER! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Eindresultaat bekijken", "impostorGuessWord": "Raadt de bedrieger het woord?", "nextRound": "Volgende ronde", - "impostorGuessTitle": "🎯 Gok van de bedrieger", "impostorCanGuess": "De geëlimineerde bedrieger mag\nproberen het woord te raden", "ifCorrectImpostorsWin": "Als het klopt, winnen de bedriegers!", @@ -140,20 +145,23 @@ "theWordWas": "Het woord was: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "De bedriegers winnen!", "wrongGuess": "Fout geraden!", "gameContinues": "Het spel gaat verder...", - "gameOver": "Einde van het spel", "playersWin": "De spelers winnen!", "theSecretWordWas": "🔍 Het woord was:", "categoryLabel": "Categorie: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 De bedrieger was:", @@ -162,13 +170,16 @@ "roundElimination": "Ronde {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Herkansing", "mainMenu": "Hoofdmenu", - "notesTitle": "📝 Notities", "notesSaved": "Notities opgeslagen", "whoAreYou": "Wie ben je?", @@ -176,14 +187,15 @@ "notesOf": "Notities van {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Aantekeningen over elke speler", "playerNoteHint": "Wat heeft hij gezegd? Verdacht?", "freeNote": "Vrije notitie", "freeNoteHint": "Persoonlijke aantekeningen...", - "rulesTitle": "📖 Hoe te spelen", "rulesWhatIsTitle": "🎭 Wat is De Bedrieger?", "rulesWhatIsBody": "Een sociaal deductiespel voor 3-20 spelers. Iedereen krijgt een geheim woord... behalve de bedrieger! Jouw missie: ontdek wie doet alsof.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Eén toestel: iedereen deelt hetzelfde apparaat. Elke speler ziet zijn woord door een knop ingedrukt te houden.\n\n• Meerdere toestellen: elke speler gebruikt zijn eigen apparaat. Ze verbinden via Bluetooth/WiFi Direct zonder internet.", "rulesExampleTitle": "✏️ Voorbeeldspel", "rulesExampleBody": "Geheim woord: \"Pizza\"\n\n• Jan: \"Je eet het warm\" ✓\n• Sanne: \"Het komt in een doos\" ✓\n• Bram (bedrieger): \"Het is heel populair\" 🤔\n• Lisa: \"Het heeft kaas\" ✓\n\nBram gaf een heel vaag antwoord... Verdacht!", - "joinGameTitle": "Deelnemen aan spel", "multiDeviceMode": "Modus meerdere toestellen", "scanQrDescription": "Scan de QR-code die de host toont om verbinding te maken met het spel via Bluetooth/WiFi Direct.", "comingSoon": "Binnenkort", "nearbyNotAvailable": "De multitoestelverbinding met Nearby Connections vereist fysieke Android-apparaten.\n\nGebruik voorlopig de modus \"Eén toestel\" om op een gedeeld apparaat te spelen.", "back": "Terug", - "yes": "Ja", "no": "Nee", "cancel": "Annuleren", "accept": "Accepteren", "next": "Volgende", - "settingsTitle": "Instellingen", "language": "Taal", "soundVolume": "Effectvolume", @@ -257,5 +266,10 @@ "defaultPlayerName": "Speler", "play": "Spelen", "history": "Geschiedenis", - "mainTagline": "Vind de bedrieger voordat het te laat is" + "mainTagline": "Vind de bedrieger voordat het te laat is", + "deviceProfile": "Apparaatprofiel", + "profileName": "Naam", + "profileNick": "Nickname", + "save": "Opslaan", + "automaticLanguage": "Automatisch" } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 946a577..967b1df 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -1,20 +1,16 @@ { "@@locale": "pl", - "appTitle": "Oszust", "subtitle": "Gra dedukcji społecznej", "loadingWords": "Ładowanie słów...", "playersRange": "3-20 graczy • Bez internetu", - "createGame": "Utwórz grę", "joinGame": "Dołącz do gry", "howToPlay": "Jak grać", "settings": "Ustawienia", - "gameMode": "Tryb gry", "singleDevice": "Jedno urządzenie", "multiDevice": "Wiele urządzeń", - "category": "Kategoria", "categoryAll": "Wszystkie", "categoryAnimals": "Zwierzęta", @@ -27,11 +23,12 @@ "categoryMovies": "Filmy", "categoryMusic": "Muzyka", "categoryTechnology": "Technologia", - "playersCount": "Gracze ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Gracz o takim imieniu już istnieje", "maxPlayersReached": "Maksymalnie 20 graczy", "minPlayersRequired": "Potrzeba co najmniej 3 graczy", - "configuration": "Konfiguracja", "impostors": "🎭 Oszuści", "impostorClue": "🔍 Wskazówka dla oszusta", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Rozpocznij grę", - "seeYourWord": "Zobacz swoje słowo", "eachPlayerMustSee": "Każdy gracz musi zobaczyć swoje słowo w tajemnicy", "roundNumber": "Runda {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Już widział swoje słowo", @@ -67,16 +63,19 @@ "playersRemaining": "Pozostało {count} graczy", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Jesteś oszustem!", "yourWordIs": "Twoje słowo to:", "clueCategory": "Wskazówka: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Przytrzymaj, aby zobaczyć swoje słowo", @@ -84,11 +83,12 @@ "showingWord": "👁️ Pokazuję...", "holdToSee": "👆 Przytrzymaj, aby zobaczyć", "seenMyWord": "Widziałem swoje słowo", - "debateRound": "Debata - Runda {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Czas minął!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} aktywnych • {impostors} ukrytych oszustów", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Wyeliminowany", "notes": "Notatki", "goToVoting": "Przejdź do głosowania", - "voting": "🗳️ Głosowanie", "turnToVote": "Kolej na głosowanie:", "votesProgress": "Głosy: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Kto twoim zdaniem jest oszustem?", @@ -120,7 +127,6 @@ "allVoted": "Wszyscy zagłosowali!", "tapToReveal": "Dotknij, aby odkryć wynik", "revealResult": "Odkryj wynik", - "result": "Wynik", "revealing": "Odkrywam...", "wasImpostor": "To był OSZUST! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Zobacz wynik końcowy", "impostorGuessWord": "Czy oszust odgadnie słowo?", "nextRound": "Następna runda", - "impostorGuessTitle": "🎯 Zgadywanie oszusta", "impostorCanGuess": "Wyeliminowany oszust może\nspróbować odgadnąć słowo", "ifCorrectImpostorsWin": "Jeśli trafi, oszuści wygrywają!", @@ -140,20 +145,23 @@ "theWordWas": "Słowo brzmiało: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Oszuści wygrywają!", "wrongGuess": "Nie trafił!", "gameContinues": "Gra toczy się dalej...", - "gameOver": "Koniec gry", "playersWin": "Gracze wygrywają!", "theSecretWordWas": "🔍 Słowo brzmiało:", "categoryLabel": "Kategoria: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 Oszustem był:", @@ -162,13 +170,16 @@ "roundElimination": "Runda {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Rewanż", "mainMenu": "Menu główne", - "notesTitle": "📝 Notatki", "notesSaved": "Notatki zapisane", "whoAreYou": "Kim jesteś?", @@ -176,14 +187,15 @@ "notesOf": "Notatki gracza {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Zapiski o każdym graczu", "playerNoteHint": "Co powiedział? Podejrzany?", "freeNote": "Wolna notatka", "freeNoteHint": "Osobiste zapiski...", - "rulesTitle": "📖 Jak grać", "rulesWhatIsTitle": "🎭 Czym jest Oszust?", "rulesWhatIsBody": "Gra dedukcji społecznej dla 3-20 graczy. Wszyscy otrzymują tajne słowo... oprócz oszusta! Twoja misja: odkryj, kto udaje.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Jedno urządzenie: wszyscy dzielą jedno urządzenie. Każdy gracz widzi swoje słowo, przytrzymując przycisk.\n\n• Wiele urządzeń: każdy gracz używa własnego urządzenia. Łączą się przez Bluetooth/WiFi Direct bez potrzeby internetu.", "rulesExampleTitle": "✏️ Przykładowa gra", "rulesExampleBody": "Tajne słowo: \"Pizza\"\n\n• Kasia: \"Je się na ciepło\" ✓\n• Tomek: \"Przychodzi w pudełku\" ✓\n• Ola (oszust): \"Jest bardzo popularna\" 🤔\n• Marek: \"Ma ser\" ✓\n\nOla dała bardzo ogólnikową odpowiedź... Podejrzana!", - "joinGameTitle": "Dołącz do gry", "multiDeviceMode": "Tryb wielu urządzeń", "scanQrDescription": "Zeskanuj kod QR wyświetlany przez hosta, aby połączyć się z grą przez Bluetooth/WiFi Direct.", "comingSoon": "Wkrótce", "nearbyNotAvailable": "Połączenie wielourządzeniowe z Nearby Connections wymaga fizycznych urządzeń z Androidem.\n\nNa razie użyj trybu \"Jedno urządzenie\", aby grać na wspólnym urządzeniu.", "back": "Wstecz", - "yes": "Tak", "no": "Nie", "cancel": "Anuluj", "accept": "Akceptuj", "next": "Dalej", - "settingsTitle": "Ustawienia", "language": "Język", "soundVolume": "Głośność efektów", @@ -257,5 +266,10 @@ "defaultPlayerName": "Gracz", "play": "Graj", "history": "Historia", - "mainTagline": "Znajdź oszusta, zanim będzie za późno" + "mainTagline": "Znajdź oszusta, zanim będzie za późno", + "deviceProfile": "Profil urządzenia", + "profileName": "Nazwa", + "profileNick": "Nick", + "save": "Zapisz", + "automaticLanguage": "Automatycznie" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index 378f276..180a380 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -1,20 +1,16 @@ { "@@locale": "pt", - "appTitle": "O Impostor", "subtitle": "Jogo de dedução social", "loadingWords": "Carregando palavras...", "playersRange": "3-20 jogadores • Sem internet", - "createGame": "Criar partida", "joinGame": "Entrar na partida", "howToPlay": "Como jogar", "settings": "Configurações", - "gameMode": "Modo de jogo", "singleDevice": "Um só celular", "multiDevice": "Multicelular", - "category": "Categoria", "categoryAll": "Todas", "categoryAnimals": "Animais", @@ -27,11 +23,12 @@ "categoryMovies": "Filmes", "categoryMusic": "Música", "categoryTechnology": "Tecnologia", - "playersCount": "Jogadores ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Já existe um jogador com esse nome", "maxPlayersReached": "Máximo de 20 jogadores", "minPlayersRequired": "São necessários pelo menos 3 jogadores", - "configuration": "Configuração", "impostors": "🎭 Impostores", "impostorClue": "🔍 Dica para o impostor", @@ -50,15 +46,15 @@ "twoMin": "2 min", "threeMin": "3 min", "fiveMin": "5 min", - "startGame": "Iniciar partida", - "seeYourWord": "Ver sua palavra", "eachPlayerMustSee": "Cada jogador deve ver sua palavra em segredo", "roundNumber": "Rodada {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Já viu sua palavra", @@ -67,16 +63,19 @@ "playersRemaining": "Faltam {count} jogadores", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Você é o impostor!", "yourWordIs": "Sua palavra é:", "clueCategory": "Dica: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Mantenha pressionado para ver sua palavra", @@ -84,11 +83,12 @@ "showingWord": "👁️ Mostrando...", "holdToSee": "👆 Mantenha pressionado para ver", "seenMyWord": "Já vi minha palavra", - "debateRound": "Debate - Rodada {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Tempo esgotado!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} ativos • {impostors} impostor(es) ocultos", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Eliminado", "notes": "Notas", "goToVoting": "Ir para votação", - "voting": "🗳️ Votação", "turnToVote": "Vez de votar:", "votesProgress": "Votos: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Quem você acha que é o impostor?", @@ -120,7 +127,6 @@ "allVoted": "Todos votaram!", "tapToReveal": "Toque para revelar o resultado", "revealResult": "Revelar resultado", - "result": "Resultado", "revealing": "Revelando...", "wasImpostor": "Era IMPOSTOR! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Ver resultado final", "impostorGuessWord": "O impostor adivinha a palavra?", "nextRound": "Próxima rodada", - "impostorGuessTitle": "🎯 Palpite do impostor", "impostorCanGuess": "O impostor eliminado pode\ntentar adivinhar a palavra", "ifCorrectImpostorsWin": "Se acertar, os impostores vencem!", @@ -140,20 +145,23 @@ "theWordWas": "A palavra era: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Os impostores vencem!", "wrongGuess": "Não acertou!", "gameContinues": "A partida continua...", - "gameOver": "Fim de partida", "playersWin": "Os jogadores vencem!", "theSecretWordWas": "🔍 A palavra era:", "categoryLabel": "Categoria: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 O impostor era:", @@ -162,13 +170,16 @@ "roundElimination": "Rodada {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Revanche", "mainMenu": "Menu principal", - "notesTitle": "📝 Notas", "notesSaved": "Notas salvas", "whoAreYou": "Quem é você?", @@ -176,14 +187,15 @@ "notesOf": "Notas de {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Anotações sobre cada jogador", "playerNoteHint": "O que disse? Suspeito?", "freeNote": "Nota livre", "freeNoteHint": "Anotações pessoais...", - "rulesTitle": "📖 Como jogar", "rulesWhatIsTitle": "🎭 O que é O Impostor?", "rulesWhatIsBody": "Um jogo de dedução social para 3-20 jogadores. Todos recebem uma palavra secreta... exceto o impostor! Sua missão: descobrir quem está fingindo.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Um só celular: todos compartilham o dispositivo. Cada jogador vê sua palavra pressionando e segurando um botão.\n\n• Multicelular: cada jogador usa seu próprio dispositivo. Conectam-se por Bluetooth/WiFi Direct sem necessidade de internet.", "rulesExampleTitle": "✏️ Exemplo de partida", "rulesExampleBody": "Palavra secreta: \"Pizza\"\n\n• João: \"Se come quente\" ✓\n• Maria: \"Vem numa caixa\" ✓\n• Pedro (impostor): \"É muito popular\" 🤔\n• Ana: \"Tem queijo\" ✓\n\nPedro deu uma resposta muito genérica... Suspeito!", - "joinGameTitle": "Entrar na partida", "multiDeviceMode": "Modo multicelular", "scanQrDescription": "Escaneie o código QR exibido pelo anfitrião para se conectar à partida via Bluetooth/WiFi Direct.", "comingSoon": "Em breve", "nearbyNotAvailable": "A conexão multicelular com Nearby Connections requer dispositivos Android físicos.\n\nPor enquanto, use o modo \"Um só celular\" para jogar em um dispositivo compartilhado.", "back": "Voltar", - "yes": "Sim", "no": "Não", "cancel": "Cancelar", "accept": "Aceitar", "next": "Próximo", - "settingsTitle": "Configurações", "language": "Idioma", "soundVolume": "Volume dos efeitos", @@ -257,5 +266,10 @@ "defaultPlayerName": "Jogador", "play": "Jogar", "history": "Histórico", - "mainTagline": "Descobre o impostor antes que seja tarde" + "mainTagline": "Descobre o impostor antes que seja tarde", + "deviceProfile": "Perfil do dispositivo", + "profileName": "Nome", + "profileNick": "Nick", + "save": "Guardar", + "automaticLanguage": "Automático" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index e577c4d..15434cf 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -1,20 +1,16 @@ { "@@locale": "ru", - "appTitle": "Самозванец", "subtitle": "Социальная игра на дедукцию", "loadingWords": "Загрузка слов...", "playersRange": "3-20 игроков • Без интернета", - "createGame": "Создать игру", "joinGame": "Присоединиться к игре", "howToPlay": "Как играть", "settings": "Настройки", - "gameMode": "Режим игры", "singleDevice": "Одно устройство", "multiDevice": "Несколько устройств", - "category": "Категория", "categoryAll": "Все", "categoryAnimals": "Животные", @@ -27,11 +23,12 @@ "categoryMovies": "Фильмы", "categoryMusic": "Музыка", "categoryTechnology": "Технологии", - "playersCount": "Игроки ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Игрок с таким именем уже существует", "maxPlayersReached": "Максимум 20 игроков", "minPlayersRequired": "Нужно минимум 3 игрока", - "configuration": "Конфигурация", "impostors": "🎭 Самозванцы", "impostorClue": "🔍 Подсказка для самозванца", @@ -50,15 +46,15 @@ "twoMin": "2 мин", "threeMin": "3 мин", "fiveMin": "5 мин", - "startGame": "Начать игру", - "seeYourWord": "Посмотри своё слово", "eachPlayerMustSee": "Каждый игрок должен тайно посмотреть своё слово", "roundNumber": "Раунд {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Уже видел своё слово", @@ -67,16 +63,19 @@ "playersRemaining": "Осталось {count} игроков", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Ты самозванец!", "yourWordIs": "Твоё слово:", "clueCategory": "Подсказка: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Удерживай, чтобы увидеть своё слово", @@ -84,11 +83,12 @@ "showingWord": "👁️ Показываю...", "holdToSee": "👆 Удерживай, чтобы увидеть", "seenMyWord": "Я увидел своё слово", - "debateRound": "Обсуждение - Раунд {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Время вышло!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} активных • {impostors} скрытый(-х) самозванец(-ев)", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Выбыл", "notes": "Заметки", "goToVoting": "Перейти к голосованию", - "voting": "🗳️ Голосование", "turnToVote": "Твоя очередь голосовать:", "votesProgress": "Голоса: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Кто, по-твоему, самозванец?", @@ -120,7 +127,6 @@ "allVoted": "Все проголосовали!", "tapToReveal": "Нажми, чтобы узнать результат", "revealResult": "Показать результат", - "result": "Результат", "revealing": "Раскрываем...", "wasImpostor": "Был САМОЗВАНЦЕМ! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Увидеть итоговый результат", "impostorGuessWord": "Самозванец угадает слово?", "nextRound": "Следующий раунд", - "impostorGuessTitle": "🎯 Догадка самозванца", "impostorCanGuess": "Выбывший самозванец может\nпопытаться угадать слово", "ifCorrectImpostorsWin": "Если угадает — самозванцы побеждают!", @@ -140,20 +145,23 @@ "theWordWas": "Слово было: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Самозванцы побеждают!", "wrongGuess": "Не угадал!", "gameContinues": "Игра продолжается...", - "gameOver": "Конец игры", "playersWin": "Игроки побеждают!", "theSecretWordWas": "🔍 Загаданное слово:", "categoryLabel": "Категория: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 Самозванцем был:", @@ -162,13 +170,16 @@ "roundElimination": "Раунд {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Реванш", "mainMenu": "Главное меню", - "notesTitle": "📝 Заметки", "notesSaved": "Заметки сохранены", "whoAreYou": "Кто ты?", @@ -176,14 +187,15 @@ "notesOf": "Заметки {name}", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Записи о каждом игроке", "playerNoteHint": "Что он сказал? Подозрительно?", "freeNote": "Свободная заметка", "freeNoteHint": "Личные записи...", - "rulesTitle": "📖 Как играть", "rulesWhatIsTitle": "🎭 Что такое «Самозванец»?", "rulesWhatIsBody": "Социальная игра на дедукцию для 3-20 игроков. Все получают секретное слово... кроме самозванца! Твоя задача: вычислить, кто притворяется.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Одно устройство: все передают телефон по кругу. Каждый игрок видит своё слово, нажав и удерживая кнопку.\n\n• Несколько устройств: каждый игрок использует собственное устройство. Подключение через Bluetooth/WiFi Direct без интернета.", "rulesExampleTitle": "✏️ Пример раунда", "rulesExampleBody": "Секретное слово: «Пицца»\n\n• Аня: «Её едят горячей» ✓\n• Кирилл: «Приходит в коробке» ✓\n• Лена (самозванец): «Очень популярная» 🤔\n• Дима: «С сыром» ✓\n\nЛена дала слишком общий ответ... Подозрительно!", - "joinGameTitle": "Присоединиться к игре", "multiDeviceMode": "Режим нескольких устройств", "scanQrDescription": "Отсканируй QR-код, который показывает хост, чтобы подключиться к игре через Bluetooth/WiFi Direct.", "comingSoon": "Скоро", "nearbyNotAvailable": "Подключение нескольких устройств через Nearby Connections требует физических Android-устройств.\n\nПока что используй режим «Одно устройство» для игры на общем телефоне.", "back": "Назад", - "yes": "Да", "no": "Нет", "cancel": "Отмена", "accept": "Принять", "next": "Далее", - "settingsTitle": "Настройки", "language": "Язык", "soundVolume": "Громкость эффектов", @@ -257,5 +266,10 @@ "defaultPlayerName": "Игрок", "play": "Играть", "history": "История", - "mainTagline": "Найди самозванца, пока не стало слишком поздно" + "mainTagline": "Найди самозванца, пока не стало слишком поздно", + "deviceProfile": "Профиль устройства", + "profileName": "Имя", + "profileNick": "Ник", + "save": "Сохранить", + "automaticLanguage": "Автоматически" } diff --git a/lib/l10n/app_tr.arb b/lib/l10n/app_tr.arb index c445610..7a23faa 100644 --- a/lib/l10n/app_tr.arb +++ b/lib/l10n/app_tr.arb @@ -1,20 +1,16 @@ { "@@locale": "tr", - "appTitle": "Sahtekar", "subtitle": "Sosyal çıkarım oyunu", "loadingWords": "Kelimeler yükleniyor...", "playersRange": "3-20 oyuncu • İnternet gerektirmez", - "createGame": "Oyun oluştur", "joinGame": "Oyuna katıl", "howToPlay": "Nasıl oynanır", "settings": "Ayarlar", - "gameMode": "Oyun modu", "singleDevice": "Tek cihaz", "multiDevice": "Çoklu cihaz", - "category": "Kategori", "categoryAll": "Tümü", "categoryAnimals": "Hayvanlar", @@ -27,11 +23,12 @@ "categoryMovies": "Filmler", "categoryMusic": "Müzik", "categoryTechnology": "Teknoloji", - "playersCount": "Oyuncular ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "Bu isimde bir oyuncu zaten var", "maxPlayersReached": "En fazla 20 oyuncu", "minPlayersRequired": "En az 3 oyuncu gerekli", - "configuration": "Yapılandırma", "impostors": "🎭 Sahtekarlar", "impostorClue": "🔍 Sahtekar için ipucu", @@ -50,15 +46,15 @@ "twoMin": "2 dk", "threeMin": "3 dk", "fiveMin": "5 dk", - "startGame": "Oyunu başlat", - "seeYourWord": "Kelimeni gör", "eachPlayerMustSee": "Her oyuncu kelimesini gizlice görmelidir", "roundNumber": "Tur {round}", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "Kelimesini zaten gördü", @@ -67,16 +63,19 @@ "playersRemaining": "{count} oyuncu kaldı", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "Sen sahtekarsın!", "yourWordIs": "Kelimen:", "clueCategory": "İpucu: {category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "Kelimeni görmek için basılı tut", @@ -84,11 +83,12 @@ "showingWord": "👁️ Gösteriliyor...", "holdToSee": "👆 Görmek için basılı tut", "seenMyWord": "Kelimemi gördüm", - "debateRound": "Tartışma - Tur {round}", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ Süre doldu!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} aktif • {impostors} gizli sahtekar", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "Elendi", "notes": "Notlar", "goToVoting": "Oylamaya geç", - "voting": "🗳️ Oylama", "turnToVote": "Oy verme sırası:", "votesProgress": "Oylar: {current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "Sahtekarın kim olduğunu düşünüyorsun?", @@ -120,7 +127,6 @@ "allVoted": "Herkes oy verdi!", "tapToReveal": "Sonucu görmek için dokun", "revealResult": "Sonucu göster", - "result": "Sonuç", "revealing": "Gösteriliyor...", "wasImpostor": "SAHTEKAR'dı! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "Nihai sonucu gör", "impostorGuessWord": "Sahtekar kelimeyi tahmin edecek mi?", "nextRound": "Sonraki tur", - "impostorGuessTitle": "🎯 Sahtekarın tahmini", "impostorCanGuess": "Elenen sahtekar\nkelimeyi tahmin etmeyi deneyebilir", "ifCorrectImpostorsWin": "Doğru tahmin ederse sahtekarlar kazanır!", @@ -140,20 +145,23 @@ "theWordWas": "Kelime şuydu: {word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "Sahtekarlar kazandı!", "wrongGuess": "Yanlış tahmin!", "gameContinues": "Oyun devam ediyor...", - "gameOver": "Oyun bitti", "playersWin": "Oyuncular kazandı!", "theSecretWordWas": "🔍 Kelime şuydu:", "categoryLabel": "Kategori: {category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 Sahtekar şuydu:", @@ -162,13 +170,16 @@ "roundElimination": "Tur {round}: {name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "Rövanş", "mainMenu": "Ana menü", - "notesTitle": "📝 Notlar", "notesSaved": "Notlar kaydedildi", "whoAreYou": "Sen kimsin?", @@ -176,14 +187,15 @@ "notesOf": "{name} adlı oyuncunun notları", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "Her oyuncu hakkında notlar", "playerNoteHint": "Ne dedi? Şüpheli mi?", "freeNote": "Serbest not", "freeNoteHint": "Kişisel notlar...", - "rulesTitle": "📖 Nasıl oynanır", "rulesWhatIsTitle": "🎭 Sahtekar nedir?", "rulesWhatIsBody": "3-20 oyuncu için sosyal bir çıkarım oyunu. Herkes gizli bir kelime alır... sahtekar hariç! Görevin: kimin numaraya yattığını bul.", @@ -199,20 +211,17 @@ "rulesModesBody": "• Tek cihaz: herkes aynı cihazı paylaşır. Her oyuncu bir düğmeye basılı tutarak kelimesini görür.\n\n• Çoklu cihaz: her oyuncu kendi cihazını kullanır. Bluetooth/WiFi Direct ile bağlanılır, internet gerekmez.", "rulesExampleTitle": "✏️ Örnek oyun", "rulesExampleBody": "Gizli kelime: \"Pizza\"\n\n• Ali: \"Sıcak yenir\" ✓\n• Ayşe: \"Kutu içinde gelir\" ✓\n• Zeynep (sahtekar): \"Çok popüler\" 🤔\n• Mehmet: \"Üstünde peynir var\" ✓\n\nZeynep çok genel bir cevap verdi... Şüpheli!", - "joinGameTitle": "Oyuna katıl", "multiDeviceMode": "Çoklu cihaz modu", "scanQrDescription": "Bluetooth/WiFi Direct ile oyuna bağlanmak için sunucunun gösterdiği QR kodunu tara.", "comingSoon": "Yakında", "nearbyNotAvailable": "Nearby Connections ile çoklu cihaz bağlantısı fiziksel Android cihazları gerektirir.\n\nŞimdilik paylaşılan bir cihazda oynamak için \"Tek cihaz\" modunu kullanın.", "back": "Geri", - "yes": "Evet", "no": "Hayır", "cancel": "İptal", "accept": "Kabul et", "next": "Sonraki", - "settingsTitle": "Ayarlar", "language": "Dil", "soundVolume": "Efekt ses düzeyi", @@ -257,5 +266,10 @@ "defaultPlayerName": "Oyuncu", "play": "Oyna", "history": "Geçmiş", - "mainTagline": "Çok geç olmadan sahtekârı bul" + "mainTagline": "Çok geç olmadan sahtekârı bul", + "deviceProfile": "Cihaz profili", + "profileName": "Ad", + "profileNick": "Takma ad", + "save": "Kaydet", + "automaticLanguage": "Otomatik" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 9d92715..47ff5a9 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -1,20 +1,16 @@ { "@@locale": "zh", - "appTitle": "冒牌者", "subtitle": "社交推理游戏", "loadingWords": "正在加载词汇...", "playersRange": "3-20名玩家 • 无需联网", - "createGame": "创建游戏", "joinGame": "加入游戏", "howToPlay": "玩法介绍", "settings": "设置", - "gameMode": "游戏模式", "singleDevice": "单设备", "multiDevice": "多设备", - "category": "分类", "categoryAll": "全部", "categoryAnimals": "动物", @@ -27,11 +23,12 @@ "categoryMovies": "电影", "categoryMusic": "音乐", "categoryTechnology": "科技", - "playersCount": "玩家 ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "已存在同名玩家", "maxPlayersReached": "最多20名玩家", "minPlayersRequired": "至少需要3名玩家", - "configuration": "配置", "impostors": "🎭 冒牌者", "impostorClue": "🔍 给冒牌者的提示", @@ -50,15 +46,15 @@ "twoMin": "2分钟", "threeMin": "3分钟", "fiveMin": "5分钟", - "startGame": "开始游戏", - "seeYourWord": "查看你的词语", "eachPlayerMustSee": "每位玩家需要秘密查看自己的词语", "roundNumber": "第 {round} 轮", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "已查看词语", @@ -67,16 +63,19 @@ "playersRemaining": "还剩 {count} 位玩家", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "你是冒牌者!", "yourWordIs": "你的词语是:", "clueCategory": "提示:{category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "长按查看你的词语", @@ -84,11 +83,12 @@ "showingWord": "👁️ 显示中...", "holdToSee": "👆 长按查看", "seenMyWord": "我已看过词语", - "debateRound": "讨论 - 第 {round} 轮", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ 时间到!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} 名在场 • {impostors} 名冒牌者潜伏中", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "已淘汰", "notes": "笔记", "goToVoting": "前往投票", - "voting": "🗳️ 投票", "turnToVote": "轮到你投票:", "votesProgress": "投票:{current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "你认为谁是冒牌者?", @@ -120,7 +127,6 @@ "allVoted": "所有人已投票!", "tapToReveal": "点击揭晓结果", "revealResult": "揭晓结果", - "result": "结果", "revealing": "揭晓中...", "wasImpostor": "是冒牌者! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "查看最终结果", "impostorGuessWord": "冒牌者要猜词吗?", "nextRound": "下一轮", - "impostorGuessTitle": "🎯 冒牌者猜词", "impostorCanGuess": "被淘汰的冒牌者可以\n尝试猜出词语", "ifCorrectImpostorsWin": "如果猜对,冒牌者获胜!", @@ -140,20 +145,23 @@ "theWordWas": "词语是:{word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "冒牌者获胜!", "wrongGuess": "猜错了!", "gameContinues": "游戏继续...", - "gameOver": "游戏结束", "playersWin": "玩家获胜!", "theSecretWordWas": "🔍 词语是:", "categoryLabel": "分类:{category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 冒牌者是:", @@ -162,13 +170,16 @@ "roundElimination": "第 {round} 轮:{name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "再来一局", "mainMenu": "主菜单", - "notesTitle": "📝 笔记", "notesSaved": "笔记已保存", "whoAreYou": "你是谁?", @@ -176,14 +187,15 @@ "notesOf": "{name}的笔记", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "关于每位玩家的记录", "playerNoteHint": "他说了什么?可疑吗?", "freeNote": "自由笔记", "freeNoteHint": "个人记录...", - "rulesTitle": "📖 玩法介绍", "rulesWhatIsTitle": "🎭 什么是冒牌者?", "rulesWhatIsBody": "一款3-20人的社交推理游戏。每个人都会收到一个秘密词语......除了冒牌者!你的任务:找出谁在假装。", @@ -199,20 +211,17 @@ "rulesModesBody": "• 单设备:所有人共享一台设备。每位玩家通过长按按钮查看自己的词语。\n\n• 多设备:每位玩家使用自己的设备。通过蓝牙/WiFi Direct连接,无需联网。", "rulesExampleTitle": "✏️ 游戏示例", "rulesExampleBody": "秘密词语:\"披萨\"\n\n• 小明:\"趁热吃的\" ✓\n• 小红:\"装在盒子里的\" ✓\n• 小丽(冒牌者):\"非常受欢迎\" 🤔\n• 小刚:\"上面有芝士\" ✓\n\n小丽的回答太笼统了......可疑!", - "joinGameTitle": "加入游戏", "multiDeviceMode": "多设备模式", "scanQrDescription": "扫描房主显示的二维码,通过蓝牙/WiFi Direct连接到游戏。", "comingSoon": "即将推出", "nearbyNotAvailable": "多设备连接的Nearby Connections功能需要实体Android设备。\n\n目前请使用\"单设备\"模式,在一台共享设备上进行游戏。", "back": "返回", - "yes": "是", "no": "否", "cancel": "取消", "accept": "确定", "next": "下一步", - "settingsTitle": "设置", "language": "语言", "soundVolume": "音效音量", @@ -257,5 +266,10 @@ "defaultPlayerName": "玩家", "play": "开始", "history": "历史", - "mainTagline": "在太晚之前找出冒牌者" + "mainTagline": "在太晚之前找出冒牌者", + "deviceProfile": "设备档案", + "profileName": "名称", + "profileNick": "昵称", + "save": "保存", + "automaticLanguage": "自动" } diff --git a/lib/l10n/app_zh_TW.arb b/lib/l10n/app_zh_TW.arb index d438f3a..83ad0ce 100644 --- a/lib/l10n/app_zh_TW.arb +++ b/lib/l10n/app_zh_TW.arb @@ -1,20 +1,16 @@ { "@@locale": "zh_TW", - "appTitle": "冒牌者", "subtitle": "社交推理遊戲", "loadingWords": "正在載入詞彙...", "playersRange": "3-20 位玩家 • 無需網路", - "createGame": "建立遊戲", "joinGame": "加入遊戲", "howToPlay": "遊戲規則", "settings": "設定", - "gameMode": "遊戲模式", "singleDevice": "單機模式", "multiDevice": "多機模式", - "category": "類別", "categoryAll": "全部", "categoryAnimals": "動物", @@ -27,11 +23,12 @@ "categoryMovies": "電影", "categoryMusic": "音樂", "categoryTechnology": "科技", - "playersCount": "玩家 ({count})", "@playersCount": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, "playersRangeHint": "3-20", @@ -39,7 +36,6 @@ "playerAlreadyExists": "已有同名玩家", "maxPlayersReached": "最多 20 位玩家", "minPlayersRequired": "至少需要 3 位玩家", - "configuration": "設定", "impostors": "🎭 冒牌者", "impostorClue": "🔍 冒牌者提示", @@ -50,15 +46,15 @@ "twoMin": "2 分鐘", "threeMin": "3 分鐘", "fiveMin": "5 分鐘", - "startGame": "開始遊戲", - "seeYourWord": "查看你的詞彙", "eachPlayerMustSee": "每位玩家必須私下查看自己的詞彙", "roundNumber": "第 {round} 回合", "@roundNumber": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "alreadySeen": "已查看過詞彙", @@ -67,16 +63,19 @@ "playersRemaining": "還有 {count} 位玩家未查看", "@playersRemaining": { "placeholders": { - "count": {"type": "int"} + "count": { + "type": "int" + } } }, - "youAreImpostor": "你是冒牌者!", "yourWordIs": "你的詞彙是:", "clueCategory": "提示:{category}", "@clueCategory": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "holdToSeeWord": "長按查看你的詞彙", @@ -84,11 +83,12 @@ "showingWord": "👁️ 顯示中...", "holdToSee": "👆 長按查看", "seenMyWord": "我已看過詞彙", - "debateRound": "討論 - 第 {round} 回合", "@debateRound": { "placeholders": { - "round": {"type": "int"} + "round": { + "type": "int" + } } }, "timeUp": "⏰ 時間到!", @@ -97,21 +97,28 @@ "activePlayersInfo": "{active} 位在場 • {impostors} 位冒牌者潛伏中", "@activePlayersInfo": { "placeholders": { - "active": {"type": "int"}, - "impostors": {"type": "int"} + "active": { + "type": "int" + }, + "impostors": { + "type": "int" + } } }, "eliminated": "已淘汰", "notes": "筆記", "goToVoting": "前往投票", - "voting": "🗳️ 投票", "turnToVote": "輪到你投票:", "votesProgress": "票數:{current}/{total}", "@votesProgress": { "placeholders": { - "current": {"type": "int"}, - "total": {"type": "int"} + "current": { + "type": "int" + }, + "total": { + "type": "int" + } } }, "whoIsImpostor": "你認為誰是冒牌者?", @@ -120,7 +127,6 @@ "allVoted": "所有人都已投票!", "tapToReveal": "點擊揭曉結果", "revealResult": "揭曉結果", - "result": "結果", "revealing": "揭曉中...", "wasImpostor": "是冒牌者! 🎉", @@ -129,7 +135,6 @@ "seeEndResult": "查看最終結果", "impostorGuessWord": "冒牌者要猜詞彙嗎?", "nextRound": "下一回合", - "impostorGuessTitle": "🎯 冒牌者猜詞", "impostorCanGuess": "被淘汰的冒牌者可以\n嘗試猜出正確詞彙", "ifCorrectImpostorsWin": "猜對的話,冒牌者就贏了!", @@ -140,20 +145,23 @@ "theWordWas": "正確詞彙是:{word}", "@theWordWas": { "placeholders": { - "word": {"type": "String"} + "word": { + "type": "String" + } } }, "impostorsWin": "冒牌者獲勝!", "wrongGuess": "猜錯了!", "gameContinues": "遊戲繼續...", - "gameOver": "遊戲結束", "playersWin": "玩家們獲勝!", "theSecretWordWas": "🔍 正確詞彙是:", "categoryLabel": "類別:{category}", "@categoryLabel": { "placeholders": { - "category": {"type": "String"} + "category": { + "type": "String" + } } }, "theImpostorWas": "🎭 冒牌者是:", @@ -162,13 +170,16 @@ "roundElimination": "第 {round} 回合:{name}", "@roundElimination": { "placeholders": { - "round": {"type": "int"}, - "name": {"type": "String"} + "round": { + "type": "int" + }, + "name": { + "type": "String" + } } }, "rematch": "再來一局", "mainMenu": "主選單", - "notesTitle": "📝 筆記", "notesSaved": "筆記已儲存", "whoAreYou": "你是誰?", @@ -176,14 +187,15 @@ "notesOf": "{name} 的筆記", "@notesOf": { "placeholders": { - "name": {"type": "String"} + "name": { + "type": "String" + } } }, "notesAboutPlayers": "關於每位玩家的紀錄", "playerNoteHint": "他說了什麼?可疑嗎?", "freeNote": "自由筆記", "freeNoteHint": "個人筆記...", - "rulesTitle": "📖 遊戲規則", "rulesWhatIsTitle": "🎭 什麼是冒牌者?", "rulesWhatIsBody": "一款適合 3-20 位玩家的社交推理遊戲。每個人都會收到一個秘密詞彙……除了冒牌者!你的任務:找出誰在假裝。", @@ -199,20 +211,17 @@ "rulesModesBody": "• 單機模式:所有人共用一台裝置。每位玩家長按按鈕查看自己的詞彙。\n\n• 多機模式:每位玩家使用自己的裝置,透過藍牙/WiFi Direct 連線,無需網路。", "rulesExampleTitle": "✏️ 遊戲範例", "rulesExampleBody": "秘密詞彙:「披薩」\n\n• 小明:「要趁熱吃」 ✓\n• 小華:「裝在盒子裡」 ✓\n• 小美(冒牌者):「很受歡迎」 🤔\n• 小強:「上面有起司」 ✓\n\n小美的回答太籠統了……有嫌疑!", - "joinGameTitle": "加入遊戲", "multiDeviceMode": "多機模式", "scanQrDescription": "掃描主機顯示的 QR 碼,透過藍牙/WiFi Direct 加入遊戲。", "comingSoon": "即將推出", "nearbyNotAvailable": "多機連線功能需要 Android 實體裝置搭配 Nearby Connections。\n\n目前請使用「單機模式」在共用裝置上進行遊戲。", "back": "返回", - "yes": "是", "no": "否", "cancel": "取消", "accept": "確定", "next": "下一步", - "settingsTitle": "設定", "language": "語言", "soundVolume": "音效音量", @@ -257,5 +266,10 @@ "defaultPlayerName": "玩家", "play": "開始", "history": "紀錄", - "mainTagline": "在太晚之前找出冒牌者" + "mainTagline": "在太晚之前找出冒牌者", + "deviceProfile": "裝置個人檔案", + "profileName": "名稱", + "profileNick": "暱稱", + "save": "儲存", + "automaticLanguage": "自動" } diff --git a/lib/l10n/generated/app_localizations.dart b/lib/l10n/generated/app_localizations.dart index 83c0d93..78e23c7 100644 --- a/lib/l10n/generated/app_localizations.dart +++ b/lib/l10n/generated/app_localizations.dart @@ -1399,4 +1399,14 @@ AppLocalizations lookupAppLocalizations(Locale locale) { 'on GitHub with a reproducible sample app and the gen-l10n configuration ' 'that was used.', ); -} + + String get deviceProfile; + + String get profileName; + + String get profileNick; + + String get save; + + String get automaticLanguage; +} \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_ar.dart b/lib/l10n/generated/app_localizations_ar.dart index 304a670..28cb503 100644 --- a/lib/l10n/generated/app_localizations_ar.dart +++ b/lib/l10n/generated/app_localizations_ar.dart @@ -712,4 +712,19 @@ class AppLocalizationsAr extends AppLocalizations { @override String get mainTagline => 'اكتشف المنتحل قبل فوات الأوان'; + @override + String get deviceProfile => 'الملف الشخصي للجهاز'; + + @override + String get profileName => 'الاسم'; + + @override + String get profileNick => 'اللقب'; + + @override + String get save => 'حفظ'; + + @override + String get automaticLanguage => 'تلقائي'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_ca.dart b/lib/l10n/generated/app_localizations_ca.dart index 60d53c4..49de744 100644 --- a/lib/l10n/generated/app_localizations_ca.dart +++ b/lib/l10n/generated/app_localizations_ca.dart @@ -715,4 +715,19 @@ class AppLocalizationsCa extends AppLocalizations { @override String get mainTagline => 'Descobreix l’impostor abans que siga massa tard'; + @override + String get deviceProfile => 'Perfil del dispositiu'; + + @override + String get profileName => 'Nom'; + + @override + String get profileNick => 'Àlies'; + + @override + String get save => 'Desa'; + + @override + String get automaticLanguage => 'Automàtic'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_de.dart b/lib/l10n/generated/app_localizations_de.dart index fc8a0e7..5e8a1e2 100644 --- a/lib/l10n/generated/app_localizations_de.dart +++ b/lib/l10n/generated/app_localizations_de.dart @@ -718,4 +718,19 @@ class AppLocalizationsDe extends AppLocalizations { @override String get mainTagline => 'Finde den Hochstapler, bevor es zu spät ist'; + @override + String get deviceProfile => 'Geräteprofil'; + + @override + String get profileName => 'Name'; + + @override + String get profileNick => 'Nickname'; + + @override + String get save => 'Speichern'; + + @override + String get automaticLanguage => 'Automatisch'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_en.dart b/lib/l10n/generated/app_localizations_en.dart index fb3c1e3..07665de 100644 --- a/lib/l10n/generated/app_localizations_en.dart +++ b/lib/l10n/generated/app_localizations_en.dart @@ -712,4 +712,19 @@ class AppLocalizationsEn extends AppLocalizations { @override String get mainTagline => 'Find the impostor before it is too late'; + @override + String get deviceProfile => 'Device profile'; + + @override + String get profileName => 'Name'; + + @override + String get profileNick => 'Nick'; + + @override + String get save => 'Save'; + + @override + String get automaticLanguage => 'Automatic'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_es.dart b/lib/l10n/generated/app_localizations_es.dart index 4310630..e15f807 100644 --- a/lib/l10n/generated/app_localizations_es.dart +++ b/lib/l10n/generated/app_localizations_es.dart @@ -714,4 +714,19 @@ class AppLocalizationsEs extends AppLocalizations { @override String get mainTagline => 'Descubre al impostor antes de que sea tarde'; + @override + String get deviceProfile => 'Perfil del dispositivo'; + + @override + String get profileName => 'Nombre'; + + @override + String get profileNick => 'Nick'; + + @override + String get save => 'Guardar'; + + @override + String get automaticLanguage => 'Automático'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_eu.dart b/lib/l10n/generated/app_localizations_eu.dart index dc8abcc..603f14c 100644 --- a/lib/l10n/generated/app_localizations_eu.dart +++ b/lib/l10n/generated/app_localizations_eu.dart @@ -717,4 +717,19 @@ class AppLocalizationsEu extends AppLocalizations { @override String get mainTagline => 'Aurkitu iruzurtia berandu baino lehen'; + @override + String get deviceProfile => 'Gailuaren profila'; + + @override + String get profileName => 'Izena'; + + @override + String get profileNick => 'Ezizena'; + + @override + String get save => 'Gorde'; + + @override + String get automaticLanguage => 'Automatikoa'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_fr.dart b/lib/l10n/generated/app_localizations_fr.dart index edec65e..4105e84 100644 --- a/lib/l10n/generated/app_localizations_fr.dart +++ b/lib/l10n/generated/app_localizations_fr.dart @@ -715,4 +715,19 @@ class AppLocalizationsFr extends AppLocalizations { @override String get mainTagline => 'Découvre l’imposteur avant qu’il ne soit trop tard'; + @override + String get deviceProfile => 'Profil de l’appareil'; + + @override + String get profileName => 'Nom'; + + @override + String get profileNick => 'Pseudo'; + + @override + String get save => 'Enregistrer'; + + @override + String get automaticLanguage => 'Automatique'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_hi.dart b/lib/l10n/generated/app_localizations_hi.dart index f3b1eae..8c2401d 100644 --- a/lib/l10n/generated/app_localizations_hi.dart +++ b/lib/l10n/generated/app_localizations_hi.dart @@ -714,4 +714,19 @@ class AppLocalizationsHi extends AppLocalizations { @override String get mainTagline => 'बहुत देर होने से पहले impostor को ढूँढें'; + @override + String get deviceProfile => 'डिवाइस प्रोफ़ाइल'; + + @override + String get profileName => 'नाम'; + + @override + String get profileNick => 'निकनेम'; + + @override + String get save => 'सहेजें'; + + @override + String get automaticLanguage => 'स्वचालित'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_it.dart b/lib/l10n/generated/app_localizations_it.dart index 811dcc5..69bec03 100644 --- a/lib/l10n/generated/app_localizations_it.dart +++ b/lib/l10n/generated/app_localizations_it.dart @@ -715,4 +715,19 @@ class AppLocalizationsIt extends AppLocalizations { @override String get mainTagline => 'Scopri l’impostore prima che sia troppo tardi'; + @override + String get deviceProfile => 'Profilo del dispositivo'; + + @override + String get profileName => 'Nome'; + + @override + String get profileNick => 'Nick'; + + @override + String get save => 'Salva'; + + @override + String get automaticLanguage => 'Automatico'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_ja.dart b/lib/l10n/generated/app_localizations_ja.dart index a81f583..9d8c63a 100644 --- a/lib/l10n/generated/app_localizations_ja.dart +++ b/lib/l10n/generated/app_localizations_ja.dart @@ -712,4 +712,19 @@ class AppLocalizationsJa extends AppLocalizations { @override String get mainTagline => '手遅れになる前にインポスターを見つけよう'; + @override + String get deviceProfile => 'デバイスプロフィール'; + + @override + String get profileName => '名前'; + + @override + String get profileNick => 'ニックネーム'; + + @override + String get save => '保存'; + + @override + String get automaticLanguage => '自動'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_ko.dart b/lib/l10n/generated/app_localizations_ko.dart index 45af00e..2c56b69 100644 --- a/lib/l10n/generated/app_localizations_ko.dart +++ b/lib/l10n/generated/app_localizations_ko.dart @@ -712,4 +712,19 @@ class AppLocalizationsKo extends AppLocalizations { @override String get mainTagline => '늦기 전에 임포스터를 찾아내세요'; + @override + String get deviceProfile => '기기 프로필'; + + @override + String get profileName => '이름'; + + @override + String get profileNick => '닉네임'; + + @override + String get save => '저장'; + + @override + String get automaticLanguage => '자동'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_nl.dart b/lib/l10n/generated/app_localizations_nl.dart index 0e2f620..dc13f2f 100644 --- a/lib/l10n/generated/app_localizations_nl.dart +++ b/lib/l10n/generated/app_localizations_nl.dart @@ -715,4 +715,19 @@ class AppLocalizationsNl extends AppLocalizations { @override String get mainTagline => 'Vind de bedrieger voordat het te laat is'; + @override + String get deviceProfile => 'Apparaatprofiel'; + + @override + String get profileName => 'Naam'; + + @override + String get profileNick => 'Nickname'; + + @override + String get save => 'Opslaan'; + + @override + String get automaticLanguage => 'Automatisch'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_pl.dart b/lib/l10n/generated/app_localizations_pl.dart index dd776ec..08263cd 100644 --- a/lib/l10n/generated/app_localizations_pl.dart +++ b/lib/l10n/generated/app_localizations_pl.dart @@ -715,4 +715,19 @@ class AppLocalizationsPl extends AppLocalizations { @override String get mainTagline => 'Znajdź oszusta, zanim będzie za późno'; + @override + String get deviceProfile => 'Profil urządzenia'; + + @override + String get profileName => 'Nazwa'; + + @override + String get profileNick => 'Nick'; + + @override + String get save => 'Zapisz'; + + @override + String get automaticLanguage => 'Automatycznie'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_pt.dart b/lib/l10n/generated/app_localizations_pt.dart index 8ba168e..ff9d988 100644 --- a/lib/l10n/generated/app_localizations_pt.dart +++ b/lib/l10n/generated/app_localizations_pt.dart @@ -716,4 +716,19 @@ class AppLocalizationsPt extends AppLocalizations { @override String get mainTagline => 'Descobre o impostor antes que seja tarde'; + @override + String get deviceProfile => 'Perfil do dispositivo'; + + @override + String get profileName => 'Nome'; + + @override + String get profileNick => 'Nick'; + + @override + String get save => 'Guardar'; + + @override + String get automaticLanguage => 'Automático'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_ru.dart b/lib/l10n/generated/app_localizations_ru.dart index 5401aca..844cd91 100644 --- a/lib/l10n/generated/app_localizations_ru.dart +++ b/lib/l10n/generated/app_localizations_ru.dart @@ -715,4 +715,19 @@ class AppLocalizationsRu extends AppLocalizations { @override String get mainTagline => 'Найди самозванца, пока не стало слишком поздно'; + @override + String get deviceProfile => 'Профиль устройства'; + + @override + String get profileName => 'Имя'; + + @override + String get profileNick => 'Ник'; + + @override + String get save => 'Сохранить'; + + @override + String get automaticLanguage => 'Автоматически'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_tr.dart b/lib/l10n/generated/app_localizations_tr.dart index 423fd97..17edf60 100644 --- a/lib/l10n/generated/app_localizations_tr.dart +++ b/lib/l10n/generated/app_localizations_tr.dart @@ -714,4 +714,19 @@ class AppLocalizationsTr extends AppLocalizations { @override String get mainTagline => 'Çok geç olmadan sahtekârı bul'; + @override + String get deviceProfile => 'Cihaz profili'; + + @override + String get profileName => 'Ad'; + + @override + String get profileNick => 'Takma ad'; + + @override + String get save => 'Kaydet'; + + @override + String get automaticLanguage => 'Otomatik'; + } \ No newline at end of file diff --git a/lib/l10n/generated/app_localizations_zh.dart b/lib/l10n/generated/app_localizations_zh.dart index 2ca6030..8cc1cfb 100644 --- a/lib/l10n/generated/app_localizations_zh.dart +++ b/lib/l10n/generated/app_localizations_zh.dart @@ -711,6 +711,21 @@ class AppLocalizationsZh extends AppLocalizations { @override String get mainTagline => '在太晚之前找出冒牌者'; + @override + String get deviceProfile => '设备档案'; + + @override + String get profileName => '名称'; + + @override + String get profileNick => '昵称'; + + @override + String get save => '保存'; + + @override + String get automaticLanguage => '自动'; + } /// The translations for Chinese, as used in Taiwan (`zh_TW`). @@ -1292,4 +1307,19 @@ class AppLocalizationsZhTw extends AppLocalizationsZh { @override String get mainTagline => '在太晚之前找出冒牌者'; -} + @override + String get deviceProfile => '裝置個人檔案'; + + @override + String get profileName => '名稱'; + + @override + String get profileNick => '暱稱'; + + @override + String get save => '儲存'; + + @override + String get automaticLanguage => '自動'; + +} \ No newline at end of file diff --git a/lib/pantallas/pantalla_ajustes.dart b/lib/pantallas/pantalla_ajustes.dart index 55adc88..2908caf 100644 --- a/lib/pantallas/pantalla_ajustes.dart +++ b/lib/pantallas/pantalla_ajustes.dart @@ -19,6 +19,10 @@ class _PantallaAjustesState extends State { final l10n = AppLocalizations.of(context)!; final servicioIdioma = context.watch(); final perfil = context.watch().perfil; + final nombrePerfil = perfil.nombre.trim().isEmpty + ? l10n.defaultPlayerName + : perfil.nombre.trim(); + final inicialPerfil = nombrePerfil.substring(0, 1).toUpperCase(); return Scaffold( appBar: AppBar(title: Text(l10n.settingsTitle)), @@ -27,62 +31,85 @@ class _PantallaAjustesState extends State { child: SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Card( - child: ListTile( - leading: AvatarFarolero( - texto: perfil.nombre.substring(0, 1).toUpperCase(), - assetPath: perfil.avatarAsset, - size: 128, - ), - title: Text(perfil.nombre), - subtitle: Text('@${perfil.nick}'), - trailing: const Icon(Icons.edit), - onTap: () => _editarPerfil(context), - ), - ), - const SizedBox(height: 12), - - // Selector de idioma - Card( - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(l10n.language, - style: Theme.of(context).textTheme.titleLarge), - const SizedBox(height: 12), - // Opción automática (sistema) - _opcionIdioma( - context, - bandera: '🌐', - nombre: 'Auto (${_nombreIdiomaDelSistema()})', - codigo: 'sistema', - seleccionado: servicioIdioma.codigoActual == 'sistema', - onTap: () => servicioIdioma.cambiarIdioma('sistema'), + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Card( + child: InkWell( + borderRadius: BorderRadius.circular(12), + onTap: () => _editarPerfil(context), + child: Padding( + padding: const EdgeInsets.all(16), + child: Row( + children: [ + AvatarFarolero( + texto: inicialPerfil, + assetPath: perfil.avatarAsset, + size: 96, + ), + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + nombrePerfil, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.titleLarge, + ), + Text( + '@${perfil.nick}', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodyMedium, + ), + ], + ), + ), + const SizedBox(width: 12), + const Icon(Icons.edit), + ], ), - const Divider(height: 1), - // Lista de idiomas - ...ServicioIdioma.idiomasSoportados.entries.map((entrada) { - return _opcionIdioma( - context, - bandera: entrada.value.bandera, - nombre: entrada.value.nombre, - codigo: entrada.key, - seleccionado: - servicioIdioma.codigoActual == entrada.key, - onTap: () => - servicioIdioma.cambiarIdioma(entrada.key), - ); - }), - ], + ), ), ), - ), - const SizedBox(height: 12), - ], + const SizedBox(height: 12), + Card( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + l10n.language, + style: Theme.of(context).textTheme.titleLarge, + ), + const SizedBox(height: 12), + _opcionIdioma( + context, + bandera: '\u{1F310}', + nombre: '${l10n.automaticLanguage} (${_nombreIdiomaDelSistema()})', + codigo: 'sistema', + seleccionado: servicioIdioma.codigoActual == 'sistema', + onTap: () => servicioIdioma.cambiarIdioma('sistema'), + ), + const Divider(height: 1), + ...ServicioIdioma.idiomasSoportados.entries.map((entrada) { + return _opcionIdioma( + context, + bandera: entrada.value.bandera, + nombre: entrada.value.nombre, + codigo: entrada.key, + seleccionado: servicioIdioma.codigoActual == entrada.key, + onTap: () => servicioIdioma.cambiarIdioma(entrada.key), + ); + }), + ], + ), + ), + ), + const SizedBox(height: 12), + ], ), ), ), @@ -112,6 +139,7 @@ class _PantallaAjustesState extends State { } Future _editarPerfil(BuildContext context) async { + final l10n = AppLocalizations.of(context)!; final servicioPerfil = context.read(); final actual = servicioPerfil.perfil; final nombreController = TextEditingController(text: actual.nombre); @@ -122,7 +150,7 @@ class _PantallaAjustesState extends State { context: context, builder: (ctx) => StatefulBuilder( builder: (ctx, setDialogState) => AlertDialog( - title: const Text('Perfil del dispositivo'), + title: Text(l10n.deviceProfile), content: SizedBox( width: 520, child: SingleChildScrollView( @@ -133,17 +161,17 @@ class _PantallaAjustesState extends State { controller: nombreController, textCapitalization: TextCapitalization.words, onChanged: (_) => setDialogState(() {}), - decoration: const InputDecoration( - labelText: 'Nombre', - prefixIcon: Icon(Icons.person), + decoration: InputDecoration( + labelText: l10n.profileName, + prefixIcon: const Icon(Icons.person), ), ), const SizedBox(height: 12), TextField( controller: nickController, - decoration: const InputDecoration( - labelText: 'Nick', - prefixIcon: Icon(Icons.alternate_email), + decoration: InputDecoration( + labelText: l10n.profileNick, + prefixIcon: const Icon(Icons.alternate_email), ), ), const SizedBox(height: 18), @@ -152,43 +180,49 @@ class _PantallaAjustesState extends State { ? '?' : nombreController.text.substring(0, 1).toUpperCase(), assetPath: avatarSeleccionado, - size: 90, + size: 112, ), const SizedBox(height: 18), - GridView.builder( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - gridDelegate: - const SliverGridDelegateWithFixedCrossAxisCount( - crossAxisCount: 4, - mainAxisSpacing: 12, - crossAxisSpacing: 12, - ), - itemCount: ServicioPerfilUsuario.avatares.length, - itemBuilder: (context, index) { - final avatar = ServicioPerfilUsuario.avatares[index]; - final seleccionado = avatar == avatarSeleccionado; - return InkWell( - borderRadius: BorderRadius.circular(999), - onTap: () => setDialogState( - () => avatarSeleccionado = avatar, + LayoutBuilder( + builder: (context, constraints) { + final columnas = constraints.maxWidth >= 420 ? 4 : 3; + return GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: columnas, + mainAxisSpacing: 14, + crossAxisSpacing: 14, ), - child: Container( - decoration: BoxDecoration( - shape: BoxShape.circle, - border: Border.all( - color: seleccionado - ? TemaApp.colorNaranja - : Colors.transparent, - width: 3, + itemCount: ServicioPerfilUsuario.avatares.length, + itemBuilder: (context, index) { + final avatar = ServicioPerfilUsuario.avatares[index]; + final seleccionado = avatar == avatarSeleccionado; + return InkWell( + borderRadius: BorderRadius.circular(999), + onTap: () => setDialogState( + () => avatarSeleccionado = avatar, ), - ), - child: AvatarFarolero( - texto: '', - assetPath: avatar, - size: 72, - ), - ), + child: DecoratedBox( + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: seleccionado + ? TemaApp.colorNaranja + : Colors.transparent, + width: 3, + ), + ), + child: Center( + child: AvatarFarolero( + texto: '', + assetPath: avatar, + size: 86, + ), + ), + ), + ); + }, ); }, ), @@ -199,7 +233,7 @@ class _PantallaAjustesState extends State { actions: [ TextButton( onPressed: () => Navigator.pop(ctx), - child: const Text('Cancelar'), + child: Text(l10n.cancel), ), TextButton( onPressed: () async { @@ -210,7 +244,7 @@ class _PantallaAjustesState extends State { ); if (ctx.mounted) Navigator.pop(ctx); }, - child: const Text('Guardar'), + child: Text(l10n.save), ), ], ), diff --git a/lib/pantallas/pantalla_crear_partida.dart b/lib/pantallas/pantalla_crear_partida.dart index 34c0e6f..b79d241 100644 --- a/lib/pantallas/pantalla_crear_partida.dart +++ b/lib/pantallas/pantalla_crear_partida.dart @@ -490,11 +490,16 @@ class _PantallaCrearPartidaState extends State { final esPerfilLocal = e.key == 0 && e.value == nombrePerfil; return ListTile( + minLeadingWidth: 62, leading: esPerfilLocal - ? AvatarFarolero( - texto: inicialPerfil, - assetPath: perfil.avatarAsset, - size: 54, + ? SizedBox( + width: 62, + height: 62, + child: AvatarFarolero( + texto: inicialPerfil, + assetPath: perfil.avatarAsset, + size: 52, + ), ) : CircleAvatar( backgroundColor: TemaApp.colorTarjeta, @@ -516,7 +521,6 @@ class _PantallaCrearPartidaState extends State { ), onPressed: () => _eliminarJugador(e.key), ), - dense: true, ); }), ], diff --git a/lib/pantallas/pantalla_lobby_host.dart b/lib/pantallas/pantalla_lobby_host.dart index c095868..54b25a0 100644 --- a/lib/pantallas/pantalla_lobby_host.dart +++ b/lib/pantallas/pantalla_lobby_host.dart @@ -49,142 +49,154 @@ class _PantallaLobbyHostState extends State { ), body: FondoFarolero( intenso: true, - child: Padding( - padding: const EdgeInsets.all(24), - child: Column( - children: [ - const _LobbySignalArt(), - const SizedBox(height: 12), - EncabezadoFarolero( - icono: Icons.wifi_tethering, - titulo: widget.nombreSala, - subtitulo: l10n.scanToJoin, - ), - const SizedBox(height: 14), - PanelFarolero( - padding: const EdgeInsets.fromLTRB(16, 18, 16, 16), - child: Column( - children: [ - SizedBox( - width: 236, - height: 236, - child: Stack( - alignment: Alignment.center, + child: SafeArea( + top: false, + child: SingleChildScrollView( + padding: const EdgeInsets.fromLTRB(20, 20, 20, 24), + child: Center( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 480), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const _LobbySignalArt(), + const SizedBox(height: 12), + EncabezadoFarolero( + icono: Icons.wifi_tethering, + titulo: widget.nombreSala, + subtitulo: l10n.scanToJoin, + ), + const SizedBox(height: 14), + PanelFarolero( + padding: const EdgeInsets.fromLTRB(18, 20, 18, 18), + child: Column( children: [ - Positioned.fill( - child: IgnorePointer( - child: Image.asset( - 'assets/ui/generated/join_lobby/qr_frame.png', - fit: BoxFit.contain, - ), - ), - ), - Container( - width: 178, - height: 178, - padding: const EdgeInsets.all(8), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(12), - boxShadow: [ - BoxShadow( - color: TemaApp.colorNaranja.withValues(alpha: 0.18), - blurRadius: 24, + SizedBox( + width: 268, + height: 268, + child: Stack( + alignment: Alignment.center, + children: [ + Positioned.fill( + child: IgnorePointer( + child: Image.asset( + 'assets/ui/generated/join_lobby/qr_frame.png', + fit: BoxFit.contain, + ), + ), + ), + Container( + width: 210, + height: 210, + padding: const EdgeInsets.all(14), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16), + border: Border.all( + color: TemaApp.colorDorado.withValues(alpha: 0.42), + width: 2, + ), + boxShadow: [ + BoxShadow( + color: TemaApp.colorNaranja.withValues(alpha: 0.20), + blurRadius: 24, + ), + ], + ), + child: QrImageView( + data: nearby.generarDatosQR(widget.nombreSala), + version: QrVersions.auto, + size: 182, + backgroundColor: Colors.white, + ), ), ], ), - child: QrImageView( - data: nearby.generarDatosQR(widget.nombreSala), - version: QrVersions.auto, - size: 162, - backgroundColor: Colors.white, - ), + ), + const SizedBox(height: 10), + Text( + l10n.scanThisCodeFromAnotherPhone, + style: Theme.of(context).textTheme.bodyMedium, + textAlign: TextAlign.center, ), ], ), ), - const SizedBox(height: 10), - Text( - l10n.scanThisCodeFromAnotherPhone, - style: Theme.of(context).textTheme.bodyMedium, - textAlign: TextAlign.center, + const SizedBox(height: 16), + _buildResumenSala( + context, + l10n, + seleccionados, + nearby.jugadores.length, + ), + const SizedBox(height: 12), + Card( + child: Padding( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + child: Text( + l10n.gameUsers, + style: Theme.of(context).textTheme.titleLarge, + ), + ), + IconButton.filledTonal( + onPressed: () => _crearNuevoUsuario(context), + icon: const Icon(Icons.person_add), + ), + ], + ), + const SizedBox(height: 8), + if (usuarios.isEmpty) + SizedBox( + height: 96, + child: Center(child: Text(l10n.waitingForPlayers)), + ) + else + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: usuarios.length, + itemBuilder: (context, index) => _buildUsuarioTile( + context, + l10n, + usuarios[index], + ), + ), + ], + ), + ), + ), + const SizedBox(height: 12), + if (!puedeIniciar) + Text( + _mensajeValidacion(validacionInicio?.codigo, l10n), + style: Theme.of(context) + .textTheme + .bodyMedium + ?.copyWith(color: TemaApp.colorNaranja), + textAlign: TextAlign.center, + ), + const SizedBox(height: 12), + BotonFarolero( + texto: _iniciando ? l10n.starting : l10n.startGame, + icono: Icons.play_arrow, + onPressed: puedeIniciar && !_iniciando + ? () { + setState(() => _iniciando = true); + widget.onIniciar(); + } + : null, ), ], ), ), - const SizedBox(height: 16), - _buildResumenSala( - context, - l10n, - seleccionados, - nearby.jugadores.length, - ), - const SizedBox(height: 12), - Expanded( - child: Card( - child: Padding( - padding: const EdgeInsets.all(12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded( - child: Text( - l10n.gameUsers, - style: Theme.of(context).textTheme.titleLarge, - ), - ), - IconButton.filledTonal( - onPressed: () => _crearNuevoUsuario(context), - icon: const Icon(Icons.person_add), - ), - ], - ), - const SizedBox(height: 8), - Expanded( - child: usuarios.isEmpty - ? Center(child: Text(l10n.waitingForPlayers)) - : ListView.builder( - itemCount: usuarios.length, - itemBuilder: (context, index) => - _buildUsuarioTile( - context, - l10n, - usuarios[index], - ), - ), - ), - ], - ), - ), - ), - ), - const SizedBox(height: 12), - if (!puedeIniciar) - Text( - _mensajeValidacion(validacionInicio?.codigo, l10n), - style: Theme.of(context) - .textTheme - .bodyMedium - ?.copyWith(color: TemaApp.colorNaranja), - textAlign: TextAlign.center, - ), - const SizedBox(height: 12), - SizedBox( - width: double.infinity, - child: BotonFarolero( - texto: _iniciando ? l10n.starting : l10n.startGame, - icono: Icons.play_arrow, - onPressed: puedeIniciar && !_iniciando - ? () { - setState(() => _iniciando = true); - widget.onIniciar(); - } - : null, - ), - ), - ], + ), ), ), ), @@ -276,8 +288,10 @@ class _PantallaLobbyHostState extends State { usuario.estaSeleccionado && usuario.clienteIdSeleccionado != miClientId; return ListTile( - leading: CircleAvatar( - backgroundColor: Colors.transparent, + minLeadingWidth: 58, + leading: SizedBox( + width: 58, + height: 58, child: AvatarFarolero( texto: usuario.nombre.isEmpty ? '?' : usuario.nombre[0], assetPath: usuario.avatar, @@ -286,7 +300,7 @@ class _PantallaLobbyHostState extends State { : seleccionadoPorOtro ? TemaApp.colorNaranja : TemaApp.colorAzul, - size: 38, + size: 48, fuego: usuario.fuego, medallas: usuario.medallas, ), diff --git a/lib/pantallas/pantalla_unirse.dart b/lib/pantallas/pantalla_unirse.dart index c6a29e9..31d84e8 100644 --- a/lib/pantallas/pantalla_unirse.dart +++ b/lib/pantallas/pantalla_unirse.dart @@ -866,12 +866,17 @@ class _PantallaUnirseState extends State { usuario.estaSeleccionado && usuario.clienteIdSeleccionado != miClientId; return ListTile( - leading: AvatarFarolero( - texto: usuario.nombre.isEmpty ? '?' : usuario.nombre[0], - assetPath: usuario.avatar, - size: 38, - fuego: usuario.fuego, - medallas: usuario.medallas, + minLeadingWidth: 58, + leading: SizedBox( + width: 58, + height: 58, + child: AvatarFarolero( + texto: usuario.nombre.isEmpty ? '?' : usuario.nombre[0], + assetPath: usuario.avatar, + size: 48, + fuego: usuario.fuego, + medallas: usuario.medallas, + ), ), title: Text(usuario.nombre), subtitle: Column( diff --git a/lib/tema/componentes_farolero.dart b/lib/tema/componentes_farolero.dart index e0808ad..18adcaf 100644 --- a/lib/tema/componentes_farolero.dart +++ b/lib/tema/componentes_farolero.dart @@ -532,7 +532,8 @@ class AvatarFarolero extends StatelessWidget { assetPath!, width: size, height: size, - fit: BoxFit.cover, + fit: BoxFit.contain, + filterQuality: FilterQuality.high, ), ), ), diff --git a/skills/premium-game-ui/SKILL.md b/skills/premium-game-ui/SKILL.md index 848808a..daaf3c7 100644 --- a/skills/premium-game-ui/SKILL.md +++ b/skills/premium-game-ui/SKILL.md @@ -33,6 +33,11 @@ metadata: 8. **Avoid expensive composition.** Do not wrap large areas in `Opacity` when a semitransparent color/image or pre-baked alpha asset works. 9. **Plan before generating.** First write the layer list: filename, role, size, alpha requirement, anchor, and Flutter usage. 10. **No placeholders in final premium work.** Generic icons, basic circles, simple radial glows, plain gradients, and procedural sparkles are acceptable only as temporary scaffolding. Replace them with generated art assets before claiming the screen is done. +11. **Generated frames are decoration, not layout.** Never stretch ornate button/card frames as functional backgrounds when they contain rails, gems, or ornaments that can cross text. Keep labels, icons, hit states, disabled states, and alignment in reusable Flutter components; put generated art behind or around them as a non-blocking layer. +12. **Preserve scrollability on mobile.** Any premium screen with variable content (users, avatars, settings, QR plus lists) must remain inside a `SingleChildScrollView` or have an explicit bounded internal scroll. Do not remove scroll by introducing full-height `Column` + `Expanded` layouts unless the content is guaranteed to fit. +13. **QR codes are functional, not decorative.** A QR must have a clean white quiet zone, enough padding, and no decorative overlay above the scannable pixels. Frames can sit behind or outside the white QR card, never over finder patterns. +14. **Avatars must not be clipped or tiny.** Do not place large avatars in `ListTile.leading` without explicit leading width/height. Use `BoxFit.contain` for generated avatar art, reserve enough tile height, and prefer visibly useful sizes (roughly 48-96 px in lists/cards, 86-112 px in pickers/previews). +15. **Localization is part of premium UI.** User-visible copy must go through the app localization system. For Spanish, use Spanish from Spain; avoid Rioplatense/Argentinian phrasing in app strings. ## Mandatory Image Generation Rule