diff --git a/lib/application/bindings/application_bindings.dart b/lib/application/bindings/application_bindings.dart new file mode 100644 index 0000000..d416023 --- /dev/null +++ b/lib/application/bindings/application_bindings.dart @@ -0,0 +1,22 @@ +import 'package:get/get.dart'; + +import 'package:app_filmes/repositories/login/login_repository_impl.dart'; +import 'package:app_filmes/repositories/login/login_repository.dart'; +import 'package:app_filmes/services/login/login_service.dart'; +import 'package:app_filmes/services/login/login_service_impl.dart'; + +class ApplicationBindings implements Bindings { + @override + void dependencies() { + Get.lazyPut( + () => LoginRepositoryImpl(), + fenix: true, + ); + Get.lazyPut( + () => LoginServiceImpl( + loginRepository: Get.find(), + ), + fenix: true, + ); + } +} diff --git a/lib/application/ui/loader/loader_mixin.dart b/lib/application/ui/loader/loader_mixin.dart new file mode 100644 index 0000000..3214923 --- /dev/null +++ b/lib/application/ui/loader/loader_mixin.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; + +mixin LoaderMixin on GetxController { + void loaderListener(RxBool loaderRx) { + ever( + loaderRx, + (loading) async { + if (loading) { + await Get.dialog( + const Center( + child: CircularProgressIndicator(), + ), + barrierDismissible: false, + ); + } else { + Get.back(); + } + }, + ); + } +} diff --git a/lib/application/ui/messages/messages_mixin.dart b/lib/application/ui/messages/messages_mixin.dart new file mode 100644 index 0000000..ec7f137 --- /dev/null +++ b/lib/application/ui/messages/messages_mixin.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; + +import 'package:get/get.dart'; + +mixin MessagesMixin on GetxController { + void messageListener(Rxn message) { + ever( + message, + (model) { + if (model != null) { + Get.snackbar( + model.title, + model.message, + backgroundColor: model.type.color(), + ); + } + }, + ); + } +} + +class MessageModel { + final String title; + final String message; + final MessageType type; + + MessageModel({ + required this.title, + required this.message, + required this.type, + }); + + MessageModel.error({ + required this.title, + required this.message, + }) : type = MessageType.error; + + MessageModel.info({ + required this.title, + required this.message, + }) : type = MessageType.info; +} + +enum MessageType { + error, + info, +} + +extension MessageTypeExtension on MessageType { + Color color() { + switch (this) { + case MessageType.error: + return Colors.red[600] ?? Colors.red; + case MessageType.info: + return Colors.blue[200] ?? Colors.blue; + } + } +} diff --git a/lib/main.dart b/lib/main.dart index 4152e88..d35a3b5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -4,6 +4,8 @@ import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_remote_config/firebase_remote_config.dart'; import 'package:get/get.dart'; +import 'application/bindings/application_bindings.dart'; +import 'modules/login/login_module.dart'; import 'modules/splash/splash_module.dart'; Future main() async { @@ -26,8 +28,10 @@ class MyApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, ), + initialBinding: ApplicationBindings(), getPages: [ ...SplashModule().routers, + ...LoginModule().routers, ], ); } diff --git a/lib/modules/login/login_bindings.dart b/lib/modules/login/login_bindings.dart new file mode 100644 index 0000000..c8bf16c --- /dev/null +++ b/lib/modules/login/login_bindings.dart @@ -0,0 +1,14 @@ +import 'package:get/get.dart'; + +import 'login_controller.dart'; + +class LoginBindings implements Bindings { + @override + void dependencies() { + Get.lazyPut( + () => LoginController( + loginService: Get.find(), + ), + ); + } +} diff --git a/lib/modules/login/login_controller.dart b/lib/modules/login/login_controller.dart new file mode 100644 index 0000000..5315774 --- /dev/null +++ b/lib/modules/login/login_controller.dart @@ -0,0 +1,44 @@ +import 'package:get/get.dart'; + +import 'package:app_filmes/services/login/login_service.dart'; +import 'package:app_filmes/application/ui/loader/loader_mixin.dart'; +import 'package:app_filmes/application/ui/messages/messages_mixin.dart'; + +class LoginController extends GetxController with LoaderMixin, MessagesMixin { + final LoginService _loginService; + final loading = false.obs; + final message = Rxn(); + + LoginController({ + required LoginService loginService, + }) : _loginService = loginService; + + @override + void onInit() { + super.onInit(); + loaderListener(loading); + messageListener(message); + } + + Future login() async { + try { + loading(true); + await _loginService.login(); + loading(false); + message( + MessageModel.info( + title: 'Success', + message: 'Login with Success', + ), + ); + } catch (e, s) { + print(e); + print(s); + loading(false); + MessageModel.error( + title: 'Error', + message: 'Login with Error', + ); + } + } +} diff --git a/lib/modules/login/login_module.dart b/lib/modules/login/login_module.dart new file mode 100644 index 0000000..eef1335 --- /dev/null +++ b/lib/modules/login/login_module.dart @@ -0,0 +1,16 @@ +import 'package:get/get.dart'; + +import 'package:app_filmes/application/modules/module.dart'; +import 'login_bindings.dart'; +import 'login_page.dart'; + +class LoginModule implements Module { + @override + List routers = [ + GetPage( + name: '/login', + page: () => const LoginPage(), + binding: LoginBindings(), + ) + ]; +} diff --git a/lib/modules/login/login_page.dart b/lib/modules/login/login_page.dart new file mode 100644 index 0000000..4122007 --- /dev/null +++ b/lib/modules/login/login_page.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_signin_button/flutter_signin_button.dart'; +import 'package:get/get.dart'; + +import 'login_controller.dart'; + +class LoginPage extends GetView { + const LoginPage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + alignment: Alignment.topCenter, + children: [ + Image.asset( + 'assets/images/background.png', + width: Get.width, + height: Get.height, + fit: BoxFit.cover, + ), + Container(color: Colors.black45), + Padding( + padding: const EdgeInsets.only(top: 80), + child: Column( + children: [ + Image.asset('assets/images/logo.png'), + const SizedBox(height: 50), + SizedBox( + width: Get.width * .9, + height: 42, + child: SignInButton( + Buttons.Google, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + text: 'Entrar com o Google', + onPressed: () => controller.login(), + ), + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/modules/splash/splash_bindings.dart b/lib/modules/splash/splash_bindings.dart new file mode 100644 index 0000000..97117e6 --- /dev/null +++ b/lib/modules/splash/splash_bindings.dart @@ -0,0 +1,12 @@ +import 'package:get/get.dart'; + +import 'splash_controller.dart'; + +class SplashBindings implements Bindings { + @override + void dependencies() { + Get.put( + SplashController(), + ); + } +} diff --git a/lib/modules/splash/splash_controller.dart b/lib/modules/splash/splash_controller.dart index 7144dc9..fd94481 100644 --- a/lib/modules/splash/splash_controller.dart +++ b/lib/modules/splash/splash_controller.dart @@ -1,3 +1,9 @@ import 'package:get/get.dart'; -class SplashController extends GetxController {} \ No newline at end of file +class SplashController extends GetxController { + @override + void onReady() { + super.onReady(); + Get.offAllNamed('/login'); + } +} diff --git a/lib/modules/splash/splash_module.dart b/lib/modules/splash/splash_module.dart index a471760..7a4f351 100644 --- a/lib/modules/splash/splash_module.dart +++ b/lib/modules/splash/splash_module.dart @@ -1,6 +1,7 @@ import 'package:get/get.dart'; import 'package:app_filmes/application/modules/module.dart'; +import 'splash_bindings.dart'; import 'splash_page.dart'; class SplashModule implements Module { @@ -9,6 +10,7 @@ class SplashModule implements Module { GetPage( name: '/', page: () => const SplashPage(), + binding: SplashBindings(), ), ]; } diff --git a/lib/repositories/login/login_repository.dart b/lib/repositories/login/login_repository.dart new file mode 100644 index 0000000..45de606 --- /dev/null +++ b/lib/repositories/login/login_repository.dart @@ -0,0 +1,5 @@ +import 'package:firebase_auth/firebase_auth.dart'; + +abstract class LoginRepository { + Future login(); +} diff --git a/lib/repositories/login/login_repository_impl.dart b/lib/repositories/login/login_repository_impl.dart new file mode 100644 index 0000000..cd8d3ec --- /dev/null +++ b/lib/repositories/login/login_repository_impl.dart @@ -0,0 +1,22 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:google_sign_in/google_sign_in.dart'; + +import 'login_repository.dart'; + +class LoginRepositoryImpl implements LoginRepository { + @override + // ignore: override_on_non_overriding_member + Future login() async { + final googleUser = await GoogleSignIn().signIn(); + final googleAuth = await googleUser?.authentication; + + if (googleAuth != null) { + final credential = GoogleAuthProvider.credential( + accessToken: googleAuth.accessToken, + idToken: googleAuth.idToken, + ); + return FirebaseAuth.instance.signInWithCredential(credential); + } + throw Exception('Erro ao realizar login com Google'); + } +} diff --git a/lib/services/login/login_service.dart b/lib/services/login/login_service.dart new file mode 100644 index 0000000..dae78f1 --- /dev/null +++ b/lib/services/login/login_service.dart @@ -0,0 +1,5 @@ +import 'package:firebase_auth/firebase_auth.dart'; + +abstract class LoginService { + Future login(); +} diff --git a/lib/services/login/login_service_impl.dart b/lib/services/login/login_service_impl.dart new file mode 100644 index 0000000..6c23252 --- /dev/null +++ b/lib/services/login/login_service_impl.dart @@ -0,0 +1,15 @@ +import 'package:firebase_auth/firebase_auth.dart'; + +import 'package:app_filmes/repositories/login/login_repository.dart'; +import 'login_service.dart'; + +class LoginServiceImpl implements LoginService { + final LoginRepository _loginRepository; + + LoginServiceImpl({ + required LoginRepository loginRepository, + }) : _loginRepository = loginRepository; + + @override + Future login() => _loginRepository.login(); +} diff --git a/pubspec.lock b/pubspec.lock index 1cdcc20..4e73314 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -125,6 +125,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.4" + flutter_signin_button: + dependency: "direct main" + description: + name: flutter_signin_button + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -135,6 +142,13 @@ packages: description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: transitive + description: + name: font_awesome_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "9.1.0" get: dependency: "direct main" description: @@ -144,6 +158,27 @@ packages: url: "git@github.com:jonataslaw/getx.git" source: git version: "4.3.8" + google_sign_in: + dependency: "direct main" + description: + name: google_sign_in + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.0" + google_sign_in_platform_interface: + dependency: transitive + description: + name: google_sign_in_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + google_sign_in_web: + dependency: transitive + description: + name: google_sign_in_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.0+2" http_parser: dependency: transitive description: @@ -200,6 +235,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" sky_engine: dependency: transitive description: flutter @@ -263,4 +305,4 @@ packages: version: "2.1.0" sdks: dart: ">=2.12.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5" + flutter: ">=2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index e54bca0..a6d8097 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,8 +13,10 @@ dependencies: firebase_remote_config: ^0.10.0+5 flutter: sdk: flutter + flutter_signin_button: ^2.0.0 get: git: git@github.com:jonataslaw/getx.git + google_sign_in: ^5.1.0 dev_dependencies: flutter_lints: ^1.0.0 @@ -23,5 +25,5 @@ dev_dependencies: flutter: uses-material-design: true - assets: + assets: - assets/images/