refactor: Projektstruktur in app/ und backend/ aufgeteilt
This commit is contained in:
225
app/lib/settings_view.dart
Normal file
225
app/lib/settings_view.dart
Normal file
@@ -0,0 +1,225 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'l10n/app_localizations.dart';
|
||||
import 'app_state.dart';
|
||||
|
||||
/// Supported languages with their display names and flag emojis
|
||||
class LanguageOption {
|
||||
final String code;
|
||||
final String name;
|
||||
final String flagEmoji;
|
||||
|
||||
const LanguageOption({
|
||||
required this.code,
|
||||
required this.name,
|
||||
required this.flagEmoji,
|
||||
});
|
||||
}
|
||||
|
||||
class SettingsView extends StatefulWidget {
|
||||
const SettingsView({super.key});
|
||||
|
||||
@override
|
||||
State<SettingsView> createState() => _SettingsViewState();
|
||||
}
|
||||
|
||||
class _SettingsViewState extends State<SettingsView> {
|
||||
late String _selectedLanguageCode;
|
||||
final AppState _appState = AppState();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_selectedLanguageCode = _appState.languageCode;
|
||||
}
|
||||
|
||||
void _onLanguageSelected(String languageCode) async {
|
||||
setState(() {
|
||||
_selectedLanguageCode = languageCode;
|
||||
});
|
||||
|
||||
// Save language preference
|
||||
await _appState.setLanguage(languageCode);
|
||||
|
||||
// Show confirmation snackbar
|
||||
_showLanguageChangedSnackBar(languageCode);
|
||||
}
|
||||
|
||||
void _showLanguageChangedSnackBar(String languageCode) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
|
||||
// Get the language name from the corresponding localization
|
||||
String languageName;
|
||||
String flagEmoji;
|
||||
switch (languageCode) {
|
||||
case 'de':
|
||||
languageName = 'Deutsch';
|
||||
flagEmoji = '🇩🇪';
|
||||
break;
|
||||
case 'en':
|
||||
languageName = 'English';
|
||||
flagEmoji = '🇬🇧';
|
||||
break;
|
||||
case 'es':
|
||||
languageName = 'Español';
|
||||
flagEmoji = '🇪🇸';
|
||||
break;
|
||||
case 'fr':
|
||||
languageName = 'Français';
|
||||
flagEmoji = '🇫🇷';
|
||||
break;
|
||||
case 'pl':
|
||||
languageName = 'Polski';
|
||||
flagEmoji = '🇵🇱';
|
||||
break;
|
||||
case 'ru':
|
||||
languageName = 'Русский';
|
||||
flagEmoji = '🇷🇺';
|
||||
break;
|
||||
case 'tr':
|
||||
languageName = 'Türkçe';
|
||||
flagEmoji = '🇹🇷';
|
||||
break;
|
||||
case 'et':
|
||||
languageName = 'Eesti';
|
||||
flagEmoji = '🇪🇪';
|
||||
break;
|
||||
case 'lv':
|
||||
languageName = 'Latviešu';
|
||||
flagEmoji = '🇱🇻';
|
||||
break;
|
||||
case 'lt':
|
||||
languageName = 'Lietuvių';
|
||||
flagEmoji = '🇱🇹';
|
||||
break;
|
||||
default:
|
||||
languageName = languageCode;
|
||||
flagEmoji = '🌐';
|
||||
}
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'${l10n.languageChanged}: $flagEmoji $languageName',
|
||||
),
|
||||
duration: const Duration(seconds: 2),
|
||||
backgroundColor: Colors.green,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Get all available language options with their localized names
|
||||
List<LanguageOption> _getLanguageOptions() {
|
||||
return [
|
||||
const LanguageOption(code: 'de', name: 'Deutsch', flagEmoji: '🇩🇪'),
|
||||
const LanguageOption(code: 'en', name: 'English', flagEmoji: '🇬🇧'),
|
||||
const LanguageOption(code: 'es', name: 'Español', flagEmoji: '🇪🇸'),
|
||||
const LanguageOption(code: 'fr', name: 'Français', flagEmoji: '🇫🇷'),
|
||||
const LanguageOption(code: 'pl', name: 'Polski', flagEmoji: '🇵🇱'),
|
||||
const LanguageOption(code: 'ru', name: 'Русский', flagEmoji: '🇷🇺'),
|
||||
const LanguageOption(code: 'tr', name: 'Türkçe', flagEmoji: '🇹🇷'),
|
||||
const LanguageOption(code: 'et', name: 'Eesti', flagEmoji: '🇪🇪'),
|
||||
const LanguageOption(code: 'lv', name: 'Latviešu', flagEmoji: '🇱🇻'),
|
||||
const LanguageOption(code: 'lt', name: 'Lietuvių', flagEmoji: '🇱🇹'),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final languageOptions = _getLanguageOptions();
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(l10n.settings),
|
||||
backgroundColor: Colors.deepPurple[100],
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
// Language Selection Section
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 24, 16, 8),
|
||||
child: Text(
|
||||
l10n.language.toUpperCase(),
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.grey,
|
||||
letterSpacing: 1.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
|
||||
// Language List
|
||||
...languageOptions.map((language) {
|
||||
final isSelected = language.code == _selectedLanguageCode;
|
||||
return Column(
|
||||
children: [
|
||||
ListTile(
|
||||
leading: Container(
|
||||
width: 40,
|
||||
height: 40,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey[100],
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
language.flagEmoji,
|
||||
style: const TextStyle(fontSize: 24),
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Text(
|
||||
language.name,
|
||||
style: TextStyle(
|
||||
fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal,
|
||||
color: isSelected ? Colors.deepPurple : Colors.black87,
|
||||
),
|
||||
),
|
||||
trailing: isSelected
|
||||
? const Icon(
|
||||
Icons.check_circle,
|
||||
color: Colors.deepPurple,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.circle_outlined,
|
||||
color: Colors.grey,
|
||||
),
|
||||
onTap: () => _onLanguageSelected(language.code),
|
||||
selected: isSelected,
|
||||
selectedTileColor: Colors.deepPurple.withValues(alpha: 0.05),
|
||||
),
|
||||
const Divider(height: 1, indent: 72),
|
||||
],
|
||||
);
|
||||
}),
|
||||
|
||||
// App Info Section
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 32, 16, 8),
|
||||
child: Text(
|
||||
l10n.appInfo,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.grey,
|
||||
letterSpacing: 1.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(height: 1),
|
||||
ListTile(
|
||||
leading: Icon(
|
||||
Icons.info_outline,
|
||||
color: Colors.grey[600],
|
||||
),
|
||||
title: Text(l10n.version),
|
||||
subtitle: const Text('0.9.2'),
|
||||
),
|
||||
const Divider(height: 1, indent: 72),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user