Skip to content

Commit

Permalink
TW-888: Refactor ContactsManager
Browse files Browse the repository at this point in the history
  • Loading branch information
nqhhdev committed Nov 20, 2023
1 parent edfbec3 commit 73a9373
Show file tree
Hide file tree
Showing 15 changed files with 130 additions and 121 deletions.
5 changes: 0 additions & 5 deletions lib/data/datasource/phonebook_datasouce.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import 'package:fluffychat/domain/model/contact/contact.dart';
import 'package:flutter/foundation.dart';

abstract class PhonebookContactDatasource {
Future<List<Contact>> fetchContacts();

void addListener(VoidCallback callback);

void removeListener(VoidCallback callback);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:fluffychat/data/datasource/phonebook_datasouce.dart';
import 'package:fluffychat/domain/model/contact/contact.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_contacts/flutter_contacts.dart' hide Contact;

class PhonebookContactDatasourceImpl implements PhonebookContactDatasource {
Expand All @@ -27,14 +26,4 @@ class PhonebookContactDatasourceImpl implements PhonebookContactDatasource {
)
.toList();
}

@override
void addListener(VoidCallback callback) {
FlutterContacts.addListener(callback);
}

@override
void removeListener(VoidCallback callback) {
FlutterContacts.removeListener(callback);
}
}
12 changes: 0 additions & 12 deletions lib/data/repository/contact/phonebook_contact_repository_impl.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:ui';

import 'package:fluffychat/data/datasource/phonebook_datasouce.dart';
import 'package:fluffychat/di/global/get_it_initializer.dart';
import 'package:fluffychat/domain/model/contact/contact.dart';
Expand All @@ -13,14 +11,4 @@ class PhonebookContactRepositoryImpl extends PhonebookContactRepository {
Future<List<Contact>> fetchContacts() {
return datasource.fetchContacts();
}

@override
void addListener(VoidCallback callback) {
datasource.addListener(callback);
}

@override
void removeListener(VoidCallback callback) {
datasource.removeListener(callback);
}
}
10 changes: 5 additions & 5 deletions lib/di/global/network_di.dart
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ class NetworkDI extends BaseDI {
() => DioClient(get.get<Dio>(instanceName: identityServerDioName)),
instanceName: identityDioClientName,
);
dio.interceptors.add(
get.get<MatrixDioCacheInterceptor>(
instanceName: memCacheDioInterceptorName,
),
);
}

void _bindDioForHomeServer(GetIt get) {
Expand All @@ -156,11 +161,6 @@ class NetworkDI extends BaseDI {
instanceName: hiveCacheDioInterceptorName,
),
);
dio.interceptors.add(
get.get<MatrixDioCacheInterceptor>(
instanceName: memCacheDioInterceptorName,
),
);
}

