refactor: update imports and restructure widget files for better organization
All checks were successful
/ mirror (push) Successful in 5s
/ build (push) Successful in 10m12s
/ build-stealth (push) Successful in 10m12s

This commit is contained in:
AlexisDanlos 2025-05-16 22:14:42 +02:00
parent afa0c5b5a4
commit d7ed797b80
11 changed files with 7 additions and 338 deletions

View File

@ -4,7 +4,7 @@ import '../../presentation/features/call/incoming_call_page.dart';
import '../../presentation/features/home/home_page.dart'; import '../../presentation/features/home/home_page.dart';
import '../../presentation/features/settings/settings.dart'; // Updated import import '../../presentation/features/settings/settings.dart'; // Updated import
import '../../presentation/features/contacts/contact_page.dart'; import '../../presentation/features/contacts/contact_page.dart';
import '../../presentation/features/dialer/composition_page.dart'; import '../../presentation/features/composition/composition.dart';
import 'dart:typed_data'; import 'dart:typed_data';
class AppRouter { class AppRouter {

View File

@ -1,5 +1,5 @@
// lib/services/obfuscate_service.dart // lib/services/obfuscate_service.dart
import 'package:dialer/widgets/color_darkener.dart'; import 'package:dialer/presentation/common/widgets/color_darkener.dart';
import '../../core/config/app_config.dart'; import '../../core/config/app_config.dart';
import 'dart:ui'; import 'dart:ui';

View File

@ -4,7 +4,6 @@ import 'package:url_launcher/url_launcher.dart';
import '../../../domain/services/contact_service.dart'; import '../../../domain/services/contact_service.dart';
import '../../../domain/services/obfuscate_service.dart'; import '../../../domain/services/obfuscate_service.dart';
import '../../../domain/services/call_service.dart'; import '../../../domain/services/call_service.dart';
import '../contacts/widgets/add_contact_button.dart';
class CompositionPage extends StatefulWidget { class CompositionPage extends StatefulWidget {
const CompositionPage({super.key}); const CompositionPage({super.key});

View File

@ -1,8 +1,8 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart'; import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../../widgets/username_color_generator.dart'; import '../../../common/widgets/username_color_generator.dart';
import '../../../../widgets/color_darkener.dart'; import '../../../common/widgets/color_darkener.dart';
import '../../../../domain/services/obfuscate_service.dart'; 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';
@ -86,15 +86,6 @@ class _ContactModalState extends State<ContactModal> {
} }
} }
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 { void _launchSms(String phoneNumber) async {
final uri = Uri(scheme: 'sms', path: phoneNumber); final uri = Uri(scheme: 'sms', path: phoneNumber);
if (await canLaunchUrl(uri)) { if (await canLaunchUrl(uri)) {

View File

@ -1,311 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_contacts/flutter_contacts.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../domain/services/contact_service.dart';
import '../../../domain/services/obfuscate_service.dart';
import '../../../domain/services/call_service.dart';
import '../contacts/widgets/add_contact_button.dart';
class CompositionPage extends StatefulWidget {
const CompositionPage({super.key});
@override
_CompositionPageState createState() => _CompositionPageState();
}
class _CompositionPageState extends State<CompositionPage> {
String dialedNumber = "";
List<Contact> _allContacts = [];
List<Contact> _filteredContacts = [];
final ContactService _contactService = ContactService();
final ObfuscateService _obfuscateService = ObfuscateService();
final CallService _callService = CallService();
// Cache for normalized phone numbers to avoid repeated processing
final Map<String, String> _normalizedPhoneCache = {};
@override
void initState() {
super.initState();
_fetchContacts();
}
Future<void> _fetchContacts() async {
_allContacts = await _contactService.fetchContacts();
_filteredContacts = _allContacts;
setState(() {});
}
String _getNormalizedPhone(String phone) {
return _normalizedPhoneCache.putIfAbsent(
phone,
() => phone.replaceAll(RegExp(r'\D'), '')
);
}
void _filterContacts() {
if (dialedNumber.isEmpty) {
setState(() {
_filteredContacts = _allContacts;
});
return;
}
final String normalizedDialed = dialedNumber.replaceAll(RegExp(r'\D'), '');
final String lowerDialed = dialedNumber.toLowerCase();
setState(() {
_filteredContacts = _allContacts.where((contact) {
// Check phone numbers
final phoneMatch = contact.phones.any((phone) =>
_getNormalizedPhone(phone.number).contains(normalizedDialed));
// Only check name if phone doesn't match (optimization)
if (phoneMatch) return true;
// Check display name
return contact.displayName.toLowerCase().contains(lowerDialed);
}).toList();
});
}
void _onNumberPress(String number) {
setState(() {
dialedNumber += number;
_filterContacts();
});
}
void _onDeletePress() {
setState(() {
if (dialedNumber.isNotEmpty) {
dialedNumber = dialedNumber.substring(0, dialedNumber.length - 1);
_filterContacts();
}
});
}
void _onClearPress() {
setState(() {
dialedNumber = "";
_filteredContacts = _allContacts;
});
}
void _makeCall(String phoneNumber) async {
try {
await _callService.makeGsmCall(context, phoneNumber: phoneNumber);
setState(() {
dialedNumber = phoneNumber;
});
} catch (e) {
debugPrint("Error making call: $e");
}
}
void _launchSms(String phoneNumber) async {
final uri = Uri(scheme: 'sms', path: phoneNumber);
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
debugPrint('Could not send SMS to $phoneNumber');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Stack(
children: [
Column(
children: [
// Top half: Display contacts matching dialed number
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.only(
top: 42.0, left: 16.0, right: 16.0, bottom: 16.0),
color: Colors.black,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
child: ListView(
children: _filteredContacts.isNotEmpty
? _filteredContacts.map((contact) {
final phoneNumber = contact.phones.isNotEmpty
? contact.phones.first.number
: 'No phone number';
return ListTile(
title: Text(
_obfuscateService.obfuscateData(contact.displayName),
style: const TextStyle(color: Colors.white),
),
subtitle: Text(
_obfuscateService.obfuscateData(phoneNumber),
style: const TextStyle(color: Colors.grey),
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: Icon(Icons.phone,
color: Colors.green[300],
size: 20),
onPressed: () {
_makeCall(phoneNumber);
},
),
IconButton(
icon: Icon(Icons.message,
color: Colors.blue[300],
size: 20),
onPressed: () {
_launchSms(phoneNumber);
},
),
],
),
onTap: () {
// Handle contact selection if needed
},
);
}).toList()
: [],
),
),
],
),
),
),
// Bottom half: Dialpad and Dialed number display with erase button
Expanded(
flex: 2,
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
// Display dialed number with erase button
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Align(
alignment: Alignment.center,
child: Text(
dialedNumber,
style: const TextStyle(
fontSize: 24, color: Colors.white),
overflow: TextOverflow.ellipsis,
),
),
),
IconButton(
onPressed: _onClearPress,
icon: const Icon(Icons.backspace,
color: Colors.white),
),
],
),
const SizedBox(height: 10),
// Dialpad
Expanded(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
_buildDialButton('1'),
_buildDialButton('2'),
_buildDialButton('3'),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
_buildDialButton('4'),
_buildDialButton('5'),
_buildDialButton('6'),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
_buildDialButton('7'),
_buildDialButton('8'),
_buildDialButton('9'),
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: [
_buildDialButton('*'),
_buildDialButton('0'),
_buildDialButton('#'),
],
),
],
),
),
),
],
),
),
),
],
),
// Add Contact Button
Positioned(
bottom: 20.0,
left: 0,
right: 0,
child: Center(
child: AddContactButton(),
),
),
// Top Row with Back Arrow
Positioned(
top: 40.0,
left: 16.0,
child: IconButton(
icon: const Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pop(context);
},
),
),
],
),
);
}
Widget _buildDialButton(String number) {
return ElevatedButton(
onPressed: () => _onNumberPress(number),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black,
shape: const CircleBorder(),
padding: const EdgeInsets.all(16),
),
child: Text(
number,
style: const TextStyle(
fontSize: 24,
color: Colors.white,
),
),
);
}
}

