💄 Better otp input
This commit is contained in:
parent
bf77bfce64
commit
dff8532229
@ -7,6 +7,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
|
||||||
import 'package:gap/gap.dart';
|
import 'package:gap/gap.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:island/models/auth.dart';
|
import 'package:island/models/auth.dart';
|
||||||
@ -339,7 +340,7 @@ class _AuthFactorSheet extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> enableFactor() async {
|
Future<void> enableFactor() async {
|
||||||
final passwordController = TextEditingController();
|
String? password;
|
||||||
final confirmed = await showDialog<bool>(
|
final confirmed = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
builder:
|
builder:
|
||||||
@ -350,13 +351,15 @@ class _AuthFactorSheet extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text('authFactorEnableHint').tr(),
|
Text('authFactorEnableHint').tr(),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
TextField(
|
OtpTextField(
|
||||||
controller: passwordController,
|
numberOfFields: 6,
|
||||||
obscureText: true,
|
obscureText: false,
|
||||||
decoration: InputDecoration(
|
showFieldAsBox: true,
|
||||||
labelText: 'password'.tr(),
|
focusedBorderColor: Theme.of(context).colorScheme.primary,
|
||||||
border: const OutlineInputBorder(),
|
onSubmit: (String verificationCode) {
|
||||||
),
|
password = verificationCode;
|
||||||
|
},
|
||||||
|
textStyle: Theme.of(context).textTheme.titleLarge!,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -372,11 +375,10 @@ class _AuthFactorSheet extends HookConsumerWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final password = passwordController.text;
|
if (confirmed == false ||
|
||||||
if (confirmed == false || password.isEmpty || !context.mounted) {
|
(password?.isEmpty ?? true) ||
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
!context.mounted) {
|
||||||
passwordController.dispose();
|
return;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final client = ref.read(apiClientProvider);
|
final client = ref.read(apiClientProvider);
|
||||||
@ -385,9 +387,6 @@ class _AuthFactorSheet extends HookConsumerWidget {
|
|||||||
data: jsonEncode(password),
|
data: jsonEncode(password),
|
||||||
);
|
);
|
||||||
if (context.mounted) Navigator.pop(context, true);
|
if (context.mounted) Navigator.pop(context, true);
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
||||||
passwordController.dispose();
|
|
||||||
});
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showErrorAlert(err);
|
showErrorAlert(err);
|
||||||
}
|
}
|
||||||
@ -398,12 +397,37 @@ class _AuthFactorSheet extends HookConsumerWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
Column(
|
||||||
title: Text(kFactorTypes[factor.type]!.$1).tr(),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
subtitle: Text(kFactorTypes[factor.type]!.$2).tr(),
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
leading: Icon(kFactorTypes[factor.type]!.$3),
|
children: [
|
||||||
contentPadding: EdgeInsets.symmetric(horizontal: 20, vertical: 8),
|
Icon(kFactorTypes[factor.type]!.$3, size: 32),
|
||||||
),
|
const Gap(8),
|
||||||
|
Text(kFactorTypes[factor.type]!.$1).tr(),
|
||||||
|
const Gap(4),
|
||||||
|
Text(
|
||||||
|
kFactorTypes[factor.type]!.$2,
|
||||||
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
|
).tr(),
|
||||||
|
const Gap(10),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
if (factor.enabledAt == null)
|
||||||
|
Badge(
|
||||||
|
label: Text('Disabled'),
|
||||||
|
textColor: Theme.of(context).colorScheme.onSecondary,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Badge(
|
||||||
|
label: Text('Enabled'),
|
||||||
|
textColor: Theme.of(context).colorScheme.onPrimary,
|
||||||
|
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).padding(all: 20),
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
if (factor.enabledAt != null)
|
if (factor.enabledAt != null)
|
||||||
ListTile(
|
ListTile(
|
||||||
|
@ -827,6 +827,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.6"
|
version: "2.4.6"
|
||||||
|
flutter_otp_text_field:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: flutter_otp_text_field
|
||||||
|
sha256: e7e589dc51cde120d63da6db55f3cef618f5d013d12adba76137ca1a51ce1390
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.5.1+1"
|
||||||
flutter_platform_alert:
|
flutter_platform_alert:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -107,6 +107,7 @@ dependencies:
|
|||||||
flutter_colorpicker: ^1.1.0
|
flutter_colorpicker: ^1.1.0
|
||||||
record: ^6.0.0
|
record: ^6.0.0
|
||||||
qr_flutter: ^4.1.0
|
qr_flutter: ^4.1.0
|
||||||
|
flutter_otp_text_field: ^1.5.1+1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user