Skip to content
50 changes: 39 additions & 11 deletions app/lib/screens/identity_verification_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -922,8 +922,7 @@ class _IdentityVerificationScreenState
if (Globals().hidePhoneButton.value == true) {
return;
}

await addPhoneNumberDialog(context);
await addPhoneNumberDialog(context, newPhone: false, oldPhone: phone);

var phoneMap = (await getPhone());
if (phoneMap.isEmpty || !phoneMap.containsKey('phone')) {
Expand Down Expand Up @@ -1072,14 +1071,25 @@ class _IdentityVerificationScreenState

Widget verifiedWidget(step, text, icon) {
return GestureDetector(
onTap: () async {
if (step == 1) {
return _changeEmailDialog(false);
}
// Only make this section clickable if it is Identity Verification + Current Phase
if (step != 3) {
return;
onTap: () async {
if (step == 1) {
return _changeEmailDialog(false);
}
if (step == 2) {
await addPhoneNumberDialog(context, newPhone: false, oldPhone: phone);
var phoneMap = (await getPhone());
String? phoneNumber = phoneMap['phone'];
if (phone != phoneNumber) {
setState(() {
phone = phoneNumber!;
});
}
return;
}
// Only make this section clickable if it is Identity Verification + Current Phase
if (step != 3) {
return;
}

return showIdentityDetails();
},
Expand Down Expand Up @@ -1143,6 +1153,18 @@ class _IdentityVerificationScreenState
),
])
: const Column(),
step == 2
? const Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(left: 15),
child: Icon(
Icons.edit,
),
),
])
: const Column(),
step == 3
? const Column(
mainAxisAlignment: MainAxisAlignment.center,
Expand Down Expand Up @@ -1610,7 +1632,7 @@ class _IdentityVerificationScreenState
color:
Theme.of(context).colorScheme.onSurface))
: Text(
'Changing your email will require you to go through the email verification process again.',
'Changing your email will require re-verification.',
style: Theme.of(context)
.textTheme
.bodyLarge!
Expand Down Expand Up @@ -1788,7 +1810,7 @@ class _IdentityVerificationScreenState
}

if (phone.isEmpty) {
await addPhoneNumberDialog(context);
await addPhoneNumberDialog(context, newPhone: true, oldPhone: phone);

var phoneMap = (await getPhone());
if (phoneMap.isEmpty || !phoneMap.containsKey('phone')) {
Expand All @@ -1806,9 +1828,15 @@ class _IdentityVerificationScreenState
FlutterPkid client = await getPkidClient();
client.setPKidDoc('phone', json.encode({'phone': phone}));

startPhoneNumberCounter();
return;
} else {
PhoneAlertDialogState().sendPhoneVerification();
return;
}
}

void startPhoneNumberCounter() {
int currentTime = DateTime.now().millisecondsSinceEpoch;
if (globals.tooManySmsAttempts && globals.lockedSmsUntil > currentTime) {
globals.sendSmsAttempts = 0;
Expand Down
155 changes: 102 additions & 53 deletions app/lib/widgets/phone_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import 'package:flutter_pkid/flutter_pkid.dart';
import 'package:http/http.dart';
import 'package:intl_phone_field/countries.dart';
import 'package:intl_phone_field/intl_phone_field.dart';
import 'package:intl_phone_field/phone_number.dart';
import 'package:threebotlogin/helpers/globals.dart';
import 'package:threebotlogin/services/open_kyc_service.dart';
import 'package:threebotlogin/services/phone_service.dart';
Expand All @@ -14,15 +13,18 @@ import 'package:threebotlogin/services/shared_preference_service.dart';

import 'custom_dialog.dart';

Future<void> addPhoneNumberDialog(context) async {
Future<void> addPhoneNumberDialog(context,
{required bool newPhone, required String oldPhone}) async {
Response res = await getCountry();
var countryCode = res.body.replaceAll('\n', '');

await showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) =>
PhoneAlertDialog(defaultCountryCode: countryCode),
builder: (BuildContext context) => PhoneAlertDialog(
defaultCountryCode: countryCode,
newPhone: newPhone,
oldPhone: oldPhone),
);
}

Expand All @@ -48,8 +50,14 @@ phoneSendDialog(context) {

class PhoneAlertDialog extends StatefulWidget {
final String defaultCountryCode;
final bool newPhone;
final String oldPhone;

const PhoneAlertDialog({Key? key, required this.defaultCountryCode})
const PhoneAlertDialog(
{Key? key,
required this.defaultCountryCode,
required this.newPhone,
required this.oldPhone})
: super(key: key);

@override
Expand All @@ -76,64 +84,105 @@ class PhoneAlertDialogState extends State<PhoneAlertDialog> {
Widget build(BuildContext context) {
return CustomDialog(
image: Icons.phone,
title: 'Add phone number',
title: widget.newPhone ? 'Add phone number' : 'Change phone number',
widgetDescription: SizedBox(
height: 100,
child: Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: IntlPhoneField(
initialCountryCode: widget.defaultCountryCode,
decoration: const InputDecoration(
labelText: 'Phone Number',
border: OutlineInputBorder(
borderSide: BorderSide(),
height: widget.newPhone ? 100 : 155,
child: Column(
children: [
if (!widget.newPhone)
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
'Changing your phone will require re-verification',
style: Theme.of(context)
.textTheme
.bodyLarge!
.copyWith(
color:
Theme.of(context).colorScheme.onSurface),
),
),
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface),
dropdownTextStyle: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
],
),
if (!widget.newPhone)
const SizedBox(
height: 30,
),
Row(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: IntlPhoneField(
initialCountryCode: widget.defaultCountryCode,
decoration: const InputDecoration(
labelText: 'Phone Number',
border: OutlineInputBorder(
borderSide: BorderSide(),
),
),
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface),
onChanged: (phone) {
PhoneNumber p = phone;
setState(() {
if (phone.number.length >= _country.minLength &&
phone.number.length <= _country.maxLength) {
valid = true;
verificationPhoneNumber = p.completeNumber;
} else {
valid = false;
}
});
},
onCountryChanged: (country) {
if (_country != country) {
valid = false;
}
_country = country;
setState(() {});
},
dropdownTextStyle: Theme.of(context)
.textTheme
.bodyMedium!
.copyWith(
color: Theme.of(context).colorScheme.onSurface),
validator: (phone) {
if (phone!.completeNumber == widget.oldPhone) {
setState(() {
valid = false;
});
return 'Please enter a different number';
} else if (phone.number.length >=
_country.minLength &&
phone.number.length <= _country.maxLength) {
setState(() {
valid = true;
});
verificationPhoneNumber = phone.completeNumber;
return null;
} else {
setState(() {
valid = false;
});
return 'Invalid Mobile Number';
}
},
disableLengthCheck: true,
onCountryChanged: (country) {
if (_country != country) {
valid = false;
}
_country = country;
setState(() {});
},
),
),
),
),
],
),
],
),
),
actions: <Widget>[
TextButton(
child: const Text(
'Cancel',
),
onPressed: () {
Navigator.pop(context);
}),
if (valid)
TextButton(onPressed: verifyButton, child: const Text('Add'))
Transform.translate(
offset: const Offset(0, -20),
child: Row(children: [
TextButton(
child: const Text(
'Cancel',
),
onPressed: () {
Navigator.pop(context);
}),
if (valid)
TextButton(onPressed: verifyButton, child: const Text('Add'))
]))
]);
}

Expand Down