fixed slot issue

This commit is contained in:
Deep Koluguri 2025-11-06 21:37:42 -05:00
parent 4af1179a23
commit 8c2d72eb84
7 changed files with 365 additions and 147 deletions

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'core/services/auth_service.dart'; import 'core/services/auth_service.dart';
import 'core/services/chit_group_service.dart'; import 'core/services/chit_group_service.dart';
@ -19,7 +20,12 @@ class App extends StatelessWidget {
// Initialize other services // Initialize other services
Get.put(ChitGroupService()); Get.put(ChitGroupService());
Get.put(PaymentService()); Get.put(PaymentService());
// Only initialize ScreenRecordingService on mobile (not on web)
if (!kIsWeb) {
Get.put(ScreenRecordingService()); Get.put(ScreenRecordingService());
}
return Obx(() { return Obx(() {
if (authService.isLoading.value) { if (authService.isLoading.value) {
return const Scaffold( return const Scaffold(

View File

@ -1,3 +1,4 @@
import 'package:flutter/widgets.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../models/chit_group.dart'; import '../models/chit_group.dart';
import '../models/group_member.dart'; import '../models/group_member.dart';
@ -179,7 +180,7 @@ class ChitGroupService extends GetxController {
} }
// Load group members // Load group members
Future<void> loadGroupMembers(String groupId, {String? status}) async { Future<void> loadGroupMembers(String groupId, {String? status, bool showErrors = true}) async {
try { try {
_isLoading.value = true; _isLoading.value = true;
@ -189,11 +190,21 @@ class ChitGroupService extends GetxController {
final membersData = response['data']['members'] as List; final membersData = response['data']['members'] as List;
_groupMembers.value = membersData.map((json) => GroupMember.fromJson(json)).toList(); _groupMembers.value = membersData.map((json) => GroupMember.fromJson(json)).toList();
} else { } else {
if (showErrors) {
// Use post frame callback to avoid showing snackbar during build
WidgetsBinding.instance.addPostFrameCallback((_) {
Get.snackbar('Error', response['message']); Get.snackbar('Error', response['message']);
});
}
} }
} catch (e) { } catch (e) {
print('Error loading group members: $e'); print('Error loading group members: $e');
if (showErrors) {
// Use post frame callback to avoid showing snackbar during build
WidgetsBinding.instance.addPostFrameCallback((_) {
Get.snackbar('Error', 'Failed to load group members'); Get.snackbar('Error', 'Failed to load group members');
});
}
} finally { } finally {
_isLoading.value = false; _isLoading.value = false;
} }

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'dart:async'; import 'dart:async';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -26,6 +27,12 @@ class ScreenRecordingService extends GetxController {
} }
Future<bool> _requestPermissions() async { Future<bool> _requestPermissions() async {
// Web doesn't need permissions for this
if (kIsWeb) return true;
// Only check Platform on non-web platforms
if (!kIsWeb) {
try {
if (Platform.isAndroid) { if (Platform.isAndroid) {
final status = await Permission.storage.request(); final status = await Permission.storage.request();
return status.isGranted; return status.isGranted;
@ -33,6 +40,11 @@ class ScreenRecordingService extends GetxController {
final status = await Permission.photos.request(); final status = await Permission.photos.request();
return status.isGranted; return status.isGranted;
} }
} catch (e) {
// Platform check failed
return true;
}
}
return true; return true;
} }
@ -49,8 +61,14 @@ class ScreenRecordingService extends GetxController {
return false; return false;
} }
// Check if on web or desktop
bool isDesktopOrWeb = kIsWeb;
if (!kIsWeb) {
isDesktopOrWeb = Platform.isWindows || Platform.isLinux || Platform.isMacOS;
}
// Check platform support // Check platform support
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { if (isDesktopOrWeb && !kIsWeb) {
Get.snackbar( Get.snackbar(
'Recording Not Supported', 'Recording Not Supported',
'Screen recording is not available on desktop platforms. Recording simulation will be used instead.', 'Screen recording is not available on desktop platforms. Recording simulation will be used instead.',
@ -62,7 +80,7 @@ class ScreenRecordingService extends GetxController {
} }
final hasPermission = await _requestPermissions(); final hasPermission = await _requestPermissions();
if (!hasPermission && !Platform.isWindows && !Platform.isLinux && !Platform.isMacOS) { if (!hasPermission && !isDesktopOrWeb && !kIsWeb) {
Get.snackbar( Get.snackbar(
'Permission Required', 'Permission Required',
'Please grant storage permission to record the draw', 'Please grant storage permission to record the draw',
@ -84,9 +102,11 @@ class ScreenRecordingService extends GetxController {
} }
}); });
// Don't show snackbar on web
if (!kIsWeb) {
Get.snackbar( Get.snackbar(
'Recording Started', 'Recording Started',
Platform.isWindows || Platform.isLinux || Platform.isMacOS isDesktopOrWeb
? 'Draw recording simulation has begun (desktop mode)' ? 'Draw recording simulation has begun (desktop mode)'
: 'Draw recording has begun', : 'Draw recording has begun',
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
@ -94,6 +114,7 @@ class ScreenRecordingService extends GetxController {
colorText: Colors.white, colorText: Colors.white,
duration: const Duration(seconds: 2), duration: const Duration(seconds: 2),
); );
}
return true; return true;
} catch (e) { } catch (e) {
@ -124,6 +145,12 @@ class ScreenRecordingService extends GetxController {
_durationTimer?.cancel(); _durationTimer?.cancel();
_isRecording.value = false; _isRecording.value = false;
// Web doesn't save files
if (kIsWeb) {
_recordingPath.value = 'web_recording_${DateTime.now().millisecondsSinceEpoch}';
return _recordingPath.value;
}
// Generate recording file path // Generate recording file path
final directory = await getApplicationDocumentsDirectory(); final directory = await getApplicationDocumentsDirectory();
final timestamp = DateTime.now().millisecondsSinceEpoch; final timestamp = DateTime.now().millisecondsSinceEpoch;
@ -132,13 +159,21 @@ class ScreenRecordingService extends GetxController {
_recordingPath.value = filePath; _recordingPath.value = filePath;
// Check if desktop
bool isDesktop = false;
String platformName = 'Unknown';
if (!kIsWeb) {
isDesktop = Platform.isWindows || Platform.isLinux || Platform.isMacOS;
platformName = Platform.operatingSystem;
}
// Create a mock recording file for desktop platforms // Create a mock recording file for desktop platforms
final file = File(filePath); final file = File(filePath);
final recordingContent = ''' final recordingContent = '''
Draw Recording - ${DateTime.now().toIso8601String()} Draw Recording - ${DateTime.now().toIso8601String()}
Platform: ${Platform.operatingSystem} Platform: $platformName
Duration: ${formatDuration(_recordingDuration.value)} Duration: ${formatDuration(_recordingDuration.value)}
Type: ${Platform.isWindows || Platform.isLinux || Platform.isMacOS ? 'Desktop Simulation' : 'Mobile Recording'} Type: ${isDesktop ? 'Desktop Simulation' : 'Mobile Recording'}
This is a mock recording file for demonstration purposes. This is a mock recording file for demonstration purposes.
In a real mobile implementation, this would contain the actual video recording. In a real mobile implementation, this would contain the actual video recording.
@ -147,7 +182,7 @@ In a real mobile implementation, this would contain the actual video recording.
Get.snackbar( Get.snackbar(
'Recording Saved', 'Recording Saved',
Platform.isWindows || Platform.isLinux || Platform.isMacOS isDesktop
? 'Draw recording simulation has been saved successfully' ? 'Draw recording simulation has been saved successfully'
: 'Draw recording has been saved successfully', : 'Draw recording has been saved successfully',
snackPosition: SnackPosition.TOP, snackPosition: SnackPosition.TOP,
@ -181,6 +216,16 @@ In a real mobile implementation, this would contain the actual video recording.
try { try {
if (_recordingPath.value.isEmpty) return; if (_recordingPath.value.isEmpty) return;
// Skip file operations on web
if (kIsWeb) {
// Just log to console on web
print('Draw recording details:');
print('Group: $groupName, Month: $month/$year');
print('Winner: $winnerName');
print('Seeds - Server: $serverSeed, Client: $clientSeed, Nonce: $nonce');
return;
}
final directory = await getApplicationDocumentsDirectory(); final directory = await getApplicationDocumentsDirectory();
final recordingsDir = Directory('${directory.path}/draw_recordings'); final recordingsDir = Directory('${directory.path}/draw_recordings');
if (!await recordingsDir.exists()) { if (!await recordingsDir.exists()) {
@ -240,6 +285,9 @@ In a real mobile implementation, this would contain the actual video recording.
Future<List<Map<String, dynamic>>> getRecordings() async { Future<List<Map<String, dynamic>>> getRecordings() async {
try { try {
// Web doesn't support file system
if (kIsWeb) return [];
final directory = await getApplicationDocumentsDirectory(); final directory = await getApplicationDocumentsDirectory();
final recordingsDir = Directory('${directory.path}/draw_recordings'); final recordingsDir = Directory('${directory.path}/draw_recordings');

View File

@ -68,14 +68,10 @@ class AppTheme {
), ),
// Card Theme // Card Theme
cardTheme: CardThemeData( // Temporarily commented out due to compilation issue
elevation: 2, // cardTheme: const CardThemeData(
color: lightSurface, // elevation: 2,
shape: RoundedRectangleBorder( // ),
borderRadius: BorderRadius.circular(16.r),
),
margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 4.h),
),
// Elevated Button Theme - Accessibility Enhanced // Elevated Button Theme - Accessibility Enhanced
elevatedButtonTheme: ElevatedButtonThemeData( elevatedButtonTheme: ElevatedButtonThemeData(
@ -235,22 +231,22 @@ class AppTheme {
), ),
// Dialog Theme - Accessibility Enhanced // Dialog Theme - Accessibility Enhanced
dialogTheme: DialogThemeData( // dialogTheme: DialogThemeData(
elevation: 8, // More elevation for better depth // elevation: 8, // More elevation for better depth
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.r), // borderRadius: BorderRadius.circular(20.r),
), // ),
titleTextStyle: TextStyle( // titleTextStyle: TextStyle(
fontSize: (22.sp * fontSizeMultiplier), // Larger titles // fontSize: (22.sp * fontSizeMultiplier), // Larger titles
fontWeight: FontWeight.bold, // fontWeight: FontWeight.bold,
color: lightTextPrimary, // color: lightTextPrimary,
), // ),
contentTextStyle: TextStyle( // contentTextStyle: TextStyle(
fontSize: (17.sp * fontSizeMultiplier), // Larger content // fontSize: (17.sp * fontSizeMultiplier), // Larger content
color: lightTextSecondary, // color: lightTextSecondary,
height: 1.5, // Better line spacing // height: 1.5, // Better line spacing
), // ),
), // ),
// Snackbar Theme - Accessibility Enhanced // Snackbar Theme - Accessibility Enhanced
snackBarTheme: SnackBarThemeData( snackBarTheme: SnackBarThemeData(
@ -309,14 +305,14 @@ class AppTheme {
), ),
// Card Theme - Accessibility Enhanced // Card Theme - Accessibility Enhanced
cardTheme: CardThemeData( // cardTheme: CardThemeData(
elevation: 6, // More elevation for better depth in dark mode // elevation: 6, // More elevation for better depth in dark mode
color: darkSurface, // color: darkSurface,
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r), // borderRadius: BorderRadius.circular(16.r),
), // ),
margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h), // More spacing // margin: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h), // More spacing
), // ),
// Elevated Button Theme - Accessibility Enhanced // Elevated Button Theme - Accessibility Enhanced
elevatedButtonTheme: ElevatedButtonThemeData( elevatedButtonTheme: ElevatedButtonThemeData(
@ -442,23 +438,23 @@ class AppTheme {
), ),
// Dialog Theme - Accessibility Enhanced // Dialog Theme - Accessibility Enhanced
dialogTheme: DialogThemeData( // dialogTheme: DialogThemeData(
backgroundColor: darkSurface, // backgroundColor: darkSurface,
elevation: 8, // More elevation // elevation: 8, // More elevation
shape: RoundedRectangleBorder( // shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.r), // borderRadius: BorderRadius.circular(20.r),
), // ),
titleTextStyle: TextStyle( // titleTextStyle: TextStyle(
fontSize: (22.sp * fontSizeMultiplier), // fontSize: (22.sp * fontSizeMultiplier),
fontWeight: FontWeight.bold, // fontWeight: FontWeight.bold,
color: darkTextPrimary, // color: darkTextPrimary,
), // ),
contentTextStyle: TextStyle( // contentTextStyle: TextStyle(
fontSize: (17.sp * fontSizeMultiplier), // fontSize: (17.sp * fontSizeMultiplier),
color: darkTextSecondary, // color: darkTextSecondary,
height: 1.5, // height: 1.5,
), // ),
), // ),
// Snackbar Theme // Snackbar Theme
snackBarTheme: SnackBarThemeData( snackBarTheme: SnackBarThemeData(

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'dart:math' as math; import 'dart:math' as math;
@ -31,7 +32,7 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
late Animation<double> _fadeAnimation; late Animation<double> _fadeAnimation;
late Animation<Offset> _slideAnimation; late Animation<Offset> _slideAnimation;
final ScreenRecordingService _recordingService = Get.find<ScreenRecordingService>(); ScreenRecordingService? _recordingService;
bool _isLoading = false; bool _isLoading = false;
bool _isDrawStarted = false; bool _isDrawStarted = false;
@ -45,8 +46,22 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
void initState() { void initState() {
super.initState(); super.initState();
_initializeForm(); _initializeForm();
_loadEligibleMembers();
_initializeAnimations(); _initializeAnimations();
// Only initialize recording service on mobile
if (!kIsWeb) {
try {
_recordingService = Get.find<ScreenRecordingService>();
} catch (e) {
// Service not available, recording will be disabled
_recordingService = null;
}
}
// Load eligible members after frame to avoid setState during build
WidgetsBinding.instance.addPostFrameCallback((_) {
_loadEligibleMembers();
});
} }
@override @override
@ -95,6 +110,11 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
} }
void _loadEligibleMembers() async { void _loadEligibleMembers() async {
setState(() {
_isLoading = true;
});
try {
// Load real members from the API // Load real members from the API
final chitGroupService = Get.find<ChitGroupService>(); final chitGroupService = Get.find<ChitGroupService>();
@ -117,6 +137,7 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
'name': member.user?.fullName ?? 'Unknown', 'name': member.user?.fullName ?? 'Unknown',
'mobile': member.user?.mobileNumber ?? '', 'mobile': member.user?.mobileNumber ?? '',
}).toList(); }).toList();
_isLoading = false;
}); });
// Show message if no eligible members // Show message if no eligible members
@ -128,11 +149,34 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
colorText: Colors.orange.shade900, colorText: Colors.orange.shade900,
); );
} }
} catch (e) {
setState(() {
_isLoading = false;
});
Get.snackbar(
'Error',
'Failed to load members: ${e.toString()}',
backgroundColor: Colors.red,
colorText: Colors.white,
);
}
} }
void _startDraw() async { void _startDraw() async {
if (!_formKey.currentState!.validate()) return; if (!_formKey.currentState!.validate()) return;
// Check if eligible members are loaded
if (_eligibleMembers.isEmpty) {
Get.snackbar(
'No Eligible Members',
'Please wait for members to load, or all members have already won.',
backgroundColor: Colors.orange,
colorText: Colors.white,
duration: const Duration(seconds: 3),
);
return;
}
// Generate seeds before navigation // Generate seeds before navigation
_generateSeeds(); _generateSeeds();
@ -184,18 +228,20 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
} }
void _startRecording() { void _startRecording() {
_recordingService.startRecording(); _recordingService?.startRecording();
} }
void _stopRecording() { void _stopRecording() {
_recordingService.stopRecording(); _recordingService?.stopRecording();
} }
void _stopRecordingWithDetails() { void _stopRecordingWithDetails() {
if (_recordingService == null) return;
final month = int.parse(_monthController.text); final month = int.parse(_monthController.text);
final year = int.parse(_yearController.text); final year = int.parse(_yearController.text);
_recordingService.saveRecordingWithDetails( _recordingService!.saveRecordingWithDetails(
groupName: widget.group.name, groupName: widget.group.name,
month: month.toString(), month: month.toString(),
year: year.toString(), year: year.toString(),
@ -334,10 +380,20 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
if (_isLoading)
SizedBox(
width: 20.w,
height: 20.w,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
)
else
Icon(Icons.play_arrow, size: 20.w), Icon(Icons.play_arrow, size: 20.w),
SizedBox(width: 8.w), SizedBox(width: 8.w),
Text( Text(
'Start Draw', _isLoading ? 'Loading...' : 'Start Draw',
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600), style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w600),
), ),
], ],
@ -478,14 +534,44 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
SizedBox(height: 16.h), SizedBox(height: 16.h),
// Eligible Members // Eligible Members
Row(
children: [
Text( Text(
'Eligible Members (${_eligibleMembers.length})', 'Eligible Members',
style: TextStyle( style: TextStyle(
fontSize: 16.sp, fontSize: 16.sp,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Colors.grey.shade800, color: Colors.grey.shade800,
), ),
), ),
SizedBox(width: 8.w),
if (_isLoading)
SizedBox(
width: 16.w,
height: 16.w,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(Colors.purple.shade600),
),
)
else
Container(
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.h),
decoration: BoxDecoration(
color: _eligibleMembers.isEmpty ? Colors.orange.shade100 : Colors.purple.shade100,
borderRadius: BorderRadius.circular(12.r),
),
child: Text(
'${_eligibleMembers.length}',
style: TextStyle(
fontSize: 14.sp,
fontWeight: FontWeight.bold,
color: _eligibleMembers.isEmpty ? Colors.orange.shade800 : Colors.purple.shade800,
),
),
),
],
),
SizedBox(height: 12.h), SizedBox(height: 12.h),
Container( Container(
height: 150.h, height: 150.h,
@ -493,30 +579,86 @@ class _CombinedDrawDialogState extends State<CombinedDrawDialog>
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(8.r), borderRadius: BorderRadius.circular(8.r),
), ),
child: ListView.builder( child: _isLoading
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
SizedBox(height: 12.h),
Text(
'Loading members...',
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey.shade600,
),
),
],
),
)
: _eligibleMembers.isEmpty
? Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.info_outline,
size: 40.w,
color: Colors.orange.shade400,
),
SizedBox(height: 8.h),
Text(
'No eligible members',
style: TextStyle(
fontSize: 14.sp,
color: Colors.grey.shade600,
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 4.h),
Text(
'All members have won',
style: TextStyle(
fontSize: 12.sp,
color: Colors.grey.shade500,
),
),
],
),
)
: ListView.builder(
itemCount: _eligibleMembers.length, itemCount: _eligibleMembers.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final member = _eligibleMembers[index]; final member = _eligibleMembers[index];
return ListTile( return ListTile(
dense: true,
leading: CircleAvatar( leading: CircleAvatar(
backgroundColor: Colors.purple.shade100, backgroundColor: Colors.purple.shade100,
radius: 18.r,
child: Text( child: Text(
(member['name']?.isNotEmpty == true ? member['name'].substring(0, 1) : 'M').toUpperCase(), (member['name']?.isNotEmpty == true ? member['name'].substring(0, 1) : 'M').toUpperCase(),
style: TextStyle( style: TextStyle(
color: Colors.purple.shade700, color: Colors.purple.shade700,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 14.sp,
), ),
), ),
), ),
title: Text( title: Text(
member['name'], member['name'],
style: TextStyle(fontWeight: FontWeight.w500), style: TextStyle(
fontWeight: FontWeight.w500,
fontSize: 14.sp,
),
),
subtitle: Text(
member['mobile'],
style: TextStyle(fontSize: 12.sp),
), ),
subtitle: Text(member['mobile']),
trailing: Icon( trailing: Icon(
Icons.check_circle, Icons.check_circle,
color: Colors.green.shade600, color: Colors.green.shade600,
size: 20.w, size: 18.w,
), ),
); );
}, },

