diff options
Diffstat (limited to 'lib/widgets/level_list_entry.dart')
-rw-r--r-- | lib/widgets/level_list_entry.dart | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/widgets/level_list_entry.dart b/lib/widgets/level_list_entry.dart new file mode 100644 index 0000000..ad7766d --- /dev/null +++ b/lib/widgets/level_list_entry.dart @@ -0,0 +1,95 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:sense_the_rhythm/utils/esense_input.dart'; +import 'package:sense_the_rhythm/utils/simfile.dart'; +import 'package:sense_the_rhythm/screens/level.dart'; +import 'package:sense_the_rhythm/widgets/esense_connect_dialog.dart'; +import 'package:sense_the_rhythm/widgets/esense_not_connected_dialog.dart'; +import 'package:sense_the_rhythm/widgets/level_info_chip.dart'; + +class LevelListEntry extends StatelessWidget { + const LevelListEntry({ + super.key, + required this.simfile, + }); + + final Simfile simfile; + + /// navigates to level screen + void _navigateToLevel(BuildContext context) { + Navigator.push(context, + MaterialPageRoute(builder: (BuildContext context) => Level(simfile))); + } + + /// opens ESenseConnectDialog + void _openESenseConnectDialog(context) { + showDialog( + context: context, + builder: (BuildContext context) { + return ESenseConnectDialog( + deviceStatus: ESenseInput.instance.deviceStatus, + connect: (String name) { + ESenseInput.instance.connectToESense(name); + }, + disconnect: () { + ESenseInput.instance.eSenseManager.disconnect(); + }, + ); + }, + ); + } + + /// when clocked on the level, warn if not connected to ESense + void _tapHandler(BuildContext context) { + if (ESenseInput.instance.connected) { + _navigateToLevel(context); + } else { + showDialog( + context: context, + builder: (BuildContext context) { + return ESenseNotConnectedDialog( + onCancel: () { + _openESenseConnectDialog(context); + }, + onContinue: () { + _navigateToLevel(context); + }, + ); + }, + ); + } + } + + @override + Widget build(BuildContext context) { + return ListTile( + leading: Image.file(File(simfile.bannerPath!)), + trailing: Icon(Icons.play_arrow), + title: Text( + simfile.tags["TITLE"]!, + style: TextStyle(fontWeight: FontWeight.bold), + ), + subtitle: Padding( + padding: const EdgeInsets.only(bottom: 2), + child: Row( + spacing: 2, + children: [ + LevelInfoChip( + label: + '${simfile.duration!.inMinutes}:${simfile.duration!.inSeconds.remainder(60).toString().padLeft(2, "0")}', + icon: Icons.timer_outlined, + ), + LevelInfoChip( + label: '${simfile.bpms.entries.first.value.toInt()} BPM', + icon: Icons.graphic_eq, + ), + ], + ), + ), + onTap: () { + _tapHandler(context); + }, + ); + } +} |