Skip to content

Commit

Permalink
Merge pull request #59 from TomerPacific/feature/replacing-contacts-p…
Browse files Browse the repository at this point in the history
…ackage

Replacing contacts package
  • Loading branch information
TomerPacific authored Apr 22, 2024
2 parents de6bdf4 + f23b055 commit 742a32c
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 78 deletions.
1 change: 1 addition & 0 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ const contactsPermissionStatusKey = "contactsPermissionStatusKey";

const contactsImportedSuccessfullyMsg = "Contacts Imported Successfully";
const noContactsFoundMsg = "There are no contacts on your device";
const alreadyAddedContactsMsg = "All of your current contacts have already been added";
const versionToMigrateNotificationStatusFrom = "1.2.1";
const didAlreadyMigrateNotificationStatusFlag = "migrateNotificationStatus";
12 changes: 7 additions & 5 deletions lib/page/birthday/birthday.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ class BirthdayWidget extends StatelessWidget {
Provider.of<BirthdayManager>(context, listen: false).updateNotificationStatusForBirthday();
}),
),
new IconButton(
icon: Icon(Icons.call, color: Provider.of<BirthdayManager>(context, listen: false).getColorBasedOnPosition(indexOfBirthday, ElementType.icon)),
onPressed: () {
Provider.of<BirthdayManager>(context, listen: false).handleCallButtonPressed(birthdayOfPerson.phoneNumber);
}),
if (birthdayOfPerson.phoneNumber.isNotEmpty) ...[
new IconButton(
icon: Icon(Icons.call, color: Provider.of<BirthdayManager>(context, listen: false).getColorBasedOnPosition(indexOfBirthday, ElementType.icon)),
onPressed: () {
Provider.of<BirthdayManager>(context, listen: false).handleCallButtonPressed(birthdayOfPerson.phoneNumber);
})
],
new IconButton(
icon: Icon(Icons.clear, color: Provider.of<BirthdayManager>(context, listen: false).getColorBasedOnPosition(indexOfBirthday, ElementType.icon)),
onPressed: onDeletePressedCallback),
Expand Down
32 changes: 20 additions & 12 deletions lib/page/settings_page/settings_screen_manager.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@

import 'package:birthday_calendar/model/user_birthday.dart';
import 'package:birthday_calendar/service/storage_service/storage_service.dart';
import 'package:flutter/material.dart';
import 'package:birthday_calendar/service/contacts_service/bc_contacts_service.dart';
import 'package:birthday_calendar/service/permission_service/permissions_service.dart';
import 'package:birthday_calendar/service/snackbar_service/SnackbarService.dart';
import 'package:birthday_calendar/widget/users_without_birthdays_dialogs.dart';
import 'package:flutter_contacts/contact.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:birthday_calendar/constants.dart';
import 'package:contacts_service/contacts_service.dart';
import 'package:birthday_calendar/service/service_locator.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:birthday_calendar/utils.dart';