View File

@ -244,9 +244,10 @@ class _DrawAnimationPageState extends State<DrawAnimationPage>
), ),
), ),
// Animation Area // Animation Area - Scrollable
Expanded( Expanded(
child: Center( child: SingleChildScrollView(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
child: DrawAnimationSelector( child: DrawAnimationSelector(
members: widget.eligibleMembers, members: widget.eligibleMembers,
onDrawComplete: _onDrawComplete, onDrawComplete: _onDrawComplete,

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../core/services/screen_recording_service.dart'; import '../../core/services/screen_recording_service.dart';
@ -15,6 +16,19 @@ class RecordingOverlay extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// On web, skip recording overlay entirely
if (kIsWeb) {
return child;
}
// Try to find the service, if not available, just show the child
try {
Get.find<ScreenRecordingService>();
} catch (e) {
// Service not available
return child;
}
return Stack( return Stack(
children: [ children: [
child, child,
@ -23,8 +37,8 @@ class RecordingOverlay extends StatelessWidget {
top: 20.h, top: 20.h,
right: 20.w, right: 20.w,
child: GetBuilder<ScreenRecordingService>( child: GetBuilder<ScreenRecordingService>(
builder: (recordingService) { builder: (service) {
if (!recordingService.isRecording) { if (!service.isRecording) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
@ -57,7 +71,7 @@ class RecordingOverlay extends StatelessWidget {
// Recording text // Recording text
Flexible( Flexible(
child: Text( child: Text(
'REC ${recordingService.formatDuration(recordingService.recordingDuration)}', 'REC ${service.formatDuration(service.recordingDuration)}',
style: TextStyle( style: TextStyle(
color: Colors.white, color: Colors.white,
fontSize: 12.sp, fontSize: 12.sp,