import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:sense_the_rhythm/esense_connect_dialog.dart'; import 'package:sense_the_rhythm/esense_input.dart'; import 'package:sense_the_rhythm/simfile.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'level.dart'; class LevelSelection extends StatefulWidget { const LevelSelection({super.key}); @override State createState() => _LevelSelectionState(); } class _LevelSelectionState extends State { String? stepmaniaCoursesPath; List stepmaniaCoursesFolders = []; @override void initState() { super.initState(); loadFolderPath(); } Future loadFolderPath() async { SharedPreferences prefs = await SharedPreferences.getInstance(); final String? stepmaniaCoursesPathSetting = prefs.getString('stepmania_courses'); if (stepmaniaCoursesPathSetting == null) return; List stepmaniaCoursesFoldersFuture = await listFilesAndFolders(stepmaniaCoursesPathSetting); setState(() { stepmaniaCoursesPath = stepmaniaCoursesPathSetting; stepmaniaCoursesFolders = stepmaniaCoursesFoldersFuture; }); } Future selectFolder() async { await Permission.manageExternalStorage.request(); String? selectedFolder = await FilePicker.platform.getDirectoryPath(); if (selectedFolder != null) { // Save the selected folder path SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString('stepmania_courses', selectedFolder); loadFolderPath(); } } Future> listFilesAndFolders(String directoryPath) async { final directory = Directory(directoryPath); try { // List all files and folders in the directory List simfiles = directory .listSync() .where((entity) => FileSystemEntity.isDirectorySync(entity.path)) .map((entity) { Simfile simfile = Simfile(entity.path); simfile.load(); return simfile; }).toList(); simfiles.sort((a,b) => a.tags['TITLE']!.compareTo(b.tags['TITLE']!)); return simfiles; } catch (e) { print("Error reading directory: $e"); return []; } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Sense the Rhythm'), actions: [ IconButton( onPressed: () => showDialog( context: context, builder: (BuildContext context) { return ESenseConnectDialog( deviceStatus: ESenseInput.instance.deviceStatus, connect: (String name) { ESenseInput.instance.connectToESense(name); }); }, ), icon: const Icon(Icons.bluetooth)) ], ), body: Builder(builder: (context) { if (stepmaniaCoursesPath == null) { return Text('Add a Directory with Stepmania Songs on \'+\''); } else if (stepmaniaCoursesFolders.isEmpty) { return Text( 'Folder empty. Add Stepmania Songs to Folder or select a different folder on \'+\''); } else { return ListView.separated( itemCount: stepmaniaCoursesFolders.length, separatorBuilder: (BuildContext context, int index) => const Divider(), itemBuilder: (context, index) { return ListTile( leading: Image.file( File(stepmaniaCoursesFolders[index].bannerPath!)), trailing: Icon(Icons.play_arrow), title: Text(stepmaniaCoursesFolders[index].tags["TITLE"]!), subtitle: Text('3:45'), onTap: () => Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) => Level(stepmaniaCoursesFolders[index]))), ); }, ); } }), floatingActionButton: FloatingActionButton( onPressed: () => {selectFolder()}, child: Icon(Icons.add)), ); } }