Compare commits
7 Commits
4c2162a158
...
85b5d4dc7c
| Author | SHA1 | Date | |
|---|---|---|---|
| 85b5d4dc7c | |||
| ebf1246a55 | |||
| 8e91388ecf | |||
| b9033014c8 | |||
| 0a877525aa | |||
| ff97898b90 | |||
| c523b7495f |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -156,4 +156,4 @@ app.*.symbols
|
|||||||
!.vscode/settings.json
|
!.vscode/settings.json
|
||||||
|
|
||||||
# Custom
|
# Custom
|
||||||
content.json
|
content/
|
||||||
3
l10n.yaml
Normal file
3
l10n.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
arb-dir: lib/l10n
|
||||||
|
template-arb-file: app_en.arb
|
||||||
|
output-localization-file: app_localizations.dart
|
||||||
@@ -1,19 +1,3 @@
|
|||||||
/// List of months 0-11
|
|
||||||
const months = [
|
|
||||||
'Januar',
|
|
||||||
'Februar',
|
|
||||||
'März',
|
|
||||||
'April',
|
|
||||||
'Mai',
|
|
||||||
'Juni',
|
|
||||||
'July',
|
|
||||||
'August',
|
|
||||||
'September',
|
|
||||||
'Oktober',
|
|
||||||
'November',
|
|
||||||
'Dezember'
|
|
||||||
];
|
|
||||||
|
|
||||||
enum ContentType {
|
enum ContentType {
|
||||||
experience,
|
experience,
|
||||||
education,
|
education,
|
||||||
|
|||||||
28
lib/l10n/app_de.arb
Normal file
28
lib/l10n/app_de.arb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"german": "Deutsch",
|
||||||
|
"english": "Englisch",
|
||||||
|
"resume": "Lebenslauf",
|
||||||
|
"skills": "Fähigkeiten",
|
||||||
|
"languages": "Sprachen",
|
||||||
|
"mother_tongue": "Muttersprache",
|
||||||
|
"very_good": "Sehr gut",
|
||||||
|
"about_me": "Über mich",
|
||||||
|
"additional_skills": "Weitere Kenntnisse",
|
||||||
|
"work_experience": "Arbeitserfahrung",
|
||||||
|
"education": "Bildungsweg",
|
||||||
|
"source_code": "Quellcode",
|
||||||
|
|
||||||
|
"@_months": {},
|
||||||
|
"january": "Januar",
|
||||||
|
"february": "Februar",
|
||||||
|
"march": "März",
|
||||||
|
"april": "April",
|
||||||
|
"may": "Mai",
|
||||||
|
"june": "Juni",
|
||||||
|
"july": "Juli",
|
||||||
|
"august": "August",
|
||||||
|
"september": "September",
|
||||||
|
"october": "Oktober",
|
||||||
|
"november": "November",
|
||||||
|
"december": "Dezember"
|
||||||
|
}
|
||||||
28
lib/l10n/app_en.arb
Normal file
28
lib/l10n/app_en.arb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"german": "German",
|
||||||
|
"english": "English",
|
||||||
|
"resume": "Resume",
|
||||||
|
"skills": "Skills",
|
||||||
|
"languages": "Languages",
|
||||||
|
"mother_tongue": "Native",
|
||||||
|
"very_good": "Very goods",
|
||||||
|
"about_me": "About me",
|
||||||
|
"additional_skills": "Additional Skills",
|
||||||
|
"work_experience": "Work experience",
|
||||||
|
"education": "Education",
|
||||||
|
"source_code": "Source Code",
|
||||||
|
|
||||||
|
"@_months": {},
|
||||||
|
"january": "January",
|
||||||
|
"february": "February",
|
||||||
|
"march": "March",
|
||||||
|
"april": "April",
|
||||||
|
"may": "May",
|
||||||
|
"june": "June",
|
||||||
|
"july": "July",
|
||||||
|
"august": "August",
|
||||||
|
"september": "September",
|
||||||
|
"october": "October",
|
||||||
|
"november": "November",
|
||||||
|
"december": "December"
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:resume/pages/landing_page.dart';
|
import 'package:resume/pages/landing_page.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'theme.dart' show darkTheme;
|
import 'theme.dart' show darkTheme;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -14,6 +16,17 @@ class Resume extends StatelessWidget {
|
|||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Resume',
|
title: 'Resume',
|
||||||
theme: darkTheme,
|
theme: darkTheme,
|
||||||
|
localizationsDelegates: const [
|
||||||
|
AppLocalizations.delegate,
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
],
|
||||||
|
supportedLocales: const [
|
||||||
|
Locale('en'),
|
||||||
|
Locale('de'),
|
||||||
|
],
|
||||||
|
locale: const Locale('en'),
|
||||||
routes: {
|
routes: {
|
||||||
'/': (context) => const LandingPage(),
|
'/': (context) => const LandingPage(),
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:resume/services/breakpoints.dart';
|
import 'package:resume/services/breakpoints.dart';
|
||||||
|
import 'package:resume/widgets/language_dropdown.dart';
|
||||||
import 'package:resume/widgets/profile.dart';
|
import 'package:resume/widgets/profile.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:resume/constants.dart' show ContentType;
|
import 'package:resume/constants.dart' show ContentType;
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
import '../services/content_provider.dart';
|
import '../services/content_provider.dart';
|
||||||
import '../widgets/content_block.dart';
|
import '../widgets/content_block.dart';
|
||||||
@@ -42,15 +44,15 @@ class _LandingPageState extends State<LandingPage> {
|
|||||||
(MediaQuery.of(context).size.width - _getMainContentWidth()) / 2;
|
(MediaQuery.of(context).size.width - _getMainContentWidth()) / 2;
|
||||||
|
|
||||||
Widget _getSideBar() {
|
Widget _getSideBar() {
|
||||||
return const Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
ContentBlock(
|
ContentBlock(
|
||||||
blockTitle: 'Fähigkeiten',
|
blockTitle: AppLocalizations.of(context)!.skills,
|
||||||
contentType: ContentType.skills,
|
contentType: ContentType.skills,
|
||||||
),
|
),
|
||||||
Padding(padding: EdgeInsets.only(bottom: 25)),
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
||||||
ContentBlock(
|
ContentBlock(
|
||||||
blockTitle: 'Sprachen',
|
blockTitle: AppLocalizations.of(context)!.languages,
|
||||||
contentType: ContentType.language,
|
contentType: ContentType.language,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -58,25 +60,25 @@ class _LandingPageState extends State<LandingPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _getMainContent() {
|
Widget _getMainContent() {
|
||||||
return const Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
ContentBlock(
|
ContentBlock(
|
||||||
blockTitle: 'Arbeitserfahrung',
|
blockTitle: AppLocalizations.of(context)!.work_experience,
|
||||||
contentType: ContentType.experience,
|
contentType: ContentType.experience,
|
||||||
),
|
),
|
||||||
Padding(padding: EdgeInsets.only(bottom: 25)),
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
||||||
ContentBlock(
|
ContentBlock(
|
||||||
blockTitle: 'Bildungsweg',
|
blockTitle: AppLocalizations.of(context)!.education,
|
||||||
contentType: ContentType.education,
|
contentType: ContentType.education,
|
||||||
),
|
),
|
||||||
Padding(padding: EdgeInsets.only(bottom: 25)),
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
||||||
ContentBlock(
|
ContentBlock(
|
||||||
blockTitle: 'Weitere Kenntnisse',
|
blockTitle: AppLocalizations.of(context)!.additional_skills,
|
||||||
contentType: ContentType.generalSkills,
|
contentType: ContentType.generalSkills,
|
||||||
),
|
),
|
||||||
Padding(padding: EdgeInsets.only(bottom: 25)),
|
const Padding(padding: EdgeInsets.only(bottom: 25)),
|
||||||
ContentBlock(
|
ContentBlock(
|
||||||
blockTitle: "Über mich",
|
blockTitle: AppLocalizations.of(context)!.about_me,
|
||||||
contentType: ContentType.text,
|
contentType: ContentType.text,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -188,9 +190,12 @@ class _LandingPageState extends State<LandingPage> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Lebenslauf'),
|
title: Text(AppLocalizations.of(context)!.resume),
|
||||||
actions: const [
|
actions: [
|
||||||
TextButton(onPressed: _launchURL, child: Text('Source Code')),
|
TextButton(
|
||||||
|
onPressed: _launchURL,
|
||||||
|
child: Text(AppLocalizations.of(context)!.source_code)),
|
||||||
|
const LanguageDropdown(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: !loadingDone
|
body: !loadingDone
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:resume/constants.dart';
|
|||||||
class ContentProvider {
|
class ContentProvider {
|
||||||
ContentProvider._();
|
ContentProvider._();
|
||||||
|
|
||||||
static const String _jsonPath = 'assets/content.json';
|
static const String _jsonPath = 'assets/content/content.json';
|
||||||
|
|
||||||
static Future<bool> init() async {
|
static Future<bool> init() async {
|
||||||
try {
|
try {
|
||||||
@@ -23,7 +23,7 @@ class ContentProvider {
|
|||||||
'education': <List<dynamic>>[],
|
'education': <List<dynamic>>[],
|
||||||
'skills': <List<dynamic>>[],
|
'skills': <List<dynamic>>[],
|
||||||
'text': <String>[],
|
'text': <String>[],
|
||||||
'general_skills': <List<dynamic>>[],
|
'general_skills': <String>[],
|
||||||
};
|
};
|
||||||
|
|
||||||
static T getContent<T>(ContentType contentType) {
|
static T getContent<T>(ContentType contentType) {
|
||||||
|
|||||||
@@ -1,12 +1,97 @@
|
|||||||
import 'package:resume/constants.dart' show months;
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
class Tools {
|
class Tools {
|
||||||
/// builds timespan-String out of two date-Strings.
|
/// Builds a formatted time string from two date strings in the format 'YYYY-MM'.
|
||||||
/// Date has to be formatted as yyyy-MM
|
///
|
||||||
static buildTimeString(String startDate, String endDate) {
|
/// Returns a string in the format 'Month Year - Month Year' using localized month names.
|
||||||
if (startDate.isEmpty || endDate.isEmpty) return '';
|
/// Returns an empty string if either input is empty or invalid.
|
||||||
final firstDate = DateTime.parse('$startDate-01');
|
///
|
||||||
final secondDate = DateTime.parse('$endDate-01');
|
/// Parameters:
|
||||||
return '${months[firstDate.month - 1]} ${firstDate.year} - ${months[secondDate.month - 1]} ${secondDate.year}';
|
/// - [startDate]: String in 'YYYY-MM' format (e.g., '2024-03')
|
||||||
|
/// - [endDate]: String in 'YYYY-MM' format (e.g., '2024-12')
|
||||||
|
/// - [context]: BuildContext for accessing localizations
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final timeString = buildTimeString('2024-03', '2024-12', context);
|
||||||
|
/// // Returns "March 2024 - December 2024" (or localized equivalent)
|
||||||
|
/// ```
|
||||||
|
static String buildTimeString(
|
||||||
|
String startDate, String endDate, BuildContext context) {
|
||||||
|
// Check for empty or null inputs
|
||||||
|
if (startDate.isEmpty || endDate.isEmpty) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Validate date format
|
||||||
|
if (!startDate.contains(RegExp(r'^\d{4}-\d{2}$')) ||
|
||||||
|
!endDate.contains(RegExp(r'^\d{4}-\d{2}$'))) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse dates with validation
|
||||||
|
final firstDate = DateTime.tryParse('$startDate-01');
|
||||||
|
final secondDate = DateTime.tryParse('$endDate-01');
|
||||||
|
|
||||||
|
// Check if parsing was successful
|
||||||
|
if (firstDate == null || secondDate == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the formatted string
|
||||||
|
return '${getLocalizedMonth(context, firstDate.month)} ${firstDate.year} - '
|
||||||
|
'${getLocalizedMonth(context, secondDate.month)} ${secondDate.year}';
|
||||||
|
} catch (e) {
|
||||||
|
// Handle any unexpected errors
|
||||||
|
debugPrint('Error building time string: $e');
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the localized month name as a [String] based on the provided month number.
|
||||||
|
///
|
||||||
|
/// The [context] is used to access the app's localizations.
|
||||||
|
/// The [monthNumber] must be between 1 and 12, where 1 represents January
|
||||||
|
/// and 12 represents December.
|
||||||
|
///
|
||||||
|
/// Throws an [ArgumentError] if the month number is not between 1 and 12.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```dart
|
||||||
|
/// final monthName = getLocalizedMonth(context, 3); // Returns "March" or "März"
|
||||||
|
/// ```
|
||||||
|
static String getLocalizedMonth(BuildContext context, int monthNumber) {
|
||||||
|
final localizations = AppLocalizations.of(context)!;
|
||||||
|
|
||||||
|
switch (monthNumber) {
|
||||||
|
case 1:
|
||||||
|
return localizations.january;
|
||||||
|
case 2:
|
||||||
|
return localizations.february;
|
||||||
|
case 3:
|
||||||
|
return localizations.march;
|
||||||
|
case 4:
|
||||||
|
return localizations.april;
|
||||||
|
case 5:
|
||||||
|
return localizations.may;
|
||||||
|
case 6:
|
||||||
|
return localizations.june;
|
||||||
|
case 7:
|
||||||
|
return localizations.july;
|
||||||
|
case 8:
|
||||||
|
return localizations.august;
|
||||||
|
case 9:
|
||||||
|
return localizations.september;
|
||||||
|
case 10:
|
||||||
|
return localizations.october;
|
||||||
|
case 11:
|
||||||
|
return localizations.november;
|
||||||
|
case 12:
|
||||||
|
return localizations.december;
|
||||||
|
default:
|
||||||
|
throw ArgumentError('Month number must be between 1 and 12');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,23 +18,13 @@ class ContentBlock extends StatelessWidget {
|
|||||||
Widget get _getContentWidget {
|
Widget get _getContentWidget {
|
||||||
if (contentType == ContentType.language) {
|
if (contentType == ContentType.language) {
|
||||||
return const LanguageWidget();
|
return const LanguageWidget();
|
||||||
} else if (contentType == ContentType.text) {
|
} else if (contentType == ContentType.text ||
|
||||||
final content = ContentProvider.getContent<String>(ContentType.text);
|
contentType == ContentType.generalSkills) {
|
||||||
|
final content = ContentProvider.getContent<String>(contentType);
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: Text(content),
|
child: Text(content),
|
||||||
);
|
);
|
||||||
} else if (contentType == ContentType.generalSkills) {
|
|
||||||
final content =
|
|
||||||
ContentProvider.getContent<List<dynamic>>(ContentType.generalSkills);
|
|
||||||
List<Widget> widgets = [];
|
|
||||||
for (int i = 0; i < content.length; i++) {
|
|
||||||
String text = i == content.length - 1
|
|
||||||
? content.elementAt(i)
|
|
||||||
: content.elementAt(i) + ', ';
|
|
||||||
widgets.add(Text(text));
|
|
||||||
}
|
|
||||||
return Row(children: widgets);
|
|
||||||
}
|
}
|
||||||
// List-based content-blocks
|
// List-based content-blocks
|
||||||
List<dynamic> content =
|
List<dynamic> content =
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class ContentListTile extends StatelessWidget {
|
|||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 8),
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
Tools.buildTimeString(startDate, endDate),
|
Tools.buildTimeString(startDate, endDate, context),
|
||||||
style: Theme.of(context).textTheme.labelSmall!.copyWith(
|
style: Theme.of(context).textTheme.labelSmall!.copyWith(
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
@@ -106,7 +106,7 @@ class ContentListTile extends StatelessWidget {
|
|||||||
: null,
|
: null,
|
||||||
trailing: Breakpoints.sm < screenWidth
|
trailing: Breakpoints.sm < screenWidth
|
||||||
? Text(
|
? Text(
|
||||||
Tools.buildTimeString(startDate, endDate),
|
Tools.buildTimeString(startDate, endDate, context),
|
||||||
style:
|
style:
|
||||||
TextStyle(color: Theme.of(context).colorScheme.secondary),
|
TextStyle(color: Theme.of(context).colorScheme.secondary),
|
||||||
)
|
)
|
||||||
@@ -149,7 +149,7 @@ class ContentListTile extends StatelessWidget {
|
|||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(bottom: 8),
|
padding: const EdgeInsets.only(bottom: 8),
|
||||||
child: Text(
|
child: Text(
|
||||||
Tools.buildTimeString(startDate, endDate),
|
Tools.buildTimeString(startDate, endDate, context),
|
||||||
style: Theme.of(context).textTheme.labelSmall!.copyWith(
|
style: Theme.of(context).textTheme.labelSmall!.copyWith(
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
),
|
),
|
||||||
@@ -160,7 +160,7 @@ class ContentListTile extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
trailing: Breakpoints.sm < screenWidth
|
trailing: Breakpoints.sm < screenWidth
|
||||||
? Text(
|
? Text(
|
||||||
Tools.buildTimeString(startDate, endDate),
|
Tools.buildTimeString(startDate, endDate, context),
|
||||||
style:
|
style:
|
||||||
TextStyle(color: Theme.of(context).colorScheme.secondary),
|
TextStyle(color: Theme.of(context).colorScheme.secondary),
|
||||||
)
|
)
|
||||||
|
|||||||
42
lib/widgets/language_dropdown.dart
Normal file
42
lib/widgets/language_dropdown.dart
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
class LanguageDropdown extends StatelessWidget {
|
||||||
|
const LanguageDropdown({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return DropdownButton(
|
||||||
|
value: 'de',
|
||||||
|
items: [
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'de',
|
||||||
|
child: getMenuItem(
|
||||||
|
AppLocalizations.of(context)!.german,
|
||||||
|
'assets/de_icon.png',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DropdownMenuItem(
|
||||||
|
value: 'en',
|
||||||
|
child: getMenuItem(
|
||||||
|
AppLocalizations.of(context)!.english,
|
||||||
|
'assets/gb_icon.png',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
onChanged: _onChanged,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onChanged(dynamic value) {}
|
||||||
|
|
||||||
|
Widget getMenuItem(String label, String imagePath) {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Text(label),
|
||||||
|
const Padding(padding: EdgeInsets.only(right: 8)),
|
||||||
|
Image.asset(imagePath, width: 30),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
|
||||||
class LanguageWidget extends StatelessWidget {
|
class LanguageWidget extends StatelessWidget {
|
||||||
const LanguageWidget({super.key});
|
const LanguageWidget({super.key});
|
||||||
@@ -18,8 +19,9 @@ class LanguageWidget extends StatelessWidget {
|
|||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('Deutsch', style: Theme.of(context).textTheme.bodyLarge),
|
Text(AppLocalizations.of(context)!.german,
|
||||||
Text('Muttersprache',
|
style: Theme.of(context).textTheme.bodyLarge),
|
||||||
|
Text(AppLocalizations.of(context)!.mother_tongue,
|
||||||
style: Theme.of(context).textTheme.bodyMedium),
|
style: Theme.of(context).textTheme.bodyMedium),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -36,8 +38,10 @@ class LanguageWidget extends StatelessWidget {
|
|||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text('Englisch', style: Theme.of(context).textTheme.bodyLarge),
|
Text(AppLocalizations.of(context)!.english,
|
||||||
Text('Sehr gut', style: Theme.of(context).textTheme.bodyMedium),
|
style: Theme.of(context).textTheme.bodyLarge),
|
||||||
|
Text(AppLocalizations.of(context)!.very_good,
|
||||||
|
style: Theme.of(context).textTheme.bodyMedium),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -12,6 +12,9 @@ dependencies:
|
|||||||
|
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
url_launcher: ^6.3.1
|
url_launcher: ^6.3.1
|
||||||
|
flutter_localizations:
|
||||||
|
sdk: flutter
|
||||||
|
intl: any
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -20,10 +23,11 @@ dev_dependencies:
|
|||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^4.0.0
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
|
generate: true
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
assets:
|
assets:
|
||||||
- assets/content.json
|
- assets/content/content.json
|
||||||
- assets/profile.jpg
|
- assets/profile.jpg
|
||||||
- assets/de_icon.png
|
- assets/de_icon.png
|
||||||
- assets/gb_icon.png
|
- assets/gb_icon.png
|
||||||
|
|||||||
Reference in New Issue
Block a user