Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/translations #4

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions lib/common/app-translation/app-translation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import 'package:get/get.dart';

import '../../screens/home/title/title.translation.dart' as home_title;
import '../../screens/home/todo/add-task/add-task.translation.dart'
as home_add_task;
import '../../screens/home/todo/filter-panel/filter-panel.translation.dart'
as home_filter_panel;
import '../remaining-items/remaining-items.translation.dart' as remaining_items;

class AppTranslation extends GetxService {
AppTranslation();

Map<String, Map<String, String>> translationsKeys =
<String, Map<String, String>>{
'en': en,
'uk': uk,
'ru': ru,
};

void _combineTranslations(Map<String, String> enTranslations,
Map<String, String> ukTranslations, Map<String, String> ruTranslations) {
translationsKeys['en']!.addAll(enTranslations);
translationsKeys['uk']!.addAll(ukTranslations);
translationsKeys['ru']!.addAll(ruTranslations);
}

Map<String, Map<String, String>> combineAllTranslations() {
_combineTranslations(
home_title.en,
home_title.uk,
home_title.ru,
);

_combineTranslations(
home_add_task.en,
home_add_task.uk,
home_add_task.ru,
);

_combineTranslations(
home_filter_panel.en,
home_filter_panel.uk,
home_filter_panel.ru,
);

_combineTranslations(
remaining_items.en,
remaining_items.uk,
remaining_items.ru,
);

return translationsKeys;
}
}

final Map<String, String> en = <String, String>{};
final Map<String, String> uk = <String, String>{};
final Map<String, String> ru = <String, String>{};
14 changes: 14 additions & 0 deletions lib/common/app-translation/translation.extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import 'package:get/get.dart';

abstract class Translation {}

extension Translations on Translation {
String get st => '$this';
String get tr => st.tr;
}

extension MapEnumExtensions on Map<Translation, String> {
Map<String, String> get st => Map<String, String>.fromEntries(entries.map(
(MapEntry<Translation, String> entry) =>
MapEntry<String, String>(entry.key.st, entry.value)));
}
30 changes: 30 additions & 0 deletions lib/common/remaining-items/remaining-items.extensions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'package:get/get.dart';
import 'package:intl/intl.dart';

import '../app-translation/translation.extensions.dart';
import 'remaining-items.translation.dart';

extension RemainingItemsFormatter on int {
String get remainingItemsText => _getPlural(
this,
one: RemainingItemsTranslationNames.oneItem.tr,
few: RemainingItemsTranslationNames.fewItems.tr,
many: RemainingItemsTranslationNames.manyItems.tr,
).trim();

String _getPlural(int value,
{required String one, required String few, required String many}) {
if (value > 0) {
return Intl.plural(
value,
zero: '',
one: '$value $one',
few: '$value $few',
many: '$value $many',
other: '$value $many',
locale: Get.locale?.languageCode,
);
}
return '';
}
}
25 changes: 25 additions & 0 deletions lib/common/remaining-items/remaining-items.translation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import '../../../../common/app-translation/translation.extensions.dart';

enum RemainingItemsTranslationNames implements Translation {
oneItem,
fewItems,
manyItems,
}

final Map<String, String> en = <RemainingItemsTranslationNames, String>{
RemainingItemsTranslationNames.oneItem: 'item left',
RemainingItemsTranslationNames.fewItems: 'items left',
RemainingItemsTranslationNames.manyItems: 'items left',
}.st;

final Map<String, String> ru = <RemainingItemsTranslationNames, String>{
RemainingItemsTranslationNames.oneItem: 'элемент остался',
RemainingItemsTranslationNames.fewItems: 'элемента осталось',
RemainingItemsTranslationNames.manyItems: 'элементов осталось',
}.st;

final Map<String, String> uk = <RemainingItemsTranslationNames, String>{
RemainingItemsTranslationNames.oneItem: 'елемент залишився',
RemainingItemsTranslationNames.fewItems: 'елементи залишились',
RemainingItemsTranslationNames.manyItems: 'елементів залишилось',
}.st;
6 changes: 6 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'common/app-translation/app-translation.dart';
import 'screens/home/home.binding.dart';
import 'screens/home/home.screen.dart';

