moved texts to locale files

This commit is contained in:
Myzel394 2022-08-17 12:18:57 +02:00
parent 08c7436bb3
commit 5670de4b68
11 changed files with 233 additions and 74 deletions

View File

@ -1,3 +1,54 @@
{
"helloWorld": "Hallo Welt"
}
"appTitleQuestion": "Quid faciam hodie?",
"generalError": "Ein Fehler ist aufgetreten",
"welcomeScreenDescription": "Finde heraus was du den ganzen Tag gemacht hast und erlebe Erinnerungen wieder, die du komplett vergessen hast!",
"welcomeScreenSubtitle": "Was hab ich heute gemacht?",
"welcomeScreenStartButtonTitle": "Loslegen",
"serverLoadingScreenDescription": "Wir laden deine Daten",
"mainScreenLoadingCamera": "Kamera wird geladen",
"mainScreenActionsTorchButton": "Taschenlampe",
"mainScreenUploadSuccess": "Erfolgreich hochgeladen",
"mainScreenTakePhotoActionTakingPhoto": "Foto wird aufgenommen, halte still...",
"mainScreenTakePhotoActionUploadingPhoto": "Foto wird hochgeladen...",
"mainScreenTakeVideoActionSaveVideo": "Video wird aufgenommen, halte still...",
"mainScreenTakeVideoActionUploadingVideo": "Video wird hochgeladen...",
"loginScreenTitle": "Anmelden",
"loginScreenLoginError": "E-Mail oder Passwort inkorrekt",
"loginScreenHelpText": "Melde dich an. Wenn du noch keinen Account besitzt, erstellen wir automatisch einen für dich.",
"loginScreenFormEmailLabel": "E-Mail",
"loginScreenFormPasswordLabel": "Passwort",
"loginScreenFormSubmitButton": "Anmelden",
"grantPermissionScreenTitle": "Berechtigungen erteilen",
"permissionsRequiredPageTitle": "Berechtigungen benötigt",
"permissionsRequiredPageDescription": "Bitte erteile die folgenden Berechtigungen, um die App zu verwenden.",
"permissionsRequiredPagePermanentlyDenied": "Du hast Berechtigungen permanent abgelehnt, welche für die App benötigt werden. Bitte erteile sie in den Einstellungen.",
"permissionsRequiredPageOpenSettings": "Einstellungen öffnen",
"permissionsRequiredPageGrantCameraPermission": "Kamera-Berechtigung erteilen",
"permissionsRequiredPageGrantMicrophonePermission": "Mikrofon-Berechtigung erteilen",
"memoryViewIsDownloading": "Erinnerung wird heruntergeladen",
"memorySheetSavedToGallery": "In Gallerie gespeichert!",
"memorySheetMemoryUpdatedToPublic": "Deine Erinnerung wurde veröffentlicht!",
"memorySheetMemoryUpdatedToPrivate": "Deine Erinnerung wurde auf privat gestellt.",
"memorySheetTitle": "Erinnerung bearbeiten",
"memorySheetDownloadMemory": "In Gallerie speichern",
"memorySheetUpdateMemoryMakePublic": "Veröffentlichen",
"memorySheetUpdateMemoryMakePrivate": "Privat machen",
"memorySheetDeleteMemory": "Erinnerung löschen"
}

View File

