diff --git a/.DS_Store b/.DS_Store index 95045bb..4f755ad 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index e3773d4..2ee0045 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -73,6 +73,12 @@ ReferencedContainer = "container:Runner.xcodeproj"> + + + + _prefs.getString('last_ip') ?? 'Sconosciuto'; String get lastCity => _prefs.getString('last_city') ?? 'Sconosciuta'; - // --- METODI TEMA AGGIORNATI A STRINGHE --- - String getTheme() => _prefs.getString('theme') ?? AppThemeType.doodle.toString(); + // --- METODI TEMA AGGIORNATI CON GESTIONE MIGRAZIONE SICURA --- + String getTheme() { + final Object? savedTheme = _prefs.get('theme'); + + if (savedTheme is String) { + return savedTheme; + } else if (savedTheme is int) { + // Trovato un vecchio salvataggio in formato intero (causa del crash). + // Puliamo la memoria per evitare futuri problemi. + _prefs.remove('theme'); + return AppThemeType.doodle.toString(); + } + + return AppThemeType.doodle.toString(); + } + Future saveTheme(String themeStr) async => await _prefs.setString('theme', themeStr); int get savedRadius => _prefs.getInt('radius') ?? 2; diff --git a/lib/ui/settings/settings_screen.dart b/lib/ui/settings/settings_screen.dart index e20f6f0..32e2e53 100644 --- a/lib/ui/settings/settings_screen.dart +++ b/lib/ui/settings/settings_screen.dart @@ -2,6 +2,7 @@ // FILE: lib/ui/settings/settings_screen.dart // =========================================================================== +import 'dart:ui'; // <--- IMPORTANTE: Aggiunto per ImageFilter.blur import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../core/theme_manager.dart'; @@ -33,15 +34,37 @@ class _SettingsScreenState extends State { extendBodyBehindAppBar: true, appBar: AppBar( toolbarHeight: 80 * vScale, - title: Text( - "SELEZIONA TEMA", - style: getSharedTextStyle(themeType, TextStyle( - fontWeight: FontWeight.w900, - color: Colors.white, - letterSpacing: 2.0, - fontSize: 20 * vScale, - shadows: [Shadow(color: Colors.black.withOpacity(0.8), blurRadius: 5, offset: const Offset(2, 2))] - )) + title: Container( + padding: EdgeInsets.symmetric(horizontal: 24 * vScale, vertical: 10 * vScale), + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Colors.white.withOpacity(0.3), + Colors.white.withOpacity(0.05), + ], + ), + borderRadius: BorderRadius.circular(15), + border: Border.all(color: Colors.white.withOpacity(0.5), width: 1.5), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 10, + offset: const Offset(0, 4), + ) + ], + ), + child: Text( + "SELEZIONA TEMA", + style: getSharedTextStyle(themeType, TextStyle( + fontWeight: FontWeight.w900, + color: Colors.white, + letterSpacing: 2.0, + fontSize: 20 * vScale, + shadows: [Shadow(color: Colors.black.withOpacity(0.8), blurRadius: 5, offset: const Offset(2, 2))] + )) + ), ), centerTitle: true, backgroundColor: Colors.transparent, @@ -159,7 +182,6 @@ class _ThemeCard extends StatelessWidget { if (type == AppThemeType.grimorio) bgImage = 'assets/images/grimorio.jpg'; Border border; - // OMBRA MARCATA PER DARE SPESSORE AL TASTO (Offset 0, 10) List shadows = [ BoxShadow(color: Colors.black.withOpacity(0.8), offset: const Offset(0, 10), blurRadius: 15) ]; @@ -197,17 +219,16 @@ class _ThemeCard extends StatelessWidget { }, child: AnimatedContainer( duration: const Duration(milliseconds: 300), - height: 140 * vScale, // Leggermente più alto per ospitare la cornice del testo + height: 140 * vScale, padding: EdgeInsets.symmetric(horizontal: 20 * vScale, vertical: 15 * vScale), decoration: BoxDecoration( color: isLocked ? Colors.black87 : previewColors.background, borderRadius: BorderRadius.circular(20), border: border, - boxShadow: shadows, // L'ombra per lo spessore viene applicata qui + boxShadow: shadows, image: bgImage != null ? DecorationImage( image: AssetImage(bgImage!), fit: BoxFit.cover, - // Scuriamo leggermente di più le card per far risaltare la targa chiara colorFilter: type == AppThemeType.doodle ? ColorFilter.mode(Colors.white.withOpacity(isLocked ? 0.9 : 0.4), BlendMode.lighten) : ColorFilter.mode(Colors.black.withOpacity(isLocked ? 0.85 : 0.5), BlendMode.darken), @@ -222,55 +243,65 @@ class _ThemeCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( - // --- LA NUOVA CORNICE CHIARA PER IL TESTO --- - child: Container( - padding: EdgeInsets.symmetric(horizontal: 15 * vScale, vertical: 10 * vScale), - decoration: BoxDecoration( - color: Colors.white.withOpacity(0.9), // Sfondo chiaro semitrasparente - borderRadius: BorderRadius.circular(12), - border: Border.all(color: Colors.white, width: 2), - boxShadow: [ - BoxShadow(color: Colors.black.withOpacity(0.3), blurRadius: 8, offset: const Offset(2, 4)) - ] - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - title, - style: getSharedTextStyle( - type, - TextStyle( - fontSize: (type == AppThemeType.arcade ? 15 : 22) * vScale, - fontWeight: FontWeight.w900, - color: const Color(0xFF111122), // Testo scuro per contrastare lo sfondo chiaro - letterSpacing: type == AppThemeType.music ? 1.5 : 0.5, - ) - ) + // --- CORNICE EFFETTO VETRO (GLASSMORPHISM) --- + child: ClipRRect( + borderRadius: BorderRadius.circular(12), + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 6.0, sigmaY: 6.0), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 15 * vScale, vertical: 10 * vScale), + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [ + Colors.white.withOpacity(0.5), // Più visibile in alto a sx + Colors.white.withOpacity(0.1), // Quasi trasparente in basso a dx + ], ), + borderRadius: BorderRadius.circular(12), + border: Border.all(color: Colors.white.withOpacity(0.3), width: 1.5), ), - SizedBox(height: 4 * vScale), - FittedBox( - fit: BoxFit.scaleDown, - alignment: Alignment.centerLeft, - child: Text( - subtitle, - style: getSharedTextStyle( - type, - TextStyle( - fontSize: (type == AppThemeType.arcade ? 8 : 12) * vScale, - color: const Color(0xFF333344), // Grigio scuro per il sottotitolo - fontWeight: FontWeight.bold, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.centerLeft, + child: Text( + title, + style: getSharedTextStyle( + type, + TextStyle( + fontSize: (type == AppThemeType.arcade ? 15 : 22) * vScale, + fontWeight: FontWeight.w900, + color: const Color(0xFF111122), + letterSpacing: type == AppThemeType.music ? 1.5 : 0.5, + ) ) - ) - ), + ), + ), + SizedBox(height: 4 * vScale), + FittedBox( + fit: BoxFit.scaleDown, + alignment: Alignment.centerLeft, + child: Text( + subtitle, + style: getSharedTextStyle( + type, + TextStyle( + fontSize: (type == AppThemeType.arcade ? 8 : 12) * vScale, + color: const Color(0xFF333344), + fontWeight: FontWeight.bold, + ) + ) + ), + ), + ], ), - ], + ), ), ), ), @@ -280,7 +311,7 @@ class _ThemeCard extends StatelessWidget { decoration: BoxDecoration( color: previewColors.playerRed, shape: type == AppThemeType.arcade ? BoxShape.rectangle : BoxShape.circle, - border: Border.all(color: Colors.white, width: 2), // Bordino bianco per far risaltare il colore + border: Border.all(color: Colors.white, width: 2), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.5), blurRadius: 5, offset: const Offset(1, 2))] ) ), @@ -290,7 +321,7 @@ class _ThemeCard extends StatelessWidget { decoration: BoxDecoration( color: previewColors.playerBlue, shape: type == AppThemeType.arcade ? BoxShape.rectangle : BoxShape.circle, - border: Border.all(color: Colors.white, width: 2), // Bordino bianco per far risaltare il colore + border: Border.all(color: Colors.white, width: 2), boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.5), blurRadius: 5, offset: const Offset(1, 2))] ) ),