void main() {
Get.lazyPut(AppTranslation.new);

runApp(const MyApp());
}

Expand All @@ -14,5 +17,8 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) => GetMaterialApp(
initialBinding: HomeBinding(),
home: const HomeScreen(),
translationsKeys: Get.find<AppTranslation>().combineAllTranslations(),
locale: const Locale('en'),
fallbackLocale: const Locale('en'),
);
}
4 changes: 4 additions & 0 deletions lib/screens/home/home.binding.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'package:get/get.dart';
import '../../common/app-translation/app-translation.dart';
import 'language-switcher/language-switcher.controller.dart';
import 'todo/add-task/add-task.controller.dart';
import 'todo/filter-panel/filter-panel.controller.dart';
import 'todo/task-list-item/task-list-item.controller.dart';
Expand All @@ -8,7 +10,9 @@ class HomeBinding extends Bindings {
@override
Future<void> dependencies() async {
Get
..lazyPut(AppTranslation.new)
..lazyPut(TodoService.new)
..lazyPut(LanguageSwitcherController.new)
..lazyPut(() => AddTaskController(Get.find()))
..lazyPut(() => FilterPanelController(Get.find()))
..lazyPut(() => TaskListItemController(Get.find(), Get.find()));
Expand Down
7 changes: 7 additions & 0 deletions lib/screens/home/home.screen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'language-switcher/language-switcher.widget.dart';
import 'todo/todo.widget.dart';
import '../home/title/title.widget.dart';

Expand All @@ -10,6 +11,12 @@ class HomeScreen extends StatelessWidget {
body: ListView(
children: const <Widget>[
Center(child: TitleWidget()),
Padding(
padding: EdgeInsets.only(bottom: 20),
child: Center(
child: LanguageSwitcherWidget(),
),
),
TodoWidget(),
],
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'package:get/get.dart';
import 'language-switcher.enum.dart';

class LanguageSwitcherController extends GetxController {
final Rx<Language> currentLanguage = Language.en.obs;

void updateLocale(Language language) {
currentLanguage.value = language;
Get.updateLocale(language.locale);
}
}
12 changes: 12 additions & 0 deletions lib/screens/home/language-switcher/language-switcher.enum.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'dart:ui';

enum Language {
en(Locale('en'), 'English'),
ru(Locale('ru'), 'Русский'),
uk(Locale('uk'), 'Українська');

const Language(this.locale, this.title);

final Locale locale;
final String title;
}
25 changes: 25 additions & 0 deletions lib/screens/home/language-switcher/language-switcher.widget.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'language-switcher.controller.dart';
import 'language-switcher.enum.dart';

class LanguageSwitcherWidget extends GetView<LanguageSwitcherController> {
const LanguageSwitcherWidget({super.key});

@override
Widget build(BuildContext context) => Obx(() => DropdownButton<Language>(
value: controller.currentLanguage.value,
onChanged: (Language? language) {
if (language != null) {
controller.updateLocale(language);
}
},
items: Language.values
.map<DropdownMenuItem<Language>>(
(Language language) => DropdownMenuItem<Language>(
value: language,
child: Text(language.title),
))
.toList(),
));
}
17 changes: 17 additions & 0 deletions lib/screens/home/title/title.translation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import '../../../common/app-translation/translation.extensions.dart';

enum TitleTranslationNames implements Translation {
title,
}

final Map<String, String> en = <TitleTranslationNames, String>{
TitleTranslationNames.title: 'todos',
}.st;

final Map<String, String> ru = <TitleTranslationNames, String>{
TitleTranslationNames.title: 'Список задач',
}.st;

final Map<String, String> uk = <TitleTranslationNames, String>{
TitleTranslationNames.title: 'Список завдань',
}.st;
12 changes: 8 additions & 4 deletions lib/screens/home/title/title.widget.dart
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import 'package:flutter/material.dart';

import 'title.translation.dart';
import '../../../common/app-translation/translation.extensions.dart';

class TitleWidget extends StatelessWidget {
const TitleWidget({super.key});

@override
Widget build(BuildContext context) => const Padding(
padding: EdgeInsets.only(top: 50, bottom: 20),
Widget build(BuildContext context) => Padding(
padding: const EdgeInsets.only(top: 50, bottom: 20),
child: Text(
'todos',
style: TextStyle(
TitleTranslationNames.title.tr,
textAlign: TextAlign.center,
style: const TextStyle(
fontSize: 80,
fontWeight: FontWeight.w300,
color: Colors.red,
Expand Down
17 changes: 17 additions & 0 deletions lib/screens/home/todo/add-task/add-task.translation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import '../../../../common/app-translation/translation.extensions.dart';

enum AddTaskTranslationNames implements Translation {
title,
}

final Map<String, String> en = <AddTaskTranslationNames, String>{
AddTaskTranslationNames.title: 'What needs to be done?',
}.st;

final Map<String, String> ru = <AddTaskTranslationNames, String>{
AddTaskTranslationNames.title: 'Что нужно сделать?',
}.st;

final Map<String, String> uk = <AddTaskTranslationNames, String>{
AddTaskTranslationNames.title: 'Що потрібно зробити?',
}.st;
4 changes: 3 additions & 1 deletion lib/screens/home/todo/add-task/add-task.widget.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../../common/app-translation/translation.extensions.dart';
import '../../../../common/input/input.widget.dart';
import 'add-task.controller.dart';
import 'add-task.translation.dart';

class AddTaskWidget extends GetView<AddTaskController> {
const AddTaskWidget({super.key});
Expand All @@ -16,7 +18,7 @@ class AddTaskWidget extends GetView<AddTaskController> {
child: InputWidget(
textController: controller.textController,
focusNode: controller.focusNode,
hintText: 'What needs to be done?',
hintText: AddTaskTranslationNames.title.tr,
onSubmitted: controller.addTask,
),
);
Expand Down
15 changes: 10 additions & 5 deletions lib/screens/home/todo/filter-panel/filter-panel.enum.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import '../../../../common/app-translation/translation.extensions.dart';
import 'filter-panel.translation.dart';

enum FilterType {
all('All'),
active('Active'),
completed('Completed');
all(FilterPanelTranslationNames.all),
active(FilterPanelTranslationNames.active),
completed(FilterPanelTranslationNames.completed);

const FilterType(this.translationKey);

const FilterType(this.type);
final FilterPanelTranslationNames translationKey;

final String type;
String get type => translationKey.tr;
}
29 changes: 29 additions & 0 deletions lib/screens/home/todo/filter-panel/filter-panel.translation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import '../../../../common/app-translation/translation.extensions.dart';

enum FilterPanelTranslationNames implements Translation {
clearItems,
all,
active,
completed
}

final Map<String, String> en = <FilterPanelTranslationNames, String>{
FilterPanelTranslationNames.clearItems: 'Clear completed',
FilterPanelTranslationNames.all: 'All',
FilterPanelTranslationNames.active: 'Active',
FilterPanelTranslationNames.completed: 'Completed',
}.st;

final Map<String, String> ru = <FilterPanelTranslationNames, String>{
FilterPanelTranslationNames.clearItems: 'Очистить выполненные',
FilterPanelTranslationNames.all: 'Все',
FilterPanelTranslationNames.active: 'Активные',
FilterPanelTranslationNames.completed: 'Выполненные',
}.st;

final Map<String, String> uk = <FilterPanelTranslationNames, String>{
FilterPanelTranslationNames.clearItems: 'Очистити виконані',
FilterPanelTranslationNames.all: 'Усі',
FilterPanelTranslationNames.active: 'Активні',
FilterPanelTranslationNames.completed: 'Виконані',
}.st;
Loading
Loading