void _bindMethodSupportHiveCache(GetIt get) {
Expand Down
93 changes: 39 additions & 54 deletions lib/domain/contact_manager/contacts_manager.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import 'dart:async';

import 'package:dartz/dartz.dart';
import 'package:fluffychat/app_state/failure.dart';
import 'package:fluffychat/app_state/success.dart';
Expand All @@ -8,12 +6,8 @@ import 'package:fluffychat/di/global/get_it_initializer.dart';
import 'package:fluffychat/domain/app_state/contact/get_contacts_state.dart';
import 'package:fluffychat/domain/app_state/contact/get_phonebook_contacts_state.dart';
import 'package:fluffychat/domain/usecase/get_tom_contacts_interactor.dart';
import 'package:fluffychat/presentation/enum/contacts/warning_contacts_banner_enum.dart';
import 'package:fluffychat/domain/usecase/phonebook_contact_interactor.dart';
import 'package:fluffychat/utils/permission_service.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/foundation.dart';
import 'package:permission_handler/permission_handler.dart';

class ContactsManager {
static const int _lookupChunkSize = 50;
Expand All @@ -22,76 +16,67 @@ class ContactsManager {

final _getTomContactsInteractor = getIt.get<GetTomContactsInteractor>();

final PermissionHandlerService _permissionHandlerService =
PermissionHandlerService();

final _phonebookContactInteractor = getIt.get<PhonebookContactInteractor>();

ValueNotifier<Either<Failure, Success>> contactsNotifier =
final ValueNotifier<Either<Failure, Success>> _contactsNotifier =
ValueNotifier(const Right(ContactsInitial()));

ValueNotifier<Either<Failure, Success>> phonebookContactsNotifier =
final ValueNotifier<Either<Failure, Success>> _phonebookContactsNotifier =
ValueNotifier(const Right(GetPhonebookContactsInitial()));

ValueNotifier<WarningContactsBannerState> warningBannerNotifier =
ValueNotifier(WarningContactsBannerState.hide);
ValueNotifier<Either<Failure, Success>> getContactsNotifier() =>
_contactsNotifier;

ContactsManager() {
_phonebookContactInteractor.addListener(_fetchPhonebookContacts);
}
ValueNotifier<Either<Failure, Success>> getPhonebookContactsNotifier() =>
_phonebookContactsNotifier;

bool get _isInitial =>
contactsNotifier.value.getSuccessOrNull<ContactsInitial>() != null;
_contactsNotifier.value.getSuccessOrNull<ContactsInitial>() != null;

void initialSynchronizeContacts() async {
if (PlatformInfos.isMobile && !_doNotShowWarningContactsBannerAgain) {
await _handleRequestContactsPermission();
}
if (!_isInitial) {
return;
}
_getAllContacts();
bool get isDoNotShowWarningContactsBannerAgain =>
_doNotShowWarningContactsBannerAgain;

set updateNotShowWarningContactsBannerAgain(bool value) {
_doNotShowWarningContactsBannerAgain = value;
}

Future<void> _handleRequestContactsPermission() async {
final currentContactsPermissionStatus =
await _permissionHandlerService.requestContactsPermissionActions();
if (currentContactsPermissionStatus == PermissionStatus.granted) {
warningBannerNotifier.value = WarningContactsBannerState.hide;
} else {
if (!_doNotShowWarningContactsBannerAgain) {
warningBannerNotifier.value = WarningContactsBannerState.display;
}
void initialSynchronizeContacts({
bool isAvailableSupportPhonebookContacts = false,
}) async {
if (!_isInitial) {
return;
}
_getAllContacts(
isAvailableSupportPhonebookContacts: isAvailableSupportPhonebookContacts,
);
}

void _getAllContacts() {
void _getAllContacts({
bool isAvailableSupportPhonebookContacts = false,
}) {
_getTomContactsInteractor
.execute(limit: AppConfig.maxFetchContacts)
.listen((event) {
contactsNotifier.value = event;
}).onDone(_fetchPhonebookContacts);
.listen(
(event) => _contactsNotifier.value = event,
)
.onDone(
() => _fetchPhonebookContacts(
isAvailableSupportPhonebookContacts:
isAvailableSupportPhonebookContacts,
),
);
}

void _fetchPhonebookContacts() async {
if (!PlatformInfos.isMobile ||
await _permissionHandlerService.contactsPermissionStatus !=
PermissionStatus.granted) {
void _fetchPhonebookContacts({
bool isAvailableSupportPhonebookContacts = false,
}) async {
if (!isAvailableSupportPhonebookContacts) {
return;
}
_phonebookContactInteractor
.execute(lookupChunkSize: _lookupChunkSize)
.listen((event) {
phonebookContactsNotifier.value = event;
});
}

void closeContactsWarningBanner() {
_doNotShowWarningContactsBannerAgain = true;
warningBannerNotifier.value = WarningContactsBannerState.notDisplayAgain;
}

void goToSettingsForPermissionActions() {
_permissionHandlerService.goToSettingsForPermissionActions();
.listen(
(event) => _phonebookContactsNotifier.value = event,
);
}
}
10 changes: 6 additions & 4 deletions lib/domain/model/extensions/contact/contacts_extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ extension ContactsExtension on Iterable<Contact> {
(field) =>
field?.toLowerCase().contains(keyword.toLowerCase()) ?? false,
);
final phoneNumberContains = contact.phoneNumber
?.msisdnSanitizer()
.contains(keyword.msisdnSanitizer()) ??
false;
final phoneNumberContains = keyword.msisdnSanitizer().isNotEmpty
? contact.phoneNumber
?.msisdnSanitizer()
.contains(keyword.msisdnSanitizer()) ??
false
: false;
return plainTextContains || phoneNumberContains;
});
return contactsMatched;
Expand Down
5 changes: 0 additions & 5 deletions lib/domain/repository/phonebook_contact_repository.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import 'package:fluffychat/domain/model/contact/contact.dart';
import 'package:flutter/foundation.dart';

abstract class PhonebookContactRepository {
Future<List<Contact>> fetchContacts();

void addListener(VoidCallback callback);

void removeListener(VoidCallback callback);
}
14 changes: 5 additions & 9 deletions lib/domain/usecase/phonebook_contact_interactor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import 'package:fluffychat/domain/model/contact/contact_status.dart';
import 'package:fluffychat/domain/model/contact/lookup_list_mxid_request.dart';
import 'package:fluffychat/domain/repository/lookup_repository.dart';
import 'package:fluffychat/domain/repository/phonebook_contact_repository.dart';
import 'package:flutter/foundation.dart';
import 'package:matrix/matrix.dart';

class PhonebookContactInteractor {
Expand Down Expand Up @@ -44,6 +43,11 @@ class PhonebookContactInteractor {
final chunks =
thirdPartyIdToHashMap.values.whereNotNull().slices(lookupChunkSize);

if (chunks.isEmpty) {
yield Right(GetPhonebookContactsSuccess(contacts: contacts));
return;
}

final int progressStep = (_progressMax - progress) ~/ chunks.length;
final Map<String, String> hashToMatrixIdMappings = {};
final Map<String, String> hashToInactiveMatrixIdMappings = {};
Expand Down Expand Up @@ -87,12 +91,4 @@ class PhonebookContactInteractor {
yield Left(GetPhonebookContactsFailure(exception: e));
}
}

void addListener(VoidCallback callback) {
_phonebookContactRepository.addListener(callback);
}

void removeListener(VoidCallback callback) {
_phonebookContactRepository.removeListener(callback);
}
}
5 changes: 5 additions & 0 deletions lib/pages/contacts_tab/contacts_tab_body_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,17 @@ class _SliverWarningBanner extends StatelessWidget {
return SliverToBoxAdapter(
child: ContactsWarningBannerView(
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner: controller.closeContactsWarningBanner,
goToSettingsForPermissionActions:
controller.goToSettingsForPermissionActions,
),
);
}
}

class _PhonebookLoading extends StatelessWidget {
final int progress;

const _PhonebookLoading({
required this.progress,
});
Expand Down Expand Up @@ -226,6 +230,7 @@ class _Contact extends StatelessWidget {
required this.contact,
required this.controller,
});

final PresentationContact contact;
final ContactsTabController controller;

Expand Down
4 changes: 4 additions & 0 deletions lib/pages/new_group/contacts_selection_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class ContactsSelectionView extends StatelessWidget {
SliverToBoxAdapter(
child: ContactsWarningBannerView(
warningBannerNotifier: controller.warningBannerNotifier,
closeContactsWarningBanner:
controller.closeContactsWarningBanner,
goToSettingsForPermissionActions:
controller.goToSettingsForPermissionActions,
),
),
SliverToBoxAdapter(
Expand Down
6 changes: 6 additions & 0 deletions lib/pages/new_private_chat/widget/expansion_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ class ExpansionList extends StatelessWidget {
onContactTap;
final TextEditingController textEditingController;
final ValueNotifier<WarningContactsBannerState> warningBannerNotifier;
final Function()? closeContactsWarningBanner;
final Function()? goToSettingsForPermissionActions;

const ExpansionList({
super.key,
Expand All @@ -37,6 +39,8 @@ class ExpansionList extends StatelessWidget {
required this.onContactTap,
required this.textEditingController,
required this.warningBannerNotifier,
this.closeContactsWarningBanner,
this.goToSettingsForPermissionActions,
});

@override
Expand Down Expand Up @@ -186,6 +190,8 @@ class ExpansionList extends StatelessWidget {
return ContactsWarningBannerView(
warningBannerNotifier: warningBannerNotifier,
isShowMargin: false,
closeContactsWarningBanner: closeContactsWarningBanner,
goToSettingsForPermissionActions: goToSettingsForPermissionActions,
);
}

Expand Down
4 changes: 3 additions & 1 deletion lib/pages/search/search_contacts_and_chats_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ class SearchContactsAndChatsController {
if (keyword.isEmpty) {
return fetchPreSearchChat();
}
final tomContacts = contactManger.contactsNotifier.value
final tomContacts = contactManger
.getContactsNotifier()
.value
.getSuccessOrNull<GetContactsSuccess>()
?.contacts ??
[];
Expand Down
Loading

0 comments on commit 73a9373

Please sign in to comment.