Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make phone number field editable #804

Merged
merged 9 commits into from
Jan 8, 2025
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
Loading