Localize app for German and English
This commit is contained in:
parent
be5cbb5988
commit
2162f2d494
@ -4,6 +4,7 @@ import 'package:calorimeter/storage/storage.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:calorimeter/food_entry/food_entry_bloc.dart';
|
||||
import 'package:calorimeter/utils/row_with_spacers_widget.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class EnterFoodWidget extends StatefulWidget {
|
||||
final Function(BuildContext context, FoodEntryState entry) onAdd;
|
||||
@ -42,8 +43,8 @@ class _EnterFoodWidgetState extends State<EnterFoodWidget> {
|
||||
return TextFormField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
decoration: const InputDecoration(
|
||||
label: Text("Name"),
|
||||
decoration: InputDecoration(
|
||||
label: Text(AppLocalizations.of(context)!.name),
|
||||
),
|
||||
);
|
||||
},
|
||||
@ -70,9 +71,11 @@ class _EnterFoodWidgetState extends State<EnterFoodWidget> {
|
||||
}),
|
||||
TextField(
|
||||
textAlign: TextAlign.end,
|
||||
decoration: const InputDecoration(
|
||||
label:
|
||||
Align(alignment: Alignment.centerRight, child: Text("Menge")),
|
||||
decoration: InputDecoration(
|
||||
label: Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(AppLocalizations.of(context)!.amount),
|
||||
),
|
||||
),
|
||||
keyboardType: TextInputType.number,
|
||||
controller: massController,
|
||||
@ -80,9 +83,10 @@ class _EnterFoodWidgetState extends State<EnterFoodWidget> {
|
||||
),
|
||||
TextField(
|
||||
textAlign: TextAlign.end,
|
||||
decoration: const InputDecoration(
|
||||
decoration: InputDecoration(
|
||||
label: Align(
|
||||
alignment: Alignment.centerRight, child: Text("kcal pro"))),
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(AppLocalizations.of(context)!.kcalper))),
|
||||
keyboardType: TextInputType.number,
|
||||
controller: kcalPerMassController,
|
||||
onSubmitted: (value) => onSubmitAction(),
|
||||
@ -107,7 +111,8 @@ class _EnterFoodWidgetState extends State<EnterFoodWidget> {
|
||||
try {
|
||||
massAsNumber = int.parse(massController.text.replaceAll(",", "."));
|
||||
} catch (e) {
|
||||
var snackbar = const SnackBar(content: Text("Menge muss eine Zahl sein"));
|
||||
var snackbar = SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.errAmountNotANumber));
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackbar);
|
||||
return;
|
||||
@ -117,8 +122,8 @@ class _EnterFoodWidgetState extends State<EnterFoodWidget> {
|
||||
kcalPerMassAsNumber =
|
||||
int.parse(kcalPerMassController.text.replaceAll(",", "."));
|
||||
} catch (e) {
|
||||
var snackbar =
|
||||
const SnackBar(content: Text("'kcal pro 100g' muss eine Zahl sein"));
|
||||
var snackbar = SnackBar(
|
||||
content: Text(AppLocalizations.of(context)!.errKcalNotANumber));
|
||||
ScaffoldMessenger.of(context).removeCurrentSnackBar();
|
||||
ScaffoldMessenger.of(context).showSnackBar(snackbar);
|
||||
return;
|
||||
|
@ -3,6 +3,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:calorimeter/food_entry/food_entry_bloc.dart';
|
||||
import 'package:calorimeter/utils/row_with_spacers_widget.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class FoodEntryWidget extends StatefulWidget {
|
||||
final FoodEntryState entry;
|
||||
@ -165,8 +166,8 @@ class _FoodEntryChangeDialogState extends State<FoodEntryChangeDialog> {
|
||||
child: TextField(
|
||||
onSubmitted: (val) => _onSubmitAction(),
|
||||
controller: nameController,
|
||||
decoration: const InputDecoration(
|
||||
label: Text("Name"),
|
||||
decoration: InputDecoration(
|
||||
label: Text(AppLocalizations.of(context)!.name),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -177,8 +178,8 @@ class _FoodEntryChangeDialogState extends State<FoodEntryChangeDialog> {
|
||||
child: TextField(
|
||||
onSubmitted: (val) => _onSubmitAction(),
|
||||
controller: massController,
|
||||
decoration: const InputDecoration(
|
||||
label: Text("Menge"),
|
||||
decoration: InputDecoration(
|
||||
label: Text(AppLocalizations.of(context)!.amount),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -189,8 +190,8 @@ class _FoodEntryChangeDialogState extends State<FoodEntryChangeDialog> {
|
||||
child: TextField(
|
||||
onSubmitted: (val) => _onSubmitAction(),
|
||||
controller: kcalPer100Controller,
|
||||
decoration: const InputDecoration(
|
||||
label: Text("kcal pro Menge"),
|
||||
decoration: InputDecoration(
|
||||
label: Text(AppLocalizations.of(context)!.kcalper),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
@ -8,8 +8,8 @@ import 'package:calorimeter/utils/settings_bloc.dart';
|
||||
import 'package:calorimeter/utils/theme_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
List<FoodEntryState> entriesForToday = [];
|
||||
DateTime timeNow = DateTime.now();
|
||||
@ -17,8 +17,6 @@ DateTime timeNow = DateTime.now();
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
var storage = await FoodStorage.create();
|
||||
await storage.buildFoodLookupDatabase();
|
||||
|
||||
@ -79,6 +77,7 @@ class MainApp extends StatelessWidget {
|
||||
}
|
||||
|
||||
return MaterialApp.router(
|
||||
//locale: Locale('de'),
|
||||
routerConfig: GoRouter(
|
||||
routes: [
|
||||
GoRoute(
|
||||
@ -91,14 +90,8 @@ class MainApp extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
localizationsDelegates: const [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: const [
|
||||
Locale('de'),
|
||||
],
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
theme: ThemeData(
|
||||
dividerTheme: const DividerThemeData(space: 2),
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
|
@ -58,7 +58,9 @@ class PerDatePageViewController extends StatelessWidget {
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Builder(builder: (context) {
|
||||
return Text(DateFormat.yMMMMd('de').format(
|
||||
return Text(DateFormat.yMMMMd(
|
||||
Localizations.localeOf(context).toString())
|
||||
.format(
|
||||
context.watch<PageViewStateProvider>().displayedDate));
|
||||
}),
|
||||
actions: const [ThemeSwitcherButton()],
|
||||
|
@ -2,6 +2,7 @@
|
||||
/* Copyright (C) 2024 Marco Groß <mgross@sw-gross.de> */
|
||||
import 'package:calorimeter/utils/settings.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class AppDrawer extends StatelessWidget {
|
||||
const AppDrawer({
|
||||
@ -25,10 +26,11 @@ class AppDrawer extends StatelessWidget {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
title: const Text('Menü')),
|
||||
title: Text(AppLocalizations.of(context)!.menu),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('Einstellungen'),
|
||||
title: Text(AppLocalizations.of(context)!.settings),
|
||||
trailing: const Icon(Icons.settings),
|
||||
onTap: () {
|
||||
Navigator.of(context).pop();
|
||||
|
@ -15,7 +15,6 @@ class CalendarFAB extends StatelessWidget {
|
||||
return FloatingActionButton(
|
||||
onPressed: () async {
|
||||
var datePicked = await showDatePicker(
|
||||
locale: const Locale('de'),
|
||||
context: context,
|
||||
initialDate: startFromDate,
|
||||
currentDate: DateTimeHelper.now(),
|
||||
|
@ -5,6 +5,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:calorimeter/utils/app_drawer.dart';
|
||||
import 'package:calorimeter/utils/settings_bloc.dart';
|
||||
import 'package:settings_ui/settings_ui.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class SettingsWidget extends StatefulWidget {
|
||||
const SettingsWidget({super.key});
|
||||
@ -23,33 +24,24 @@ class _SettingsWidgetState extends State<SettingsWidget> {
|
||||
builder: (context, state) {
|
||||
return SettingsList(sections: [
|
||||
SettingsSection(
|
||||
title: const Text('Deine persönlichen Einstellungen'),
|
||||
title: Text(AppLocalizations.of(context)!.yourSettings),
|
||||
tiles: [
|
||||
SettingsTile.navigation(
|
||||
leading: const Icon(Icons.food_bank),
|
||||
title: const Text('Kalorienlimit pro Tag'),
|
||||
title: Text(AppLocalizations.of(context)!.dayLimit),
|
||||
value: Text(state.kcalLimit.toString()),
|
||||
onPressed: (context) async {
|
||||
await showDialog(
|
||||
builder: (ctx) {
|
||||
return AlertDialog(
|
||||
title: const Text("Kalorienlimit pro Tag"),
|
||||
content: TextField(controller: kcalPerDayCtrl),
|
||||
title: Text(AppLocalizations.of(context)!.dayLimit),
|
||||
content: TextField(
|
||||
controller: kcalPerDayCtrl,
|
||||
onSubmitted: (val) => submitDailyKcal()),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
double setting;
|
||||
try {
|
||||
setting =
|
||||
double.parse(kcalPerDayCtrl.text);
|
||||
} catch (e) {
|
||||
setting = 2000.0;
|
||||
}
|
||||
context.read<SettingsDataBloc>().add(
|
||||
DailyKcalLimitUpdated(kcal: setting));
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: const Text('Ok'))
|
||||
onPressed: () => submitDailyKcal(),
|
||||
child: Text(AppLocalizations.of(context)!.ok))
|
||||
],
|
||||
);
|
||||
},
|
||||
@ -60,7 +52,18 @@ class _SettingsWidgetState extends State<SettingsWidget> {
|
||||
]);
|
||||
}),
|
||||
drawer: const AppDrawer(),
|
||||
appBar: AppBar(title: const Text('Einstellungen')),
|
||||
appBar: AppBar(title: Text(AppLocalizations.of(context)!.settings)),
|
||||
);
|
||||
}
|
||||
|
||||
void submitDailyKcal() {
|
||||
double setting;
|
||||
try {
|
||||
setting = double.parse(kcalPerDayCtrl.text);
|
||||
} catch (e) {
|
||||
setting = 2000.0;
|
||||
}
|
||||
context.read<SettingsDataBloc>().add(DailyKcalLimitUpdated(kcal: setting));
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:calorimeter/food_entry/food_entry_bloc.dart';
|
||||
import 'package:calorimeter/utils/settings_bloc.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
class SumWidget extends StatelessWidget {
|
||||
final DateTime date;
|
||||
@ -48,7 +49,7 @@ class SumWidget extends StatelessWidget {
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
'kcal heute: ${sum.ceil().toString()}/${settingsState.kcalLimit.ceil()}',
|
||||
'${AppLocalizations.of(context)!.kcalToday}: ${sum.ceil().toString()}/${settingsState.kcalLimit.ceil()}',
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge!
|
||||
|
@ -30,6 +30,7 @@ dev_dependencies:
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
generate: true
|
||||
|
||||
flutter_launcher_icons:
|
||||
android: "launcher_icon"
|
||||
|
Loading…
Reference in New Issue
Block a user