level_list_entry.dart (2713B)
1 import 'dart:io'; 2 3 import 'package:flutter/material.dart'; 4 import 'package:sense_the_rhythm/utils/esense_input.dart'; 5 import 'package:sense_the_rhythm/utils/simfile.dart'; 6 import 'package:sense_the_rhythm/screens/level.dart'; 7 import 'package:sense_the_rhythm/widgets/esense_connect_dialog.dart'; 8 import 'package:sense_the_rhythm/widgets/esense_not_connected_dialog.dart'; 9 import 'package:sense_the_rhythm/widgets/level_info_chip.dart'; 10 11 class LevelListEntry extends StatelessWidget { 12 const LevelListEntry({ 13 super.key, 14 required this.simfile, 15 }); 16 17 final Simfile simfile; 18 19 /// navigates to level screen 20 void _navigateToLevel(BuildContext context) { 21 Navigator.push(context, 22 MaterialPageRoute(builder: (BuildContext context) => Level(simfile))); 23 } 24 25 /// opens ESenseConnectDialog 26 void _openESenseConnectDialog(context) { 27 showDialog( 28 context: context, 29 builder: (BuildContext context) { 30 return ESenseConnectDialog( 31 deviceStatus: ESenseInput.instance.deviceStatus, 32 connect: (String name) { 33 ESenseInput.instance.connectToESense(name); 34 }, 35 disconnect: () { 36 ESenseInput.instance.eSenseManager.disconnect(); 37 }, 38 ); 39 }, 40 ); 41 } 42 43 /// when clocked on the level, warn if not connected to ESense 44 void _tapHandler(BuildContext context) { 45 if (ESenseInput.instance.connected) { 46 _navigateToLevel(context); 47 } else { 48 showDialog( 49 context: context, 50 builder: (BuildContext context) { 51 return ESenseNotConnectedDialog( 52 onCancel: () { 53 _openESenseConnectDialog(context); 54 }, 55 onContinue: () { 56 _navigateToLevel(context); 57 }, 58 ); 59 }, 60 ); 61 } 62 } 63 64 @override 65 Widget build(BuildContext context) { 66 return ListTile( 67 leading: Image.file(File(simfile.bannerPath!)), 68 trailing: Icon(Icons.play_arrow), 69 title: Text( 70 simfile.tags["TITLE"]!, 71 style: TextStyle(fontWeight: FontWeight.bold), 72 ), 73 subtitle: Padding( 74 padding: const EdgeInsets.only(bottom: 2), 75 child: Row( 76 spacing: 2, 77 children: [ 78 LevelInfoChip( 79 label: 80 '${simfile.duration!.inMinutes}:${simfile.duration!.inSeconds.remainder(60).toString().padLeft(2, "0")}', 81 icon: Icons.timer_outlined, 82 ), 83 LevelInfoChip( 84 label: '${simfile.bpms.entries.first.value.toInt()} BPM', 85 icon: Icons.graphic_eq, 86 ), 87 ], 88 ), 89 ), 90 onTap: () { 91 _tapHandler(context); 92 }, 93 ); 94 } 95 }