chitfund/luckychit/lib/shared/widgets/recording_overlay.dart

285 lines
8.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import '../../core/services/screen_recording_service.dart';
class RecordingOverlay extends StatelessWidget {
final Widget child;
final bool showRecordingIndicator;
const RecordingOverlay({
Key? key,
required this.child,
this.showRecordingIndicator = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Stack(
children: [
child,
if (showRecordingIndicator)
Positioned(
top: 20.h,
right: 20.w,
child: GetBuilder<ScreenRecordingService>(
builder: (recordingService) {
if (!recordingService.isRecording) {
return const SizedBox.shrink();
}
return Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.h),
decoration: BoxDecoration(
color: Colors.red.shade600,
borderRadius: BorderRadius.circular(20.r),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
blurRadius: 8.r,
offset: Offset(0, 2.h),
),
],
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// Recording dot
Container(
width: 8.w,
height: 8.h,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
SizedBox(width: 8.w),
// Recording text
Flexible(
child: Text(
'REC ${recordingService.formatDuration(recordingService.recordingDuration)}',
style: TextStyle(
color: Colors.white,
fontSize: 12.sp,
fontWeight: FontWeight.bold,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
);
},
),
),
],
);
}
}
class RecordingControls extends StatelessWidget {
final VoidCallback? onStartRecording;
final VoidCallback? onStopRecording;
final bool isRecording;
final double recordingDuration;
const RecordingControls({
Key? key,
this.onStartRecording,
this.onStopRecording,
this.isRecording = false,
this.recordingDuration = 0.0,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(12.r),
border: Border.all(color: Colors.grey.shade300),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Icon(
Icons.videocam,
color: Colors.red.shade600,
size: 20.w,
),
SizedBox(width: 8.w),
Expanded(
child: Text(
'Draw Recording',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
color: Colors.grey.shade800,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
SizedBox(height: 12.h),
if (isRecording) ...[
// Recording in progress
Row(
children: [
Container(
width: 12.w,
height: 12.h,
decoration: BoxDecoration(
color: Colors.red.shade600,
shape: BoxShape.circle,
),
),
SizedBox(width: 8.w),
Expanded(
child: Text(
'Recording: ${_formatDuration(recordingDuration)}',
style: TextStyle(
fontSize: 14.sp,
color: Colors.red.shade600,
fontWeight: FontWeight.w500,
),
overflow: TextOverflow.ellipsis,
),
),
],
),
SizedBox(height: 12.h),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: onStopRecording,
icon: Icon(Icons.stop, size: 18.w),
label: Text('Stop Recording'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red.shade600,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 12.h),
),
),
),
] else ...[
// Not recording
Text(
'Record the draw process for transparency and verification',
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey.shade600,
),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 2,
),
SizedBox(height: 12.h),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: onStartRecording,
icon: Icon(Icons.videocam, size: 18.w),
label: Text('Start Recording'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.green.shade600,
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 12.h),
),
),
),
],
],
),
);
}
String _formatDuration(double seconds) {
final minutes = (seconds / 60).floor();
final remainingSeconds = (seconds % 60).floor();
return '${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}';
}
}
class RecordingStatusBanner extends StatelessWidget {
final bool isRecording;
final double duration;
final VoidCallback? onStop;
const RecordingStatusBanner({
Key? key,
required this.isRecording,
this.duration = 0.0,
this.onStop,
}) : super(key: key);
@override
Widget build(BuildContext context) {
if (!isRecording) return const SizedBox.shrink();
return Container(
width: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h),
decoration: BoxDecoration(
color: Colors.red.shade600,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.1),
blurRadius: 4.r,
offset: Offset(0, 2.h),
),
],
),
child: Row(
children: [
Container(
width: 8.w,
height: 8.h,
decoration: BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
SizedBox(width: 12.w),
Expanded(
child: Text(
'Recording Draw Process - ${_formatDuration(duration)}',
style: TextStyle(
color: Colors.white,
fontSize: 14.sp,
fontWeight: FontWeight.w500,
),
),
),
if (onStop != null)
GestureDetector(
onTap: onStop,
child: Container(
padding: EdgeInsets.all(4.w),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(4.r),
),
child: Icon(
Icons.stop,
color: Colors.white,
size: 16.w,
),
),
),
],
),
);
}
String _formatDuration(double seconds) {
final minutes = (seconds / 60).floor();
final remainingSeconds = (seconds % 60).floor();
return '${minutes.toString().padLeft(2, '0')}:${remainingSeconds.toString().padLeft(2, '0')}';
}
}