119 lines
3.3 KiB
Dart
119 lines
3.3 KiB
Dart
|
|
import 'package:flutter/material.dart';
|
||
|
|
import '../models/call_info.dart';
|
||
|
|
|
||
|
|
class CallControls extends StatelessWidget {
|
||
|
|
final CallInfo callInfo;
|
||
|
|
final VoidCallback onMute;
|
||
|
|
final VoidCallback onSpeaker;
|
||
|
|
final VoidCallback onHold;
|
||
|
|
final VoidCallback onDialpad;
|
||
|
|
final VoidCallback onTransfer;
|
||
|
|
final VoidCallback onHangUp;
|
||
|
|
|
||
|
|
const CallControls({
|
||
|
|
super.key,
|
||
|
|
required this.callInfo,
|
||
|
|
required this.onMute,
|
||
|
|
required this.onSpeaker,
|
||
|
|
required this.onHold,
|
||
|
|
required this.onDialpad,
|
||
|
|
required this.onTransfer,
|
||
|
|
required this.onHangUp,
|
||
|
|
});
|
||
|
|
|
||
|
|
@override
|
||
|
|
Widget build(BuildContext context) {
|
||
|
|
return Padding(
|
||
|
|
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||
|
|
child: Column(
|
||
|
|
children: [
|
||
|
|
Row(
|
||
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||
|
|
children: [
|
||
|
|
_ControlButton(
|
||
|
|
icon: callInfo.isMuted ? Icons.mic_off : Icons.mic,
|
||
|
|
label: 'Mute',
|
||
|
|
active: callInfo.isMuted,
|
||
|
|
onTap: onMute,
|
||
|
|
),
|
||
|
|
_ControlButton(
|
||
|
|
icon: callInfo.isSpeakerOn
|
||
|
|
? Icons.volume_up
|
||
|
|
: Icons.volume_down,
|
||
|
|
label: 'Speaker',
|
||
|
|
active: callInfo.isSpeakerOn,
|
||
|
|
onTap: onSpeaker,
|
||
|
|
),
|
||
|
|
_ControlButton(
|
||
|
|
icon: callInfo.isOnHold ? Icons.play_arrow : Icons.pause,
|
||
|
|
label: callInfo.isOnHold ? 'Resume' : 'Hold',
|
||
|
|
active: callInfo.isOnHold,
|
||
|
|
onTap: onHold,
|
||
|
|
),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
const SizedBox(height: 16),
|
||
|
|
Row(
|
||
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||
|
|
children: [
|
||
|
|
_ControlButton(
|
||
|
|
icon: Icons.dialpad,
|
||
|
|
label: 'Dialpad',
|
||
|
|
onTap: onDialpad,
|
||
|
|
),
|
||
|
|
_ControlButton(
|
||
|
|
icon: Icons.phone_forwarded,
|
||
|
|
label: 'Transfer',
|
||
|
|
onTap: onTransfer,
|
||
|
|
),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
const SizedBox(height: 24),
|
||
|
|
FloatingActionButton.large(
|
||
|
|
onPressed: onHangUp,
|
||
|
|
backgroundColor: Colors.red,
|
||
|
|
child: const Icon(Icons.call_end, color: Colors.white, size: 36),
|
||
|
|
),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
class _ControlButton extends StatelessWidget {
|
||
|
|
final IconData icon;
|
||
|
|
final String label;
|
||
|
|
final bool active;
|
||
|
|
final VoidCallback onTap;
|
||
|
|
|
||
|
|
const _ControlButton({
|
||
|
|
required this.icon,
|
||
|
|
required this.label,
|
||
|
|
this.active = false,
|
||
|
|
required this.onTap,
|
||
|
|
});
|
||
|
|
|
||
|
|
@override
|
||
|
|
Widget build(BuildContext context) {
|
||
|
|
return Column(
|
||
|
|
mainAxisSize: MainAxisSize.min,
|
||
|
|
children: [
|
||
|
|
IconButton.filled(
|
||
|
|
onPressed: onTap,
|
||
|
|
icon: Icon(icon),
|
||
|
|
style: IconButton.styleFrom(
|
||
|
|
backgroundColor: active
|
||
|
|
? Theme.of(context).colorScheme.primaryContainer
|
||
|
|
: Theme.of(context).colorScheme.surfaceContainerHighest,
|
||
|
|
foregroundColor: active
|
||
|
|
? Theme.of(context).colorScheme.primary
|
||
|
|
: Theme.of(context).colorScheme.onSurface,
|
||
|
|
),
|
||
|
|
),
|
||
|
|
const SizedBox(height: 4),
|
||
|
|
Text(label, style: Theme.of(context).textTheme.labelSmall),
|
||
|
|
],
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|