import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:intl/intl.dart'; import '../../../core/models/datalog_session.dart'; import '../../../core/providers/datalog_provider.dart'; import 'datalog_playback_bar.dart'; class DatalogListScreen extends ConsumerWidget { const DatalogListScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final sessionsAsync = ref.watch(sessionListProvider); final playback = ref.watch(playbackProvider); return Scaffold( appBar: AppBar(title: const Text('Saved Sessions')), body: Column( children: [ if (playback.isActive) DatalogPlaybackBar(state: playback), Expanded( child: sessionsAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center( child: Text('Error: $e', style: const TextStyle(color: Colors.red))), data: (sessions) => sessions.isEmpty ? const Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.videocam_off, size: 56, color: Colors.grey), SizedBox(height: 12), Text('No recorded sessions', style: TextStyle(color: Colors.grey)), ], ), ) : ListView.separated( itemCount: sessions.length, separatorBuilder: (_, __) => const Divider(height: 1, color: Colors.white10), itemBuilder: (context, i) => _SessionTile(session: sessions[i]), ), ), ), ], ), ); } } class _SessionTile extends ConsumerWidget { final DatalogSession session; const _SessionTile({required this.session}); @override Widget build(BuildContext context, WidgetRef ref) { final fmt = DateFormat('dd MMM yyyy HH:mm'); final isPlaying = ref.watch(playbackProvider).sessionId == session.id; return Dismissible( key: ValueKey(session.id), direction: DismissDirection.endToStart, background: Container( color: Colors.red, alignment: Alignment.centerRight, padding: const EdgeInsets.only(right: 20), child: const Icon(Icons.delete, color: Colors.white), ), confirmDismiss: (_) async { return await showDialog( context: context, builder: (ctx) => AlertDialog( title: const Text('Delete session?'), content: const Text('This cannot be undone.'), actions: [ TextButton( onPressed: () => Navigator.pop(ctx, false), child: const Text('Cancel')), TextButton( onPressed: () => Navigator.pop(ctx, true), child: const Text('Delete', style: TextStyle(color: Colors.red))), ], ), ); }, onDismissed: (_) async { await ref .read(datalogDbProvider) .deleteSession(session.id!); ref.invalidate(sessionListProvider); }, child: ListTile( leading: Icon( isPlaying ? Icons.play_circle : Icons.videocam, color: isPlaying ? Colors.green : Colors.grey, ), title: Text( fmt.format(session.startTime), style: const TextStyle(fontSize: 13), ), subtitle: Text( '${session.ecuType.toUpperCase()} • ' '${session.frameCount} frames • ${session.durationLabel}', style: const TextStyle(color: Colors.grey, fontSize: 11), ), trailing: const Icon(Icons.play_arrow, size: 18), onTap: () async { await ref .read(playbackProvider.notifier) .loadSession(session.id!); ref.read(playbackProvider.notifier).play(); }, ), ); } }