251 lines
6.6 KiB
Dart
251 lines
6.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'dart:typed_data';
|
|
import '../../../domain/services/call_service.dart';
|
|
import '../../../domain/services/obfuscate_service.dart';
|
|
import '../../../core/utils/color_utils.dart';
|
|
import '../../../presentation/common/widgets/obfuscated_avatar.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<CallPage> {
|
|
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 _hangUp() async {
|
|
try {
|
|
await _callService.hangUpCall(context);
|
|
} catch (e) {
|
|
debugPrint("Error hanging up: $e");
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final double avatarRadius = 45.0;
|
|
|
|
return Scaffold(
|
|
backgroundColor: Colors.black,
|
|
body: SafeArea(
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 24.0),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
ObfuscatedAvatar(
|
|
imageBytes: widget.thumbnail,
|
|
radius: avatarRadius,
|
|
backgroundColor: generateColorFromName(widget.displayName),
|
|
fallbackInitial: widget.displayName,
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
_obfuscateService.obfuscateData(widget.displayName),
|
|
style: const TextStyle(
|
|
fontSize: 24,
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
),
|
|
),
|
|
Text(
|
|
widget.phoneNumber,
|
|
style: const TextStyle(fontSize: 16, color: Colors.white70),
|
|
),
|
|
const SizedBox(height: 8),
|
|
Text(
|
|
'Calling...',
|
|
style: const TextStyle(fontSize: 16, color: Colors.white70),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
Expanded(
|
|
child: isKeypadVisible
|
|
? _buildKeypad()
|
|
: _buildCallControls(),
|
|
),
|
|
|
|
Padding(
|
|
padding: const EdgeInsets.only(bottom: 24.0),
|
|
child: GestureDetector(
|
|
onTap: _hangUp,
|
|
child: Container(
|
|
padding: const EdgeInsets.all(16),
|
|
decoration: const BoxDecoration(
|
|
color: Colors.red,
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: const Icon(
|
|
Icons.call_end,
|
|
color: Colors.white,
|
|
size: 32,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildKeypad() {
|
|
return Column(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 24.0),
|
|
child: Text(
|
|
_typedDigits,
|
|
style: const TextStyle(
|
|
fontSize: 24,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Expanded(
|
|
child: GridView.count(
|
|
crossAxisCount: 3,
|
|
childAspectRatio: 1.5,
|
|
children: [
|
|
_buildDialButton('1'),
|
|
_buildDialButton('2'),
|
|
_buildDialButton('3'),
|
|
_buildDialButton('4'),
|
|
_buildDialButton('5'),
|
|
_buildDialButton('6'),
|
|
_buildDialButton('7'),
|
|
_buildDialButton('8'),
|
|
_buildDialButton('9'),
|
|
_buildDialButton('*'),
|
|
_buildDialButton('0'),
|
|
_buildDialButton('#'),
|
|
],
|
|
),
|
|
),
|
|
TextButton(
|
|
onPressed: _toggleKeypad,
|
|
child: const Text('Hide Keypad'),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildCallControls() {
|
|
return Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: [
|
|
_buildControlButton(
|
|
icon: isMuted ? Icons.mic_off : Icons.mic,
|
|
label: isMuted ? 'Unmute' : 'Mute',
|
|
onPressed: _toggleMute,
|
|
),
|
|
_buildControlButton(
|
|
icon: Icons.dialpad,
|
|
label: 'Keypad',
|
|
onPressed: _toggleKeypad,
|
|
),
|
|
_buildControlButton(
|
|
icon: isSpeakerOn ? Icons.volume_up : Icons.volume_off,
|
|
label: 'Speaker',
|
|
onPressed: _toggleSpeaker,
|
|
iconColor: isSpeakerOn ? Colors.amber : Colors.white,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildDialButton(String digit) {
|
|
return InkWell(
|
|
onTap: () => _addDigit(digit),
|
|
child: Container(
|
|
margin: const EdgeInsets.all(4),
|
|
decoration: BoxDecoration(
|
|
shape: BoxShape.circle,
|
|
color: Colors.grey[800],
|
|
),
|
|
child: Center(
|
|
child: Text(
|
|
digit,
|
|
style: const TextStyle(
|
|
fontSize: 24,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildControlButton({
|
|
required IconData icon,
|
|
required String label,
|
|
required VoidCallback onPressed,
|
|
Color iconColor = Colors.white,
|
|
}) {
|
|
return Column(
|
|
children: [
|
|
IconButton(
|
|
iconSize: 32,
|
|
icon: Icon(icon, color: iconColor),
|
|
onPressed: onPressed,
|
|
),
|
|
Text(
|
|
label,
|
|
style: const TextStyle(color: Colors.white),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
} |