@ -1,6 +1,54 @@
{
"helloWorld": "Hello World!",
"@helloWorld": {
"description": "The conventional newborn programmer greeting"
}
"appTitleQuestion": "Quid faciam hodie?",
"generalError": "There was an error",
"welcomeScreenDescription": "Find out what you did all the days and unlock moments you completely forgot!",
"welcomeScreenSubtitle": "What did I do today?",
"welcomeScreenStartButtonTitle": "Start",
"serverLoadingScreenDescription": "We are loading your data",
"mainScreenLoadingCamera": "Loading camera",
"mainScreenActionsTorchButton": "Torch",
"mainScreenUploadSuccess": "Uploaded successfully!",
"mainScreenTakePhotoActionTakingPhoto": "Taking photo, please hold still...",
"mainScreenTakePhotoActionUploadingPhoto": "Uploading photo...",
"mainScreenTakeVideoActionSaveVideo": "Taking video, please hold still...",
"mainScreenTakeVideoActionUploadingVideo": "Uploading video...",
"loginScreenTitle": "Login",
"loginScreenLoginError": "Invalid password or email",
"loginScreenHelpText": "Sign in to your account. If you do not have one already, we will automatically set up one for you.",
"loginScreenFormEmailLabel": "Email",
"loginScreenFormPasswordLabel": "Password",
"loginScreenFormSubmitButton": "Login",
"grantPermissionScreenTitle": "Grant Permissions",
"permissionsRequiredPageTitle": "Permissions Required",
"permissionsRequiredPageDescription": "Please grant the following permissions to use this app.",
"permissionsRequiredPagePermanentlyDenied": "You have permanently denied permissions required to use this app. Please enable them in the settings.",
"permissionsRequiredPageOpenSettings": "Open Settings",
"permissionsRequiredPageGrantCameraPermission": "Grant camera permission",
"permissionsRequiredPageGrantMicrophonePermission": "Grant microphone permission",
"memoryViewIsDownloading": "Downloading memory",
"memorySheetSavedToGallery": "Saved to Gallery!",
"memorySheetMemoryUpdatedToPublic": "Your Memory is public now!",
"memorySheetMemoryUpdatedToPrivate": "Your Memory is private now.",
"memorySheetTitle": "Edit Memory",
"memorySheetDownloadMemory": "Download to Gallery",
"memorySheetUpdateMemoryMakePublic": "Make Public",
"memorySheetUpdateMemoryMakePrivate": "Make Private",
"memorySheetDeleteMemory": "Delete Memory"
}

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/screens/main_screen.dart';
import 'main_screen/permissions_required_page.dart';
@ -10,9 +11,11 @@ class GrantPermissionScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(
title: const Text('Grant Permission'),
title: Text(localizations.grantPermissionScreenTitle),
),
body: Center(
child: PermissionsRequiredPage(

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
import 'package:quid_faciam_hodie/managers/authentication_manager.dart';
@ -56,6 +57,8 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
}
Future<void> signIn() async {
final localizations = AppLocalizations.of(context)!;
try {
await _signUp();
} catch (error) {
@ -63,7 +66,9 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
await _signIn();
} catch (error) {
if (mounted) {
context.showLongErrorSnackBar(message: 'Invalid password or email');
context.showLongErrorSnackBar(
message: localizations.loginScreenLoginError,
);
emailController.clear();
passwordController.clear();
@ -79,11 +84,12 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final theme = Theme.of(context);
return Scaffold(
appBar: AppBar(
title: const Text('Login'),
title: Text(localizations.loginScreenTitle),
),
body: Padding(
padding: const EdgeInsets.all(MEDIUM_SPACE),
@ -96,9 +102,7 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
style: theme.textTheme.headline1,
),
const SizedBox(height: LARGE_SPACE),
const Text(
'Sign in to your account. If you do not have one already, we will automatically set up one for you.',
),
Text(localizations.loginScreenHelpText),
const SizedBox(height: MEDIUM_SPACE),
TextField(
controller: emailController,
@ -106,25 +110,25 @@ class _LoginScreenState extends AuthState<LoginScreen> with Loadable {
autofillHints: const [AutofillHints.email],
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
decoration: const InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email),
decoration: InputDecoration(
labelText: localizations.loginScreenFormEmailLabel,
prefixIcon: const Icon(Icons.email),
),
),
const SizedBox(height: SMALL_SPACE),
TextField(
obscureText: true,
controller: passwordController,
decoration: const InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
decoration: InputDecoration(
labelText: localizations.loginScreenFormPasswordLabel,
prefixIcon: const Icon(Icons.lock),
),
onSubmitted: (value) => callWithLoading(signIn),
),
const SizedBox(height: MEDIUM_SPACE),
ElevatedButton.icon(
icon: const Icon(Icons.arrow_right),
label: const Text('Login'),
label: Text(localizations.loginScreenFormSubmitButton),
onPressed: isLoading ? null : () => callWithLoading(signIn),
)
],

View File

@ -4,6 +4,7 @@ import 'dart:typed_data';
import 'package:camera/camera.dart';
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/constants/values.dart';
import 'package:quid_faciam_hodie/extensions/snackbar.dart';
@ -152,6 +153,8 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
}
Future<void> takePhoto() async {
final localizations = AppLocalizations.of(context)!;
if (controller!.value.isTakingPicture) {
return;
}
@ -162,7 +165,7 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
try {
context.showPendingSnackBar(
message: 'Taking photo, please hold still...',
message: localizations.mainScreenTakePhotoActionTakingPhoto,
);
controller!.setFlashMode(FlashMode.off);
@ -172,7 +175,9 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
uploadingPhotoAnimation = file.readAsBytesSync();
});
context.showPendingSnackBar(message: 'Uploading photo...');
context.showPendingSnackBar(
message: localizations.mainScreenTakePhotoActionUploadingPhoto,
);
try {
await FileManager.uploadFile(_user, file);
@ -181,7 +186,9 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
return;
}
context.showSuccessSnackBar(message: 'Photo uploaded!');
context.showSuccessSnackBar(
message: localizations.mainScreenUploadSuccess,
);
} finally {
setState(() {
lockCamera = false;
@ -191,6 +198,8 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
}
Future<void> takeVideo() async {
final localizations = AppLocalizations.of(context)!;
setState(() {
isRecording = false;
});
@ -205,11 +214,15 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
});
try {
context.showPendingSnackBar(message: 'Saving video...');
context.showPendingSnackBar(
message: localizations.mainScreenTakeVideoActionSaveVideo,
);
final file = File((await controller!.stopVideoRecording()).path);
context.showPendingSnackBar(message: 'Uploading video...');
context.showPendingSnackBar(
message: localizations.mainScreenTakeVideoActionUploadingVideo,
);
try {
await FileManager.uploadFile(_user, file);
@ -220,7 +233,9 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
return;
}
context.showSuccessSnackBar(message: 'Video uploaded!');
context.showSuccessSnackBar(
message: localizations.mainScreenUploadSuccess,
);
} finally {
setState(() {
lockCamera = false;
@ -230,6 +245,8 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
backgroundColor: Colors.black,
bottomSheet: () {
@ -238,10 +255,10 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const <Widget>[
CircularProgressIndicator(),
SizedBox(height: MEDIUM_SPACE),
Text('Loading camera'),
children: <Widget>[
const CircularProgressIndicator(),
const SizedBox(height: MEDIUM_SPACE),
Text(localizations.mainScreenLoadingCamera),
],
),
);
@ -371,7 +388,8 @@ class _MainScreenState extends AuthRequiredState<MainScreen> with Loadable {
children: <Widget>[
ElevatedButton.icon(
icon: const Icon(Icons.flashlight_on_rounded),
label: const Text('Torch'),
label: Text(AppLocalizations.of(context)!
.mainScreenActionsTorchButton),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(_) => isTorchEnabled ? Colors.white : Colors.black,

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
@ -52,28 +53,26 @@ class _PermissionsRequiredPageState extends State<PermissionsRequiredPage> {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Permissions Required',
localizations.permissionsRequiredPageTitle,
style: Theme.of(context).textTheme.headline1,
),
const SizedBox(height: MEDIUM_SPACE),
const Text(
'Please grant the following permissions to use this app',
),
Text(localizations.permissionsRequiredPageDescription),
const SizedBox(height: LARGE_SPACE),
if (hasDeniedForever) ...[
const Text(
'You have permanently denied permissions required to use this app. Please enable them in the settings.',
),
Text(localizations.permissionsRequiredPagePermanentlyDenied),
const SizedBox(height: LARGE_SPACE),
TextButton.icon(
onPressed: () => openAppSettings(),
icon: const Icon(Icons.settings),
label: const Text('Open Settings'),
label: Text(localizations.permissionsRequiredPageOpenSettings),
),
] else ...[
TextButton.icon(
@ -84,8 +83,15 @@ class _PermissionsRequiredPageState extends State<PermissionsRequiredPage> {
await checkPermissions();
},
icon: const Icon(Icons.camera_alt),
label: Text(
'Grant camera permission${hasGrantedCameraPermission ? ' - Granted!' : ''}',
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
localizations.permissionsRequiredPageGrantCameraPermission,
),
if (hasGrantedCameraPermission) const Icon(Icons.check),
if (!hasGrantedCameraPermission) const SizedBox(),
],
),
),
const SizedBox(height: MEDIUM_SPACE),
@ -97,8 +103,16 @@ class _PermissionsRequiredPageState extends State<PermissionsRequiredPage> {
await checkPermissions();
},
icon: const Icon(Icons.mic),
label: Text(
'Grant microphone permission ${hasGrantedMicrophonePermission ? ' - Granted!' : ''}',
label: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
localizations
.permissionsRequiredPageGrantMicrophonePermission,
),
if (hasGrantedMicrophonePermission) const Icon(Icons.check),
if (!hasGrantedMicrophonePermission) const SizedBox(),
],
),
),
],

View File

@ -1,5 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/managers/global_values_manager.dart';
@ -54,42 +55,42 @@ class _ServerLoadingScreenState extends State<ServerLoadingScreen> {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: const <Widget>[
Icon(Icons.cloud, size: 60),
SizedBox(height: SMALL_SPACE),
DotAnimation(
children: <Widget>[
const Icon(Icons.cloud, size: 60),
const SizedBox(height: SMALL_SPACE),
const DotAnimation(
initialFadeInDelay: Duration.zero,
fadeInDuration: Duration(seconds: 1),
fadeOutDuration: Duration(seconds: 1),
fadeInDelay: Duration(seconds: 4),
fadeOutDelay: Duration.zero,
),
DotAnimation(
const DotAnimation(
initialFadeInDelay: Duration(seconds: 2),
fadeInDuration: Duration(seconds: 1),
fadeOutDuration: Duration(seconds: 1),
fadeInDelay: Duration(seconds: 4),
fadeOutDelay: Duration.zero,
),
DotAnimation(
const DotAnimation(
initialFadeInDelay: Duration(seconds: 4),
fadeInDuration: Duration(seconds: 1),
fadeOutDuration: Duration(seconds: 1),
fadeInDelay: Duration(seconds: 4),
fadeOutDelay: Duration.zero,
),
SizedBox(height: SMALL_SPACE),
Icon(Icons.smartphone, size: 60),
SizedBox(height: LARGE_SPACE),
Text(
'We are loading your data',
),
const SizedBox(height: SMALL_SPACE),
const Icon(Icons.smartphone, size: 60),
const SizedBox(height: LARGE_SPACE),
Text(localizations.serverLoadingScreenDescription),
],
),
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/widgets/logo.dart';
@ -11,6 +12,7 @@ class WelcomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final theme = Theme.of(context);
return Scaffold(
@ -23,25 +25,25 @@ class WelcomeScreen extends StatelessWidget {
const Logo(),
const SizedBox(height: LARGE_SPACE),
Text(
'Quid faciam hodie?',
localizations.appTitleQuestion,
textAlign: TextAlign.center,
style: theme.textTheme.headline1,
),
const SizedBox(height: SMALL_SPACE),
Text(
'What did I do today?',
localizations.welcomeScreenSubtitle,
style: theme.textTheme.bodySmall,
),
const SizedBox(height: LARGE_SPACE),
Text(
'Find out what you did all the days and unlock moments you completely forgot!',
localizations.welcomeScreenDescription,
textAlign: TextAlign.center,
style: theme.textTheme.bodyText2,
),
const SizedBox(height: LARGE_SPACE),
ElevatedButton.icon(
icon: const Icon(Icons.arrow_right),
label: const Text('Start'),
label: Text(localizations.welcomeScreenStartButtonTitle),
onPressed: () {
Navigator.pushReplacementNamed(
context,

View File

@ -2,6 +2,7 @@ import 'dart:typed_data';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/enums.dart';
import 'package:quid_faciam_hodie/foreign_types/memory.dart';
@ -79,6 +80,7 @@ class _MemoryViewState extends State<MemoryView> {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final theme = Theme.of(context);
if (status == MemoryFetchStatus.error) {
@ -130,7 +132,7 @@ class _MemoryViewState extends State<MemoryView> {
switch (status) {
case MemoryFetchStatus.downloading:
return Text(
'Downloading memory',
localizations.memoryViewIsDownloading,
style: theme.textTheme.bodyText2!.copyWith(
color: Colors.white,
),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:quid_faciam_hodie/constants/spacing.dart';
import 'package:quid_faciam_hodie/enums.dart';
@ -35,13 +36,11 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
}
Future<void> downloadFile() async {
final localizations = AppLocalizations.of(context)!;
try {
final file = await widget.memory.downloadToFile();
if (!mounted) {
return;
}
switch (widget.memory.type) {
case MemoryType.photo:
await GallerySaver.saveImage(file.path);
@ -51,15 +50,22 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
break;
}
if (!mounted) {
return;
}
Navigator.pop(context);
context.showSuccessSnackBar(message: 'File saved to Gallery!');
context.showSuccessSnackBar(
message: localizations.memorySheetSavedToGallery);
} catch (error) {
context.showErrorSnackBar(message: 'There was an error.');
context.showErrorSnackBar(message: localizations.generalError);
}
}
Future<void> changeVisibility() async {
final localizations = AppLocalizations.of(context)!;
final isNowPublic = !widget.memory.isPublic == true;
try {
@ -69,15 +75,21 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
'id': widget.memory.id,
}).execute();
if (!mounted) {
return;
}
Navigator.pop(context);
if (isNowPublic) {
context.showSuccessSnackBar(message: 'Your Memory is public now!');
context.showSuccessSnackBar(
message: localizations.memorySheetMemoryUpdatedToPublic);
} else {
context.showSuccessSnackBar(message: 'Your Memory is private now.');
context.showSuccessSnackBar(
message: localizations.memorySheetMemoryUpdatedToPrivate);
}
} catch (error) {
context.showErrorSnackBar(message: 'There was an error.');
context.showErrorSnackBar(message: localizations.generalError);
}
}
@ -96,19 +108,20 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
final theme = Theme.of(context);
return ModalSheet(
child: Column(
children: <Widget>[
Text(
'Edit Memory',
localizations.memorySheetTitle,
style: theme.textTheme.headline1,
),
const SizedBox(height: MEDIUM_SPACE),
ListTile(
leading: const Icon(Icons.download),
title: const Text('Download to Gallery'),
title: Text(localizations.memorySheetDownloadMemory),
enabled: !getIsLoadingSpecificID('download'),
onTap: getIsLoadingSpecificID('download')
? null
@ -121,8 +134,11 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
leading: Icon(widget.memory.isPublic
? Icons.public_off_rounded
: Icons.public_rounded),
title:
Text(widget.memory.isPublic ? 'Make private' : 'Make public'),
title: Text(
widget.memory.isPublic
? localizations.memorySheetUpdateMemoryMakePrivate
: localizations.memorySheetUpdateMemoryMakePublic,
),
enabled: !getIsLoadingSpecificID('public'),
onTap: getIsLoadingSpecificID('public')
? null
@ -133,7 +149,7 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
),
ListTile(
leading: const Icon(Icons.delete_forever_sharp),
title: const Text('Delete Memory'),
title: Text(localizations.memorySheetDeleteMemory),
enabled: !getIsLoadingSpecificID('delete'),
onTap: getIsLoadingSpecificID('delete')
? null

View File

@ -34,7 +34,7 @@ class TimelineOverlay extends StatelessWidget {
curve: Curves.linearToEaseOut,
opacity: timeline.showOverlay ? 1.0 : 0.0,
child: Text(
DateFormat('dd. MMMM yyyy').format(date),
DateFormat.yMMMd().format(date),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline1!.copyWith(
color: Colors.white,