feat: can block/unblock in history page (#29)
All checks were successful
/ mirror (push) Successful in 4s
All checks were successful
/ mirror (push) Successful in 4s
Reviewed-on: #29 Co-authored-by: Florian Griffon <florian.griffon@epitech.eu> Co-committed-by: Florian Griffon <florian.griffon@epitech.eu>
This commit is contained in:
parent
ee1f2ee4b1
commit
f99fdaa160
@ -6,6 +6,7 @@ import 'package:intl/intl.dart';
|
|||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:dialer/features/contacts/contact_state.dart';
|
import 'package:dialer/features/contacts/contact_state.dart';
|
||||||
import 'package:dialer/widgets/username_color_generator.dart';
|
import 'package:dialer/widgets/username_color_generator.dart';
|
||||||
|
import '../../services/block_service.dart';
|
||||||
|
|
||||||
class History {
|
class History {
|
||||||
final Contact contact;
|
final Contact contact;
|
||||||
@ -30,7 +31,8 @@ class HistoryPage extends StatefulWidget {
|
|||||||
_HistoryPageState createState() => _HistoryPageState();
|
_HistoryPageState createState() => _HistoryPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HistoryPageState extends State<HistoryPage> with SingleTickerProviderStateMixin {
|
class _HistoryPageState extends State<HistoryPage>
|
||||||
|
with SingleTickerProviderStateMixin {
|
||||||
List<History> histories = [];
|
List<History> histories = [];
|
||||||
bool loading = true;
|
bool loading = true;
|
||||||
int? _expandedIndex;
|
int? _expandedIndex;
|
||||||
@ -91,7 +93,8 @@ class _HistoryPageState extends State<HistoryPage> with SingleTickerProviderStat
|
|||||||
List<History> olderHistories = [];
|
List<History> olderHistories = [];
|
||||||
|
|
||||||
for (var history in historyList) {
|
for (var history in historyList) {
|
||||||
final callDate = DateTime(history.date.year, history.date.month, history.date.day);
|
final callDate =
|
||||||
|
DateTime(history.date.year, history.date.month, history.date.day);
|
||||||
if (callDate == today) {
|
if (callDate == today) {
|
||||||
todayHistories.add(history);
|
todayHistories.add(history);
|
||||||
} else if (callDate == yesterday) {
|
} else if (callDate == yesterday) {
|
||||||
@ -145,7 +148,8 @@ class _HistoryPageState extends State<HistoryPage> with SingleTickerProviderStat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Filter missed calls
|
// Filter missed calls
|
||||||
List<History> missedCalls = histories.where((h) => h.callStatus == 'missed').toList();
|
List<History> missedCalls =
|
||||||
|
histories.where((h) => h.callStatus == 'missed').toList();
|
||||||
|
|
||||||
final allItems = _buildGroupedList(histories);
|
final allItems = _buildGroupedList(histories);
|
||||||
final missedItems = _buildGroupedList(missedCalls);
|
final missedItems = _buildGroupedList(missedCalls);
|
||||||
@ -215,13 +219,6 @@ class _HistoryPageState extends State<HistoryPage> with SingleTickerProviderStat
|
|||||||
backgroundColor: avatarColor,
|
backgroundColor: avatarColor,
|
||||||
fallbackInitial: contact.displayName,
|
fallbackInitial: contact.displayName,
|
||||||
),
|
),
|
||||||
// child: Text(
|
|
||||||
// contact.displayName.isNotEmpty
|
|
||||||
// ? contact.displayName[0].toUpperCase()
|
|
||||||
// : '?',
|
|
||||||
// style: TextStyle(color: darken(avatarColor, 0.4)),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
title: Text(
|
title: Text(
|
||||||
_obfuscateService.obfuscateData(contact.displayName),
|
_obfuscateService.obfuscateData(contact.displayName),
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(color: Colors.white),
|
||||||
@ -241,18 +238,20 @@ class _HistoryPageState extends State<HistoryPage> with SingleTickerProviderStat
|
|||||||
icon: const Icon(Icons.phone, color: Colors.green),
|
icon: const Icon(Icons.phone, color: Colors.green),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (contact.phones.isNotEmpty) {
|
if (contact.phones.isNotEmpty) {
|
||||||
final Uri callUri =
|
final Uri callUri = Uri(
|
||||||
Uri(scheme: 'tel', path: contact.phones.first.number);
|
scheme: 'tel', path: contact.phones.first.number);
|
||||||
if (await canLaunchUrl(callUri)) {
|
if (await canLaunchUrl(callUri)) {
|
||||||
await launchUrl(callUri);
|
await launchUrl(callUri);
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Could not launch call')),
|
const SnackBar(
|
||||||
|
content: Text('Could not launch call')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Contact has no phone number')),
|
const SnackBar(
|
||||||
|
content: Text('Contact has no phone number')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -268,56 +267,99 @@ class _HistoryPageState extends State<HistoryPage> with SingleTickerProviderStat
|
|||||||
if (isExpanded)
|
if (isExpanded)
|
||||||
Container(
|
Container(
|
||||||
color: Colors.grey[850],
|
color: Colors.grey[850],
|
||||||
child: Row(
|
child: FutureBuilder<bool>(
|
||||||
|
future: BlockService().isNumberBlocked(
|
||||||
|
contact.phones.isNotEmpty
|
||||||
|
? contact.phones.first.number
|
||||||
|
: ''),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
final isBlocked = snapshot.data ?? false;
|
||||||
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||||
children: [
|
children: [
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (history.contact.phones.isNotEmpty) {
|
if (history.contact.phones.isNotEmpty) {
|
||||||
final Uri smsUri =
|
final Uri smsUri = Uri(
|
||||||
Uri(scheme: 'sms', path: history.contact.phones.first.number);
|
scheme: 'sms',
|
||||||
|
path: history.contact.phones.first.number);
|
||||||
if (await canLaunchUrl(smsUri)) {
|
if (await canLaunchUrl(smsUri)) {
|
||||||
await launchUrl(smsUri);
|
await launchUrl(smsUri);
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Could not send message')),
|
const SnackBar(
|
||||||
|
content:
|
||||||
|
Text('Could not send message')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(content: Text('Contact has no phone number')),
|
const SnackBar(
|
||||||
|
content:
|
||||||
|
Text('Contact has no phone number')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.message, color: Colors.white),
|
icon:
|
||||||
label: const Text('Message', style: TextStyle(color: Colors.white)),
|
const Icon(Icons.message, color: Colors.white),
|
||||||
|
label: const Text('Message',
|
||||||
|
style: TextStyle(color: Colors.white)),
|
||||||
),
|
),
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
// Navigate to Call Details page
|
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (_) => CallDetailsPage(history: history),
|
builder: (_) =>
|
||||||
|
CallDetailsPage(history: history),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.info, color: Colors.white),
|
icon: const Icon(Icons.info, color: Colors.white),
|
||||||
label: const Text('Details', style: TextStyle(color: Colors.white)),
|
label: const Text('Details',
|
||||||
|
style: TextStyle(color: Colors.white)),
|
||||||
),
|
),
|
||||||
TextButton.icon(
|
TextButton.icon(
|
||||||
onPressed: () {
|
onPressed: () async {
|
||||||
// Implement block number functionality
|
final phoneNumber = contact.phones.isNotEmpty
|
||||||
|
? contact.phones.first.number
|
||||||
|
: null;
|
||||||
|
if (phoneNumber == null) {
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
const SnackBar(
|
const SnackBar(
|
||||||
content: Text('Number blocked (functionality not implemented)'),
|
content:
|
||||||
|
Text('Contact has no phone number'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBlocked) {
|
||||||
|
await BlockService().unblockNumber(phoneNumber);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('$phoneNumber unblocked')),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
await BlockService().blockNumber(phoneNumber);
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text('$phoneNumber blocked')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
setState(() {}); // Refresh the button state
|
||||||
},
|
},
|
||||||
icon: const Icon(Icons.block, color: Colors.white),
|
icon: Icon(
|
||||||
label: const Text('Block', style: TextStyle(color: Colors.white)),
|
isBlocked ? Icons.lock_open : Icons.block,
|
||||||
|
color: Colors.white),
|
||||||
|
label: Text(
|
||||||
|
isBlocked ? 'Unblock' : 'Block',
|
||||||
|
style: const TextStyle(color: Colors.white),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -363,7 +405,8 @@ class CallDetailsPage extends StatelessWidget {
|
|||||||
fallbackInitial: contact.displayName,
|
fallbackInitial: contact.displayName,
|
||||||
)
|
)
|
||||||
: CircleAvatar(
|
: CircleAvatar(
|
||||||
backgroundColor: generateColorFromName(contact.displayName),
|
backgroundColor:
|
||||||
|
generateColorFromName(contact.displayName),
|
||||||
radius: 30,
|
radius: 30,
|
||||||
child: Text(
|
child: Text(
|
||||||
contact.displayName.isNotEmpty
|
contact.displayName.isNotEmpty
|
||||||
@ -407,7 +450,8 @@ class CallDetailsPage extends StatelessWidget {
|
|||||||
if (contact.phones.isNotEmpty)
|
if (contact.phones.isNotEmpty)
|
||||||
DetailRow(
|
DetailRow(
|
||||||
label: 'Number:',
|
label: 'Number:',
|
||||||
value: _obfuscateService.obfuscateData(contact.phones.first.number),
|
value: _obfuscateService
|
||||||
|
.obfuscateData(contact.phones.first.number),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -420,7 +464,8 @@ class DetailRow extends StatelessWidget {
|
|||||||
final String label;
|
final String label;
|
||||||
final String value;
|
final String value;
|
||||||
|
|
||||||
const DetailRow({Key? key, required this.label, required this.value}) : super(key: key);
|
const DetailRow({Key? key, required this.label, required this.value})
|
||||||
|
: super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -430,7 +475,8 @@ class DetailRow extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
style: const TextStyle(color: Colors.white70, fontWeight: FontWeight.bold),
|
style: const TextStyle(
|
||||||
|
color: Colors.white70, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
|
Loading…
Reference in New Issue
Block a user