View File

@ -6,8 +6,8 @@ import 'package:intl/intl.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../../domain/services/obfuscate_service.dart'; import '../../../domain/services/obfuscate_service.dart';
import '../../../widgets/color_darkener.dart'; import '../../common/widgets/color_darkener.dart';
import '../../../widgets/username_color_generator.dart'; import '../../common/widgets/username_color_generator.dart';
import '../../../domain/services/block_service.dart'; import '../../../domain/services/block_service.dart';
import '../../../domain/services/call_service.dart'; import '../../../domain/services/call_service.dart';
import '../contacts/contact_state.dart'; import '../contacts/contact_state.dart';

View File

@ -3,7 +3,7 @@ import '../../../domain/services/obfuscate_service.dart';
import '../contacts/contact_page.dart'; import '../contacts/contact_page.dart';
import '../favorites/favorites_page.dart'; import '../favorites/favorites_page.dart';
import '../history/history_page.dart'; import '../history/history_page.dart';
import '../dialer/composition_page.dart'; import '../composition/composition.dart';
import '../settings/settings.dart'; import '../settings/settings.dart';
import '../voicemail/voicemail_page.dart'; import '../voicemail/voicemail_page.dart';
import '../contacts/contact_state.dart'; import '../contacts/contact_state.dart';

View File

@ -1,10 +0,0 @@
import 'package:flutter/material.dart';
class LoadingIndicatorWidget extends StatelessWidget {
const LoadingIndicatorWidget({super.key});
@override
Widget build(BuildContext context) {
return const Center(child: CircularProgressIndicator());
}
}