diff --git a/.DS_Store b/.DS_Store index 0821c08..5db0715 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 62dddd3..a8437fb 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } android { - namespace = "com.sanza.tetraq" + namespace = "com.amastra.tetraq" compileSdk = flutter.compileSdkVersion ndkVersion = flutter.ndkVersion @@ -24,7 +24,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId = "com.sanza.tetraq" + applicationId = "com.amastra.tetraq" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. minSdk = flutter.minSdkVersion diff --git a/android/app/google-services.json b/android/app/google-services.json index 2af9bd8..7ab3169 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -5,6 +5,25 @@ "storage_bucket": "tetraq-32a4a.firebasestorage.app" }, "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:705460445314:android:ceac21bb06b7a9f07b949b", + "android_client_info": { + "package_name": "com.amastra.tetraq" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyBsXO595xVITDPrRnXrW8HPQLOe7Rz4Gg4" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + }, { "client_info": { "mobilesdk_app_id": "1:705460445314:android:4d35fef29cfd63727b949b", diff --git a/android/app/src/main/kotlin/com/sanza/tetraq/MainActivity.kt b/android/app/src/main/kotlin/com/amastra/tetraq/MainActivity.kt similarity index 77% rename from android/app/src/main/kotlin/com/sanza/tetraq/MainActivity.kt rename to android/app/src/main/kotlin/com/amastra/tetraq/MainActivity.kt index 8c2bbf4..e0b6e97 100644 --- a/android/app/src/main/kotlin/com/sanza/tetraq/MainActivity.kt +++ b/android/app/src/main/kotlin/com/amastra/tetraq/MainActivity.kt @@ -1,4 +1,4 @@ -package com.sanza.tetraq +package com.amastra.tetraq import io.flutter.embedding.android.FlutterActivity diff --git a/firebase.json b/firebase.json index 01ff3f8..76a181a 100644 --- a/firebase.json +++ b/firebase.json @@ -1 +1 @@ -{"flutter":{"platforms":{"android":{"default":{"projectId":"tetraq-32a4a","appId":"1:705460445314:android:4d35fef29cfd63727b949b","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"tetraq-32a4a","appId":"1:705460445314:ios:da11cbca5d1f6bc27b949b","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"tetraq-32a4a","appId":"1:705460445314:ios:da11cbca5d1f6bc27b949b","uploadDebugSymbols":false,"fileOutput":"macos/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"tetraq-32a4a","configurations":{"android":"1:705460445314:android:4d35fef29cfd63727b949b","ios":"1:705460445314:ios:da11cbca5d1f6bc27b949b","macos":"1:705460445314:ios:da11cbca5d1f6bc27b949b"}}}}}} \ No newline at end of file +{"flutter":{"platforms":{"android":{"default":{"projectId":"tetraq-32a4a","appId":"1:705460445314:android:ceac21bb06b7a9f07b949b","fileOutput":"android/app/google-services.json"}},"ios":{"default":{"projectId":"tetraq-32a4a","appId":"1:705460445314:ios:54d64cb7592954327b949b","uploadDebugSymbols":false,"fileOutput":"ios/Runner/GoogleService-Info.plist"}},"macos":{"default":{"projectId":"tetraq-32a4a","appId":"1:705460445314:ios:da11cbca5d1f6bc27b949b","uploadDebugSymbols":false,"fileOutput":"macos/Runner/GoogleService-Info.plist"}},"dart":{"lib/firebase_options.dart":{"projectId":"tetraq-32a4a","configurations":{"android":"1:705460445314:android:ceac21bb06b7a9f07b949b","ios":"1:705460445314:ios:54d64cb7592954327b949b","macos":"1:705460445314:ios:da11cbca5d1f6bc27b949b"}}}}}} \ No newline at end of file diff --git a/genera_lingue.dart b/genera_lingue.dart new file mode 100644 index 0000000..8129f8b --- /dev/null +++ b/genera_lingue.dart @@ -0,0 +1,27 @@ +import 'dart:io'; +import 'dart:convert'; + +void main() async { + final dir = Directory('lib/l10n'); + if (!await dir.exists()) await dir.create(recursive: true); + + final Map> translations = { + 'it': {"appTitle": "TetraQ", "welcomeTitle": "BENVENUTO IN TETRAQ!", "nameHint": "NOME", "saveAndPlay": "SALVA E GIOCA", "onlineTitle": "ONLINE", "onlineSub": "Sfida il mondo", "cpuTitle": "VS CPU", "cpuSub": "Allenati con l'IA", "localTitle": "LOCALE", "localSub": "Stesso schermo", "leaderboardTitle": "CLASSIFICA", "questsTitle": "SFIDE", "themesTitle": "TEMI", "tutorialTitle": "TUTORIAL", "startGame": "AVVIA PARTITA", "createMatch": "CREA PARTITA", "joinMatch": "UNISCITI", "gameOver": "FINE PARTITA", "mainMenu": "TORNA AL MENU", "exit": "ESCI"}, + 'en': {"appTitle": "TetraQ", "welcomeTitle": "WELCOME TO TETRAQ!", "nameHint": "NAME", "saveAndPlay": "SAVE & PLAY", "onlineTitle": "ONLINE", "onlineSub": "Challenge the world", "cpuTitle": "VS CPU", "cpuSub": "Train with AI", "localTitle": "LOCAL", "localSub": "Same screen", "leaderboardTitle": "LEADERBOARD", "questsTitle": "QUESTS", "themesTitle": "THEMES", "tutorialTitle": "TUTORIAL", "startGame": "START GAME", "createMatch": "CREATE MATCH", "joinMatch": "JOIN", "gameOver": "GAME OVER", "mainMenu": "BACK TO MENU", "exit": "EXIT"}, + 'es': {"appTitle": "TetraQ", "welcomeTitle": "¡BIENVENIDO A TETRAQ!", "nameHint": "NOMBRE", "saveAndPlay": "GUARDAR Y JUGAR", "onlineTitle": "ONLINE", "onlineSub": "Desafía al mundo", "cpuTitle": "VS CPU", "cpuSub": "Entrena con IA", "localTitle": "LOCAL", "localSub": "Misma pantalla", "leaderboardTitle": "RANKING", "questsTitle": "MISIONES", "themesTitle": "TEMAS", "tutorialTitle": "TUTORIAL", "startGame": "INICIAR JUEGO", "createMatch": "CREAR PARTIDA", "joinMatch": "UNIRSE", "gameOver": "FIN DEL JUEGO", "mainMenu": "VOLVER AL MENÚ", "exit": "SALIR"}, + 'fr': {"appTitle": "TetraQ", "welcomeTitle": "BIENVENUE DANS TETRAQ !", "nameHint": "NOM", "saveAndPlay": "SAUVEGARDER ET JOUER", "onlineTitle": "EN LIGNE", "onlineSub": "Défiez le monde", "cpuTitle": "VS CPU", "cpuSub": "Entraînez avec l'IA", "localTitle": "LOCAL", "localSub": "Même écran", "leaderboardTitle": "CLASSEMENT", "questsTitle": "QUÊTES", "themesTitle": "THÈMES", "tutorialTitle": "TUTORIEL", "startGame": "JOUER", "createMatch": "CRÉER UN MATCH", "joinMatch": "REJOINDRE", "gameOver": "FIN DE PARTIE", "mainMenu": "RETOUR AU MENU", "exit": "QUITTER"}, + 'de': {"appTitle": "TetraQ", "welcomeTitle": "WILLKOMMEN BEI TETRAQ!", "nameHint": "NAME", "saveAndPlay": "SPEICHERN & SPIELEN", "onlineTitle": "ONLINE", "onlineSub": "Fordere die Welt heraus", "cpuTitle": "VS CPU", "cpuSub": "Trainiere mit KI", "localTitle": "LOKAL", "localSub": "Gleicher Bildschirm", "leaderboardTitle": "RANGLISTE", "questsTitle": "MISSIONEN", "themesTitle": "THEMEN", "tutorialTitle": "TUTORIAL", "startGame": "SPIEL STARTEN", "createMatch": "SPIEL ERSTELLEN", "joinMatch": "BEITRETEN", "gameOver": "SPIELENDE", "mainMenu": "ZURÜCK ZUM MENÜ", "exit": "BEENDEN"}, + 'pt': {"appTitle": "TetraQ", "welcomeTitle": "BEM-VINDO AO TETRAQ!", "nameHint": "NOME", "saveAndPlay": "SALVAR E JOGAR", "onlineTitle": "ONLINE", "onlineSub": "Desafie o mundo", "cpuTitle": "VS CPU", "cpuSub": "Treine com a IA", "localTitle": "LOCAL", "localSub": "Mesma tela", "leaderboardTitle": "CLASSIFICAÇÃO", "questsTitle": "DESAFIOS", "themesTitle": "TEMAS", "tutorialTitle": "TUTORIAL", "startGame": "INICIAR JOGO", "createMatch": "CRIAR PARTIDA", "joinMatch": "ENTRAR", "gameOver": "FIM DE JOGO", "mainMenu": "VOLTAR AO MENU", "exit": "SAIR"}, + 'ru': {"appTitle": "TetraQ", "welcomeTitle": "ДОБРО ПОЖАЛОВАТЬ В TETRAQ!", "nameHint": "ИМЯ", "saveAndPlay": "СОХРАНИТЬ И ИГРАТЬ", "onlineTitle": "ОНЛАЙН", "onlineSub": "Брось вызов миру", "cpuTitle": "VS ИИ", "cpuSub": "Тренировка с ИИ", "localTitle": "ЛОКАЛЬНО", "localSub": "Один экран", "leaderboardTitle": "РЕЙТИНГ", "questsTitle": "ЗАДАНИЯ", "themesTitle": "ТЕМЫ", "tutorialTitle": "ОБУЧЕНИЕ", "startGame": "НАЧАТЬ ИГРУ", "createMatch": "СОЗДАТЬ ИГРУ", "joinMatch": "ПРИСОЕДИНИТЬСЯ", "gameOver": "ИГРА ОКОНЧЕНА", "mainMenu": "В ГЛАВНОЕ МЕНЮ", "exit": "ВЫХОД"}, + 'zh': {"appTitle": "TetraQ", "welcomeTitle": "欢迎来到 TETRAQ!", "nameHint": "名字", "saveAndPlay": "保存并开始", "onlineTitle": "在线匹配", "onlineSub": "挑战世界", "cpuTitle": "人机对战", "cpuSub": "与AI训练", "localTitle": "本地游戏", "localSub": "同屏对战", "leaderboardTitle": "排行榜", "questsTitle": "任务", "themesTitle": "主题", "tutorialTitle": "教程", "startGame": "开始游戏", "createMatch": "创建比赛", "joinMatch": "加入", "gameOver": "游戏结束", "mainMenu": "返回主菜单", "exit": "退出"} + }; + + for (var lang in translations.keys) { + final file = File('lib/l10n/app_$lang.arb'); + final Map finalContent = {"@@locale": lang, ...translations[lang]!}; + await file.writeAsString(JsonEncoder.withIndent(' ').convert(finalContent)); + } + + // Crea anche il file di configurazione + await File('l10n.yaml').writeAsString("arb-dir: lib/l10n\ntemplate-arb-file: app_it.arb\noutput-localization-file: app_localizations.dart\n"); +} \ No newline at end of file diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index aabb61d..db0a89b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -483,7 +483,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0.2; - PRODUCT_BUNDLE_IDENTIFIER = com.sanza.tetraq; + PRODUCT_BUNDLE_IDENTIFIER = com.amastra.tetraq; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -500,7 +500,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.sanza.tetraq.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.amastra.tetraq.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -518,7 +518,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.sanza.tetraq.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.amastra.tetraq.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -534,7 +534,7 @@ CURRENT_PROJECT_VERSION = 1; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.sanza.tetraq.RunnerTests; + PRODUCT_BUNDLE_IDENTIFIER = com.amastra.tetraq.RunnerTests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; @@ -668,7 +668,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0.2; - PRODUCT_BUNDLE_IDENTIFIER = com.sanza.tetraq; + PRODUCT_BUNDLE_IDENTIFIER = com.amastra.tetraq; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -693,7 +693,7 @@ "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0.2; - PRODUCT_BUNDLE_IDENTIFIER = com.sanza.tetraq; + PRODUCT_BUNDLE_IDENTIFIER = com.amastra.tetraq; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist index f4889f9..fd527d2 100644 --- a/ios/Runner/GoogleService-Info.plist +++ b/ios/Runner/GoogleService-Info.plist @@ -9,7 +9,7 @@ PLIST_VERSION 1 BUNDLE_ID - com.sanza.tetraq + com.amastra.tetraq PROJECT_ID tetraq-32a4a STORAGE_BUCKET @@ -25,6 +25,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:705460445314:ios:da11cbca5d1f6bc27b949b + 1:705460445314:ios:54d64cb7592954327b949b \ No newline at end of file diff --git a/l10n.yaml b/l10n.yaml new file mode 100644 index 0000000..9680456 --- /dev/null +++ b/l10n.yaml @@ -0,0 +1,4 @@ +arb-dir: lib/l10n +template-arb-file: app_it.arb +output-localization-file: app_localizations.dart +output-dir: lib/l10n \ No newline at end of file diff --git a/lib/.DS_Store b/lib/.DS_Store index 82ae50d..45c664f 100644 Binary files a/lib/.DS_Store and b/lib/.DS_Store differ diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart index d2d2aae..3a624e7 100644 --- a/lib/firebase_options.dart +++ b/lib/firebase_options.dart @@ -48,7 +48,7 @@ class DefaultFirebaseOptions { static const FirebaseOptions android = FirebaseOptions( apiKey: 'AIzaSyBsXO595xVITDPrRnXrW8HPQLOe7Rz4Gg4', - appId: '1:705460445314:android:4d35fef29cfd63727b949b', + appId: '1:705460445314:android:ceac21bb06b7a9f07b949b', messagingSenderId: '705460445314', projectId: 'tetraq-32a4a', storageBucket: 'tetraq-32a4a.firebasestorage.app', @@ -56,11 +56,11 @@ class DefaultFirebaseOptions { static const FirebaseOptions ios = FirebaseOptions( apiKey: 'AIzaSyB77j18Jgeb9gBAEwp-uyOQvr4m-RJ_rAE', - appId: '1:705460445314:ios:da11cbca5d1f6bc27b949b', + appId: '1:705460445314:ios:54d64cb7592954327b949b', messagingSenderId: '705460445314', projectId: 'tetraq-32a4a', storageBucket: 'tetraq-32a4a.firebasestorage.app', - iosBundleId: 'com.sanza.tetraq', + iosBundleId: 'com.amastra.tetraq', ); static const FirebaseOptions macos = FirebaseOptions( @@ -71,4 +71,5 @@ class DefaultFirebaseOptions { storageBucket: 'tetraq-32a4a.firebasestorage.app', iosBundleId: 'com.sanza.tetraq', ); -} + +} \ No newline at end of file diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb new file mode 100644 index 0000000..e19b3bf --- /dev/null +++ b/lib/l10n/app_de.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "de", + "appTitle": "TetraQ", + "welcomeTitle": "WILLKOMMEN BEI TETRAQ!", + "nameHint": "NAME", + "saveAndPlay": "SPEICHERN & SPIELEN", + "onlineTitle": "ONLINE", + "onlineSub": "Fordere die Welt heraus", + "cpuTitle": "VS CPU", + "cpuSub": "Trainiere mit KI", + "localTitle": "LOKAL", + "localSub": "Gleicher Bildschirm", + "leaderboardTitle": "RANGLISTE", + "questsTitle": "MISSIONEN", + "themesTitle": "THEMEN", + "tutorialTitle": "TUTORIAL", + "startGame": "SPIEL STARTEN", + "createMatch": "SPIEL ERSTELLEN", + "joinMatch": "BEITRETEN", + "gameOver": "SPIELENDE", + "mainMenu": "ZURÜCK ZUM MENÜ", + "exit": "BEENDEN" +} \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index a7ed8a0..482936c 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1,4 +1,23 @@ { + "@@locale": "en", "appTitle": "TetraQ", - "playLocal": "PASS & PLAY (Local)" -} + "welcomeTitle": "WELCOME TO TETRAQ!", + "nameHint": "NAME", + "saveAndPlay": "SAVE & PLAY", + "onlineTitle": "ONLINE", + "onlineSub": "Challenge the world", + "cpuTitle": "VS CPU", + "cpuSub": "Train with AI", + "localTitle": "LOCAL", + "localSub": "Same screen", + "leaderboardTitle": "LEADERBOARD", + "questsTitle": "QUESTS", + "themesTitle": "THEMES", + "tutorialTitle": "TUTORIAL", + "startGame": "START GAME", + "createMatch": "CREATE MATCH", + "joinMatch": "JOIN", + "gameOver": "GAME OVER", + "mainMenu": "BACK TO MENU", + "exit": "EXIT" +} \ No newline at end of file diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb new file mode 100644 index 0000000..c932d20 --- /dev/null +++ b/lib/l10n/app_es.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "es", + "appTitle": "TetraQ", + "welcomeTitle": "¡BIENVENIDO A TETRAQ!", + "nameHint": "NOMBRE", + "saveAndPlay": "GUARDAR Y JUGAR", + "onlineTitle": "ONLINE", + "onlineSub": "Desafía al mundo", + "cpuTitle": "VS CPU", + "cpuSub": "Entrena con IA", + "localTitle": "LOCAL", + "localSub": "Misma pantalla", + "leaderboardTitle": "RANKING", + "questsTitle": "MISIONES", + "themesTitle": "TEMAS", + "tutorialTitle": "TUTORIAL", + "startGame": "INICIAR JUEGO", + "createMatch": "CREAR PARTIDA", + "joinMatch": "UNIRSE", + "gameOver": "FIN DEL JUEGO", + "mainMenu": "VOLVER AL MENÚ", + "exit": "SALIR" +} \ No newline at end of file diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb new file mode 100644 index 0000000..4caf624 --- /dev/null +++ b/lib/l10n/app_fr.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "fr", + "appTitle": "TetraQ", + "welcomeTitle": "BIENVENUE DANS TETRAQ !", + "nameHint": "NOM", + "saveAndPlay": "SAUVEGARDER ET JOUER", + "onlineTitle": "EN LIGNE", + "onlineSub": "Défiez le monde", + "cpuTitle": "VS CPU", + "cpuSub": "Entraînez avec l'IA", + "localTitle": "LOCAL", + "localSub": "Même écran", + "leaderboardTitle": "CLASSEMENT", + "questsTitle": "QUÊTES", + "themesTitle": "THÈMES", + "tutorialTitle": "TUTORIEL", + "startGame": "JOUER", + "createMatch": "CRÉER UN MATCH", + "joinMatch": "REJOINDRE", + "gameOver": "FIN DE PARTIE", + "mainMenu": "RETOUR AU MENU", + "exit": "QUITTER" +} \ No newline at end of file diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index ff1eba0..7e4e3d9 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -1,4 +1,23 @@ { + "@@locale": "it", "appTitle": "TetraQ", - "playLocal": "PASS & PLAY (Locale)" -} + "welcomeTitle": "BENVENUTO IN TETRAQ!", + "nameHint": "NOME", + "saveAndPlay": "SALVA E GIOCA", + "onlineTitle": "ONLINE", + "onlineSub": "Sfida il mondo", + "cpuTitle": "VS CPU", + "cpuSub": "Allenati con l'IA", + "localTitle": "LOCALE", + "localSub": "Stesso schermo", + "leaderboardTitle": "CLASSIFICA", + "questsTitle": "SFIDE", + "themesTitle": "TEMI", + "tutorialTitle": "TUTORIAL", + "startGame": "AVVIA PARTITA", + "createMatch": "CREA PARTITA", + "joinMatch": "UNISCITI", + "gameOver": "FINE PARTITA", + "mainMenu": "TORNA AL MENU", + "exit": "ESCI" +} \ No newline at end of file diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart new file mode 100644 index 0000000..66b0b21 --- /dev/null +++ b/lib/l10n/app_localizations.dart @@ -0,0 +1,286 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:intl/intl.dart' as intl; + +import 'app_localizations_de.dart'; +import 'app_localizations_en.dart'; +import 'app_localizations_es.dart'; +import 'app_localizations_fr.dart'; +import 'app_localizations_it.dart'; +import 'app_localizations_pt.dart'; +import 'app_localizations_ru.dart'; +import 'app_localizations_zh.dart'; + +// ignore_for_file: type=lint + +/// Callers can lookup localized strings with an instance of AppLocalizations +/// returned by `AppLocalizations.of(context)`. +/// +/// Applications need to include `AppLocalizations.delegate()` in their app's +/// `localizationDelegates` list, and the locales they support in the app's +/// `supportedLocales` list. For example: +/// +/// ```dart +/// import 'l10n/app_localizations.dart'; +/// +/// return MaterialApp( +/// localizationsDelegates: AppLocalizations.localizationsDelegates, +/// supportedLocales: AppLocalizations.supportedLocales, +/// home: MyApplicationHome(), +/// ); +/// ``` +/// +/// ## Update pubspec.yaml +/// +/// Please make sure to update your pubspec.yaml to include the following +/// packages: +/// +/// ```yaml +/// dependencies: +/// # Internationalization support. +/// flutter_localizations: +/// sdk: flutter +/// intl: any # Use the pinned version from flutter_localizations +/// +/// # Rest of dependencies +/// ``` +/// +/// ## iOS Applications +/// +/// iOS applications define key application metadata, including supported +/// locales, in an Info.plist file that is built into the application bundle. +/// To configure the locales supported by your app, you’ll need to edit this +/// file. +/// +/// First, open your project’s ios/Runner.xcworkspace Xcode workspace file. +/// Then, in the Project Navigator, open the Info.plist file under the Runner +/// project’s Runner folder. +/// +/// Next, select the Information Property List item, select Add Item from the +/// Editor menu, then select Localizations from the pop-up menu. +/// +/// Select and expand the newly-created Localizations item then, for each +/// locale your application supports, add a new item and select the locale +/// you wish to add from the pop-up menu in the Value field. This list should +/// be consistent with the languages listed in the AppLocalizations.supportedLocales +/// property. +abstract class AppLocalizations { + AppLocalizations(String locale) + : localeName = intl.Intl.canonicalizedLocale(locale.toString()); + + final String localeName; + + static AppLocalizations? of(BuildContext context) { + return Localizations.of(context, AppLocalizations); + } + + static const LocalizationsDelegate delegate = + _AppLocalizationsDelegate(); + + /// A list of this localizations delegate along with the default localizations + /// delegates. + /// + /// Returns a list of localizations delegates containing this delegate along with + /// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate, + /// and GlobalWidgetsLocalizations.delegate. + /// + /// Additional delegates can be added by appending to this list in + /// MaterialApp. This list does not have to be used at all if a custom list + /// of delegates is preferred or required. + static const List> localizationsDelegates = + >[ + delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ]; + + /// A list of this localizations delegate's supported locales. + static const List supportedLocales = [ + Locale('de'), + Locale('en'), + Locale('es'), + Locale('fr'), + Locale('it'), + Locale('pt'), + Locale('ru'), + Locale('zh'), + ]; + + /// No description provided for @appTitle. + /// + /// In it, this message translates to: + /// **'TetraQ'** + String get appTitle; + + /// No description provided for @welcomeTitle. + /// + /// In it, this message translates to: + /// **'BENVENUTO IN TETRAQ!'** + String get welcomeTitle; + + /// No description provided for @nameHint. + /// + /// In it, this message translates to: + /// **'NOME'** + String get nameHint; + + /// No description provided for @saveAndPlay. + /// + /// In it, this message translates to: + /// **'SALVA E GIOCA'** + String get saveAndPlay; + + /// No description provided for @onlineTitle. + /// + /// In it, this message translates to: + /// **'ONLINE'** + String get onlineTitle; + + /// No description provided for @onlineSub. + /// + /// In it, this message translates to: + /// **'Sfida il mondo'** + String get onlineSub; + + /// No description provided for @cpuTitle. + /// + /// In it, this message translates to: + /// **'VS CPU'** + String get cpuTitle; + + /// No description provided for @cpuSub. + /// + /// In it, this message translates to: + /// **'Allenati con l\'IA'** + String get cpuSub; + + /// No description provided for @localTitle. + /// + /// In it, this message translates to: + /// **'LOCALE'** + String get localTitle; + + /// No description provided for @localSub. + /// + /// In it, this message translates to: + /// **'Stesso schermo'** + String get localSub; + + /// No description provided for @leaderboardTitle. + /// + /// In it, this message translates to: + /// **'CLASSIFICA'** + String get leaderboardTitle; + + /// No description provided for @questsTitle. + /// + /// In it, this message translates to: + /// **'SFIDE'** + String get questsTitle; + + /// No description provided for @themesTitle. + /// + /// In it, this message translates to: + /// **'TEMI'** + String get themesTitle; + + /// No description provided for @tutorialTitle. + /// + /// In it, this message translates to: + /// **'TUTORIAL'** + String get tutorialTitle; + + /// No description provided for @startGame. + /// + /// In it, this message translates to: + /// **'AVVIA PARTITA'** + String get startGame; + + /// No description provided for @createMatch. + /// + /// In it, this message translates to: + /// **'CREA PARTITA'** + String get createMatch; + + /// No description provided for @joinMatch. + /// + /// In it, this message translates to: + /// **'UNISCITI'** + String get joinMatch; + + /// No description provided for @gameOver. + /// + /// In it, this message translates to: + /// **'FINE PARTITA'** + String get gameOver; + + /// No description provided for @mainMenu. + /// + /// In it, this message translates to: + /// **'TORNA AL MENU'** + String get mainMenu; + + /// No description provided for @exit. + /// + /// In it, this message translates to: + /// **'ESCI'** + String get exit; +} + +class _AppLocalizationsDelegate + extends LocalizationsDelegate { + const _AppLocalizationsDelegate(); + + @override + Future load(Locale locale) { + return SynchronousFuture(lookupAppLocalizations(locale)); + } + + @override + bool isSupported(Locale locale) => [ + 'de', + 'en', + 'es', + 'fr', + 'it', + 'pt', + 'ru', + 'zh', + ].contains(locale.languageCode); + + @override + bool shouldReload(_AppLocalizationsDelegate old) => false; +} + +AppLocalizations lookupAppLocalizations(Locale locale) { + // Lookup logic when only language code is specified. + switch (locale.languageCode) { + case 'de': + return AppLocalizationsDe(); + case 'en': + return AppLocalizationsEn(); + case 'es': + return AppLocalizationsEs(); + case 'fr': + return AppLocalizationsFr(); + case 'it': + return AppLocalizationsIt(); + case 'pt': + return AppLocalizationsPt(); + case 'ru': + return AppLocalizationsRu(); + case 'zh': + return AppLocalizationsZh(); + } + + throw FlutterError( + 'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely ' + 'an issue with the localizations generation tool. Please file an issue ' + 'on GitHub with a reproducible sample app and the gen-l10n configuration ' + 'that was used.', + ); +} diff --git a/lib/l10n/app_localizations_de.dart b/lib/l10n/app_localizations_de.dart new file mode 100644 index 0000000..130b01b --- /dev/null +++ b/lib/l10n/app_localizations_de.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for German (`de`). +class AppLocalizationsDe extends AppLocalizations { + AppLocalizationsDe([String locale = 'de']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => 'WILLKOMMEN BEI TETRAQ!'; + + @override + String get nameHint => 'NAME'; + + @override + String get saveAndPlay => 'SPEICHERN & SPIELEN'; + + @override + String get onlineTitle => 'ONLINE'; + + @override + String get onlineSub => 'Fordere die Welt heraus'; + + @override + String get cpuTitle => 'VS CPU'; + + @override + String get cpuSub => 'Trainiere mit KI'; + + @override + String get localTitle => 'LOKAL'; + + @override + String get localSub => 'Gleicher Bildschirm'; + + @override + String get leaderboardTitle => 'RANGLISTE'; + + @override + String get questsTitle => 'MISSIONEN'; + + @override + String get themesTitle => 'THEMEN'; + + @override + String get tutorialTitle => 'TUTORIAL'; + + @override + String get startGame => 'SPIEL STARTEN'; + + @override + String get createMatch => 'SPIEL ERSTELLEN'; + + @override + String get joinMatch => 'BEITRETEN'; + + @override + String get gameOver => 'SPIELENDE'; + + @override + String get mainMenu => 'ZURÜCK ZUM MENÜ'; + + @override + String get exit => 'BEENDEN'; +} diff --git a/lib/l10n/app_localizations_en.dart b/lib/l10n/app_localizations_en.dart new file mode 100644 index 0000000..31748d3 --- /dev/null +++ b/lib/l10n/app_localizations_en.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for English (`en`). +class AppLocalizationsEn extends AppLocalizations { + AppLocalizationsEn([String locale = 'en']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => 'WELCOME TO TETRAQ!'; + + @override + String get nameHint => 'NAME'; + + @override + String get saveAndPlay => 'SAVE & PLAY'; + + @override + String get onlineTitle => 'ONLINE'; + + @override + String get onlineSub => 'Challenge the world'; + + @override + String get cpuTitle => 'VS CPU'; + + @override + String get cpuSub => 'Train with AI'; + + @override + String get localTitle => 'LOCAL'; + + @override + String get localSub => 'Same screen'; + + @override + String get leaderboardTitle => 'LEADERBOARD'; + + @override + String get questsTitle => 'QUESTS'; + + @override + String get themesTitle => 'THEMES'; + + @override + String get tutorialTitle => 'TUTORIAL'; + + @override + String get startGame => 'START GAME'; + + @override + String get createMatch => 'CREATE MATCH'; + + @override + String get joinMatch => 'JOIN'; + + @override + String get gameOver => 'GAME OVER'; + + @override + String get mainMenu => 'BACK TO MENU'; + + @override + String get exit => 'EXIT'; +} diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart new file mode 100644 index 0000000..06b88f7 --- /dev/null +++ b/lib/l10n/app_localizations_es.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Spanish Castilian (`es`). +class AppLocalizationsEs extends AppLocalizations { + AppLocalizationsEs([String locale = 'es']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => '¡BIENVENIDO A TETRAQ!'; + + @override + String get nameHint => 'NOMBRE'; + + @override + String get saveAndPlay => 'GUARDAR Y JUGAR'; + + @override + String get onlineTitle => 'ONLINE'; + + @override + String get onlineSub => 'Desafía al mundo'; + + @override + String get cpuTitle => 'VS CPU'; + + @override + String get cpuSub => 'Entrena con IA'; + + @override + String get localTitle => 'LOCAL'; + + @override + String get localSub => 'Misma pantalla'; + + @override + String get leaderboardTitle => 'RANKING'; + + @override + String get questsTitle => 'MISIONES'; + + @override + String get themesTitle => 'TEMAS'; + + @override + String get tutorialTitle => 'TUTORIAL'; + + @override + String get startGame => 'INICIAR JUEGO'; + + @override + String get createMatch => 'CREAR PARTIDA'; + + @override + String get joinMatch => 'UNIRSE'; + + @override + String get gameOver => 'FIN DEL JUEGO'; + + @override + String get mainMenu => 'VOLVER AL MENÚ'; + + @override + String get exit => 'SALIR'; +} diff --git a/lib/l10n/app_localizations_fr.dart b/lib/l10n/app_localizations_fr.dart new file mode 100644 index 0000000..c9c75c5 --- /dev/null +++ b/lib/l10n/app_localizations_fr.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for French (`fr`). +class AppLocalizationsFr extends AppLocalizations { + AppLocalizationsFr([String locale = 'fr']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => 'BIENVENUE DANS TETRAQ !'; + + @override + String get nameHint => 'NOM'; + + @override + String get saveAndPlay => 'SAUVEGARDER ET JOUER'; + + @override + String get onlineTitle => 'EN LIGNE'; + + @override + String get onlineSub => 'Défiez le monde'; + + @override + String get cpuTitle => 'VS CPU'; + + @override + String get cpuSub => 'Entraînez avec l\'IA'; + + @override + String get localTitle => 'LOCAL'; + + @override + String get localSub => 'Même écran'; + + @override + String get leaderboardTitle => 'CLASSEMENT'; + + @override + String get questsTitle => 'QUÊTES'; + + @override + String get themesTitle => 'THÈMES'; + + @override + String get tutorialTitle => 'TUTORIEL'; + + @override + String get startGame => 'JOUER'; + + @override + String get createMatch => 'CRÉER UN MATCH'; + + @override + String get joinMatch => 'REJOINDRE'; + + @override + String get gameOver => 'FIN DE PARTIE'; + + @override + String get mainMenu => 'RETOUR AU MENU'; + + @override + String get exit => 'QUITTER'; +} diff --git a/lib/l10n/app_localizations_it.dart b/lib/l10n/app_localizations_it.dart new file mode 100644 index 0000000..ef8f2ad --- /dev/null +++ b/lib/l10n/app_localizations_it.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Italian (`it`). +class AppLocalizationsIt extends AppLocalizations { + AppLocalizationsIt([String locale = 'it']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => 'BENVENUTO IN TETRAQ!'; + + @override + String get nameHint => 'NOME'; + + @override + String get saveAndPlay => 'SALVA E GIOCA'; + + @override + String get onlineTitle => 'ONLINE'; + + @override + String get onlineSub => 'Sfida il mondo'; + + @override + String get cpuTitle => 'VS CPU'; + + @override + String get cpuSub => 'Allenati con l\'IA'; + + @override + String get localTitle => 'LOCALE'; + + @override + String get localSub => 'Stesso schermo'; + + @override + String get leaderboardTitle => 'CLASSIFICA'; + + @override + String get questsTitle => 'SFIDE'; + + @override + String get themesTitle => 'TEMI'; + + @override + String get tutorialTitle => 'TUTORIAL'; + + @override + String get startGame => 'AVVIA PARTITA'; + + @override + String get createMatch => 'CREA PARTITA'; + + @override + String get joinMatch => 'UNISCITI'; + + @override + String get gameOver => 'FINE PARTITA'; + + @override + String get mainMenu => 'TORNA AL MENU'; + + @override + String get exit => 'ESCI'; +} diff --git a/lib/l10n/app_localizations_pt.dart b/lib/l10n/app_localizations_pt.dart new file mode 100644 index 0000000..ae8e66a --- /dev/null +++ b/lib/l10n/app_localizations_pt.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Portuguese (`pt`). +class AppLocalizationsPt extends AppLocalizations { + AppLocalizationsPt([String locale = 'pt']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => 'BEM-VINDO AO TETRAQ!'; + + @override + String get nameHint => 'NOME'; + + @override + String get saveAndPlay => 'SALVAR E JOGAR'; + + @override + String get onlineTitle => 'ONLINE'; + + @override + String get onlineSub => 'Desafie o mundo'; + + @override + String get cpuTitle => 'VS CPU'; + + @override + String get cpuSub => 'Treine com a IA'; + + @override + String get localTitle => 'LOCAL'; + + @override + String get localSub => 'Mesma tela'; + + @override + String get leaderboardTitle => 'CLASSIFICAÇÃO'; + + @override + String get questsTitle => 'DESAFIOS'; + + @override + String get themesTitle => 'TEMAS'; + + @override + String get tutorialTitle => 'TUTORIAL'; + + @override + String get startGame => 'INICIAR JOGO'; + + @override + String get createMatch => 'CRIAR PARTIDA'; + + @override + String get joinMatch => 'ENTRAR'; + + @override + String get gameOver => 'FIM DE JOGO'; + + @override + String get mainMenu => 'VOLTAR AO MENU'; + + @override + String get exit => 'SAIR'; +} diff --git a/lib/l10n/app_localizations_ru.dart b/lib/l10n/app_localizations_ru.dart new file mode 100644 index 0000000..bec57e8 --- /dev/null +++ b/lib/l10n/app_localizations_ru.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Russian (`ru`). +class AppLocalizationsRu extends AppLocalizations { + AppLocalizationsRu([String locale = 'ru']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => 'ДОБРО ПОЖАЛОВАТЬ В TETRAQ!'; + + @override + String get nameHint => 'ИМЯ'; + + @override + String get saveAndPlay => 'СОХРАНИТЬ И ИГРАТЬ'; + + @override + String get onlineTitle => 'ОНЛАЙН'; + + @override + String get onlineSub => 'Брось вызов миру'; + + @override + String get cpuTitle => 'VS ИИ'; + + @override + String get cpuSub => 'Тренировка с ИИ'; + + @override + String get localTitle => 'ЛОКАЛЬНО'; + + @override + String get localSub => 'Один экран'; + + @override + String get leaderboardTitle => 'РЕЙТИНГ'; + + @override + String get questsTitle => 'ЗАДАНИЯ'; + + @override + String get themesTitle => 'ТЕМЫ'; + + @override + String get tutorialTitle => 'ОБУЧЕНИЕ'; + + @override + String get startGame => 'НАЧАТЬ ИГРУ'; + + @override + String get createMatch => 'СОЗДАТЬ ИГРУ'; + + @override + String get joinMatch => 'ПРИСОЕДИНИТЬСЯ'; + + @override + String get gameOver => 'ИГРА ОКОНЧЕНА'; + + @override + String get mainMenu => 'В ГЛАВНОЕ МЕНЮ'; + + @override + String get exit => 'ВЫХОД'; +} diff --git a/lib/l10n/app_localizations_zh.dart b/lib/l10n/app_localizations_zh.dart new file mode 100644 index 0000000..32a8905 --- /dev/null +++ b/lib/l10n/app_localizations_zh.dart @@ -0,0 +1,70 @@ +// ignore: unused_import +import 'package:intl/intl.dart' as intl; +import 'app_localizations.dart'; + +// ignore_for_file: type=lint + +/// The translations for Chinese (`zh`). +class AppLocalizationsZh extends AppLocalizations { + AppLocalizationsZh([String locale = 'zh']) : super(locale); + + @override + String get appTitle => 'TetraQ'; + + @override + String get welcomeTitle => '欢迎来到 TETRAQ!'; + + @override + String get nameHint => '名字'; + + @override + String get saveAndPlay => '保存并开始'; + + @override + String get onlineTitle => '在线匹配'; + + @override + String get onlineSub => '挑战世界'; + + @override + String get cpuTitle => '人机对战'; + + @override + String get cpuSub => '与AI训练'; + + @override + String get localTitle => '本地游戏'; + + @override + String get localSub => '同屏对战'; + + @override + String get leaderboardTitle => '排行榜'; + + @override + String get questsTitle => '任务'; + + @override + String get themesTitle => '主题'; + + @override + String get tutorialTitle => '教程'; + + @override + String get startGame => '开始游戏'; + + @override + String get createMatch => '创建比赛'; + + @override + String get joinMatch => '加入'; + + @override + String get gameOver => '游戏结束'; + + @override + String get mainMenu => '返回主菜单'; + + @override + String get exit => '退出'; +} diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb new file mode 100644 index 0000000..6577a82 --- /dev/null +++ b/lib/l10n/app_pt.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "pt", + "appTitle": "TetraQ", + "welcomeTitle": "BEM-VINDO AO TETRAQ!", + "nameHint": "NOME", + "saveAndPlay": "SALVAR E JOGAR", + "onlineTitle": "ONLINE", + "onlineSub": "Desafie o mundo", + "cpuTitle": "VS CPU", + "cpuSub": "Treine com a IA", + "localTitle": "LOCAL", + "localSub": "Mesma tela", + "leaderboardTitle": "CLASSIFICAÇÃO", + "questsTitle": "DESAFIOS", + "themesTitle": "TEMAS", + "tutorialTitle": "TUTORIAL", + "startGame": "INICIAR JOGO", + "createMatch": "CRIAR PARTIDA", + "joinMatch": "ENTRAR", + "gameOver": "FIM DE JOGO", + "mainMenu": "VOLTAR AO MENU", + "exit": "SAIR" +} \ No newline at end of file diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb new file mode 100644 index 0000000..4e0072d --- /dev/null +++ b/lib/l10n/app_ru.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "ru", + "appTitle": "TetraQ", + "welcomeTitle": "ДОБРО ПОЖАЛОВАТЬ В TETRAQ!", + "nameHint": "ИМЯ", + "saveAndPlay": "СОХРАНИТЬ И ИГРАТЬ", + "onlineTitle": "ОНЛАЙН", + "onlineSub": "Брось вызов миру", + "cpuTitle": "VS ИИ", + "cpuSub": "Тренировка с ИИ", + "localTitle": "ЛОКАЛЬНО", + "localSub": "Один экран", + "leaderboardTitle": "РЕЙТИНГ", + "questsTitle": "ЗАДАНИЯ", + "themesTitle": "ТЕМЫ", + "tutorialTitle": "ОБУЧЕНИЕ", + "startGame": "НАЧАТЬ ИГРУ", + "createMatch": "СОЗДАТЬ ИГРУ", + "joinMatch": "ПРИСОЕДИНИТЬСЯ", + "gameOver": "ИГРА ОКОНЧЕНА", + "mainMenu": "В ГЛАВНОЕ МЕНЮ", + "exit": "ВЫХОД" +} \ No newline at end of file diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb new file mode 100644 index 0000000..f971862 --- /dev/null +++ b/lib/l10n/app_zh.arb @@ -0,0 +1,23 @@ +{ + "@@locale": "zh", + "appTitle": "TetraQ", + "welcomeTitle": "欢迎来到 TETRAQ!", + "nameHint": "名字", + "saveAndPlay": "保存并开始", + "onlineTitle": "在线匹配", + "onlineSub": "挑战世界", + "cpuTitle": "人机对战", + "cpuSub": "与AI训练", + "localTitle": "本地游戏", + "localSub": "同屏对战", + "leaderboardTitle": "排行榜", + "questsTitle": "任务", + "themesTitle": "主题", + "tutorialTitle": "教程", + "startGame": "开始游戏", + "createMatch": "创建比赛", + "joinMatch": "加入", + "gameOver": "游戏结束", + "mainMenu": "返回主菜单", + "exit": "退出" +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 838e30a..76231fa 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,45 +3,41 @@ // =========================================================================== import 'package:flutter/material.dart'; -import 'package:flutter/foundation.dart'; // <-- AGGIUNTO PER kDebugMode +import 'package:flutter/foundation.dart'; import 'package:provider/provider.dart'; import 'core/theme_manager.dart'; import 'logic/game_controller.dart'; import 'ui/home/home_screen.dart'; import 'services/storage_service.dart'; -import 'services/audio_service.dart'; // <-- NUOVO IMPORT PER L'AUDIO +import 'services/audio_service.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'firebase_options.dart'; -import 'package:firebase_app_check/firebase_app_check.dart'; // <-- IMPORT APP CHECK +import 'package:firebase_app_check/firebase_app_check.dart'; + +// --- IMPORT PER IL SUPPORTO MULTILINGUA --- +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:tetraq/l10n/app_localizations.dart'; void main() async { - // Assicuriamoci che i motori di Flutter siano pronti WidgetsFlutterBinding.ensureInitialized(); - // 1. Accendiamo Firebase! await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); - // --- NUOVO: SCUDO APP CHECK --- await FirebaseAppCheck.instance.activate( - // Se stai programmando (Debug), usa una chiave finta. Se l'app è sugli Store, usa i veri sistemi di sicurezza Apple/Google. androidProvider: kDebugMode ? AndroidProvider.debug : AndroidProvider.playIntegrity, appleProvider: kDebugMode ? AppleProvider.debug : AppleProvider.deviceCheck, ); - // 2. Login Silenzioso (Crea la nostra "Identità Sicura" per Firebase) try { await FirebaseAuth.instance.signInAnonymously(); } catch (e) { debugPrint("Errore Auth: $e"); } - // 3. Accendiamo la Memoria Locale! await StorageService.instance.init(); - - // 4. Accendiamo la Radio! (Lettore Musicale) await AudioService.instance.init(); runApp( @@ -67,6 +63,14 @@ class TetraQApp extends StatelessWidget { fontFamily: 'Roboto', useMaterial3: true, ), + + // --- BIVIO DELLE LINGUE ATTIVATO! --- + // Flutter si occuperà di caricare automaticamente tutte le lingue + // che hai generato tramite lo script. + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + // ------------------------------------ + home: const HomeScreen(), ); } diff --git a/lib/ui/home/home_screen.dart b/lib/ui/home/home_screen.dart index 71ca543..6677b04 100644 --- a/lib/ui/home/home_screen.dart +++ b/lib/ui/home/home_screen.dart @@ -21,6 +21,7 @@ import '../../services/storage_service.dart'; import '../multiplayer/lobby_screen.dart'; import 'history_screen.dart'; import 'package:firebase_auth/firebase_auth.dart'; +import 'package:tetraq/l10n/app_localizations.dart'; TextStyle _getTextStyle(AppThemeType themeType, TextStyle baseStyle) { if (themeType == AppThemeType.doodle) { @@ -429,6 +430,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { final theme = themeManager.currentColors; final themeType = themeManager.currentThemeType; Color inkColor = const Color(0xFF111122); + final loc = AppLocalizations.of(context)!; Widget dialogContent = themeType == AppThemeType.doodle ? CustomPaint( @@ -438,7 +440,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text('BENVENUTO!', style: _getTextStyle(themeType, TextStyle(color: inkColor, fontWeight: FontWeight.w900, fontSize: 28, letterSpacing: 2.0)), textAlign: TextAlign.center), + Text(loc.welcomeTitle, style: _getTextStyle(themeType, TextStyle(color: inkColor, fontWeight: FontWeight.w900, fontSize: 28, letterSpacing: 2.0)), textAlign: TextAlign.center), const SizedBox(height: 20), Text('Scegli il tuo nome da battaglia', style: _getTextStyle(themeType, TextStyle(color: inkColor.withOpacity(0.8), fontSize: 18)), textAlign: TextAlign.center), const SizedBox(height: 30), @@ -446,7 +448,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { controller: nameController, textCapitalization: TextCapitalization.characters, textAlign: TextAlign.center, maxLength: 5, style: _getTextStyle(themeType, TextStyle(color: inkColor, fontSize: 36, fontWeight: FontWeight.bold, letterSpacing: 8)), decoration: InputDecoration( - hintText: 'NOME', hintStyle: _getTextStyle(themeType, TextStyle(color: inkColor.withOpacity(0.3), letterSpacing: 4)), + hintText: loc.nameHint, hintStyle: _getTextStyle(themeType, TextStyle(color: inkColor.withOpacity(0.3), letterSpacing: 4)), filled: false, counterText: "", enabledBorder: UnderlineInputBorder(borderSide: BorderSide(color: inkColor, width: 3)), focusedBorder: UnderlineInputBorder(borderSide: BorderSide(color: Colors.red.shade200, width: 5)), @@ -467,7 +469,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: Container( width: double.infinity, height: 60, alignment: Alignment.center, - child: Text('SALVA E GIOCA', style: _getTextStyle(themeType, TextStyle(color: inkColor, fontSize: 22, fontWeight: FontWeight.bold, letterSpacing: 1.5))), + child: Text(loc.saveAndPlay, style: _getTextStyle(themeType, TextStyle(color: inkColor, fontSize: 22, fontWeight: FontWeight.bold, letterSpacing: 1.5))), ), ), ), @@ -488,7 +490,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text('BENVENUTO IN TETRAQ!', style: _getTextStyle(themeType, TextStyle(color: theme.text, fontWeight: FontWeight.w900, fontSize: 24, letterSpacing: 1.5)), textAlign: TextAlign.center), + Text(loc.welcomeTitle, style: _getTextStyle(themeType, TextStyle(color: theme.text, fontWeight: FontWeight.w900, fontSize: 24, letterSpacing: 1.5)), textAlign: TextAlign.center), const SizedBox(height: 20), Text('Scegli il tuo nome da battaglia per sfidare i tuoi amici online.', style: _getTextStyle(themeType, TextStyle(color: theme.text.withOpacity(0.8), fontSize: 16)), textAlign: TextAlign.center), const SizedBox(height: 40), @@ -496,7 +498,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { controller: nameController, textCapitalization: TextCapitalization.characters, textAlign: TextAlign.center, maxLength: 5, style: _getTextStyle(themeType, TextStyle(color: theme.text, fontSize: 32, fontWeight: FontWeight.bold, letterSpacing: 8)), decoration: InputDecoration( - hintText: 'NOME', hintStyle: _getTextStyle(themeType, TextStyle(color: theme.text.withOpacity(0.3), letterSpacing: 4)), + hintText: loc.nameHint, hintStyle: _getTextStyle(themeType, TextStyle(color: theme.text.withOpacity(0.3), letterSpacing: 4)), filled: true, fillColor: theme.text.withOpacity(0.05), counterText: "", enabledBorder: OutlineInputBorder(borderSide: BorderSide(color: theme.gridLine.withOpacity(0.5), width: 2), borderRadius: BorderRadius.circular(15)), focusedBorder: OutlineInputBorder(borderSide: BorderSide(color: theme.playerBlue, width: 3), borderRadius: BorderRadius.circular(15)), @@ -515,7 +517,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { setState(() {}); } }, - child: Text('SALVA E GIOCA', style: _getTextStyle(themeType, const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, letterSpacing: 1.5))), + child: Text(loc.saveAndPlay, style: _getTextStyle(themeType, const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, letterSpacing: 1.5))), ), ), ], @@ -575,7 +577,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { Navigator.of(context).pop(); Navigator.push(context, MaterialPageRoute(builder: (_) => LobbyScreen(initialRoomCode: roomCode))); }, - child: Text("Unisciti", style: _getTextStyle(themeType, TextStyle(color: themeType == AppThemeType.doodle ? theme.text : Colors.white, fontWeight: FontWeight.bold))), + child: Text(AppLocalizations.of(context)!.joinMatch, style: _getTextStyle(themeType, TextStyle(color: themeType == AppThemeType.doodle ? theme.text : Colors.white, fontWeight: FontWeight.bold))), ), ], ); @@ -588,6 +590,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { ArenaShape localShape = ArenaShape.classic; bool localTimeMode = true; bool isChaosUnlocked = StorageService.instance.playerLevel >= 10; + final loc = AppLocalizations.of(context)!; showDialog( context: context, @@ -612,7 +615,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text(isVsCPU ? "SFIDA IA" : "MODALITÀ LOCALE", style: _getTextStyle(themeType, TextStyle(fontSize: 26, fontWeight: FontWeight.w900, color: inkColor, letterSpacing: 2))), + Text(isVsCPU ? loc.cpuTitle : loc.localTitle, style: _getTextStyle(themeType, TextStyle(fontSize: 26, fontWeight: FontWeight.w900, color: inkColor, letterSpacing: 2))), const SizedBox(height: 25), Text("FORMA ARENA", style: _getTextStyle(themeType, TextStyle(fontSize: 14, fontWeight: FontWeight.w900, color: inkColor.withOpacity(0.6), letterSpacing: 1.5))), @@ -667,7 +670,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: Container( height: 65, width: double.infinity, alignment: Alignment.center, - child: Text("AVVIA PARTITA", style: _getTextStyle(themeType, TextStyle(fontSize: 22, fontWeight: FontWeight.w900, letterSpacing: 3.0, color: inkColor))), + child: Text(loc.startGame, style: _getTextStyle(themeType, TextStyle(fontSize: 22, fontWeight: FontWeight.w900, letterSpacing: 3.0, color: inkColor))), ), ), ), @@ -692,7 +695,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: Column( mainAxisSize: MainAxisSize.min, children: [ - Text(isVsCPU ? "SFIDA IA" : "MODALITÀ LOCALE", style: _getTextStyle(themeType, TextStyle(fontSize: 24, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 2))), + Text(isVsCPU ? loc.cpuTitle : loc.localTitle, style: _getTextStyle(themeType, TextStyle(fontSize: 24, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 2))), const SizedBox(height: 20), Text("FORMA ARENA", style: _getTextStyle(themeType, TextStyle(fontSize: 12, fontWeight: FontWeight.w900, color: theme.text.withOpacity(0.5), letterSpacing: 1.5))), @@ -743,7 +746,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { context.read().startNewGame(localRadius, vsCPU: isVsCPU, shape: localShape, timeMode: localTimeMode); Navigator.push(context, MaterialPageRoute(builder: (_) => const GameScreen())); }, - child: const Text("AVVIA PARTITA", style: TextStyle(fontSize: 18, fontWeight: FontWeight.w900, letterSpacing: 2)), + child: Text(loc.startGame, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w900, letterSpacing: 2)), ), ) ], @@ -775,6 +778,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { final theme = themeManager.currentColors; final themeType = themeManager.currentThemeType; Color inkColor = const Color(0xFF111122); + final loc = AppLocalizations.of(context)!; return Dialog( backgroundColor: Colors.transparent, @@ -792,7 +796,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { children: [ Icon(Icons.assignment_turned_in, size: 50, color: theme.playerBlue), const SizedBox(height: 10), - Text("SFIDE GIORNALIERE", style: _getTextStyle(themeType, TextStyle(fontSize: 22, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 1.5))), + Text(loc.questsTitle, style: _getTextStyle(themeType, TextStyle(fontSize: 22, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 1.5))), const SizedBox(height: 25), // Generiamo dinamicamente le 3 missioni salvate in memoria @@ -874,6 +878,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { final themeManager = ctx.watch(); final theme = themeManager.currentColors; final themeType = themeManager.currentThemeType; + final loc = AppLocalizations.of(context)!; Widget content = Container( padding: const EdgeInsets.all(20.0), @@ -888,7 +893,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { children: [ Icon(Icons.emoji_events, size: 50, color: Colors.amber), const SizedBox(height: 10), - Text("CLASSIFICA MONDIALE", style: _getTextStyle(themeType, TextStyle(fontSize: 20, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 1.5))), + Text(loc.leaderboardTitle, style: _getTextStyle(themeType, TextStyle(fontSize: 20, fontWeight: FontWeight.w900, color: theme.text, letterSpacing: 1.5))), const SizedBox(height: 20), // Lista giocatori pescata da Firebase! @@ -971,6 +976,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { final theme = themeManager.currentColors; final themeType = themeManager.currentThemeType; Color inkColor = const Color(0xFF111122); + final loc = AppLocalizations.of(context)!; String goldLabel = themeType == AppThemeType.grimorio ? "CORONA:" : "ORO:"; String bombLabel = themeType == AppThemeType.grimorio ? "STREGA:" : "BOMBA:"; @@ -1106,6 +1112,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { final themeType = themeManager.currentThemeType; final theme = themeManager.currentColors; Color inkColor = const Color(0xFF111122); + final loc = AppLocalizations.of(context)!; String? bgImage; if (themeType == AppThemeType.wood) bgImage = 'assets/images/wood_bg.jpg'; @@ -1245,7 +1252,7 @@ class _HomeScreenState extends State with WidgetsBindingObserver { child: FittedBox( fit: BoxFit.scaleDown, child: Text( - "TETRAQ", + loc.appTitle.toUpperCase(), style: _getTextStyle(themeType, TextStyle( fontSize: 65, fontWeight: FontWeight.w900, @@ -1268,19 +1275,19 @@ class _HomeScreenState extends State with WidgetsBindingObserver { Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - _buildCyberCard(_FeatureCard(title: "ONLINE", subtitle: "Sfida il mondo", icon: Icons.public, color: Colors.lightBlue.shade200, theme: theme, themeType: themeType, isFeatured: true, onTap: () { Navigator.push(context, MaterialPageRoute(builder: (_) => const LobbyScreen())); }), themeType), + _buildCyberCard(_FeatureCard(title: loc.onlineTitle, subtitle: loc.onlineSub, icon: Icons.public, color: Colors.lightBlue.shade200, theme: theme, themeType: themeType, isFeatured: true, onTap: () { Navigator.push(context, MaterialPageRoute(builder: (_) => const LobbyScreen())); }), themeType), const SizedBox(height: 12), - _buildCyberCard(_FeatureCard(title: "VS CPU", subtitle: "Allenati con l'IA", icon: Icons.smart_toy, color: Colors.purple.shade200, theme: theme, themeType: themeType, onTap: () => _showMatchSetupDialog(true)), themeType), + _buildCyberCard(_FeatureCard(title: loc.cpuTitle, subtitle: loc.cpuSub, icon: Icons.smart_toy, color: Colors.purple.shade200, theme: theme, themeType: themeType, onTap: () => _showMatchSetupDialog(true)), themeType), const SizedBox(height: 12), - _buildCyberCard(_FeatureCard(title: "LOCALE", subtitle: "Stesso schermo", icon: Icons.people_alt, color: Colors.red.shade200, theme: theme, themeType: themeType, onTap: () => _showMatchSetupDialog(false)), themeType), + _buildCyberCard(_FeatureCard(title: loc.localTitle, subtitle: loc.localSub, icon: Icons.people_alt, color: Colors.red.shade200, theme: theme, themeType: themeType, onTap: () => _showMatchSetupDialog(false)), themeType), const SizedBox(height: 12), // NUOVI BOTTONI PER LA VERSIONE 2.0 Row( children: [ - Expanded(child: _buildCyberCard(_FeatureCard(title: "CLASSIFICA", subtitle: "Top 50 Globale", icon: Icons.leaderboard, color: Colors.amber.shade200, theme: theme, themeType: themeType, onTap: _showLeaderboardDialog, compact: true), themeType)), + Expanded(child: _buildCyberCard(_FeatureCard(title: loc.leaderboardTitle, subtitle: "Top 50 Globale", icon: Icons.leaderboard, color: Colors.amber.shade200, theme: theme, themeType: themeType, onTap: _showLeaderboardDialog, compact: true), themeType)), const SizedBox(width: 12), - Expanded(child: _buildCyberCard(_FeatureCard(title: "SFIDE", subtitle: "Missioni", icon: Icons.assignment_turned_in, color: Colors.green.shade200, theme: theme, themeType: themeType, onTap: _showDailyQuestsDialog, compact: true), themeType)), + Expanded(child: _buildCyberCard(_FeatureCard(title: loc.questsTitle, subtitle: "Missioni", icon: Icons.assignment_turned_in, color: Colors.green.shade200, theme: theme, themeType: themeType, onTap: _showDailyQuestsDialog, compact: true), themeType)), ], ), @@ -1288,9 +1295,9 @@ class _HomeScreenState extends State with WidgetsBindingObserver { Row( children: [ - Expanded(child: _buildCyberCard(_FeatureCard(title: "TEMI", subtitle: "Personalizza", icon: Icons.palette, color: Colors.teal.shade200, theme: theme, themeType: themeType, onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen())), compact: true), themeType)), + Expanded(child: _buildCyberCard(_FeatureCard(title: loc.themesTitle, subtitle: "Personalizza", icon: Icons.palette, color: Colors.teal.shade200, theme: theme, themeType: themeType, onTap: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen())), compact: true), themeType)), const SizedBox(width: 12), - Expanded(child: _buildCyberCard(_FeatureCard(title: "TUTORIAL", subtitle: "Come giocare", icon: Icons.school, color: Colors.indigo.shade200, theme: theme, themeType: themeType, onTap: _showTutorialDialog, compact: true), themeType)), + Expanded(child: _buildCyberCard(_FeatureCard(title: loc.tutorialTitle, subtitle: "Come giocare", icon: Icons.school, color: Colors.indigo.shade200, theme: theme, themeType: themeType, onTap: _showTutorialDialog, compact: true), themeType)), ], ), ], diff --git a/pubspec.lock b/pubspec.lock index 2c27c80..75e7c78 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -129,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + change_app_package_name: + dependency: "direct dev" + description: + name: change_app_package_name + sha256: "8e43b754fe960426904d77ed4c62fa8c9834deaf6e293ae40963fa447482c4c5" + url: "https://pub.dev" + source: hosted + version: "1.5.0" characters: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 2fa4fa4..45b47ed 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: tetraq description: A new Flutter project. publish_to: 'none' -version: 1.0.2+4 +version: 1.1.3+5 environment: sdk: ^3.10.7 @@ -31,6 +31,7 @@ dev_dependencies: sdk: flutter flutter_lints: ^6.0.0 flutter_launcher_icons: ^0.13.1 + change_app_package_name: ^1.5.0 flutter: uses-material-design: true