Files
sxchnge/frontend/packages/sxchnge_auth/lib/src/providers/verification.dart
T

74 lines
2.3 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);
} 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();
}
}