Add CallPage for initiating calls with contact details #37

Merged
stcb merged 7 commits from call-page into dev 2025-03-07 22:40:16 +00:00
Showing only changes of commit 858305d42b - Show all commits

View File

@ -19,6 +19,13 @@ class _CallPageState extends State<CallPage> {
bool isSpeakerOn = false; bool isSpeakerOn = false;
bool isKeypadVisible = false; bool isKeypadVisible = false;
bool icingProtocolOk = true; bool icingProtocolOk = true;
String _typedDigits = ""; // New state variable for pressed digits
void _addDigit(String digit) {
setState(() {
_typedDigits += digit;
});
}
void _toggleMute() { void _toggleMute() {
setState(() { setState(() {
@ -50,9 +57,9 @@ class _CallPageState extends State<CallPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double avatarRadius = isKeypadVisible ? 30.0 : 60.0; final double avatarRadius = isKeypadVisible ? 45.0 : 45.0; // Smaller avatar
final double nameFontSize = isKeypadVisible ? 20.0 : 32.0; final double nameFontSize = isKeypadVisible ? 24.0 : 24.0; // Smaller font
final double statusFontSize = isKeypadVisible ? 14.0 : 20.0; final double statusFontSize = isKeypadVisible ? 16.0 : 16.0; // Smaller status
return Scaffold( return Scaffold(
body: Container( body: Container(
@ -60,42 +67,40 @@ class _CallPageState extends State<CallPage> {
child: SafeArea( child: SafeArea(
child: Column( child: Column(
children: [ children: [
// Header area with Icing protocol status first // Top section - make it more compact
Column( Container(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
const SizedBox(height: 60), SizedBox(height: 35),
// Icing protocol status moved here
ObfuscatedAvatar( ObfuscatedAvatar(
imageBytes: widget.thumbnail, imageBytes: widget.thumbnail,
radius: avatarRadius, radius: avatarRadius,
backgroundColor: generateColorFromName(widget.displayName), backgroundColor: generateColorFromName(widget.displayName),
fallbackInitial: widget.displayName, fallbackInitial: widget.displayName,
), ),
const SizedBox(height: 20), const SizedBox(height: 4),
GestureDetector( Row(
onTap: _toggleIcingProtocol,
child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon( Icon(
icingProtocolOk ? Icons.lock : Icons.lock_open, icingProtocolOk ? Icons.lock : Icons.lock_open,
color: icingProtocolOk ? Colors.green : Colors.red, color: icingProtocolOk ? Colors.green : Colors.red,
size: 20, size: 16,
), ),
const SizedBox(width: 8), const SizedBox(width: 4),
Text( Text(
'Icing protocol: ${icingProtocolOk ? "ok" : "ko"}', 'Icing protocol: ${icingProtocolOk ? "ok" : "ko"}',
style: TextStyle( style: TextStyle(
color: icingProtocolOk ? Colors.green : Colors.red, color: icingProtocolOk ? Colors.green : Colors.red,
fontSize: 14, fontSize: 12,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
], ],
), ),
), const SizedBox(height: 4),
const SizedBox(height: 10),
Text( Text(
_obfuscateService.obfuscateData(widget.displayName), _obfuscateService.obfuscateData(widget.displayName),
style: TextStyle( style: TextStyle(
@ -104,51 +109,61 @@ class _CallPageState extends State<CallPage> {
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
), ),
), ),
const SizedBox(height: 5),
Text( Text(
'Calling...', 'Calling...',
style: TextStyle(fontSize: statusFontSize, color: Colors.white70), style: TextStyle(fontSize: statusFontSize, color: Colors.white70),
), ),
], ],
), ),
),
// Middle section with keypad or control buttons // Middle section - make it flexible and scrollable if needed
Expanded( Expanded(
child: Column( child: Column(
children: [ children: [
// Add a smaller top spacer to move buttons higher if (isKeypadVisible) ...[
// Add spacer to push keypad down
const Spacer(flex: 2), const Spacer(flex: 2),
if (isKeypadVisible) ...[ // Typed digits display
// Close keypad button Padding(
Align( padding: const EdgeInsets.symmetric(horizontal: 20.0),
alignment: Alignment.topRight, child: Row(
child: Padding( mainAxisAlignment: MainAxisAlignment.spaceBetween,
padding: const EdgeInsets.only(right: 20.0), children: [
child: IconButton( Expanded(
onPressed: _toggleKeypad, child: Text(
icon: const Icon( _typedDigits,
Icons.close, maxLines: 1,
textAlign: TextAlign.right,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 24,
color: Colors.white, color: Colors.white,
size: 24, fontWeight: FontWeight.bold,
), ),
), ),
), ),
IconButton(
padding: EdgeInsets.zero,
onPressed: _toggleKeypad,
icon: const Icon(Icons.close, color: Colors.white),
), ),
// Keypad ],
),
),
// Keypad grid
Container( Container(
margin: const EdgeInsets.symmetric(horizontal: 40), height: MediaQuery.of(context).size.height * 0.35,
padding: const EdgeInsets.all(10), margin: const EdgeInsets.symmetric(horizontal: 20),
decoration: BoxDecoration(
color: Colors.black45,
borderRadius: BorderRadius.circular(10),
),
child: GridView.count( child: GridView.count(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
crossAxisCount: 3, crossAxisCount: 3,
mainAxisSpacing: 10, childAspectRatio: 1.3,
crossAxisSpacing: 10, mainAxisSpacing: 8,
crossAxisSpacing: 8,
children: List.generate(12, (index) { children: List.generate(12, (index) {
String label; String label;
if (index < 9) { if (index < 9) {
@ -160,23 +175,40 @@ class _CallPageState extends State<CallPage> {
} else { } else {
label = '#'; label = '#';
} }
return Center( return GestureDetector(
onTap: () => _addDigit(label),
child: Container(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Colors.transparent,
),
child: Center(
child: Text( child: Text(
label, label,
style: const TextStyle(fontSize: 24, color: Colors.white), style: const TextStyle(fontSize: 32, color: Colors.white),
),
),
), ),
); );
}), }),
), ),
), ),
// Add spacer after keypad
const Spacer(flex: 1),
] else ...[ ] else ...[
// Control buttons row with labels under each button const Spacer(),
// Control buttons
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0), padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Row( child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// Main control buttons
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
// Mic button with label // Mute
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -194,17 +226,13 @@ class _CallPageState extends State<CallPage> {
), ),
], ],
), ),
// Dialpad button with label // Keypad
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
IconButton( IconButton(
onPressed: _toggleKeypad, onPressed: _toggleKeypad,
icon: Icon( icon: const Icon(Icons.dialpad, color: Colors.white, size: 32),
Icons.dialpad,
color: Colors.white,
size: 32,
),
), ),
const Text( const Text(
'Keypad', 'Keypad',
@ -212,7 +240,7 @@ class _CallPageState extends State<CallPage> {
), ),
], ],
), ),
// Speaker button with label // Speaker
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -232,76 +260,57 @@ class _CallPageState extends State<CallPage> {
), ),
], ],
), ),
),
const SizedBox(height: 20), const SizedBox(height: 20),
// Additional buttons
// Additional buttons row: "Add Contact" and "Change SIM" Row(
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
// "Add Contact" button // Add Contact
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
IconButton( IconButton(
onPressed: () { onPressed: () {
// Implement your add contact logic here // ...existing code...
}, },
icon: const Icon( icon: const Icon(Icons.person_add, color: Colors.white, size: 32),
Icons.person_add,
color: Colors.white,
size: 32,
),
),
const Text(
'Add Contact',
style: TextStyle(color: Colors.white, fontSize: 14),
), ),
const Text('Add Contact',
style: TextStyle(color: Colors.white, fontSize: 14)),
], ],
), ),
// "Change SIM" button // Change SIM
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
IconButton( IconButton(
onPressed: () { onPressed: () {
// Implement your change SIM logic here // ...existing code...
}, },
icon: const Icon( icon: const Icon(Icons.sim_card, color: Colors.white, size: 32),
Icons.sim_card,
color: Colors.white,
size: 32,
), ),
), const Text('Change SIM',
const Text( style: TextStyle(color: Colors.white, fontSize: 14)),
'Change SIM', ],
style: TextStyle(color: Colors.white, fontSize: 14),
), ),
], ],
), ),
], ],
), ),
), ),
const Spacer(flex: 3),
], ],
// Add a larger bottom spacer
const Spacer(flex: 6),
], ],
), ),
), ),
// Hang up button // Bottom section - hang up button
Transform.translate( Padding(
offset: const Offset(0, -40), // Moves button 20 pixels upward padding: const EdgeInsets.only(bottom: 16.0),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 10.0),
child: GestureDetector( child: GestureDetector(
onTap: _hangUp, onTap: _hangUp,
child: Container( child: Container(
padding: const EdgeInsets.all(10), // adjust to desired size padding: const EdgeInsets.all(12),
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.red, color: Colors.red,
shape: BoxShape.circle, shape: BoxShape.circle,
@ -309,8 +318,7 @@ class _CallPageState extends State<CallPage> {
child: const Icon( child: const Icon(
Icons.call_end, Icons.call_end,
color: Colors.white, color: Colors.white,
size: 40, size: 32,
),
), ),
), ),
), ),