import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:dialer/services/obfuscate_service.dart'; import 'package:dialer/widgets/username_color_generator.dart'; class CallPage extends StatefulWidget { final String displayName; final Uint8List? thumbnail; const CallPage({super.key, required this.displayName, this.thumbnail}); @override _CallPageState createState() => _CallPageState(); } class _CallPageState extends State { final ObfuscateService _obfuscateService = ObfuscateService(); bool isMuted = false; bool isSpeakerOn = false; bool isKeypadVisible = false; bool icingProtocolOk = true; String _typedDigits = ""; // New state variable for pressed digits bool isOnHold = false; // New state variable for hold status void _addDigit(String digit) { setState(() { _typedDigits += digit; }); } void _toggleMute() { setState(() { isMuted = !isMuted; }); } void _toggleSpeaker() { setState(() { isSpeakerOn = !isSpeakerOn; }); } void _toggleKeypad() { setState(() { isKeypadVisible = !isKeypadVisible; }); } void _toggleIcingProtocol() { setState(() { icingProtocolOk = !icingProtocolOk; }); } void _toggleHold() { setState(() { isOnHold = !isOnHold; }); } void _hangUp() { Navigator.pop(context); } @override Widget build(BuildContext context) { final double avatarRadius = isKeypadVisible ? 45.0 : 45.0; // Smaller avatar final double nameFontSize = isKeypadVisible ? 24.0 : 24.0; // Smaller font final double statusFontSize = isKeypadVisible ? 16.0 : 16.0; // Smaller status // Calculate max visible chars based on screen width double screenWidth = MediaQuery.of(context).size.width; // Estimate ~14 pixels per character for the digit display (fontSize 24) // Subtract some padding (40) for the margins int estimatedMaxChars = ((screenWidth - 80) ~/ 14).clamp(10, 100) - 1; // Helper function to format the displayed digits with dynamic width String _formatDisplayDigits() { if (_typedDigits.length <= estimatedMaxChars) { return _typedDigits; } else { // Show ellipsis at the beginning and the most recent digits return '...' + _typedDigits.substring(_typedDigits.length - estimatedMaxChars + 3); } } return Scaffold( body: Container( color: Colors.black, child: SafeArea( child: Column( children: [ // Top section - make it more compact Container( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 35), ObfuscatedAvatar( imageBytes: widget.thumbnail, radius: avatarRadius, backgroundColor: generateColorFromName(widget.displayName), fallbackInitial: widget.displayName, ), const SizedBox(height: 4), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( icingProtocolOk ? Icons.lock : Icons.lock_open, color: icingProtocolOk ? Colors.green : Colors.red, size: 16, ), const SizedBox(width: 4), Text( 'Icing protocol: ${icingProtocolOk ? "ok" : "ko"}', style: TextStyle( color: icingProtocolOk ? Colors.green : Colors.red, fontSize: 12, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 4), Text( _obfuscateService.obfuscateData(widget.displayName), style: TextStyle( fontSize: nameFontSize, color: Colors.white, fontWeight: FontWeight.bold, ), ), Text( 'Calling...', style: TextStyle(fontSize: statusFontSize, color: Colors.white70), ), ], ), ), // Middle section - make it flexible and scrollable if needed Expanded( child: Column( children: [ if (isKeypadVisible) ... [ // Updated typed digits display with dynamic width Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( _formatDisplayDigits(), maxLines: 1, textAlign: TextAlign.right, overflow: TextOverflow.visible, style: const TextStyle( fontSize: 24, color: Colors.white, fontWeight: FontWeight.bold, ), ), ), IconButton( padding: EdgeInsets.zero, onPressed: _toggleKeypad, icon: const Icon(Icons.close, color: Colors.white), ), ], ), ), // Modified keypad section Container( padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20), child: Column( mainAxisSize: MainAxisSize.min, children: [ for (var i = 0; i < 4; i++) Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ for (var j = 1; j <= 3; j++) Expanded( child: AspectRatio( aspectRatio: 1.5, child: Padding( padding: const EdgeInsets.all(4.0), child: Material( color: Colors.transparent, child: InkWell( customBorder: const CircleBorder(), onTap: () { String label; if (i < 3) { label = '${i * 3 + j}'; } else { if (j == 1) label = '*'; else if (j == 2) label = '0'; else label = '#'; } _addDigit(label); }, child: Container( decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.grey[900]?.withOpacity(0.5), ), child: Center( child: Text( i < 3 ? '${i * 3 + j}' : (j == 1 ? '*' : (j == 2 ? '0' : '#')), style: const TextStyle( fontSize: 32, color: Colors.white, ), ), ), ), ), ), ), ), ), ], ), ], ), ), ] else ... [ const Spacer(), const Spacer(), // Control buttons Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Main control buttons Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // Mute Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: _toggleMute, icon: Icon( isMuted ? Icons.mic_off : Icons.mic, color: Colors.white, size: 32, ), ), Text( isMuted ? 'Unmute' : 'Mute', style: const TextStyle(color: Colors.white, fontSize: 14), ), ], ), // Keypad Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: _toggleKeypad, icon: const Icon(Icons.dialpad, color: Colors.white, size: 32), ), const Text( 'Keypad', style: TextStyle(color: Colors.white, fontSize: 14), ), ], ), // Speaker Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: _toggleSpeaker, icon: Icon( isSpeakerOn ? Icons.volume_up : Icons.volume_off, color: isSpeakerOn ? Colors.amber : Colors.white, size: 32, ), ), const Text( 'Speaker', style: TextStyle(color: Colors.white, fontSize: 14), ), ], ), // New "mettre en attente" / Hold button ], ), const SizedBox(height: 20), // Additional buttons Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ // Add Contact Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: () { // ...existing code... }, icon: const Icon(Icons.person_add, color: Colors.white, size: 32), ), const Text('Add Contact', style: TextStyle(color: Colors.white, fontSize: 14)), ], ), // New "Hold" button inserted between Add Contact and Change SIM Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: _toggleHold, icon: Icon( isOnHold ? Icons.play_arrow : Icons.pause, color: Colors.white, size: 32, ), ), Text( isOnHold ? 'Resume' : 'Hold', style: const TextStyle(color: Colors.white, fontSize: 14), ), ], ), // Change SIM Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: () { // ...existing code... }, icon: const Icon(Icons.sim_card, color: Colors.white, size: 32), ), const Text('Change SIM', style: TextStyle(color: Colors.white, fontSize: 14)), ], ), ], ), ], ), ), const Spacer(flex: 3), ], ], ), ), // Bottom section - hang up button Padding( padding: const EdgeInsets.only(bottom: 16.0), child: GestureDetector( onTap: _hangUp, child: Container( padding: const EdgeInsets.all(12), decoration: const BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), child: const Icon( Icons.call_end, color: Colors.white, size: 32, ), ), ), ), ], ), ), ), ); } }