import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:dialer/services/call_service.dart'; import 'package:dialer/services/obfuscate_service.dart'; import 'package:dialer/widgets/username_color_generator.dart'; class CallPage extends StatefulWidget { final String displayName; final String phoneNumber; final Uint8List? thumbnail; const CallPage({ super.key, required this.displayName, required this.phoneNumber, this.thumbnail, }); @override _CallPageState createState() => _CallPageState(); } class _CallPageState extends State { final ObfuscateService _obfuscateService = ObfuscateService(); final CallService _callService = CallService(); bool isMuted = false; bool isSpeakerOn = false; bool isKeypadVisible = false; bool icingProtocolOk = true; String _typedDigits = ""; 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 _hangUp() async { try { await _callService.hangUpCall(context); } catch (e) { print("Error hanging up: $e"); } } @override Widget build(BuildContext context) { final double avatarRadius = isKeypadVisible ? 45.0 : 45.0; final double nameFontSize = isKeypadVisible ? 24.0 : 24.0; final double statusFontSize = isKeypadVisible ? 16.0 : 16.0; return Scaffold( body: Container( color: Colors.black, child: SafeArea( child: Column( children: [ Container( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: 35), ObfuscatedAvatar( imageBytes: widget.thumbnail, // Uses thumbnail if provided 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( widget.phoneNumber, style: TextStyle(fontSize: statusFontSize, color: Colors.white70), ), Text( 'Calling...', style: TextStyle(fontSize: statusFontSize, color: Colors.white70), ), ], ), ), Expanded( child: Column( children: [ if (isKeypadVisible) ...[ const Spacer(flex: 2), Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Text( _typedDigits, maxLines: 1, textAlign: TextAlign.right, overflow: TextOverflow.ellipsis, 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), ), ], ), ), Container( height: MediaQuery.of(context).size.height * 0.35, margin: const EdgeInsets.symmetric(horizontal: 20), child: GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), crossAxisCount: 3, childAspectRatio: 1.3, mainAxisSpacing: 8, crossAxisSpacing: 8, children: List.generate(12, (index) { String label; if (index < 9) { label = '${index + 1}'; } else if (index == 9) { label = '*'; } else if (index == 10) { label = '0'; } else { label = '#'; } return GestureDetector( onTap: () => _addDigit(label), child: Container( decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.transparent, ), child: Center( child: Text( label, style: const TextStyle(fontSize: 32, color: Colors.white), ), ), ), ); }), ), ), const Spacer(flex: 1), ] else ...[ const Spacer(), Padding( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ 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), ), ], ), 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), ), ], ), 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), ), ], ), ], ), const SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: () {}, icon: const Icon(Icons.person_add, color: Colors.white, size: 32), ), const Text('Add Contact', style: TextStyle(color: Colors.white, fontSize: 14)), ], ), Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: () {}, 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), ], ], ), ), 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, ), ), ), ), ], ), ), ), ); } }