diff --git a/README.md b/README.md index 6f55b12..d9e5d75 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,3 @@ # video_calling_app -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +A new video calling mobile application using Flutter, Agora SDK and GetX state management. diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro deleted file mode 100644 index 5aad577..0000000 --- a/android/app/proguard-rules.pro +++ /dev/null @@ -1,8 +0,0 @@ -## Flutter wrapper --keep class io.flutter.app.** { *; } --keep class io.flutter.plugin.** { *; } --keep class io.flutter.util.** { *; } --keep class io.flutter.view.** { *; } --keep class io.flutter.** { *; } --keep class io.flutter.plugins.** { *; } --dontwarn io.flutter.embedding.** diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 4d9252f..0f9ea7f 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -16,7 +16,7 @@ tools:ignore="ProtectedPermissions" /> - + \ No newline at end of file diff --git a/lib/common/count_widget.dart b/lib/common/count_widget.dart deleted file mode 100644 index 2f176f5..0000000 --- a/lib/common/count_widget.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:video_calling_app/constants/colors.dart'; -import 'package:video_calling_app/constants/dimens.dart'; -import 'package:video_calling_app/constants/styles.dart'; - -class NxCountWidget extends StatelessWidget { - const NxCountWidget({ - Key? key, - required this.title, - required this.value, - this.bgColor, - this.padding, - this.borderRadius, - this.onTap, - }) : super(key: key); - - final String title; - final String value; - final Color? bgColor; - final EdgeInsets? padding; - final double? borderRadius; - final VoidCallback? onTap; - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - child: Container( - padding: padding ?? Dimens.edgeInsets4, - decoration: BoxDecoration( - color: bgColor ?? Colors.transparent, - borderRadius: BorderRadius.circular(borderRadius ?? Dimens.four), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - value, - style: AppStyles.style16Bold, - ), - Text( - title, - style: const TextStyle(color: ColorValues.grayColor), - ), - ], - ), - ), - ); - } -} diff --git a/lib/common/custom_app_bar.dart b/lib/common/custom_app_bar.dart index 2e24231..533c026 100644 --- a/lib/common/custom_app_bar.dart +++ b/lib/common/custom_app_bar.dart @@ -38,7 +38,7 @@ class NxAppBar extends StatelessWidget { InkWell( onTap: RouteManagement.goToBack, child: CircleAvatar( - backgroundColor: Theme.of(context).dividerColor, + backgroundColor: ColorValues.primaryColor, radius: Dimens.fourteen, child: Icon( CupertinoIcons.left_chevron, diff --git a/lib/common/custom_list_tile.dart b/lib/common/custom_list_tile.dart deleted file mode 100644 index c6f83ce..0000000 --- a/lib/common/custom_list_tile.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:video_calling_app/constants/dimens.dart'; - -class NxListTile extends StatelessWidget { - const NxListTile({ - Key? key, - this.leading, - this.title, - this.subtitle, - this.padding, - this.bgColor, - this.onTap, - this.onLongPressed, - }) : super(key: key); - - final Widget? leading; - final Widget? title; - final Widget? subtitle; - final EdgeInsets? padding; - final Color? bgColor; - final VoidCallback? onTap; - final VoidCallback? onLongPressed; - - @override - Widget build(BuildContext context) { - return InkWell( - onTap: onTap, - onLongPress: onLongPressed, - child: Container( - color: bgColor ?? Colors.transparent, - padding: padding ?? Dimens.edgeInsets0, - width: double.infinity, - constraints: BoxConstraints( - maxWidth: Dimens.screenWidth, - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (leading != null) leading!, - if (title != null || subtitle != null) Dimens.boxWidth16, - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - if (title != null) title!, - if (subtitle != null) Dimens.boxHeight4, - if (subtitle != null) subtitle! - ], - ), - ) - ], - ), - ), - ); - } -} diff --git a/lib/common/elevated_card.dart b/lib/common/elevated_card.dart deleted file mode 100644 index d6cd937..0000000 --- a/lib/common/elevated_card.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:video_calling_app/constants/dimens.dart'; - -class NxElevatedCard extends StatelessWidget { - const NxElevatedCard({ - Key? key, - required this.child, - this.borderRadius, - this.padding, - this.margin, - this.elevation, - this.bgColor, - this.shadowColor, - }) : super(key: key); - - final Widget child; - final double? borderRadius; - final EdgeInsets? padding; - final EdgeInsets? margin; - final double? elevation; - final Color? bgColor; - final Color? shadowColor; - - @override - Widget build(BuildContext context) { - return Card( - margin: margin ?? Dimens.edgeInsets8, - elevation: elevation ?? Dimens.zero, - color: bgColor ?? Theme.of(context).cardTheme.color, - shadowColor: shadowColor ?? Theme.of(context).cardTheme.shadowColor, - clipBehavior: Clip.none, - child: Padding( - padding: padding ?? Dimens.edgeInsets0, - child: child, - ), - ); - } -} diff --git a/lib/common/keep_alive_page.dart b/lib/common/keep_alive_page.dart deleted file mode 100644 index 5ea4463..0000000 --- a/lib/common/keep_alive_page.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -class KeepAlivePage extends StatefulWidget { - const KeepAlivePage({Key? key, required this.child}) : super(key: key); - - final Widget child; - - @override - State createState() => _KeepAlivePageState(); -} - -class _KeepAlivePageState extends State - with AutomaticKeepAliveClientMixin { - @override - Widget build(BuildContext context) { - super.build(context); - return widget.child; - } - - @override - bool get wantKeepAlive => true; -} diff --git a/lib/common/loading_indicator.dart b/lib/common/loading_indicator.dart deleted file mode 100644 index ec7f159..0000000 --- a/lib/common/loading_indicator.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'dart:math' as math; - -import 'package:flutter/material.dart'; -import 'package:video_calling_app/constants/colors.dart'; -import 'package:video_calling_app/constants/dimens.dart'; - -class NxLoadingIndicator extends StatefulWidget { - final double? size; - final Color? strokeColor; - final bool? transparentCenter; - - const NxLoadingIndicator({ - Key? key, - this.size, - this.strokeColor, - this.transparentCenter = true, - }) : super(key: key); - - @override - _NxLoadingIndicatorState createState() => _NxLoadingIndicatorState(); -} - -class _NxLoadingIndicatorState extends State - with SingleTickerProviderStateMixin { - late AnimationController _controller; - late Animation _animation; - - @override - void initState() { - super.initState(); - _controller = AnimationController( - vsync: this, - duration: const Duration(milliseconds: 1000), - ); - _animation = Tween( - begin: 1.0, - end: 1.25, - ).animate(CurvedAnimation( - parent: _controller, - curve: Curves.easeInCubic, - )); - _controller.repeat(reverse: true); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return AnimatedBuilder( - animation: _animation, - builder: (ctx, w) { - return Transform.rotate( - angle: _controller.status == AnimationStatus.forward - ? (math.pi * 2) * _controller.value - : -(math.pi * 2) * _controller.value, - child: SizedBox( - width: widget.size ?? Dimens.thirtyTwo, - height: widget.size ?? Dimens.thirtyTwo, - child: CustomPaint( - painter: LoaderCanvas( - transparentCenter: widget.transparentCenter, - radius: _animation.value, - strokeColor: - widget.strokeColor ?? Theme.of(context).colorScheme.primary, - ), - ), - ), - ); - }, - ); - } -} - -class LoaderCanvas extends CustomPainter { - final double radius; - final Color? strokeColor; - final bool? transparentCenter; - - LoaderCanvas({ - required this.radius, - required this.strokeColor, - this.transparentCenter, - }); - - @override - void paint(Canvas canvas, Size size) { - var _arc = Paint() - ..color = strokeColor! - ..style = PaintingStyle.stroke - ..strokeWidth = 2.5; - - var _circle = Paint() - ..color = transparentCenter! - ? Colors.transparent - : ColorValues.primaryColor.withOpacity(0.25) - ..style = PaintingStyle.fill; - - var _center = Offset(size.width / 2, size.height / 2); - - canvas.drawCircle(_center, size.width / 2, _circle); - - canvas.drawArc( - Rect.fromCenter( - center: _center, - width: size.width * radius, - height: size.height * radius, - ), - math.pi / 2, - math.pi / 2, - false, - _arc); - - canvas.drawArc( - Rect.fromCenter( - center: _center, - width: size.width * radius, - height: size.height * radius, - ), - -math.pi / 2, - -math.pi / 2, - false, - _arc); - } - - @override - bool shouldRepaint(LoaderCanvas oldDelegate) { - return true; - } -} diff --git a/lib/common/overlay.dart b/lib/common/overlay.dart deleted file mode 100644 index f8c4a92..0000000 --- a/lib/common/overlay.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:video_calling_app/constants/colors.dart'; -import 'package:video_calling_app/constants/dimens.dart'; - -import 'loading_indicator.dart'; - -final _tKey = GlobalKey(debugLabel: 'overlay_parent'); - -OverlayEntry? _loaderEntry; - -bool _loaderShown = false; - -class NxOverlayWidget extends StatelessWidget { - final Widget child; - - const NxOverlayWidget({ - Key? key, - required this.child, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - key: _tKey, - child: child, - ); - } -} - -OverlayState? get _overLayState { - final context = _tKey.currentContext; - if (context == null) return null; - - NavigatorState? navigatorState; - - void visitor(Element element) { - if (navigatorState != null) return; - - if (element.widget is Navigator) { - navigatorState = (element as StatefulElement).state as NavigatorState; - } else { - element.visitChildElements(visitor); - } - } - - context.visitChildElements(visitor); - - assert(navigatorState != null, '''unable to show overlay'''); - return navigatorState!.overlay; -} - -abstract class AppOverlay { - static Future showLoadingIndicator({ - bool? isModal, - Color? modalColor, - String? message, - bool? dismissible, - }) async { - try { - final _child = Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - const NxLoadingIndicator(), - if (message != null) Dimens.boxHeight8, - if (message != null) - RichText( - text: TextSpan( - text: message, - style: TextStyle( - fontSize: Dimens.sixTeen, - color: Colors.white, - ), - ), - ) - ], - ), - ); - await _showOverlay( - child: isModal ?? true - ? Stack( - children: [ - ModalBarrier( - color: modalColor ?? - ColorValues.grayColor.withOpacity(0.75).withAlpha(200), - dismissible: dismissible ?? false, - ), - _child - ], - ) - : _child, - ); - } catch (err) { - rethrow; - } - } - - static Future hideLoadingIndicator() async { - try { - await _hideOverlay(); - } catch (err) { - rethrow; - } - } - - static Future _showOverlay({required Widget child}) async { - try { - final overlay = _overLayState; - - if (_loaderShown) { - return Future.value(); - } - - final overlayEntry = OverlayEntry( - builder: (context) => child, - ); - - overlay?.insert(overlayEntry); - _loaderEntry = overlayEntry; - _loaderShown = true; - } catch (err) { - rethrow; - } - } - - static Future _hideOverlay() async { - try { - _loaderEntry!.remove(); - _loaderShown = false; - } catch (err) { - rethrow; - } - } -} diff --git a/lib/common/primary_outlined_btn.dart b/lib/common/primary_outlined_btn.dart index 4a05f31..99a0f96 100644 --- a/lib/common/primary_outlined_btn.dart +++ b/lib/common/primary_outlined_btn.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:video_calling_app/constants/colors.dart'; import 'package:video_calling_app/constants/dimens.dart'; class NxOutlinedButton extends StatelessWidget { @@ -48,7 +49,7 @@ class NxOutlinedButton extends StatelessWidget { primary: Colors.transparent, padding: padding ?? Dimens.edgeInsets8, side: BorderSide( - color: borderColor ?? Theme.of(context).iconTheme.color!, + color: borderColor ?? ColorValues.primaryColor, width: borderWidth ?? Dimens.one, style: borderStyle ?? BorderStyle.solid, ), @@ -67,8 +68,7 @@ class NxOutlinedButton extends StatelessWidget { Text( label, style: TextStyle( - color: - labelColor ?? Theme.of(context).textTheme.bodyText1!.color!, + color: labelColor ?? ColorValues.primaryColor, fontSize: fontSize ?? Dimens.fourteen, ), ), diff --git a/lib/common/sliver_app_bar.dart b/lib/common/sliver_app_bar.dart deleted file mode 100644 index 8e34090..0000000 --- a/lib/common/sliver_app_bar.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:video_calling_app/constants/dimens.dart'; - -class NxSliverAppBar extends StatelessWidget { - const NxSliverAppBar({ - Key? key, - required this.leading, - this.bgColor, - this.title, - this.actions, - this.isFloating, - this.isPinned, - this.centerTitle, - }) : super(key: key); - - final Widget leading; - final Widget? title; - final bool? centerTitle; - final Widget? actions; - final Color? bgColor; - final bool? isFloating; - final bool? isPinned; - - @override - Widget build(BuildContext context) { - return SliverAppBar( - floating: isFloating ?? true, - pinned: isPinned ?? false, - toolbarHeight: Dimens.fourty, - elevation: Dimens.zero, - backgroundColor: bgColor ?? Theme.of(context).scaffoldBackgroundColor, - flexibleSpace: Padding( - padding: Dimens.edgeInsets8, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - leading, - if (title != null) title!, - if (actions != null) actions!, - ], - ), - ), - ); - } -} diff --git a/lib/constants/colors.dart b/lib/constants/colors.dart index 96193b5..696785e 100644 --- a/lib/constants/colors.dart +++ b/lib/constants/colors.dart @@ -2,23 +2,23 @@ import 'package:flutter/material.dart'; abstract class ColorValues { static const MaterialColor primarySwatch = MaterialColor( - 0xFF2878F0, + 0xFF1ABC9C, { - 50: Color.fromRGBO(40, 120, 240, .1), - 100: Color.fromRGBO(40, 120, 240, .2), - 200: Color.fromRGBO(40, 120, 240, .3), - 300: Color.fromRGBO(40, 120, 240, .4), - 400: Color.fromRGBO(40, 120, 240, .5), - 500: Color.fromRGBO(40, 120, 240, .6), - 600: Color.fromRGBO(40, 120, 240, .7), - 700: Color.fromRGBO(40, 120, 240, .8), - 800: Color.fromRGBO(40, 120, 240, .9), - 900: Color.fromRGBO(40, 120, 240, 1), + 50: Color.fromRGBO(26, 188, 156, .1), + 100: Color.fromRGBO(26, 188, 156, .2), + 200: Color.fromRGBO(26, 188, 156, .3), + 300: Color.fromRGBO(26, 188, 156, .4), + 400: Color.fromRGBO(26, 188, 156, .5), + 500: Color.fromRGBO(26, 188, 156, .6), + 600: Color.fromRGBO(26, 188, 156, .7), + 700: Color.fromRGBO(26, 188, 156, .8), + 800: Color.fromRGBO(26, 188, 156, .9), + 900: Color.fromRGBO(26, 188, 156, 1), }, ); - static const Color primaryColor = Color(0xFF2878F0); - static const Color primaryLightColor = Color(0xFF72A3ED); + static const Color primaryColor = Color(0xFF1ABC9C); + static const Color primaryLightColor = Color(0xFF6EAFA2); static const Color primaryTextColor = Color(0xFF505050); static const Color successColor = Color(0xFF4CAF50); diff --git a/lib/constants/strings.dart b/lib/constants/strings.dart index 9fb4e34..5697a09 100644 --- a/lib/constants/strings.dart +++ b/lib/constants/strings.dart @@ -1,5 +1,5 @@ abstract class StringValues { - static const appName = 'Video Calling App'; + static const appName = 'LiveBox'; static const welcome = 'Welcome'; static const hello = 'Hello'; static const register = 'Register'; @@ -120,9 +120,7 @@ abstract class StringValues { } abstract class AssetValues { - static const String appLogo = 'assets/logo_trans.png'; - static const String appIcon = 'assets/icon_trans.png'; - static const String appName = 'assets/app_name_trans.png'; + static const String appIcon = 'assets/icon.png'; static const String avatar = 'assets/avatar.png'; static const String vector1 = 'assets/vector-1.png'; static const String error = 'assets/error.png'; diff --git a/lib/main.dart b/lib/main.dart index 21b7b1f..11c7bac 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -6,7 +6,6 @@ import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:video_calling_app/apis/services/auth_service.dart'; import 'package:video_calling_app/apis/services/theme_controller.dart'; -import 'package:video_calling_app/common/overlay.dart'; import 'package:video_calling_app/constants/colors.dart'; import 'package:video_calling_app/constants/strings.dart'; import 'package:video_calling_app/constants/themes.dart'; @@ -33,14 +32,16 @@ Future initServices() async { ..put(AuthService(), permanent: true) ..put(ProfileController(), permanent: true); - await Get.find().getToken().then((value) { + await Get.find().getToken().then((value) async { isLogin = value.isEmpty ? false : true; isLogin ? AppUtils.printLog("User is logged in.") : AppUtils.printLog("User is not logged in."); + if (isLogin) { + await Get.find().getProfileDetails(); + await Get.find().getChannelInfo(); + } }); - await Get.find().getChannelInfo(); - await Get.find().getProfileDetails(); } class MyApp extends StatelessWidget { @@ -74,20 +75,18 @@ class MyApp extends StatelessWidget { return GetBuilder( builder: (logic) => ScreenUtilInit( designSize: const Size(392, 744), - builder: (_) => NxOverlayWidget( - child: GetMaterialApp( - title: StringValues.appName, - debugShowCheckedModeBanner: false, - themeMode: logic.themeMode == StringValues.system - ? ThemeMode.system - : logic.themeMode == StringValues.dark - ? ThemeMode.dark - : ThemeMode.light, - theme: AppThemes.lightTheme, - darkTheme: AppThemes.darkTheme, - getPages: AppPages.pages, - initialRoute: isLogin ? AppRoutes.home : AppRoutes.login, - ), + builder: (_) => GetMaterialApp( + title: StringValues.appName, + debugShowCheckedModeBanner: false, + themeMode: logic.themeMode == StringValues.system + ? ThemeMode.system + : logic.themeMode == StringValues.dark + ? ThemeMode.dark + : ThemeMode.light, + theme: AppThemes.lightTheme, + darkTheme: AppThemes.darkTheme, + getPages: AppPages.pages, + initialRoute: isLogin ? AppRoutes.home : AppRoutes.login, ), ), ); diff --git a/lib/modules/auth/controllers/login_controller.dart b/lib/modules/auth/controllers/login_controller.dart index f464e02..70aae68 100644 --- a/lib/modules/auth/controllers/login_controller.dart +++ b/lib/modules/auth/controllers/login_controller.dart @@ -10,12 +10,14 @@ import 'package:video_calling_app/apis/providers/api_provider.dart'; import 'package:video_calling_app/apis/services/auth_service.dart'; import 'package:video_calling_app/constants/strings.dart'; import 'package:video_calling_app/helpers/utils.dart'; +import 'package:video_calling_app/modules/profile/controllers/profile_controller.dart'; import 'package:video_calling_app/routes/route_management.dart'; class LoginController extends GetxController { static LoginController get find => Get.find(); final _auth = AuthService.find; + final _profileController = ProfileController.find; final _apiProvider = ApiProvider(http.Client()); @@ -93,6 +95,7 @@ class LoginController extends GetxController { await AppUtils.saveChannelDataToLocalStorage(); await _auth.getChannelInfo(); + await _profileController.getProfileDetails(); AppUtils.closeDialog(); _isLoading.value = false; diff --git a/lib/modules/auth/views/forgot_password_view.dart b/lib/modules/auth/views/forgot_password_view.dart index ac78a0d..26a0536 100644 --- a/lib/modules/auth/views/forgot_password_view.dart +++ b/lib/modules/auth/views/forgot_password_view.dart @@ -26,6 +26,7 @@ class ForgotPasswordView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Dimens.boxHeight8, _buildImageHeader(), Dimens.boxHeight16, _buildForgotPasswordFields(), @@ -39,18 +40,18 @@ class ForgotPasswordView extends StatelessWidget { Widget _buildImageHeader() => Column( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ NxAssetImage( - imgAsset: AssetValues.vector1, - maxHeight: Dimens.hundred * 2.0, + imgAsset: AssetValues.appIcon, + maxHeight: Dimens.eighty, ), - Padding( - padding: Dimens.edgeInsets0_16, - child: Text( - StringValues.forgotPassword, - style: AppStyles.style24Bold, + Text( + StringValues.appName, + textAlign: TextAlign.center, + style: AppStyles.style24Bold.copyWith( + color: ColorValues.primaryColor, ), ), ], @@ -58,76 +59,98 @@ class ForgotPasswordView extends StatelessWidget { Widget _buildForgotPasswordFields() => GetBuilder( builder: (logic) => Expanded( - child: SingleChildScrollView( - child: Padding( - padding: Dimens.edgeInsets0_16, - child: FocusScope( - node: logic.focusNode, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: StringValues.email, - hintStyle: TextStyle( - color: ColorValues.grayColor, - ), - ), - keyboardType: TextInputType.emailAddress, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.emailTextController, - onEditingComplete: logic.focusNode.unfocus, - ), - Dimens.boxHeight32, - NxFilledButton( - onTap: () => logic.sendResetPasswordOTP(), - label: StringValues.getOtp, - fontSize: Dimens.sixTeen, - width: double.infinity, - ), - Dimens.boxHeight32, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, + child: Stack( + children: [ + SingleChildScrollView( + child: Padding( + padding: Dimens.edgeInsets0_8, + child: FocusScope( + node: logic.focusNode, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - StringValues.alreadyHaveOtp, - style: AppStyles.style16Normal, + StringValues.forgotPassword, + style: AppStyles.style24Bold, ), - Dimens.boxWidth4, - const NxTextButton( - label: StringValues.resetPassword, - onTap: RouteManagement.goToResetPasswordView, - ), - ], - ), - Dimens.boxHeight16, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ + Dimens.boxHeight16, Text( - StringValues.alreadyHaveAccount, - style: AppStyles.style16Normal, + 'We will send an OTP on this email address.', + style: AppStyles.style14Normal.copyWith( + color: ColorValues.darkGrayColor, + ), + ), + Dimens.boxHeight16, + TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: StringValues.email, + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), + ), + keyboardType: TextInputType.emailAddress, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.emailTextController, + onEditingComplete: logic.focusNode.unfocus, + ), + Dimens.boxHeight16, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + StringValues.alreadyHaveOtp, + style: AppStyles.style16Normal, + ), + Dimens.boxWidth4, + const NxTextButton( + label: StringValues.resetPassword, + onTap: RouteManagement.goToResetPasswordView, + ), + ], ), - Dimens.boxWidth4, - const NxTextButton( - label: StringValues.login, - onTap: RouteManagement.goToLoginView, + Dimens.boxHeight16, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + StringValues.alreadyHaveAccount, + style: AppStyles.style16Normal, + ), + Dimens.boxWidth4, + const NxTextButton( + label: StringValues.login, + onTap: RouteManagement.goToLoginView, + ), + ], ), + Dimens.boxHeight16, ], ), - Dimens.boxHeight32, - ], + ), ), ), - ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: NxFilledButton( + onTap: () => logic.sendResetPasswordOTP(), + label: StringValues.getOtp, + fontSize: Dimens.sixTeen, + borderRadius: 0.0, + ), + ), + ], ), ), ); diff --git a/lib/modules/auth/views/login_view.dart b/lib/modules/auth/views/login_view.dart index 19d7f2b..f749d2a 100644 --- a/lib/modules/auth/views/login_view.dart +++ b/lib/modules/auth/views/login_view.dart @@ -27,6 +27,7 @@ class LoginView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Dimens.boxHeight8, _buildImageHeader(), Dimens.boxHeight16, _buildLoginFields(), @@ -40,18 +41,18 @@ class LoginView extends StatelessWidget { Widget _buildImageHeader() => Column( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ NxAssetImage( - imgAsset: AssetValues.vector1, - maxHeight: Dimens.hundred * 2.0, + imgAsset: AssetValues.appIcon, + maxHeight: Dimens.eighty, ), - Padding( - padding: Dimens.edgeInsets0_16, - child: Text( - StringValues.login, - style: AppStyles.style24Bold, + Text( + StringValues.appName, + textAlign: TextAlign.center, + style: AppStyles.style24Bold.copyWith( + color: ColorValues.primaryColor, ), ), ], @@ -59,92 +60,109 @@ class LoginView extends StatelessWidget { Widget _buildLoginFields() => GetBuilder( builder: (logic) => Expanded( - child: SingleChildScrollView( - child: Padding( - padding: Dimens.edgeInsets0_16, - child: FocusScope( - node: logic.focusNode, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: StringValues.email, - hintStyle: TextStyle( - color: ColorValues.grayColor, + child: Stack( + children: [ + SingleChildScrollView( + child: Padding( + padding: Dimens.edgeInsets0_8, + child: FocusScope( + node: logic.focusNode, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + StringValues.login, + style: AppStyles.style24Bold, ), - ), - keyboardType: TextInputType.emailAddress, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.emailTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight24, - TextFormField( - obscureText: logic.showPassword, - decoration: InputDecoration( - border: const OutlineInputBorder(), - suffixIcon: InkWell( - onTap: logic.toggleViewPassword, - child: Icon( - logic.showPassword - ? CupertinoIcons.eye - : CupertinoIcons.eye_slash, + Dimens.boxHeight16, + TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: StringValues.email, + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), ), + keyboardType: TextInputType.emailAddress, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.emailTextController, + onEditingComplete: logic.focusNode.nextFocus, ), - hintText: StringValues.password, - hintStyle: const TextStyle( - color: ColorValues.grayColor, - ), - ), - keyboardType: TextInputType.visiblePassword, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.passwordTextController, - onEditingComplete: logic.focusNode.unfocus, - ), - Dimens.boxHeight32, - const NxTextButton( - label: StringValues.forgotPassword, - onTap: RouteManagement.goToForgotPasswordView, - ), - Dimens.boxHeight32, - NxFilledButton( - onTap: () => logic.login(), - label: StringValues.login, - fontSize: Dimens.sixTeen, - width: double.infinity, - ), - Dimens.boxHeight32, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - StringValues.doNotHaveAccount, - style: AppStyles.style16Normal, + Dimens.boxHeight24, + TextFormField( + obscureText: logic.showPassword, + decoration: InputDecoration( + border: const OutlineInputBorder(), + suffixIcon: InkWell( + onTap: logic.toggleViewPassword, + child: Icon( + logic.showPassword + ? CupertinoIcons.eye + : CupertinoIcons.eye_slash, + ), + ), + hintText: StringValues.password, + hintStyle: const TextStyle( + color: ColorValues.grayColor, + ), + ), + keyboardType: TextInputType.visiblePassword, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.passwordTextController, + onEditingComplete: logic.focusNode.unfocus, ), - Dimens.boxWidth4, + Dimens.boxHeight16, const NxTextButton( - label: StringValues.register, - onTap: RouteManagement.goToRegisterView, + label: StringValues.forgotPassword, + onTap: RouteManagement.goToForgotPasswordView, ), + Dimens.boxHeight16, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + StringValues.doNotHaveAccount, + style: AppStyles.style16Normal, + ), + Dimens.boxWidth4, + const NxTextButton( + label: StringValues.register, + onTap: RouteManagement.goToRegisterView, + ), + ], + ), + Dimens.boxHeight16, ], ), - Dimens.boxHeight32, - ], + ), ), ), - ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: NxFilledButton( + onTap: () => logic.login(), + label: StringValues.login, + fontSize: Dimens.sixTeen, + borderRadius: 0.0, + ), + ), + ], ), ), ); diff --git a/lib/modules/auth/views/register_view.dart b/lib/modules/auth/views/register_view.dart index c10d3b9..5d11a2d 100644 --- a/lib/modules/auth/views/register_view.dart +++ b/lib/modules/auth/views/register_view.dart @@ -27,6 +27,7 @@ class RegisterView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Dimens.boxHeight8, _buildImageHeader(), Dimens.boxHeight16, _buildRegistrationFields(), @@ -40,18 +41,18 @@ class RegisterView extends StatelessWidget { Widget _buildImageHeader() => Column( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ NxAssetImage( - imgAsset: AssetValues.vector1, - maxHeight: Dimens.hundred * 2.0, + imgAsset: AssetValues.appIcon, + maxHeight: Dimens.eighty, ), - Padding( - padding: Dimens.edgeInsets0_16, - child: Text( - StringValues.register, - style: AppStyles.style24Bold, + Text( + StringValues.appName, + textAlign: TextAlign.center, + style: AppStyles.style24Bold.copyWith( + color: ColorValues.primaryColor, ), ), ], @@ -59,169 +60,202 @@ class RegisterView extends StatelessWidget { Widget _buildRegistrationFields() => GetBuilder( builder: (logic) => Expanded( - child: SingleChildScrollView( - child: Padding( - padding: Dimens.edgeInsets0_16, - child: FocusScope( - node: logic.focusNode, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintStyle: TextStyle( - color: ColorValues.grayColor, - ), - hintText: StringValues.firstName, - ), - keyboardType: TextInputType.name, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.fNameTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight24, - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintStyle: TextStyle( - color: ColorValues.grayColor, - ), - hintText: StringValues.lastName, - ), - keyboardType: TextInputType.name, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.lNameTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight24, - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: StringValues.email, - hintStyle: TextStyle( - color: ColorValues.grayColor, - ), - ), - keyboardType: TextInputType.emailAddress, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.emailTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight24, - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintStyle: TextStyle( - color: ColorValues.grayColor, + child: Stack( + children: [ + SingleChildScrollView( + child: Padding( + padding: Dimens.edgeInsets0_8, + child: FocusScope( + node: logic.focusNode, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + StringValues.register, + style: AppStyles.style24Bold, ), - hintText: StringValues.username, - ), - keyboardType: TextInputType.text, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.unameTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight16, - TextFormField( - obscureText: logic.showPassword, - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintStyle: const TextStyle( - color: ColorValues.grayColor, + Dimens.boxHeight16, + Row( + children: [ + Expanded( + child: TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.firstName, + ), + keyboardType: TextInputType.name, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.fNameTextController, + onEditingComplete: logic.focusNode.nextFocus, + ), + ), + Dimens.boxWidth8, + Expanded( + child: TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.lastName, + ), + keyboardType: TextInputType.name, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.lNameTextController, + onEditingComplete: logic.focusNode.nextFocus, + ), + ), + ], ), - hintText: StringValues.password, - suffixIcon: InkWell( - onTap: logic.toggleViewPassword, - child: Icon( - logic.showPassword - ? CupertinoIcons.eye - : CupertinoIcons.eye_slash, + Dimens.boxHeight24, + TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: StringValues.email, + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), ), + keyboardType: TextInputType.emailAddress, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.emailTextController, + onEditingComplete: logic.focusNode.nextFocus, ), - ), - keyboardType: TextInputType.visiblePassword, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.passwordTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight16, - TextFormField( - obscureText: logic.showPassword, - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintStyle: const TextStyle( - color: ColorValues.grayColor, + Dimens.boxHeight24, + TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.username, + ), + keyboardType: TextInputType.text, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.unameTextController, + onEditingComplete: logic.focusNode.nextFocus, ), - hintText: StringValues.confirmPassword, - suffixIcon: InkWell( - onTap: logic.toggleViewPassword, - child: Icon( - logic.showPassword - ? CupertinoIcons.eye - : CupertinoIcons.eye_slash, + Dimens.boxHeight16, + TextFormField( + obscureText: logic.showPassword, + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintStyle: const TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.password, + suffixIcon: InkWell( + onTap: logic.toggleViewPassword, + child: Icon( + logic.showPassword + ? CupertinoIcons.eye + : CupertinoIcons.eye_slash, + ), + ), + ), + keyboardType: TextInputType.visiblePassword, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, ), + controller: logic.passwordTextController, + onEditingComplete: logic.focusNode.nextFocus, ), - ), - keyboardType: TextInputType.visiblePassword, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.confirmPasswordTextController, - onEditingComplete: logic.focusNode.unfocus, - ), - Dimens.boxHeight32, - NxFilledButton( - onTap: () => logic.register(), - label: StringValues.register, - fontSize: Dimens.sixTeen, - width: double.infinity, - ), - Dimens.boxHeight32, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - StringValues.alreadyHaveAccount, - style: AppStyles.style16Normal, + Dimens.boxHeight16, + TextFormField( + obscureText: logic.showPassword, + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintStyle: const TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.confirmPassword, + suffixIcon: InkWell( + onTap: logic.toggleViewPassword, + child: Icon( + logic.showPassword + ? CupertinoIcons.eye + : CupertinoIcons.eye_slash, + ), + ), + ), + keyboardType: TextInputType.visiblePassword, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.confirmPasswordTextController, + onEditingComplete: logic.focusNode.unfocus, ), - Dimens.boxWidth4, - const NxTextButton( - label: StringValues.login, - onTap: RouteManagement.goToLoginView, + Dimens.boxHeight16, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + StringValues.alreadyHaveAccount, + style: AppStyles.style16Normal, + ), + Dimens.boxWidth4, + const NxTextButton( + label: StringValues.login, + onTap: RouteManagement.goToLoginView, + ), + ], ), + Dimens.boxHeight16, ], ), - Dimens.boxHeight32, - ], + ), ), ), - ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: NxFilledButton( + onTap: () => logic.register(), + label: StringValues.register, + fontSize: Dimens.sixTeen, + borderRadius: 0.0, + ), + ), + ], ), ), ); diff --git a/lib/modules/auth/views/reset_password_view.dart b/lib/modules/auth/views/reset_password_view.dart index 734797b..5066a80 100644 --- a/lib/modules/auth/views/reset_password_view.dart +++ b/lib/modules/auth/views/reset_password_view.dart @@ -28,6 +28,7 @@ class ResetPasswordView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ + Dimens.boxHeight8, _buildImageHeader(), Dimens.boxHeight16, _buildResetPasswordFields(), @@ -41,18 +42,18 @@ class ResetPasswordView extends StatelessWidget { Widget _buildImageHeader() => Column( mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisSize: MainAxisSize.min, children: [ NxAssetImage( - imgAsset: AssetValues.vector1, - maxHeight: Dimens.hundred * 2.0, + imgAsset: AssetValues.appIcon, + maxHeight: Dimens.eighty, ), - Padding( - padding: Dimens.edgeInsets0_16, - child: Text( - StringValues.resetPassword, - style: AppStyles.style24Bold, + Text( + StringValues.appName, + textAlign: TextAlign.center, + style: AppStyles.style24Bold.copyWith( + color: ColorValues.primaryColor, ), ), ], @@ -60,118 +61,144 @@ class ResetPasswordView extends StatelessWidget { Widget _buildResetPasswordFields() => GetBuilder( builder: (logic) => Expanded( - child: SingleChildScrollView( - child: Padding( - padding: Dimens.edgeInsets0_16, - child: FocusScope( - node: logic.focusNode, - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintStyle: TextStyle( - color: ColorValues.grayColor, - ), - hintText: StringValues.otp, - ), - keyboardType: TextInputType.number, - maxLines: 1, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly, - LengthLimitingTextInputFormatter(6), - ], - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.otpTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight24, - TextFormField( - obscureText: logic.showPassword, - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintStyle: const TextStyle( - color: ColorValues.grayColor, + child: Stack( + children: [ + SingleChildScrollView( + child: Padding( + padding: Dimens.edgeInsets0_8, + child: FocusScope( + node: logic.focusNode, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + StringValues.resetPassword, + style: AppStyles.style24Bold, ), - hintText: StringValues.newPassword, - suffixIcon: InkWell( - onTap: logic.toggleViewPassword, - child: Icon( - logic.showPassword - ? CupertinoIcons.eye - : CupertinoIcons.eye_slash, + Dimens.boxHeight16, + Text( + 'Enter the OTP that we sent to your email and create new password.', + style: AppStyles.style14Normal.copyWith( + color: ColorValues.darkGrayColor, ), ), - ), - keyboardType: TextInputType.visiblePassword, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.passwordTextController, - onEditingComplete: logic.focusNode.nextFocus, - ), - Dimens.boxHeight24, - TextFormField( - obscureText: logic.showPassword, - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintStyle: const TextStyle( - color: ColorValues.grayColor, + Dimens.boxHeight16, + TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.otp, + ), + keyboardType: TextInputType.number, + maxLines: 1, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + LengthLimitingTextInputFormatter(6), + ], + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.otpTextController, + onEditingComplete: logic.focusNode.nextFocus, ), - hintText: StringValues.confirmPassword, - suffixIcon: InkWell( - onTap: logic.toggleViewPassword, - child: Icon( - logic.showPassword - ? CupertinoIcons.eye - : CupertinoIcons.eye_slash, + Dimens.boxHeight24, + TextFormField( + obscureText: logic.showPassword, + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintStyle: const TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.newPassword, + suffixIcon: InkWell( + onTap: logic.toggleViewPassword, + child: Icon( + logic.showPassword + ? CupertinoIcons.eye + : CupertinoIcons.eye_slash, + ), + ), + ), + keyboardType: TextInputType.visiblePassword, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, ), + controller: logic.passwordTextController, + onEditingComplete: logic.focusNode.nextFocus, ), - ), - keyboardType: TextInputType.visiblePassword, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: - Theme.of(Get.context!).textTheme.bodyText1!.color, - ), - controller: logic.confirmPasswordTextController, - onEditingComplete: logic.focusNode.unfocus, - ), - Dimens.boxHeight32, - NxFilledButton( - onTap: () => logic.resetPassword(), - label: StringValues.resetPassword, - fontSize: Dimens.sixTeen, - width: double.infinity, - ), - Dimens.boxHeight32, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - StringValues.doNotHaveOtp, - style: AppStyles.style16Normal, + Dimens.boxHeight24, + TextFormField( + obscureText: logic.showPassword, + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintStyle: const TextStyle( + color: ColorValues.grayColor, + ), + hintText: StringValues.confirmPassword, + suffixIcon: InkWell( + onTap: logic.toggleViewPassword, + child: Icon( + logic.showPassword + ? CupertinoIcons.eye + : CupertinoIcons.eye_slash, + ), + ), + ), + keyboardType: TextInputType.visiblePassword, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: logic.confirmPasswordTextController, + onEditingComplete: logic.focusNode.unfocus, ), - Dimens.boxWidth4, - const NxTextButton( - label: StringValues.getOtp, - onTap: RouteManagement.goToForgotPasswordView, + Dimens.boxHeight16, + Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + StringValues.doNotHaveOtp, + style: AppStyles.style16Normal, + ), + Dimens.boxWidth4, + const NxTextButton( + label: StringValues.getOtp, + onTap: RouteManagement.goToForgotPasswordView, + ), + ], ), + Dimens.boxHeight16, ], ), - Dimens.boxHeight32, - ], + ), ), ), - ), + Positioned( + bottom: 0, + left: 0, + right: 0, + child: NxFilledButton( + onTap: () => logic.resetPassword(), + label: StringValues.resetPassword, + fontSize: Dimens.sixTeen, + borderRadius: 0.0, + ), + ), + ], ), ), ); diff --git a/lib/modules/calling/bindings/start_binding.dart b/lib/modules/calling/bindings/start_binding.dart new file mode 100644 index 0000000..7242faa --- /dev/null +++ b/lib/modules/calling/bindings/start_binding.dart @@ -0,0 +1,9 @@ +import 'package:get/get.dart'; +import 'package:video_calling_app/modules/calling/controllers/start_channel_controller.dart'; + +class StartBinding extends Bindings { + @override + void dependencies() { + Get.lazyPut(StartChannelController.new); + } +} diff --git a/lib/modules/calling/controllers/channel_controller.dart b/lib/modules/calling/controllers/channel_controller.dart index f33b24b..d5ddba1 100644 --- a/lib/modules/calling/controllers/channel_controller.dart +++ b/lib/modules/calling/controllers/channel_controller.dart @@ -191,7 +191,6 @@ class ChannelController extends GetxController { _addAgoraEventHandlers(); await _rtcEngine.enableVideo(); - await _rtcEngine.startPreview(); await _rtcEngine.setChannelProfile(ChannelProfile.LiveBroadcasting); await _rtcEngine.setClientRole(ClientRole.Broadcaster); } @@ -226,7 +225,9 @@ class ChannelController extends GetxController { @override void onInit() { super.onInit(); - _channelId = Get.arguments ?? _auth.channelId; + _channelId = Get.arguments[0] ?? _auth.channelId; + _cameraToggle = Get.arguments[1] ?? true; + _micToggle = Get.arguments[2] ?? true; _init(); } diff --git a/lib/modules/calling/controllers/join_channel_controller.dart b/lib/modules/calling/controllers/join_channel_controller.dart index f8df49b..533db27 100644 --- a/lib/modules/calling/controllers/join_channel_controller.dart +++ b/lib/modules/calling/controllers/join_channel_controller.dart @@ -7,4 +7,21 @@ class JoinChannelController extends GetxController { final channelIdTextController = TextEditingController(); final FocusScopeNode focusNode = FocusScopeNode(); + + bool _micToggle = true; + bool _cameraToggle = true; + + bool get micToggle => _micToggle; + + bool get cameraToggle => _cameraToggle; + + void enableVideo(value) { + _cameraToggle = value; + update(); + } + + void enableAudio(value) { + _micToggle = value; + update(); + } } diff --git a/lib/modules/calling/controllers/start_channel_controller.dart b/lib/modules/calling/controllers/start_channel_controller.dart new file mode 100644 index 0000000..3384751 --- /dev/null +++ b/lib/modules/calling/controllers/start_channel_controller.dart @@ -0,0 +1,22 @@ +import 'package:get/get.dart'; + +class StartChannelController extends GetxController { + static StartChannelController get find => Get.find(); + + bool _micToggle = true; + bool _cameraToggle = true; + + bool get micToggle => _micToggle; + + bool get cameraToggle => _cameraToggle; + + void enableVideo(value) { + _cameraToggle = value; + update(); + } + + void enableAudio(value) { + _micToggle = value; + update(); + } +} diff --git a/lib/modules/calling/views/calling_view.dart b/lib/modules/calling/views/calling_view.dart index 8579a98..26f64ca 100644 --- a/lib/modules/calling/views/calling_view.dart +++ b/lib/modules/calling/views/calling_view.dart @@ -5,7 +5,6 @@ import 'package:get/get.dart'; import 'package:video_calling_app/common/primary_icon_btn.dart'; import 'package:video_calling_app/constants/colors.dart'; import 'package:video_calling_app/constants/dimens.dart'; -import 'package:video_calling_app/helpers/utils.dart'; import 'package:video_calling_app/modules/calling/controllers/channel_controller.dart'; class CallingView extends StatefulWidget { @@ -308,11 +307,7 @@ class _CallingViewState extends State iconColor: logic.cameraToggle ? Theme.of(Get.context!).iconTheme.color : ColorValues.whiteColor, - //onTap: () => logic.toggleMuteVideo(), - onTap: () { - logic.participants.add(AppUtils.randomIntNumeric(8)); - logic.update(); - }, + onTap: () => logic.toggleMuteVideo(), ), ), CircleAvatar( diff --git a/lib/modules/calling/views/join_view.dart b/lib/modules/calling/views/join_view.dart index 8d814d2..239201d 100644 --- a/lib/modules/calling/views/join_view.dart +++ b/lib/modules/calling/views/join_view.dart @@ -37,26 +37,63 @@ class JoinView extends StatelessWidget { const Expanded(child: SizedBox()), Padding( padding: Dimens.edgeInsets8, - child: Center( - child: TextFormField( - decoration: const InputDecoration( - border: OutlineInputBorder(), - hintText: 'Channel ID', - hintStyle: TextStyle( - color: ColorValues.grayColor, + child: Column( + children: [ + TextFormField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + hintText: 'Channel ID', + hintStyle: TextStyle( + color: ColorValues.grayColor, + ), ), + keyboardType: TextInputType.emailAddress, + maxLines: 1, + style: AppStyles.style16Normal.copyWith( + color: Theme.of(Get.context!) + .textTheme + .bodyText1! + .color, + ), + controller: con.channelIdTextController, + onEditingComplete: con.focusNode.unfocus, + ), + Dimens.boxHeight8, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Camera", + style: AppStyles.style18Normal, + ), + Switch( + onChanged: (value) { + con.enableVideo(value); + }, + value: con.cameraToggle, + activeColor: ColorValues.primaryColor, + ), + ], ), - keyboardType: TextInputType.emailAddress, - maxLines: 1, - style: AppStyles.style16Normal.copyWith( - color: Theme.of(Get.context!) - .textTheme - .bodyText1! - .color, + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Text( + "Audio", + style: AppStyles.style18Normal, + ), + Switch( + onChanged: (value) { + con.enableAudio(value); + }, + value: con.micToggle, + activeColor: ColorValues.primaryColor, + ), + ], ), - controller: con.channelIdTextController, - onEditingComplete: con.focusNode.unfocus, - ), + ], ), ), const Expanded(child: SizedBox()), @@ -69,8 +106,11 @@ class JoinView extends StatelessWidget { return; } RouteManagement.goToCallingView( - channelId: - con.channelIdTextController.text.trim()); + channelId: + con.channelIdTextController.text.trim(), + enableAudio: con.micToggle, + enableVideo: con.cameraToggle, + ); }, ), ], diff --git a/lib/modules/calling/views/start_view.dart b/lib/modules/calling/views/start_view.dart index ccfdc40..91cfa6e 100644 --- a/lib/modules/calling/views/start_view.dart +++ b/lib/modules/calling/views/start_view.dart @@ -1,9 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:get/get.dart'; import 'package:video_calling_app/common/custom_app_bar.dart'; import 'package:video_calling_app/common/primary_filled_btn.dart'; +import 'package:video_calling_app/constants/colors.dart'; import 'package:video_calling_app/constants/dimens.dart'; import 'package:video_calling_app/constants/strings.dart'; import 'package:video_calling_app/constants/styles.dart'; +import 'package:video_calling_app/modules/calling/controllers/start_channel_controller.dart'; import 'package:video_calling_app/routes/route_management.dart'; class StartView extends StatelessWidget { @@ -24,22 +27,62 @@ class StartView extends StatelessWidget { title: StringValues.start, ), Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const Expanded(child: SizedBox()), - Text( - "Options", - style: AppStyles.style16Bold, - ), - const Expanded(child: SizedBox()), - const NxFilledButton( - label: StringValues.start, - borderRadius: 0.0, - onTap: RouteManagement.goToCallingView, - ), - ], + child: GetBuilder( + builder: (logic) => Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const Expanded(child: SizedBox()), + Padding( + padding: Dimens.edgeInsets8, + child: Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Camera", + style: AppStyles.style18Normal, + ), + Switch( + onChanged: (value) { + logic.enableVideo(value); + }, + value: logic.cameraToggle, + activeColor: ColorValues.primaryColor, + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + "Audio", + style: AppStyles.style18Normal, + ), + Switch( + onChanged: (value) { + logic.enableAudio(value); + }, + value: logic.micToggle, + activeColor: ColorValues.primaryColor, + ), + ], + ), + ], + ), + ), + const Expanded(child: SizedBox()), + NxFilledButton( + label: StringValues.start, + borderRadius: 0.0, + onTap: () => RouteManagement.goToCallingView( + enableAudio: logic.micToggle, + enableVideo: logic.cameraToggle, + ), + ), + ], + ), ), ), ], diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index 7c4a08c..ea9ed4a 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -7,6 +7,7 @@ import 'package:video_calling_app/common/circular_network_image.dart'; import 'package:video_calling_app/common/custom_app_bar.dart'; import 'package:video_calling_app/common/primary_filled_btn.dart'; import 'package:video_calling_app/common/primary_outlined_btn.dart'; +import 'package:video_calling_app/constants/colors.dart'; import 'package:video_calling_app/constants/dimens.dart'; import 'package:video_calling_app/constants/strings.dart'; import 'package:video_calling_app/constants/styles.dart'; @@ -32,10 +33,21 @@ class HomeView extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ - NxAssetImage( - imgAsset: AssetValues.appName, - width: Dimens.hundred * 1.2, - fit: BoxFit.cover, + Row( + children: [ + NxAssetImage( + imgAsset: AssetValues.appIcon, + fit: BoxFit.cover, + height: Dimens.twentyFour, + ), + Dimens.boxWidth8, + Text( + StringValues.appName, + style: AppStyles.style20Bold.copyWith( + color: ColorValues.primaryColor, + ), + ), + ], ), GetBuilder( builder: (logic) => InkWell( diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 46163c2..c1d888d 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -10,6 +10,7 @@ import 'package:video_calling_app/modules/auth/views/register_view.dart'; import 'package:video_calling_app/modules/auth/views/reset_password_view.dart'; import 'package:video_calling_app/modules/calling/bindings/calling_binding.dart'; import 'package:video_calling_app/modules/calling/bindings/join_binding.dart'; +import 'package:video_calling_app/modules/calling/bindings/start_binding.dart'; import 'package:video_calling_app/modules/calling/views/calling_view.dart'; import 'package:video_calling_app/modules/calling/views/join_view.dart'; import 'package:video_calling_app/modules/calling/views/start_view.dart'; @@ -76,6 +77,7 @@ abstract class AppPages { GetPage( name: _Routes.start, page: StartView.new, + binding: StartBinding(), transitionDuration: transitionDuration, transition: Transition.downToUp, ), diff --git a/lib/routes/route_management.dart b/lib/routes/route_management.dart index ee389ac..5341826 100644 --- a/lib/routes/route_management.dart +++ b/lib/routes/route_management.dart @@ -38,8 +38,10 @@ abstract class RouteManagement { Get.toNamed(AppRoutes.changePassword); } - static void goToCallingView({String? channelId}) { - Get.offAndToNamed(AppRoutes.calling, arguments: channelId); + static void goToCallingView( + {String? channelId, bool? enableVideo, bool? enableAudio}) { + Get.offAndToNamed(AppRoutes.calling, + arguments: [channelId, enableVideo, enableAudio]); } static void goToStartView() {