Skip to content

Instantly share code, notes, and snippets.

@locskot
Created March 18, 2022 07:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save locskot/3b049050eaea5c57d102b7cff52e0f3a to your computer and use it in GitHub Desktop.
Save locskot/3b049050eaea5c57d102b7cff52e0f3a to your computer and use it in GitHub Desktop.
import 'dart:core';
import 'package:components/api/graphql_api.dart';
import 'package:components/base/viewmodel/base_viewmodel.dart';
import 'package:components/events/event_sender.dart';
import 'package:components/model/enums/profile_enums.dart';
import 'package:components/model/invitations/dynamic_links_service.dart';
import 'package:components/model/phi/client_model.dart';
import 'package:rxdart/rxdart.dart';
import '../../../app/data/phi/profile_repository.dart';
import '../../../repo/verification/verification_repository.dart';
enum UserPreverifyEvents {
alreadyVerified,
resendVerificationError,
resendVerificationOk,
verificationOk,
verificationError,
verificationErrorToken,
profileLoadError,
leaveBack,
}
abstract class UserPreverifyViewModel extends BaseViewModel<void, void> {
UserPreverifyViewModel(GraphqlAPI graphqlAPI, EventSender eventSender) : super(graphqlAPI, eventSender);
factory UserPreverifyViewModel.create({
ProfileRepository profileRepository,
VerificationRepository verificationRepository,
DynamicLinksService dynamicLinksService,
}) {
return UserPreverifyViewModelImpl(profileRepository, verificationRepository, dynamicLinksService);
}
// Account info
String get email;
Stream<UserPreverifyEvents> get events;
bool get initializing;
bool get requestInProgress;
Future<void> init(String userId);
Future<void> resendVerification();
Future<void> goBack();
}
class UserPreverifyViewModelImpl extends UserPreverifyViewModel {
final ProfileRepository _profileRepository;
final VerificationRepository _verificationRepository;
final DynamicLinksService _linksService;
final _eventsPublishSubject = PublishSubject<UserPreverifyEvents>();
bool _requestInProgress = false;
bool _initializing = true;
String _email = '';
UserPreverifyViewModelImpl(
this._profileRepository,
this._verificationRepository,
this._linksService,
) : super(null, null);
@override
String get email => _email;
@override
Stream<UserPreverifyEvents> get events => _eventsPublishSubject.stream;
@override
bool get requestInProgress => _requestInProgress;
@override
bool get initializing => _initializing;
set requestInProgress(bool val) {
_requestInProgress = val;
notifyListeners();
}
set initializing(bool val) {
_initializing = val;
notifyListeners();
}
@override
void onRemove() {
_linksService.removeListener(emailTokenListener);
super.onRemove();
}
Future<void> verifyEmailAndEmitEvent(String link) async {
//Sometimes link contains dot in the end
final response = await _verificationRepository.verifyEmail(link.replaceAll('.', ''));
if (response.result) {
_eventsPublishSubject.add(UserPreverifyEvents.verificationOk);
} else if (response.value == 'Verification link is expired') {
_eventsPublishSubject.add(UserPreverifyEvents.verificationErrorToken);
} else {
_eventsPublishSubject.add(UserPreverifyEvents.verificationError);
}
}
Future<void> emailTokenListener() async {
if (requestInProgress) {
return;
}
if (_linksService.emailVerificationToken != null) {
requestInProgress = true;
await verifyEmailAndEmitEvent(_linksService.emailVerificationToken);
_linksService.emailVerificationToken = null;
requestInProgress = false;
}
}
Future<ProfileModel> loadProfile(String userId) async {
try {
await _profileRepository.loadBaseInfo(userId);
return _profileRepository.getProfile();
} on Exception catch (_) {
return null;
}
}
Future<void> init(String userId) async {
initializing = true;
_linksService.addListener(emailTokenListener);
final profile = await loadProfile(userId);
if (profile == null) {
_eventsPublishSubject.add(UserPreverifyEvents.profileLoadError);
initializing = false;
return;
}
_email = profile.email;
if (profile.emailVerified) {
_eventsPublishSubject.add(UserPreverifyEvents.alreadyVerified);
return;
}
if (_linksService.emailVerificationToken != null) {
await verifyEmailAndEmitEvent(_linksService.emailVerificationToken);
_linksService.emailVerificationToken = null;
}
initializing = false;
}
@override
Future<void> goBack() async {
_eventsPublishSubject.add(UserPreverifyEvents.leaveBack);
}
@override
Future<void> resendVerification() async {
requestInProgress = true;
final result = await _verificationRepository.sendVerificationCode(email, VerificationType.email);
if (result.result) {
_eventsPublishSubject.add(UserPreverifyEvents.resendVerificationOk);
} else {
_eventsPublishSubject.add(UserPreverifyEvents.resendVerificationError);
}
requestInProgress = false;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment