Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 69 additions & 20 deletions lib/features/base/base_controller.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import 'dart:async';
import 'package:core/core.dart';
import 'package:flutter/services.dart' as services;

import 'package:contact/contact/model/capability_contact.dart';
import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:fcm/model/firebase_capability.dart';
import 'package:fcm/model/firebase_registration_id.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' as services;
import 'package:flutter_svg/flutter_svg.dart';
import 'package:forward/forward/capability_forward.dart';
import 'package:get/get.dart';
Expand All @@ -24,9 +25,11 @@ import 'package:tmail_ui_user/features/home/domain/extensions/session_extensions
import 'package:tmail_ui_user/features/login/data/network/config/oidc_constant.dart';
import 'package:tmail_ui_user/features/login/data/network/interceptors/authorization_interceptors.dart';
import 'package:tmail_ui_user/features/login/domain/exceptions/logout_exception.dart';
import 'package:tmail_ui_user/features/login/domain/model/login_source.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_authority_oidc_interactor.dart';
import 'package:tmail_ui_user/features/login/domain/usecases/delete_credential_interactor.dart';
import 'package:tmail_ui_user/features/login/presentation/login_form_type.dart';
import 'package:tmail_ui_user/features/login/presentation/model/auto_refresh_arguments.dart';
import 'package:tmail_ui_user/features/login/presentation/model/login_arguments.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/contact_autocomplete_bindings.dart';
import 'package:tmail_ui_user/features/mailbox_dashboard/presentation/bindings/tmail_autocomplete_bindings.dart';
Expand Down Expand Up @@ -56,8 +59,8 @@ import 'package:tmail_ui_user/main/exceptions/remote_exception.dart';
import 'package:tmail_ui_user/main/localizations/app_localizations.dart';
import 'package:tmail_ui_user/main/routes/app_routes.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart';
import 'package:tmail_ui_user/main/utils/app_config.dart';
import 'package:tmail_ui_user/main/universal_import/html_stub.dart' as html;
import 'package:tmail_ui_user/main/utils/app_config.dart';
import 'package:tmail_ui_user/main/utils/toast_manager.dart';
import 'package:tmail_ui_user/main/utils/twake_app_manager.dart';
import 'package:uuid/uuid.dart';
Expand Down Expand Up @@ -152,7 +155,8 @@ abstract class BaseController extends GetxController
bool validateUrgentException(dynamic exception) {
return exception is NoNetworkError
|| exception is BadCredentialsException
|| exception is ConnectionError;
|| exception is ConnectionError
|| exception is ClientAuthenticationException;
}

void handleErrorViewState(Object error, StackTrace stackTrace) {}
Expand All @@ -169,10 +173,14 @@ abstract class BaseController extends GetxController

void handleUrgentExceptionOnMobile({Failure? failure, Exception? exception}) {
logError('$runtimeType::handleUrgentExceptionOnMobile():Failure: $failure | Exception: $exception');
if (exception is ConnectionError) {
if (exception is NoNetworkError) {
_handleNotNetworkErrorException();
} else if (exception is ConnectionError) {
_handleConnectionErrorException();
} else if (exception is BadCredentialsException) {
handleBadCredentialsException();
} else if (exception is ClientAuthenticationException) {
handleClientAuthenticationException(exception);
}
}

Expand All @@ -184,13 +192,17 @@ abstract class BaseController extends GetxController
_handleConnectionErrorException();
} else if (exception is BadCredentialsException) {
handleBadCredentialsException();
} else if (exception is ClientAuthenticationException) {
handleClientAuthenticationException(exception);
}
}

Future<void> _executeBeforeReconnectAndLogOut() async {
Future<void> _executeBeforeReconnectAndLogOut({
LoginSource source = LoginSource.manual,
}) async {
twakeAppManager.setExecutingBeforeReconnect(true);
await executeBeforeReconnect();
clearDataAndGoToLoginPage();
clearDataAndGoToLoginPage(source: source);
}

void onCancelReconnectWhenSessionExpired() {}
Expand All @@ -213,29 +225,49 @@ abstract class BaseController extends GetxController
leadingSVGIcon: imagePaths.icNotConnection,
backgroundColor: AppColor.textFieldErrorBorderColor,
textColor: Colors.white,
infinityToast: true);
infinityToast: PlatformInfo.isWeb,
);
}
}

void handleBadCredentialsException() {
log('$runtimeType::handleBadCredentialsException:');
if (twakeAppManager.hasComposer) {
_performSaveAndReconnection();
_performSaveAndReconnection(source: LoginSource.auto);
} else {
_performReconnection();
_performReconnection(source: LoginSource.auto);
}
}

void _performSaveAndReconnection() {
void handleClientAuthenticationException(
ClientAuthenticationException exception,
) {
final message = exception.message;
final firstErrorCode = exception.code;
final secondErrorCode = exception.secondErrorCode;
log('$runtimeType::handleClientAuthenticationException: Message is $message, [$firstErrorCode - $secondErrorCode]');
if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage(
currentOverlayContext!,
'$message [$firstErrorCode - $secondErrorCode]',
);
}
}

