feat: add MessageService for sending SMS and integrate into ContactModal
This commit is contained in:
parent
afa0c5b5a4
commit
4ecf7c546b
18
dialer/lib/domain/services/message_service.dart
Normal file
18
dialer/lib/domain/services/message_service.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import 'dart:io' show Platform;
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
/// A service to handle sending SMS messages using the url_launcher package.
|
||||||
|
class MessageService {
|
||||||
|
/// Launches the SMS dialer for the given [phoneNumber].
|
||||||
|
Future<void> sendSms(String phoneNumber) async {
|
||||||
|
// Sanitize number (keep only digits and plus sign)
|
||||||
|
final sanitized = phoneNumber.replaceAll(RegExp(r'[^0-9+]'), '');
|
||||||
|
|
||||||
|
Uri uri;
|
||||||
|
|
||||||
|
uri = Uri(scheme: 'sms', path: sanitized);
|
||||||
|
|
||||||
|
await launchUrl(uri);
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ import '../../../../domain/services/obfuscate_service.dart';
|
|||||||
import '../../../../domain/services/block_service.dart';
|
import '../../../../domain/services/block_service.dart';
|
||||||
import '../../../../domain/services/contact_service.dart';
|
import '../../../../domain/services/contact_service.dart';
|
||||||
import '../../../../domain/services/call_service.dart';
|
import '../../../../domain/services/call_service.dart';
|
||||||
|
import '../../../../domain/services/message_service.dart';
|
||||||
|
|
||||||
class ContactModal extends StatefulWidget {
|
class ContactModal extends StatefulWidget {
|
||||||
final Contact contact;
|
final Contact contact;
|
||||||
@ -32,6 +33,7 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
final ObfuscateService _obfuscateService = ObfuscateService();
|
final ObfuscateService _obfuscateService = ObfuscateService();
|
||||||
final CallService _callService = CallService();
|
final CallService _callService = CallService();
|
||||||
final ContactService _contactService = ContactService();
|
final ContactService _contactService = ContactService();
|
||||||
|
final MessageService _messageService = MessageService();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -60,7 +62,7 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBlocked) {
|
if (isBlocked) {
|
||||||
await BlockService().unblockNumber(phoneNumber);
|
await BlockService().unblockNumber(phoneNumber);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
@ -80,30 +82,12 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
if (phoneNumber != 'No phone number' && mounted) {
|
if (phoneNumber != 'No phone number' && mounted) {
|
||||||
_checkIfBlocked();
|
_checkIfBlocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _launchPhoneDialer(String phoneNumber) async {
|
|
||||||
final uri = Uri(scheme: 'tel', path: phoneNumber);
|
|
||||||
if (await canLaunchUrl(uri)) {
|
|
||||||
await launchUrl(uri);
|
|
||||||
} else {
|
|
||||||
debugPrint('Could not launch $phoneNumber');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _launchSms(String phoneNumber) async {
|
|
||||||
final uri = Uri(scheme: 'sms', path: phoneNumber);
|
|
||||||
if (await canLaunchUrl(uri)) {
|
|
||||||
await launchUrl(uri);
|
|
||||||
} else {
|
|
||||||
debugPrint('Could not launch SMS to $phoneNumber');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _launchEmail(String email) async {
|
void _launchEmail(String email) async {
|
||||||
final uri = Uri(scheme: 'mailto', path: email);
|
final uri = Uri(scheme: 'mailto', path: email);
|
||||||
if (await canLaunchUrl(uri)) {
|
if (await canLaunchUrl(uri)) {
|
||||||
@ -246,7 +230,8 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
widget.contact.thumbnail != null && widget.contact.thumbnail!.isNotEmpty
|
widget.contact.thumbnail != null &&
|
||||||
|
widget.contact.thumbnail!.isNotEmpty
|
||||||
? ClipOval(
|
? ClipOval(
|
||||||
child: Image.memory(
|
child: Image.memory(
|
||||||
widget.contact.thumbnail!,
|
widget.contact.thumbnail!,
|
||||||
@ -260,7 +245,8 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
radius: 50,
|
radius: 50,
|
||||||
child: Text(
|
child: Text(
|
||||||
widget.contact.displayName.isNotEmpty
|
widget.contact.displayName.isNotEmpty
|
||||||
? widget.contact.displayName[0].toUpperCase()
|
? widget.contact.displayName[0]
|
||||||
|
.toUpperCase()
|
||||||
: '?',
|
: '?',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: darken(avatarColor),
|
color: darken(avatarColor),
|
||||||
@ -287,7 +273,8 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.phone, color: Colors.green),
|
leading:
|
||||||
|
const Icon(Icons.phone, color: Colors.green),
|
||||||
title: Text(
|
title: Text(
|
||||||
_obfuscateService.obfuscateData(phoneNumber),
|
_obfuscateService.obfuscateData(phoneNumber),
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(color: Colors.white),
|
||||||
@ -300,19 +287,21 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.message, color: Colors.blue),
|
leading:
|
||||||
|
const Icon(Icons.message, color: Colors.blue),
|
||||||
title: Text(
|
title: Text(
|
||||||
_obfuscateService.obfuscateData(phoneNumber),
|
_obfuscateService.obfuscateData(phoneNumber),
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(color: Colors.white),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (widget.contact.phones.isNotEmpty) {
|
if (widget.contact.phones.isNotEmpty) {
|
||||||
_launchSms(phoneNumber);
|
_messageService.sendSms(phoneNumber);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(Icons.email, color: Colors.orange),
|
leading:
|
||||||
|
const Icon(Icons.email, color: Colors.orange),
|
||||||
title: Text(
|
title: Text(
|
||||||
email,
|
email,
|
||||||
style: const TextStyle(color: Colors.white),
|
style: const TextStyle(color: Colors.white),
|
||||||
@ -326,7 +315,8 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
const Divider(color: Colors.grey),
|
const Divider(color: Colors.grey),
|
||||||
// Favorite, Edit, and Block/Unblock Buttons
|
// Favorite, Edit, and Block/Unblock Buttons
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
padding:
|
||||||
|
const EdgeInsets.symmetric(horizontal: 16.0),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Favorite button
|
// Favorite button
|
||||||
@ -342,8 +332,9 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
icon: Icon(widget.isFavorite
|
icon: Icon(widget.isFavorite
|
||||||
? Icons.star
|
? Icons.star
|
||||||
: Icons.star_border),
|
: Icons.star_border),
|
||||||
label: Text(
|
label: Text(widget.isFavorite
|
||||||
widget.isFavorite ? 'Unfavorite' : 'Favorite'),
|
? 'Unfavorite'
|
||||||
|
: 'Favorite'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
@ -362,9 +353,11 @@ class _ContactModalState extends State<ContactModal> {
|
|||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
onPressed: _toggleBlockState,
|
onPressed: _toggleBlockState,
|
||||||
icon: Icon(
|
icon: Icon(isBlocked
|
||||||
isBlocked ? Icons.block : Icons.block_flipped),
|
? Icons.block
|
||||||
label: Text(isBlocked ? 'Unblock' : 'Block'),
|
: Icons.block_flipped),
|
||||||
|
label:
|
||||||
|
Text(isBlocked ? 'Unblock' : 'Block'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user