78 lines
2.4 KiB
Dart
78 lines
2.4 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
|
|
import '../models/verification.dart';
|
|
import '../services/verification.dart';
|
|
|
|
class VerificationProvider extends ChangeNotifier {
|
|
VerificationProvider(this.service);
|
|
final VerificationService service;
|
|
VerificationState _state = const VerificationState(VerificationStatus.idle);
|
|
VerificationState get state => _state;
|
|
bool _disposed = false;
|
|
int _generation = 0;
|
|
|
|
Future<void> send({required String email, required String locale}) => _run(
|
|
() => service.send(email: email.trim(), locale: locale),
|
|
VerificationStatus.sending,
|
|
VerificationStatus.sent,
|
|
);
|
|
Future<void> confirm(String token) => _run(
|
|
() => service.confirm(token: token),
|
|
VerificationStatus.checking,
|
|
VerificationStatus.verified,
|
|
);
|
|
|
|
Future<void> _run(
|
|
Future<VerificationResult> Function() operation,
|
|
VerificationStatus loading,
|
|
VerificationStatus success,
|
|
) async {
|
|
if (_disposed || _state.isLoading) return;
|
|
final generation = ++_generation;
|
|
_state = VerificationState(loading);
|
|
notifyListeners();
|
|
if (_disposed || generation != _generation) return;
|
|
try {
|
|
final result = await operation();
|
|
if (_disposed || generation != _generation) return;
|
|
_state = VerificationState(
|
|
success,
|
|
isSimulated: result.isSimulated,
|
|
result: success == VerificationStatus.verified ? result : null,
|
|
);
|
|
} catch (error) {
|
|
if (_disposed || generation != _generation) return;
|
|
final code = error is VerificationException
|
|
? error.code
|
|
: VerificationError.internal;
|
|
// Send failures must not be presented as confirmation-token failures.
|
|
_state = VerificationState(
|
|
loading == VerificationStatus.sending
|
|
? VerificationStatus.error
|
|
: switch (code) {
|
|
VerificationError.expired => VerificationStatus.expired,
|
|
VerificationError.invalid => VerificationStatus.invalid,
|
|
VerificationError.internal => VerificationStatus.error,
|
|
VerificationError.needsAssistance => VerificationStatus.error,
|
|
},
|
|
error: code,
|
|
);
|
|
}
|
|
notifyListeners();
|
|
}
|
|
|
|
void reset() {
|
|
if (_disposed) return;
|
|
++_generation;
|
|
_state = const VerificationState(VerificationStatus.idle);
|
|
notifyListeners();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_disposed = true;
|
|
++_generation;
|
|
super.dispose();
|
|
}
|
|
}
|