void _performSaveAndReconnection({
LoginSource source = LoginSource.manual,
}) {
if (PlatformInfo.isWeb) {
_executeBeforeReconnectAndLogOut();
_executeBeforeReconnectAndLogOut(source: source);
} else if (PlatformInfo.isMobile) {
clearDataAndGoToLoginPage();
clearDataAndGoToLoginPage(source: source);
}
}

void _performReconnection() {
clearDataAndGoToLoginPage();
void _performReconnection({
LoginSource source = LoginSource.manual,
}) {
clearDataAndGoToLoginPage(source: source);
}

void onDataFailureViewState(Failure failure) {
Expand Down Expand Up @@ -396,9 +428,24 @@ abstract class BaseController extends GetxController
}
}

void removeAllPageAndGoToLogin() {
void removeAllPageAndGoToLogin({
LoginSource source = LoginSource.manual,
}) {
if (PlatformInfo.isMobile) {
pushAndPopAll(AppRoutes.twakeWelcome);
final jmapUrl = dynamicUrlInterceptors.jmapUrl ?? '';

final isAutoRefresh = source == LoginSource.auto &&
Get.currentRoute != AppRoutes.login &&
jmapUrl.isNotEmpty;

if (isAutoRefresh) {
pushAndPopAll(
AppRoutes.login,
arguments: AutoRefreshArguments(jmapUrl),
);
} else {
pushAndPopAll(AppRoutes.twakeWelcome);
}
} else {
navigateToLoginPage();
}
Expand Down Expand Up @@ -540,10 +587,12 @@ abstract class BaseController extends GetxController
await beforeReconnectManager?.executeBeforeReconnectListeners();
}

Future<void> clearDataAndGoToLoginPage() async {
log('$runtimeType::clearDataAndGoToLoginPage:');
Future<void> clearDataAndGoToLoginPage({
LoginSource source = LoginSource.manual,
}) async {
log('$runtimeType::clearDataAndGoToLoginPage: Login source is $source');
await clearAllData();
removeAllPageAndGoToLogin();
removeAllPageAndGoToLogin(source: source);
}

Future<void> clearAllData() async {
Expand Down
10 changes: 8 additions & 2 deletions lib/features/caching/clients/hive_cache_version_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,19 @@ class HiveCacheVersionClient extends CacheVersionClient {
return Future.sync(() {
final latestVersion = _sharedPreferences.getInt(versionKey);
return latestVersion;
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Future<bool> storeVersion(int newVersion) {
return Future.sync(() async {
return await _sharedPreferences.setInt(versionKey, newVersion);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,39 @@ class CleanupDataSourceImpl extends CleanupDataSource {
Future<void> cleanEmailCache(EmailCleanupRule cleanupRule) {
return Future.sync(() async {
return await emailCacheManager.clean(cleanupRule);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Future<void> cleanRecentSearchCache(RecentSearchCleanupRule cleanupRule) {
return Future.sync(() async {
return await recentSearchCacheManager.clean(cleanupRule);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Future<void> cleanRecentLoginUrlCache(RecentLoginUrlCleanupRule cleanupRule) {
return Future.sync(() async {
return await recentLoginUrlCacheManager.clean(cleanupRule);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Future<void> cleanRecentLoginUsernameCache(RecentLoginUsernameCleanupRule cleanupRule) {
return Future.sync(() async {
return await recentLoginUsernameCacheManager.clean(cleanupRule);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class ComposerDataSourceImpl extends ComposerDataSource {
filePath: fileInfo.filePath,
maxWidth: maxWidth,
compress: compress);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ class ContactDataSourceImpl extends ContactDataSource {
return <DeviceContact>[];
}
}
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

List<DeviceContact> _toDeviceContact(contact_service.Contact contact) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class TMailContactDataSourceImpl extends AutoCompleteDataSource {
return Future.sync(() async {
final listContacts = await _contactAPI.getAutoComplete(autoCompletePattern);
return listContacts.map((contact) => contact.toEmailAddress()).toList();
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ class CalendarEventDataSourceImpl extends CalendarEventDataSource {
Future<List<BlobCalendarEvent>> parse(AccountId accountId, Set<Id> blobIds) {
return Future.sync(() async {
return await _calendarEventAPI.parse(accountId, blobIds);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Expand All @@ -30,7 +33,10 @@ class CalendarEventDataSourceImpl extends CalendarEventDataSource {
String? language) {
return Future.sync(() async {
return await _calendarEventAPI.acceptEventInvitation(accountId, blobIds, language);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Expand All @@ -40,7 +46,10 @@ class CalendarEventDataSourceImpl extends CalendarEventDataSource {
String? language) {
return Future.sync(() async {
return await _calendarEventAPI.maybeEventInvitation(accountId, blobIds, language);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Expand All @@ -50,7 +59,10 @@ class CalendarEventDataSourceImpl extends CalendarEventDataSource {
String? language) {
return Future.sync(() async {
return await _calendarEventAPI.rejectEventInvitation(accountId, blobIds, language);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}

@override
Expand All @@ -60,6 +72,9 @@ class CalendarEventDataSourceImpl extends CalendarEventDataSource {
) {
return Future.sync(() async {
return await _calendarEventAPI.acceptCounterEvent(accountId, blobIds);
}).catchError(_exceptionThrower.throwException);
}).catchError((error, stackTrace) async {
await _exceptionThrower.throwException(error, stackTrace);
throw error;
});
}
}
Loading
Loading