Add CallPage for initiating calls with contact details #37
@ -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,
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
Loading…
Reference in New Issue
Block a user