class SettingsScreenManager extends ChangeNotifier {

Expand Down Expand Up @@ -99,29 +101,31 @@ class SettingsScreenManager extends ChangeNotifier {
void _processContacts(BuildContext context) async {
List<Contact> contacts = await _bcContactsService.fetchContacts(false);

if (contacts.length == 0) {
if (contacts.isEmpty) {
_snackbarService.showSnackbarWithMessage(context, noContactsFoundMsg);
return;
}

_bcContactsService.addContactsWithBirthdays(contacts);
List<Contact> contactsWithoutBirthDates = await _bcContactsService.gatherContactsWithoutBirthdays(contacts);
contacts = await Utils.filterAlreadyImportedContacts(_storageService, contacts);

if (contactsWithoutBirthDates.length > 0) {
_handleAddingBirthdaysToContacts(context, contactsWithoutBirthDates);
} else {
_snackbarService.showSnackbarWithMessage(context, contactsImportedSuccessfullyMsg);
if (contacts.isEmpty) {
_snackbarService.showSnackbarWithMessage(context, alreadyAddedContactsMsg);
return;
}

_handleAddingBirthdaysToContacts(context, contacts);
}

void addContactToCalendar(Contact contact) {


void addContactToCalendar(UserBirthday contact) {
_bcContactsService.addContactToCalendar(contact);
}

void _handleAddingBirthdaysToContacts(BuildContext context, List<Contact> contactsWithoutBirthDates) async {
UsersWithoutBirthdaysDialogs assignBirthdaysToUsers = UsersWithoutBirthdaysDialogs(contactsWithoutBirthDates);
List<Contact> users = await assignBirthdaysToUsers.showConfirmationDialog(context);
if (users.length > 0) {
if (users.isNotEmpty) {
_gatherBirthdaysForUsers(context, users);
}
}
Expand All @@ -141,8 +145,12 @@ class SettingsScreenManager extends ChangeNotifier {
);

if (chosenBirthDate != null) {
contact.birthday = chosenBirthDate;
addContactToCalendar(contact);
UserBirthday userBirthday = new UserBirthday(contact.displayName,
chosenBirthDate,
true,
contact.phones.length > 0 ? contact.phones.first.number : "");

addContactToCalendar(userBirthday);
amountOfBirthdaysSet++;
}
}
Expand Down
7 changes: 3 additions & 4 deletions lib/service/contacts_service/bc_contacts_service.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import 'package:contacts_service/contacts_service.dart';
import 'package:birthday_calendar/model/user_birthday.dart';
import 'package:flutter_contacts/flutter_contacts.dart';

abstract class BCContactsService {
Future<List<Contact>> fetchContacts(bool withThumbnails);
Future<List<Contact>> gatherContactsWithoutBirthdays(List<Contact> contacts);
void addContactsWithBirthdays(List<Contact> contacts);
void addContactToCalendar(Contact contact);
void addContactToCalendar(UserBirthday contact);
}
41 changes: 8 additions & 33 deletions lib/service/contacts_service/bc_contacts_service_impl.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:contacts_service/contacts_service.dart';
import 'package:birthday_calendar/service/contacts_service/bc_contacts_service.dart';
import 'package:birthday_calendar/service/service_locator.dart';
import 'package:birthday_calendar/service/storage_service/storage_service.dart';
import 'package:birthday_calendar/service/notification_service/notification_service.dart';
import 'package:birthday_calendar/model/user_birthday.dart';
import 'package:collection/collection.dart';
import 'package:flutter_contacts/flutter_contacts.dart';

class BCContactsServiceImpl extends BCContactsService {

Expand All @@ -13,28 +13,12 @@ class BCContactsServiceImpl extends BCContactsService {

@override
Future<List<Contact>> fetchContacts(bool withThumbnails) async {
return await ContactsService.getContacts(withThumbnails: false);
return await FlutterContacts.getContacts();
}

Future<List<Contact>> gatherContactsWithoutBirthdays(List<Contact> contacts) async {
List<Contact> usersWithoutBirthdays = contacts.where((element) => element.birthday == null).toList();
return usersWithoutBirthdays;
}

void addContactsWithBirthdays(List<Contact> contacts) {
for (Contact person in contacts) {
if (person.birthday != null &&
person.displayName != null &&
person.phones != null) {
addContactToCalendar(person);
}
}
}

void addContactToCalendar(Contact contact) async {
String phoneNumber = "";
List<UserBirthday> birthdays = await _storageService.getBirthdaysForDate(contact.birthday!, false);
String contactName = contact.displayName!;
void addContactToCalendar(UserBirthday contact) async {
List<UserBirthday> birthdays = await _storageService.getBirthdaysForDate(contact.birthdayDate, false);
String contactName = contact.name;

UserBirthday? birthdayWithSameName = birthdays.firstWhereOrNull((element) => element.name == contactName);

Expand All @@ -43,21 +27,12 @@ class BCContactsServiceImpl extends BCContactsService {
return;
}

if (contact.phones != null && contact.phones!.length > 0) {
phoneNumber = contact.phones!.first.value!;
}

UserBirthday birthday = new UserBirthday(
contact.displayName!,
contact.birthday!,
true,
phoneNumber);
_notificationService.scheduleNotificationForBirthday(
birthday, "${contact.displayName!} has an upcoming birthday!");
contact, "${contact.name} has an upcoming birthday!");

birthdays.add(birthday);
birthdays.add(contact);

_storageService.saveBirthdaysForDate(contact.birthday!, birthdays);
_storageService.saveBirthdaysForDate(contact.birthdayDate, birthdays);
}

}
29 changes: 28 additions & 1 deletion lib/service/storage_service/shared_preferences_storage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import 'package:birthday_calendar/constants.dart';
import 'package:birthday_calendar/model/user_birthday.dart';
import 'package:intl/intl.dart';
import 'storage_service.dart';
import '../date_service/date_service.dart';
import 'package:birthday_calendar/service/date_service/date_service.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:birthday_calendar/service/service_locator.dart';

Expand Down Expand Up @@ -124,29 +124,56 @@ class StorageServiceSharedPreferences extends StorageService {
return streamController.stream;
}

@override
void saveIsContactsPermissionPermanentlyDenied(bool isPermanentlyDenied) async {
final sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setBool(contactsPermissionStatusKey, isPermanentlyDenied);
}

@override
Future<bool> getIsContactPermissionPermanentlyDenied() async {
final sharedPreferences = await SharedPreferences.getInstance();
bool? isPermanentlyDenied = sharedPreferences.getBool(contactsPermissionStatusKey);
return isPermanentlyDenied != null ? isPermanentlyDenied : false;
}

@override
void saveDidAlreadyMigrateNotificationStatus(bool status) async {
final sharedPreferences = await SharedPreferences.getInstance();
sharedPreferences.setBool(didAlreadyMigrateNotificationStatusFlag, status);
}


@override
Future<bool> getAlreadyMigrateNotificationStatus() async {
final sharedPreferences = await SharedPreferences.getInstance();
bool? hasAlreadyMigratedNotificationStatus = sharedPreferences.getBool(didAlreadyMigrateNotificationStatusFlag);
return hasAlreadyMigratedNotificationStatus != null ? hasAlreadyMigratedNotificationStatus : false;
}

@override
Future<List<UserBirthday>> getAllBirthdays() async {
List<UserBirthday> birthdays = [];
final sharedPreferences = await SharedPreferences.getInstance();
Set<String> dates = sharedPreferences.getKeys();

for (String date in dates) {
if (!_dateService.isADate(date)) {
continue;
}

String? birthdaysJSON = sharedPreferences.getString(date);
if (birthdaysJSON != null) {
List decodedBirthdaysForDate = jsonDecode(birthdaysJSON);
List<UserBirthday> userBirthdays = decodedBirthdaysForDate
.map((decodedBirthday) => UserBirthday.fromJson(decodedBirthday)).toList();
birthdays = birthdays + userBirthdays;
}
}

return birthdays;
}

void dispose() {
streamController.close();
}
Expand Down
1 change: 1 addition & 0 deletions lib/service/storage_service/storage_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ abstract class StorageService {
Future<bool> getIsContactPermissionPermanentlyDenied();
void saveDidAlreadyMigrateNotificationStatus(bool status);
Future<bool> getAlreadyMigrateNotificationStatus();
Future<List<UserBirthday>> getAllBirthdays();
void dispose();
}
18 changes: 18 additions & 0 deletions lib/utils.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

import 'package:birthday_calendar/service/storage_service/storage_service.dart';
import 'package:flutter_contacts/contact.dart';

import 'model/user_birthday.dart';

class Utils {

static Future<List<Contact>> filterAlreadyImportedContacts(
StorageService _storageService,
List<Contact> contacts) async {
List<UserBirthday> allStoredBirthdays = await _storageService.getAllBirthdays();
List<String> names = allStoredBirthdays.map((e) => e.name).toList();
List<Contact> filtered = contacts.where((contact) => !names.contains(contact.displayName)).toList();
return filtered;
}

}
10 changes: 4 additions & 6 deletions lib/widget/users_without_birthdays_dialogs.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import 'package:flutter/material.dart';
import 'package:contacts_service/contacts_service.dart';
import 'package:flutter_contacts/contact.dart';

class UsersWithoutBirthdaysDialogs {

Expand All @@ -10,10 +10,8 @@ class UsersWithoutBirthdaysDialogs {

Future<List<Contact>> showConfirmationDialog(BuildContext context) async {
AlertDialog alert = AlertDialog(
title: Text("Add Birthdays For People"),
content: Text(
"There are contacts on your phone who do not have a birth date. "
"Would you like to manually add birth dates for them?"),
title: Text("Add Birthdays To Contacts"),
content: Text("Would you like to add birth dates for your imported contacts?"),
actions: [
TextButton(
onPressed: () {
Expand Down Expand Up @@ -60,7 +58,7 @@ class UsersWithoutBirthdaysDialogs {
itemCount: usersWithoutBirthdays.length,
itemBuilder: (BuildContext context, int index) {
return CheckboxListTile(
title: Text(usersWithoutBirthdays[index].displayName!),
title: Text(usersWithoutBirthdays[index].displayName),
value: _usersSelectedToAddBirthdaysFor[index],
onChanged: (bool? value) {
if (value != null) {
Expand Down
24 changes: 8 additions & 16 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.18.0"
contacts_service:
dependency: "direct main"
description:
name: contacts_service
sha256: f6d5ea33b31dfcdcd2e65d8abdc836502e04ddb0f66a96aa726fa9891ea9671e
url: "https://pub.dev"
source: hosted
version: "0.6.3"
convert:
dependency: transitive
description:
Expand Down Expand Up @@ -134,6 +126,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_contacts:
dependency: "direct main"
description:
name: flutter_contacts
sha256: "4fb4910fbe401ff234bc672304ef37f90319144920e940d1349b96fe089c6da7"
url: "https://pub.dev"
source: hosted
version: "1.1.7+1"
flutter_launcher_icons:
dependency: "direct main"
description:
Expand Down Expand Up @@ -432,14 +432,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.1.1"
quiver:
dependency: transitive
description:
name: quiver
sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47
url: "https://pub.dev"
source: hosted
version: "3.2.1"
shared_preferences:
dependency: "direct main"
description:
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies:
url_launcher: ^6.0.17
package_info_plus: ^3.1.2
permission_handler: ^10.2.0
contacts_service: ^0.6.3
flutter_contacts: ^1.1.7+1
get_it: ^6.0.0
provider: ^6.0.2
in_app_update: ^3.0.0
Expand Down

0 comments on commit 742a32c

Please sign in to comment.