diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 90fbbef..dd5575f 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -44,4 +44,7 @@
+
+
+
diff --git a/lib/classes/contactClass.dart b/lib/classes/contactClass.dart
new file mode 100644
index 0000000..005ef24
--- /dev/null
+++ b/lib/classes/contactClass.dart
@@ -0,0 +1,26 @@
+// contactClass.dart
+
+class Contact {
+ final String name;
+ final String phoneNumber;
+ final bool isFavorite;
+ final bool isLocked;
+ final String? publicKey;
+
+ Contact(
+ this.name,
+ this.phoneNumber, {
+ this.isFavorite = false,
+ this.isLocked = false,
+ this.publicKey,
+ });
+}
+
+// Sample contacts list
+List contacts = [
+ Contact('Alice', '1234567890'),
+ Contact('Bob', '0987654321', isFavorite: true, publicKey: 'ABCD...WXYZ'),
+ Contact('Charlie', '5555555555', isLocked: true),
+ // Add more contacts as needed
+];
+
diff --git a/lib/classes/displayAvatar.dart b/lib/classes/displayAvatar.dart
new file mode 100644
index 0000000..934a0c8
--- /dev/null
+++ b/lib/classes/displayAvatar.dart
@@ -0,0 +1,31 @@
+// displayAvatar.dart
+
+import 'package:dialer/classes/contactClass.dart';
+import 'package:flutter/material.dart';
+
+class DisplayAvatar extends StatelessWidget {
+ final Contact contact;
+
+ const DisplayAvatar({super.key, required this.contact});
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ CircleAvatar(
+ child: Text(contact.name[0]),
+ ),
+ if (contact.isLocked)
+ const Positioned(
+ right: 0,
+ bottom: 0,
+ child: Icon(
+ Icons.lock,
+ color: Colors.white,
+ size: 20.0,
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/classes/displayContact.dart b/lib/classes/displayContact.dart
new file mode 100644
index 0000000..cd24f6c
--- /dev/null
+++ b/lib/classes/displayContact.dart
@@ -0,0 +1,83 @@
+// DisplayContact.dart
+
+import 'package:dialer/features/composition/composition.dart';
+import 'package:dialer/classes/contactClass.dart';
+import 'package:dialer/classes/displayAvatar.dart';
+import 'package:flutter/material.dart';
+import 'package:dialer/features/history/history_page.dart';
+
+class DisplayContact extends StatelessWidget {
+ final Contact contact;
+ final History? history;
+
+ const DisplayContact({
+ super.key,
+ required this.contact,
+ this.history,
+ });
+
+ String getTimeElapsed(DateTime date) {
+ final now = DateTime.now();
+ final difference = now.difference(date);
+ if (difference.inDays > 0) {
+ return '${difference.inDays} days ago';
+ } else if (difference.inHours > 0) {
+ return '${difference.inHours} hours ago';
+ } else if (difference.inMinutes > 0) {
+ return '${difference.inMinutes} minutes ago';
+ } else {
+ return 'Just now';
+ }
+ }
+
+ void _openVisualPage(BuildContext context) {
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (context) => const CompositionPage(),
+ ),
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return ListTile(
+ leading: DisplayAvatar(contact: contact),
+ title: Text(contact.name),
+ subtitle: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(contact.phoneNumber),
+ if (contact.publicKey != null)
+ Text(
+ 'key: ${contact.publicKey!.substring(0, 2)}...${contact.publicKey!.substring(contact.publicKey!.length - 2)}',
+ ),
+ if (history != null) ...[
+ Row(
+ children: [
+ Icon(
+ history!.callType == 'incoming'
+ ? Icons.call_received
+ : Icons.call_made,
+ size: 16,
+ color: history!.callStatus == 'missed' ? Colors.red : Colors.green,
+ ),
+ const SizedBox(width: 4),
+ Text('${history!.callStatus}, attempts: ${history!.attempts}'),
+ ],
+ ),
+ Text(getTimeElapsed(history!.date)),
+ ],
+ ],
+ ),
+ trailing: InkWell(
+ onTap: () => _openVisualPage(context),
+ child: const Icon(Icons.call),
+ ),
+ isThreeLine: true,
+ onTap: () {
+ // Add code here to handle contact tap
+ },
+ );
+ }
+}
diff --git a/lib/features/Settings/call/settingsCall.dart b/lib/features/Settings/call/settingsCall.dart
new file mode 100644
index 0000000..497c4ec
--- /dev/null
+++ b/lib/features/Settings/call/settingsCall.dart
@@ -0,0 +1,92 @@
+import 'package:flutter/material.dart';
+
+class SettingsCallPage extends StatefulWidget {
+ const SettingsCallPage({super.key});
+
+ @override
+ _SettingsCallPageState createState() => _SettingsCallPageState();
+}
+
+class _SettingsCallPageState extends State {
+ bool _enableVoicemail = true;
+ bool _enableCallRecording = false;
+ String _ringtone = 'Default';
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ title: const Text('Calling Settings'),
+ ),
+ body: ListView(
+ children: [
+ SwitchListTile(
+ title: const Text('Enable Voicemail', style: TextStyle(color: Colors.white)),
+ value: _enableVoicemail,
+ onChanged: (bool value) {
+ setState(() {
+ _enableVoicemail = value;
+ });
+ },
+ ),
+ SwitchListTile(
+ title: const Text('Enable call Recording', style: TextStyle(color: Colors.white)),
+ value: _enableCallRecording,
+ onChanged: (bool value) {
+ setState(() {
+ _enableCallRecording = value;
+ });
+ },
+ ),
+ ListTile(
+ title: const Text('Ringtone', style: TextStyle(color: Colors.white)),
+ subtitle: Text(_ringtone, style: const TextStyle(color: Colors.grey)),
+ trailing: const Icon(Icons.arrow_forward_ios, color: Colors.white),
+ onTap: () {
+ _selectRingtone(context);
+ },
+ ),
+ ],
+ ),
+ );
+ }
+
+ void _selectRingtone(BuildContext context) {
+ showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return SimpleDialog(
+ title: const Text('Select Ringtone'),
+ children: [
+ SimpleDialogOption(
+ onPressed: () {
+ Navigator.pop(context, 'Default');
+ },
+ child: const Text('Default'),
+ ),
+ SimpleDialogOption(
+ onPressed: () {
+ Navigator.pop(context, 'Classic');
+ },
+ child: const Text('Classic'),
+ ),
+ SimpleDialogOption(
+ onPressed: () {
+ Navigator.pop(context, 'Beep');
+ },
+ child: const Text('Beep'),
+ ),
+ // Add more ringtone options
+ ],
+ );
+ },
+ ).then((value) {
+ if (value != null) {
+ setState(() {
+ _ringtone = value;
+ });
+ }
+ });
+ }
+}
diff --git a/lib/features/Settings/key/delete_keyPair.dart b/lib/features/Settings/key/delete_keyPair.dart
new file mode 100644
index 0000000..2ef7a1b
--- /dev/null
+++ b/lib/features/Settings/key/delete_keyPair.dart
@@ -0,0 +1,68 @@
+// delete_keyPair.dart
+
+import 'package:flutter/material.dart';
+
+class SuppressionPaireClesPage extends StatelessWidget {
+ const SuppressionPaireClesPage({super.key});
+
+ void _deleteKeyPair(BuildContext context) {
+ // key deletion logic (not implemented here)
+ // ...
+
+ // Show confirmation message
+ ScaffoldMessenger.of(context).showSnackBar(
+ const SnackBar(
+ content: Text('La paire de clés a été supprimée.'),
+ ),
+ );
+
+ // Navigate back or update the UI as needed
+ Navigator.pop(context);
+ }
+
+ void _showConfirmationDialog(BuildContext context) {
+ showDialog(
+ context: context,
+ builder: (BuildContext context) {
+ return AlertDialog(
+ title: const Text('Confirmer la Suppression'),
+ content: const Text(
+ 'Êtes-vous sûr de vouloir supprimer la paire de clés ? Cette action est irréversible.'),
+ actions: [
+ TextButton(
+ child: const Text('Annuler'),
+ onPressed: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ TextButton(
+ child: const Text('Supprimer'),
+ onPressed: () {
+ Navigator.of(context).pop();
+ _deleteKeyPair(context);
+ },
+ ),
+ ],
+ );
+ },
+ );
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ title: const Text('Suppression d\'une Paire de Clés'),
+ ),
+ body: Center(
+ child: ElevatedButton(
+ onPressed: () {
+ _showConfirmationDialog(context);
+ },
+ child: const Text('Supprimer la Paire de Clés'),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/features/Settings/key/export_privateKey.dart b/lib/features/Settings/key/export_privateKey.dart
new file mode 100644
index 0000000..27d1fa7
--- /dev/null
+++ b/lib/features/Settings/key/export_privateKey.dart
@@ -0,0 +1,112 @@
+// export_privateKey.dart
+
+import 'package:flutter/material.dart';
+import 'dart:typed_data';
+import 'dart:convert';
+import 'package:pointycastle/export.dart' as crypto;
+import 'package:file_picker/file_picker.dart';
+
+class ExportationClePriveePage extends StatefulWidget {
+ const ExportationClePriveePage({super.key});
+
+ @override
+ _ExportationClePriveePageState createState() => _ExportationClePriveePageState();
+}
+
+class _ExportationClePriveePageState extends State {
+ final TextEditingController _passwordController = TextEditingController();
+
+ Future _exportPrivateKey() async {
+ // Replace with your actual private key retrieval logic
+ final String privateKeyPem = 'Votre clé privée ici';
+
+ // Get the password from the user input
+ final password = _passwordController.text;
+ if (password.isEmpty) {
+ // Show error message
+ return;
+ }
+
+ // Encrypt the private key using AES-256
+ final encryptedData = _encryptPrivateKey(privateKeyPem, password);
+
+ // Let the user pick a file location
+ final outputFile = await FilePicker.platform.saveFile(
+ dialogTitle: 'Enregistrer la clé privée chiffrée',
+ fileName: 'private_key_encrypted.aes',
+ );
+
+ if (outputFile != null) {
+ // Write the encrypted data to the file
+ // Use appropriate file I/O methods (not shown here)
+ // ...
+ // Show a confirmation dialog or message
+ showDialog(
+ context: context,
+ builder: (context) => AlertDialog(
+ title: const Text('Clé Exportée'),
+ content: const Text('La clé privée chiffrée a été exportée avec succès.'),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.pop(context),
+ child: const Text('OK'),
+ ),
+ ],
+ ),
+ );
+ }
+ }
+
+ Uint8List _encryptPrivateKey(String privateKey, String password) {
+ // Encryption logic using AES-256
+ final key = crypto.PBKDF2KeyDerivator(crypto.HMac(crypto.SHA256Digest(), 64))
+ .process(Uint8List.fromList(utf8.encode(password)));
+
+ final params = crypto.PaddedBlockCipherParameters(
+ crypto.ParametersWithIV(crypto.KeyParameter(key), Uint8List(16)), // Initialization Vector
+ null,
+ );
+ final cipher = crypto.PaddedBlockCipher('AES/CBC/PKCS7');
+ cipher.init(true, params);
+
+ final input = Uint8List.fromList(utf8.encode(privateKey));
+ final output = cipher.process(input);
+
+ return output;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.black,
+ appBar: AppBar(
+ title: const Text('Exportation de la Clé Privée'),
+ ),
+ body: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ children: [
+ const Text(
+ 'Entrez un mot de passe pour chiffrer la clé privée:',
+ style: TextStyle(color: Colors.white),
+ ),
+ TextField(
+ controller: _passwordController,
+ obscureText: true,
+ style: const TextStyle(color: Colors.white),
+ decoration: const InputDecoration(
+ hintText: 'Mot de passe',
+ hintStyle: TextStyle(color: Colors.grey),
+ ),
+ ),
+ const SizedBox(height: 20),
+ ElevatedButton(
+ onPressed: _exportPrivateKey,
+ child: const Text('Exporter la Clé Privée Chiffrée'),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/features/Settings/key/generate_newKeyPair.dart b/lib/features/Settings/key/generate_newKeyPair.dart
new file mode 100644
index 0000000..0f8e08d
--- /dev/null
+++ b/lib/features/Settings/key/generate_newKeyPair.dart
@@ -0,0 +1,123 @@
+import 'package:flutter/material.dart';
+import 'package:pointycastle/export.dart' as crypto;
+import 'dart:math';
+import 'dart:convert';
+import 'dart:typed_data';
+import 'package:asn1lib/asn1lib.dart';
+
+class GenerationNouvellePaireClesPage extends StatelessWidget {
+ const GenerationNouvellePaireClesPage({super.key});
+
+ Future