From 360ab9a501198895cb3e814abc2401c42082ea56 Mon Sep 17 00:00:00 2001 From: dab246 Date: Tue, 27 Jul 2021 12:54:28 +0700 Subject: [PATCH] Init home feature add presentation layer --- .../home/presentation/home_bindings.dart | 22 +++++ .../home/presentation/home_controller.dart | 39 ++++++++ lib/features/home/presentation/home_view.dart | 26 ++++++ lib/l10n/intl_en.arb | 63 +++++++++++++ lib/l10n/intl_fr.arb | 63 +++++++++++++ lib/l10n/intl_messages.arb | 63 +++++++++++++ lib/l10n/intl_ru.arb | 63 +++++++++++++ lib/l10n/intl_vi.arb | 63 +++++++++++++ lib/main/bindings/core/core_bindings.dart | 30 +++++++ lib/main/bindings/main_bindings.dart | 11 +++ .../bindings/network/network_bindings.dart | 49 ++++++++++ lib/main/localizations/app_localizations.dart | 90 +++++++++++++++++++ .../app_localizations_delegate.dart | 19 ++++ lib/main/main.dart | 46 ++++++++++ lib/main/pages/app_pages.dart | 25 ++++++ lib/main/routes/app_routes.dart | 5 ++ 16 files changed, 677 insertions(+) create mode 100644 lib/features/home/presentation/home_bindings.dart create mode 100644 lib/features/home/presentation/home_controller.dart create mode 100644 lib/features/home/presentation/home_view.dart create mode 100644 lib/l10n/intl_en.arb create mode 100644 lib/l10n/intl_fr.arb create mode 100644 lib/l10n/intl_messages.arb create mode 100644 lib/l10n/intl_ru.arb create mode 100644 lib/l10n/intl_vi.arb create mode 100644 lib/main/bindings/core/core_bindings.dart create mode 100644 lib/main/bindings/main_bindings.dart create mode 100644 lib/main/bindings/network/network_bindings.dart create mode 100644 lib/main/localizations/app_localizations.dart create mode 100644 lib/main/localizations/app_localizations_delegate.dart create mode 100644 lib/main/main.dart create mode 100644 lib/main/pages/app_pages.dart create mode 100644 lib/main/routes/app_routes.dart diff --git a/lib/features/home/presentation/home_bindings.dart b/lib/features/home/presentation/home_bindings.dart new file mode 100644 index 000000000..adf26e136 --- /dev/null +++ b/lib/features/home/presentation/home_bindings.dart @@ -0,0 +1,22 @@ +import 'package:core/core.dart'; +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:tmail_ui_user/features/home/presentation/home_controller.dart'; +import 'package:tmail_ui_user/features/login/data/repository/credential_repository_impl.dart'; +import 'package:tmail_ui_user/features/login/domain/repository/credential_repository.dart'; +import 'package:tmail_ui_user/features/login/domain/usecases/get_credential_interactor.dart'; + +class HomeBindings extends Bindings { + @override + void dependencies() { + Get.lazyPut(() => CredentialRepositoryImpl(Get.find())); + Get.lazyPut(() => Get.find()); + + Get.lazyPut(() => GetCredentialInteractor(Get.find())); + + Get.lazyPut(() => HomeController( + Get.find(), + Get.find(), + Get.find())); + } +} \ No newline at end of file diff --git a/lib/features/home/presentation/home_controller.dart b/lib/features/home/presentation/home_controller.dart new file mode 100644 index 000000000..99a554d60 --- /dev/null +++ b/lib/features/home/presentation/home_controller.dart @@ -0,0 +1,39 @@ +import 'package:core/core.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/login/domain/state/get_credential_state.dart'; +import 'package:tmail_ui_user/features/login/domain/usecases/get_credential_interactor.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; + +class HomeController extends GetxController { + final GetCredentialInteractor _getCredentialInteractor; + final DynamicUrlInterceptors _dynamicUrlInterceptors; + final AuthorizationInterceptors _authorizationInterceptors; + + HomeController(this._getCredentialInteractor, this._dynamicUrlInterceptors, this._authorizationInterceptors); + + @override + void onReady() { + super.onReady(); + _getCredentialAction(); + } + + void _getCredentialAction() async { + await _getCredentialInteractor.execute() + .then((response) => response.fold( + (failure) => _goToLogin(), + (success) => success is GetCredentialViewState ? _goToMailbox(success) : _goToLogin())); + } + + void _goToLogin() { + Get.offNamed(AppRoutes.LOGIN); + } + + void _goToMailbox(GetCredentialViewState credentialViewState) { + _dynamicUrlInterceptors.changeBaseUrl(credentialViewState.baseUrl.origin); + _authorizationInterceptors.changeAuthorization( + credentialViewState.userName.userName, + credentialViewState.password.value, + ); + Get.offNamed(AppRoutes.MAILBOX); + } +} \ No newline at end of file diff --git a/lib/features/home/presentation/home_view.dart b/lib/features/home/presentation/home_view.dart new file mode 100644 index 000000000..488f2a0f3 --- /dev/null +++ b/lib/features/home/presentation/home_view.dart @@ -0,0 +1,26 @@ +import 'package:core/core.dart'; +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/features/home/presentation/home_controller.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class HomeView extends GetWidget { + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: AppColor.primaryColor, + body: SafeArea( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(AppLocalizations.of(context).initializing_data, style: TextStyle(color: Colors.white, fontSize: 17)), + ], + ), + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb new file mode 100644 index 000000000..1c996fae4 --- /dev/null +++ b/lib/l10n/intl_en.arb @@ -0,0 +1,63 @@ +{ + "@@last_modified": "2021-07-01T16:29:46.979874", + "initializing_data": "Initializing data...", + "@initializing_data": { + "type": "text", + "placeholders": {} + }, + "login_text_slogan": "TMail", + "@login_text_slogan": { + "type": "text", + "placeholders": {} + }, + "prefix_https": "https://", + "@prefix_https": { + "type": "text", + "placeholders": {} + }, + "username": "username", + "@username": { + "type": "text", + "placeholders": {} + }, + "password": "password", + "@password": { + "type": "text", + "placeholders": {} + }, + "login": "Login", + "@login": { + "type": "text", + "placeholders": {} + }, + "login_text_login_to_continue": "Please login to continue", + "@login_text_login_to_continue": { + "type": "text", + "placeholders": {} + }, + "unknown_error_login_message": "Unknown error occurred, please try again", + "@unknown_error_login_message": { + "type": "text", + "placeholders": {} + }, + "search_folder": "Search folder", + "@search_folder": { + "type": "text", + "placeholders": {} + }, + "storage": "STORAGE", + "@storage": { + "type": "text", + "placeholders": {} + }, + "my_folders": "MY FOLDERS", + "@my_folders": { + "type": "text", + "placeholders": {} + }, + "new_folder": "New folder", + "@new_folder": { + "type": "text", + "placeholders": {} + } +} \ No newline at end of file diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb new file mode 100644 index 000000000..1c996fae4 --- /dev/null +++ b/lib/l10n/intl_fr.arb @@ -0,0 +1,63 @@ +{ + "@@last_modified": "2021-07-01T16:29:46.979874", + "initializing_data": "Initializing data...", + "@initializing_data": { + "type": "text", + "placeholders": {} + }, + "login_text_slogan": "TMail", + "@login_text_slogan": { + "type": "text", + "placeholders": {} + }, + "prefix_https": "https://", + "@prefix_https": { + "type": "text", + "placeholders": {} + }, + "username": "username", + "@username": { + "type": "text", + "placeholders": {} + }, + "password": "password", + "@password": { + "type": "text", + "placeholders": {} + }, + "login": "Login", + "@login": { + "type": "text", + "placeholders": {} + }, + "login_text_login_to_continue": "Please login to continue", + "@login_text_login_to_continue": { + "type": "text", + "placeholders": {} + }, + "unknown_error_login_message": "Unknown error occurred, please try again", + "@unknown_error_login_message": { + "type": "text", + "placeholders": {} + }, + "search_folder": "Search folder", + "@search_folder": { + "type": "text", + "placeholders": {} + }, + "storage": "STORAGE", + "@storage": { + "type": "text", + "placeholders": {} + }, + "my_folders": "MY FOLDERS", + "@my_folders": { + "type": "text", + "placeholders": {} + }, + "new_folder": "New folder", + "@new_folder": { + "type": "text", + "placeholders": {} + } +} \ No newline at end of file diff --git a/lib/l10n/intl_messages.arb b/lib/l10n/intl_messages.arb new file mode 100644 index 000000000..42bf1a0dd --- /dev/null +++ b/lib/l10n/intl_messages.arb @@ -0,0 +1,63 @@ +{ + "@@last_modified": "2021-07-23T09:09:13.997889", + "initializing_data": "Initializing data...", + "@initializing_data": { + "type": "text", + "placeholders": {} + }, + "login_text_slogan": "TMail", + "@login_text_slogan": { + "type": "text", + "placeholders": {} + }, + "prefix_https": "https://", + "@prefix_https": { + "type": "text", + "placeholders": {} + }, + "username": "username", + "@username": { + "type": "text", + "placeholders": {} + }, + "password": "password", + "@password": { + "type": "text", + "placeholders": {} + }, + "login": "Login", + "@login": { + "type": "text", + "placeholders": {} + }, + "login_text_login_to_continue": "Please login to continue", + "@login_text_login_to_continue": { + "type": "text", + "placeholders": {} + }, + "unknown_error_login_message": "Unknown error occurred, please try again", + "@unknown_error_login_message": { + "type": "text", + "placeholders": {} + }, + "search_folder": "Search folder", + "@search_folder": { + "type": "text", + "placeholders": {} + }, + "storage": "STORAGE", + "@storage": { + "type": "text", + "placeholders": {} + }, + "my_folders": "MY FOLDERS", + "@my_folders": { + "type": "text", + "placeholders": {} + }, + "new_folder": "New folder", + "@new_folder": { + "type": "text", + "placeholders": {} + } +} \ No newline at end of file diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb new file mode 100644 index 000000000..1c996fae4 --- /dev/null +++ b/lib/l10n/intl_ru.arb @@ -0,0 +1,63 @@ +{ + "@@last_modified": "2021-07-01T16:29:46.979874", + "initializing_data": "Initializing data...", + "@initializing_data": { + "type": "text", + "placeholders": {} + }, + "login_text_slogan": "TMail", + "@login_text_slogan": { + "type": "text", + "placeholders": {} + }, + "prefix_https": "https://", + "@prefix_https": { + "type": "text", + "placeholders": {} + }, + "username": "username", + "@username": { + "type": "text", + "placeholders": {} + }, + "password": "password", + "@password": { + "type": "text", + "placeholders": {} + }, + "login": "Login", + "@login": { + "type": "text", + "placeholders": {} + }, + "login_text_login_to_continue": "Please login to continue", + "@login_text_login_to_continue": { + "type": "text", + "placeholders": {} + }, + "unknown_error_login_message": "Unknown error occurred, please try again", + "@unknown_error_login_message": { + "type": "text", + "placeholders": {} + }, + "search_folder": "Search folder", + "@search_folder": { + "type": "text", + "placeholders": {} + }, + "storage": "STORAGE", + "@storage": { + "type": "text", + "placeholders": {} + }, + "my_folders": "MY FOLDERS", + "@my_folders": { + "type": "text", + "placeholders": {} + }, + "new_folder": "New folder", + "@new_folder": { + "type": "text", + "placeholders": {} + } +} \ No newline at end of file diff --git a/lib/l10n/intl_vi.arb b/lib/l10n/intl_vi.arb new file mode 100644 index 000000000..1c996fae4 --- /dev/null +++ b/lib/l10n/intl_vi.arb @@ -0,0 +1,63 @@ +{ + "@@last_modified": "2021-07-01T16:29:46.979874", + "initializing_data": "Initializing data...", + "@initializing_data": { + "type": "text", + "placeholders": {} + }, + "login_text_slogan": "TMail", + "@login_text_slogan": { + "type": "text", + "placeholders": {} + }, + "prefix_https": "https://", + "@prefix_https": { + "type": "text", + "placeholders": {} + }, + "username": "username", + "@username": { + "type": "text", + "placeholders": {} + }, + "password": "password", + "@password": { + "type": "text", + "placeholders": {} + }, + "login": "Login", + "@login": { + "type": "text", + "placeholders": {} + }, + "login_text_login_to_continue": "Please login to continue", + "@login_text_login_to_continue": { + "type": "text", + "placeholders": {} + }, + "unknown_error_login_message": "Unknown error occurred, please try again", + "@unknown_error_login_message": { + "type": "text", + "placeholders": {} + }, + "search_folder": "Search folder", + "@search_folder": { + "type": "text", + "placeholders": {} + }, + "storage": "STORAGE", + "@storage": { + "type": "text", + "placeholders": {} + }, + "my_folders": "MY FOLDERS", + "@my_folders": { + "type": "text", + "placeholders": {} + }, + "new_folder": "New folder", + "@new_folder": { + "type": "text", + "placeholders": {} + } +} \ No newline at end of file diff --git a/lib/main/bindings/core/core_bindings.dart b/lib/main/bindings/core/core_bindings.dart new file mode 100644 index 000000000..b02f95ff5 --- /dev/null +++ b/lib/main/bindings/core/core_bindings.dart @@ -0,0 +1,30 @@ +import 'package:core/core.dart'; +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class CoreBindings extends Bindings { + + @override + Future dependencies() async { + await _bindingSharePreference(); + _bindingAppImagePaths(); + _bindingResponsiveManager(); + _bindingKeyboardManager(); + } + + void _bindingAppImagePaths() { + Get.put(ImagePaths()); + } + + void _bindingResponsiveManager() { + Get.put(ResponsiveUtils()); + } + + Future _bindingSharePreference() async { + await Get.putAsync(() async => await SharedPreferences.getInstance(), permanent: true); + } + + void _bindingKeyboardManager() { + Get.put(KeyboardUtils()); + } +} \ No newline at end of file diff --git a/lib/main/bindings/main_bindings.dart b/lib/main/bindings/main_bindings.dart new file mode 100644 index 000000000..b5e4c3056 --- /dev/null +++ b/lib/main/bindings/main_bindings.dart @@ -0,0 +1,11 @@ +import 'package:get/get.dart'; +import 'package:tmail_ui_user/main/bindings/core/core_bindings.dart'; +import 'package:tmail_ui_user/main/bindings/network/network_bindings.dart'; + +class MainBindings extends Bindings { + @override + Future dependencies() async { + await CoreBindings().dependencies(); + NetworkBindings().dependencies(); + } +} \ No newline at end of file diff --git a/lib/main/bindings/network/network_bindings.dart b/lib/main/bindings/network/network_bindings.dart new file mode 100644 index 000000000..b58dc7911 --- /dev/null +++ b/lib/main/bindings/network/network_bindings.dart @@ -0,0 +1,49 @@ +import 'dart:io'; + +import 'package:core/core.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:get/get.dart'; +import 'package:jmap_dart_client/http/http_client.dart' as JmapHttpClient; +import 'package:tmail_ui_user/features/login/data/network/login_api.dart'; +import 'package:tmail_ui_user/features/mailbox/data/network/mailbox_api.dart'; + +class NetworkBindings extends Bindings { + + @override + void dependencies() { + _bindingDio(); + _bindingApi(); + } + + void _bindingBaseOption() { + final headers = { + HttpHeaders.acceptHeader: Constant.acceptHeaderDefault, + HttpHeaders.contentTypeHeader: Constant.contentTypeHeaderDefault + }; + Get.put(BaseOptions(headers: headers)); + } + + void _bindingDio() { + _bindingBaseOption(); + Get.put(Dio(Get.find())); + _bindingInterceptors(); + Get.find().interceptors.add(Get.find()); + Get.find().interceptors.add(Get.find()); + if (kDebugMode) { + Get.find().interceptors.add(LogInterceptor(requestBody: true)); + } + } + + void _bindingInterceptors() { + Get.put(DynamicUrlInterceptors()); + Get.put(AuthorizationInterceptors()); + } + + void _bindingApi() { + Get.put(DioClient(Get.find())); + Get.put(JmapHttpClient.HttpClient(Get.find())); + Get.put(LoginAPI(Get.find())); + Get.put(MailboxAPI(Get.find())); + } +} \ No newline at end of file diff --git a/lib/main/localizations/app_localizations.dart b/lib/main/localizations/app_localizations.dart new file mode 100644 index 000000000..60df7edea --- /dev/null +++ b/lib/main/localizations/app_localizations.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:tmail_ui_user/l10n/messages_all.dart'; + +class AppLocalizations { + + static AppLocalizations of(BuildContext context) { + return Localizations.of(context, AppLocalizations)!; + } + + static Future load(Locale locale) async { + final name = locale.countryCode == null ? locale.languageCode : locale.toString(); + + final localeName = Intl.canonicalizedLocale(name); + + return initializeMessages(localeName).then((_) { + Intl.defaultLocale = localeName; + return AppLocalizations(); + }); + } + + String get initializing_data { + return Intl.message('Initializing data...', + name: 'initializing_data'); + } + + String get login_text_slogan { + return Intl.message('TMail', + name: 'login_text_slogan'); + } + + String get prefix_https { + return Intl.message('https://', + name: 'prefix_https'); + } + + String get username { + return Intl.message('username', + name: 'username'); + } + + String get password { + return Intl.message('password', + name: 'password'); + } + + String get login { + return Intl.message('Login', + name: 'login'); + } + + String get login_text_login_to_continue { + return Intl.message('Please login to continue', + name: 'login_text_login_to_continue'); + } + + String get unknown_error_login_message { + return Intl.message('Unknown error occurred, please try again', + name: 'unknown_error_login_message'); + } + + String get search_folder { + return Intl.message( + 'Search folder', + name: 'search_folder', + ); + } + + String get storage { + return Intl.message( + 'STORAGE', + name: 'storage', + ); + } + + String get my_folders { + return Intl.message( + 'MY FOLDERS', + name: 'my_folders', + ); + } + + String get new_folder { + return Intl.message( + 'New folder', + name: 'new_folder', + ); + } +} + diff --git a/lib/main/localizations/app_localizations_delegate.dart b/lib/main/localizations/app_localizations_delegate.dart new file mode 100644 index 000000000..dcb388941 --- /dev/null +++ b/lib/main/localizations/app_localizations_delegate.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations.dart'; + +class AppLocalizationsDelegate extends LocalizationsDelegate { + const AppLocalizationsDelegate(); + + @override + bool isSupported(Locale locale) { + return ['en', 'vi', 'fr', 'ru'].contains(locale.languageCode); + } + + @override + Future load(Locale locale) async { + return AppLocalizations.load(locale); + } + + @override + bool shouldReload(covariant LocalizationsDelegate old) => false; +} \ No newline at end of file diff --git a/lib/main/main.dart b/lib/main/main.dart new file mode 100644 index 000000000..bcd768ad8 --- /dev/null +++ b/lib/main/main.dart @@ -0,0 +1,46 @@ +import 'package:core/core.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:get/get.dart'; +import 'package:tmail_ui_user/main/bindings/main_bindings.dart'; +import 'package:tmail_ui_user/main/localizations/app_localizations_delegate.dart'; +import 'package:tmail_ui_user/main/pages/app_pages.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; + +void main() async { + WidgetsFlutterBinding.ensureInitialized(); + await MainBindings().dependencies(); + runApp(TMailApp()); +} + +class TMailApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return GetMaterialApp( + debugShowCheckedModeBanner: false, + theme: appTheme(), + supportedLocales: [ + Locale('en'), + Locale('vi'), + Locale('ru'), + Locale('fr') + ], + localizationsDelegates: [ + AppLocalizationsDelegate(), + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + localeResolutionCallback: (deviceLocale, supportedLocales) { + for (var locale in supportedLocales) { + if (locale.languageCode == deviceLocale?.languageCode) { + return deviceLocale; + } + } + return supportedLocales.first; + }, + defaultTransition: Transition.fade, + initialRoute: AppRoutes.HOME, + getPages: AppPages.pages); + } +} \ No newline at end of file diff --git a/lib/main/pages/app_pages.dart b/lib/main/pages/app_pages.dart new file mode 100644 index 000000000..7eb5efc97 --- /dev/null +++ b/lib/main/pages/app_pages.dart @@ -0,0 +1,25 @@ +import 'package:get/get_navigation/src/routes/get_route.dart'; +import 'package:tmail_ui_user/features/home/presentation/home_bindings.dart'; +import 'package:tmail_ui_user/features/home/presentation/home_view.dart'; +import 'package:tmail_ui_user/features/login/presentation/login_bindings.dart'; +import 'package:tmail_ui_user/features/login/presentation/login_view.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_bindings.dart'; +import 'package:tmail_ui_user/features/mailbox/presentation/mailbox_view.dart'; +import 'package:tmail_ui_user/main/routes/app_routes.dart'; + +class AppPages { + static final pages = [ + GetPage( + name: AppRoutes.HOME, + page: () => HomeView(), + binding: HomeBindings()), + GetPage( + name: AppRoutes.LOGIN, + page: () => LoginView(), + binding: LoginBindings()), + GetPage( + name: AppRoutes.MAILBOX, + page: () => MailboxView(), + binding: MailboxBindings()), + ]; +} diff --git a/lib/main/routes/app_routes.dart b/lib/main/routes/app_routes.dart new file mode 100644 index 000000000..988ac9785 --- /dev/null +++ b/lib/main/routes/app_routes.dart @@ -0,0 +1,5 @@ +abstract class AppRoutes { + static const HOME = '/'; + static const LOGIN = '/login'; + static const MAILBOX = '/mailbox'; +} \ No newline at end of file