mirror of
https://github.com/meditohq/medito-app.git
synced 2024-09-11 12:15:46 +03:00
Undo OTP removal
This commit is contained in:
parent
ff2b4c64f1
commit
4800da847d
@ -106,8 +106,6 @@ android {
|
||||
signingConfig signingConfigs.release
|
||||
shrinkResources true
|
||||
minifyEnabled true
|
||||
useProguard true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
namespace 'meditofoundation.medito'
|
||||
|
@ -34,8 +34,8 @@ import 'constants/environments/environment_constants.dart';
|
||||
import 'services/notifications/notifications_service.dart';
|
||||
|
||||
var audioStateNotifier = AudioStateNotifier();
|
||||
var currentEnvironment =
|
||||
kDebugMode ? EnvironmentConstants.stagingEnv : EnvironmentConstants.prodEnv;
|
||||
var currentEnvironment = EnvironmentConstants.stagingEnv;
|
||||
// kDebugMode ? EnvironmentConstants.stagingEnv : EnvironmentConstants.prodEnv;
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@ -46,15 +46,8 @@ Future<void> main() async {
|
||||
|
||||
var sharedPreferences = await initializeSharedPreferences();
|
||||
if (await areGooglePlayServicesAvailable()) {
|
||||
try {
|
||||
await Firebase.initializeApp();
|
||||
await registerNotification();
|
||||
} catch (err) {
|
||||
unawaited(Sentry.captureException(
|
||||
err,
|
||||
stackTrace: err,
|
||||
));
|
||||
}
|
||||
await Firebase.initializeApp();
|
||||
await registerNotification();
|
||||
}
|
||||
|
||||
usePathUrlStrategy();
|
||||
|
@ -2,6 +2,7 @@ import 'package:Medito/constants/constants.dart';
|
||||
import 'package:Medito/main.dart';
|
||||
import 'package:Medito/models/models.dart';
|
||||
import 'package:Medito/repositories/repositories.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../me/me_provider.dart';
|
||||
|
@ -6,6 +6,7 @@ import 'package:Medito/providers/providers.dart';
|
||||
import 'package:Medito/utils/utils.dart';
|
||||
import 'package:Medito/views/auth/join_email_view.dart';
|
||||
import 'package:Medito/views/auth/join_intro_view.dart';
|
||||
import 'package:Medito/views/auth/join_verify_OTP_view.dart';
|
||||
import 'package:Medito/views/auth/join_welcome_view.dart';
|
||||
import 'package:Medito/views/background_sound/background_sound_view.dart';
|
||||
import 'package:Medito/views/bottom_navigation/bottom_navigation_bar_view.dart';
|
||||
@ -75,6 +76,22 @@ final router = GoRouter(
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
parentNavigatorKey: _rootNavigatorKey,
|
||||
path: RouteConstants.joinVerifyOTPPath,
|
||||
pageBuilder: (context, state) {
|
||||
final params =
|
||||
state.extra != null ? state.extra as JoinRouteParamsModel : null;
|
||||
|
||||
return MaterialPage(
|
||||
key: state.pageKey,
|
||||
child: JoinVerifyOTPView(
|
||||
email: params?.email ?? '',
|
||||
fromScreen: params?.screen ?? Screen.splash,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
parentNavigatorKey: _rootNavigatorKey,
|
||||
path: RouteConstants.joinWelcomePath,
|
||||
|
@ -25,13 +25,18 @@ Future<void> registerNotification() async {
|
||||
}
|
||||
|
||||
Future<String?> requestGenerateFirebaseToken() async {
|
||||
try {
|
||||
if (_messaging != null) {
|
||||
var token = await _messaging?.getToken();
|
||||
|
||||
return token;
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Future removeFirebaseToken() async {
|
||||
|
@ -199,10 +199,14 @@ Future<bool> areGooglePlayServicesAvailable() async {
|
||||
if (Platform.isIOS) {
|
||||
return true;
|
||||
} else if (Platform.isAndroid) {
|
||||
return (await GoogleApiAvailability.instance
|
||||
.checkGooglePlayServicesAvailability()) ==
|
||||
GooglePlayServicesAvailability.success;
|
||||
var availability = await GoogleApiAvailability.instance
|
||||
.checkGooglePlayServicesAvailability();
|
||||
if (availability == GooglePlayServicesAvailability.success) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (e) {
|
||||
unawaited(Sentry.captureException(
|
||||
e,
|
||||
@ -211,8 +215,6 @@ Future<bool> areGooglePlayServicesAvailable() async {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extension SanitisePath on String {
|
||||
|
273
lib/views/auth/join_verify_OTP_view.dart
Normal file
273
lib/views/auth/join_verify_OTP_view.dart
Normal file
@ -0,0 +1,273 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:Medito/constants/constants.dart';
|
||||
import 'package:Medito/models/models.dart';
|
||||
import 'package:Medito/providers/providers.dart';
|
||||
import 'package:Medito/routes/routes.dart';
|
||||
import 'package:Medito/services/network/api_response.dart';
|
||||
import 'package:Medito/services/notifications/notifications_service.dart';
|
||||
import 'package:Medito/utils/validation_utils.dart';
|
||||
import 'package:Medito/widgets/widgets.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:pin_code_fields/pin_code_fields.dart';
|
||||
|
||||
import '../../providers/me/me_provider.dart';
|
||||
import '../../utils/utils.dart';
|
||||
|
||||
class JoinVerifyOTPView extends ConsumerStatefulWidget {
|
||||
const JoinVerifyOTPView({
|
||||
super.key,
|
||||
required this.email,
|
||||
required this.fromScreen,
|
||||
});
|
||||
|
||||
final Screen fromScreen;
|
||||
final String email;
|
||||
|
||||
@override
|
||||
ConsumerState<JoinVerifyOTPView> createState() => _JoinVerifyOTPViewState();
|
||||
}
|
||||
|
||||
class _JoinVerifyOTPViewState extends ConsumerState<JoinVerifyOTPView> {
|
||||
late AuthNotifier auth;
|
||||
final TextEditingController _otpTextEditingController =
|
||||
TextEditingController();
|
||||
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
|
||||
void _handleVerify() async {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
await auth.verifyOTP(widget.email, _otpTextEditingController.text);
|
||||
var status = auth.verifyOTPResponse.status;
|
||||
if (status == Status.COMPLETED) {
|
||||
await removeFirebaseToken();
|
||||
await auth.saveFcmTokenEvent();
|
||||
// ignore: unused_result
|
||||
ref.invalidate(meProvider);
|
||||
ref.read(meProvider);
|
||||
var params = JoinRouteParamsModel(
|
||||
screen: widget.fromScreen,
|
||||
email: widget.email,
|
||||
);
|
||||
unawaited(context.push(
|
||||
RouteConstants.joinWelcomePath,
|
||||
extra: params,
|
||||
));
|
||||
} else if (status == Status.ERROR) {
|
||||
showSnackBar(context, auth.verifyOTPResponse.message.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
auth = ref.watch(authProvider);
|
||||
var textTheme = Theme.of(context).textTheme;
|
||||
var isLoading = auth.verifyOTPResponse == ApiResponse.loading();
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: ColorConstants.ebony,
|
||||
body: SafeArea(
|
||||
maintainBottomViewPadding: true,
|
||||
bottom: false,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 16, bottom: 0, left: 16, right: 16), // Updated padding
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
StringConstants.verifyYourAccount,
|
||||
style: textTheme.headlineMedium?.copyWith(
|
||||
color: ColorConstants.walterWhite,
|
||||
fontFamily: SourceSerif,
|
||||
height: 1.2,
|
||||
fontSize: 24,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 16, bottom: 24),
|
||||
child: Text(
|
||||
StringConstants.verifyYourAccountInstruction
|
||||
.replaceAll('replaceme', widget.email),
|
||||
style: textTheme.bodyMedium?.copyWith(
|
||||
color: ColorConstants.walterWhite,
|
||||
fontFamily: DmSans,
|
||||
height: 1.4,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
PinCodeTextField(
|
||||
appContext: context,
|
||||
controller: _otpTextEditingController,
|
||||
backgroundColor: Colors.transparent,
|
||||
keyboardType: TextInputType.number,
|
||||
pinTheme: PinTheme(
|
||||
fieldHeight: 56,
|
||||
fieldWidth: 56,
|
||||
selectedColor: ColorConstants.onyx,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderWidth: 0,
|
||||
activeFillColor: ColorConstants.onyx,
|
||||
inactiveFillColor: ColorConstants.onyx,
|
||||
selectedFillColor: ColorConstants.onyx,
|
||||
activeColor: ColorConstants.onyx,
|
||||
inactiveColor: ColorConstants.onyx,
|
||||
shape: PinCodeFieldShape.box,
|
||||
),
|
||||
textStyle: textTheme.displayMedium?.copyWith(
|
||||
color: ColorConstants.walterWhite,
|
||||
fontFamily: SourceSerif,
|
||||
fontSize: 24,
|
||||
),
|
||||
enableActiveFill: true,
|
||||
autoFocus: true,
|
||||
animationCurve: Curves.easeIn,
|
||||
cursorColor: ColorConstants.walterWhite,
|
||||
length: 6,
|
||||
validator: ValidationUtils().validateOTP,
|
||||
onChanged: (String _) => setState(() => {}),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: _ResendCodeWidget(
|
||||
email: widget.email,
|
||||
),
|
||||
),
|
||||
height16,
|
||||
],
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: 48, // Set the height to 48 pixels
|
||||
child: LoadingButtonWidget(
|
||||
onPressed: () => context.pop(),
|
||||
btnText: StringConstants.goBack,
|
||||
),
|
||||
),
|
||||
width8,
|
||||
Container(
|
||||
height: 48, // Set the height to 48 pixels
|
||||
child: LoadingButtonWidget(
|
||||
onPressed: _otpTextEditingController.text != ''
|
||||
? _handleVerify
|
||||
: null,
|
||||
btnText: StringConstants.verify,
|
||||
bgColor: ColorConstants.walterWhite,
|
||||
textColor: ColorConstants.onyx,
|
||||
isLoading: isLoading,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: getBottomPadding(context), // Added SizedBox
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ResendCodeWidget extends ConsumerWidget {
|
||||
const _ResendCodeWidget({required this.email});
|
||||
|
||||
final String email;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
var textTheme = Theme.of(context).textTheme;
|
||||
var auth = ref.watch(authProvider);
|
||||
|
||||
void _handleResendOTP() async {
|
||||
await auth.sendOTP(email);
|
||||
auth.setCounter();
|
||||
var status = auth.sendOTPResponse.status;
|
||||
if (status == Status.COMPLETED) {
|
||||
showSnackBar(context, auth.sendOTPResponse.body.toString());
|
||||
} else if (status == Status.ERROR) {
|
||||
showSnackBar(context, auth.sendOTPResponse.message.toString());
|
||||
auth.setCounter();
|
||||
}
|
||||
}
|
||||
|
||||
if (auth.sendOTPResponse.status == Status.LOADING) {
|
||||
return SizedBox(
|
||||
height: 16,
|
||||
width: 16,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: ColorConstants.walterWhite,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () => {},
|
||||
child: Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: _handleResendOTP,
|
||||
child: Text(
|
||||
auth.counter
|
||||
? StringConstants.resendCodeIn
|
||||
: StringConstants.resendCode,
|
||||
style: textTheme.bodyMedium?.copyWith(
|
||||
color: ColorConstants.walterWhite,
|
||||
fontFamily: DmSans,
|
||||
height: 1.5,
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w700,
|
||||
decoration: auth.counter
|
||||
? TextDecoration.none
|
||||
: TextDecoration.underline,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (auth.counter) _counterAnimation(auth, textTheme),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
TweenAnimationBuilder<Duration> _counterAnimation(
|
||||
AuthNotifier auth,
|
||||
TextTheme textTheme,
|
||||
) {
|
||||
return TweenAnimationBuilder<Duration>(
|
||||
duration: Duration(seconds: 45),
|
||||
tween: Tween(begin: Duration(seconds: 45), end: Duration.zero),
|
||||
onEnd: () {
|
||||
auth.setCounter();
|
||||
},
|
||||
builder: (BuildContext context, Duration value, Widget? child) {
|
||||
final minutes = value.inMinutes;
|
||||
final seconds = value.inSeconds % 60;
|
||||
|
||||
return Text(
|
||||
'$minutes:$seconds',
|
||||
textAlign: TextAlign.center,
|
||||
style: textTheme.bodyMedium?.copyWith(
|
||||
color: ColorConstants.walterWhite,
|
||||
fontFamily: DmSans,
|
||||
height: 1.5,
|
||||
fontSize: 14,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
@ -1000,6 +1000,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "16.0.5"
|
||||
pin_code_fields:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: pin_code_fields
|
||||
sha256: c8652519d14688f3fe2a8288d86910a46aa0b9046d728f292d3bf6067c31b4c7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
63
pubspec.yaml
63
pubspec.yaml
@ -19,45 +19,46 @@ environment:
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
http: ^0.13.3
|
||||
dio: ^5.4.0
|
||||
flutter_svg: ^1.1.6
|
||||
path_provider: ^2.0.1
|
||||
url_launcher: ^6.1.14
|
||||
flutter_markdown: ^0.6.7
|
||||
shared_preferences: ^2.2.2
|
||||
app_settings: ^5.1.1
|
||||
auto_size_text: ^3.0.0-nullsafety.0
|
||||
rxdart: ^0.27.1
|
||||
share: ^2.0.1
|
||||
flutter_html: ^3.0.0-alpha.2
|
||||
package_info_plus: ^4.0.2
|
||||
pedantic: ^1.11.0
|
||||
back_button_interceptor: ^6.0.2
|
||||
cached_network_image: ^3.2.3
|
||||
connectivity: ^3.0.3
|
||||
device_info_plus: ^9.0.2
|
||||
dio: ^5.4.0
|
||||
email_validator: '^2.1.16'
|
||||
equatable: ^2.0.0
|
||||
sentry_flutter: ^7.16.0
|
||||
back_button_interceptor: ^6.0.2
|
||||
go_router: ^6.5.5
|
||||
firebase_core: ^1.24.0
|
||||
firebase_messaging: ^13.1.0
|
||||
flutter_dotenv: ^5.0.2
|
||||
flutter_downloader: ^1.10.2
|
||||
flutter_html: ^3.0.0-alpha.2
|
||||
flutter_local_notifications: ^15.0.0
|
||||
flutter_markdown: ^0.6.7
|
||||
flutter_riverpod: ^2.4.10
|
||||
riverpod_annotation: ^2.3.4
|
||||
flutter_svg: ^1.1.6
|
||||
freezed: ^2.3.2
|
||||
freezed_annotation: ^2.2.0
|
||||
json_annotation: ^4.8.1
|
||||
flutter_dotenv: ^5.0.2
|
||||
shimmer: ^2.0.0
|
||||
flutter_downloader: ^1.10.2
|
||||
cached_network_image: ^3.2.3
|
||||
email_validator: '^2.1.16'
|
||||
share_plus: ^7.0.2
|
||||
firebase_messaging: ^13.1.0
|
||||
firebase_core: ^1.24.0
|
||||
flutter_local_notifications: ^15.0.0
|
||||
marquee: ^2.2.3
|
||||
image: ^4.0.17
|
||||
permission_handler: ^11.2.0
|
||||
app_settings: ^5.1.1
|
||||
reorderables: ^0.6.0
|
||||
go_router: ^6.5.5
|
||||
google_api_availability: ^5.0.0
|
||||
http: ^0.13.3
|
||||
image: ^4.0.17
|
||||
json_annotation: ^4.8.1
|
||||
marquee: ^2.2.3
|
||||
package_info_plus: ^4.0.2
|
||||
path_provider: ^2.0.1
|
||||
pedantic: ^1.11.0
|
||||
permission_handler: ^11.2.0
|
||||
pin_code_fields: ^7.4.0
|
||||
reorderables: ^0.6.0
|
||||
riverpod_annotation: ^2.3.4
|
||||
rxdart: ^0.27.1
|
||||
sentry_flutter: ^7.16.0
|
||||
share: ^2.0.1
|
||||
share_plus: ^7.0.2
|
||||
shimmer: ^2.0.0
|
||||
shared_preferences: ^2.2.2
|
||||
url_launcher: ^6.1.14
|
||||
workmanager: ^0.5.2
|
||||
|
||||
dependency_overrides:
|
||||
|
Loading…
Reference in New Issue
Block a user