style: refactored searching files into Simfile class
This commit is contained in:
		
							parent
							
								
									685323adea
								
							
						
					
					
						commit
						9c229b94d0
					
				| 
						 | 
				
			
			@ -50,8 +50,8 @@ class GameOverStats extends StatelessWidget {
 | 
			
		|||
            ]),
 | 
			
		||||
            TextButton(
 | 
			
		||||
                onPressed: () {
 | 
			
		||||
                  Route route = MaterialPageRoute(
 | 
			
		||||
                      builder: (context) => Level(stepmaniaFolderPath: simfile.directoryPath));
 | 
			
		||||
                  Route route =
 | 
			
		||||
                      MaterialPageRoute(builder: (context) => Level(simfile));
 | 
			
		||||
                  Navigator.pushReplacement(context, route);
 | 
			
		||||
                },
 | 
			
		||||
                child: Text('Retry'))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,8 @@ import 'package:sense_the_rhythm/game_over_stats.dart';
 | 
			
		|||
import 'package:sense_the_rhythm/simfile.dart';
 | 
			
		||||
 | 
			
		||||
class Level extends StatefulWidget {
 | 
			
		||||
  const Level({super.key, required this.stepmaniaFolderPath});
 | 
			
		||||
  final String stepmaniaFolderPath;
 | 
			
		||||
  const Level(this.simfile, {super.key});
 | 
			
		||||
  final Simfile simfile;
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
  State<Level> createState() => _LevelState();
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,6 @@ class InputDirection {
 | 
			
		|||
 | 
			
		||||
class _LevelState extends State<Level> {
 | 
			
		||||
  final player = AudioPlayer();
 | 
			
		||||
  Simfile? simfile;
 | 
			
		||||
  bool _isPlaying = true;
 | 
			
		||||
  Duration? _duration;
 | 
			
		||||
  Duration? _position;
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +76,7 @@ class _LevelState extends State<Level> {
 | 
			
		|||
    player.onPlayerComplete.listen((void _) {
 | 
			
		||||
      Route route = MaterialPageRoute(
 | 
			
		||||
          builder: (context) => GameOverStats(
 | 
			
		||||
                simfile: simfile!,
 | 
			
		||||
                simfile: widget.simfile,
 | 
			
		||||
                notes: notes,
 | 
			
		||||
              ));
 | 
			
		||||
      Navigator.pushReplacement(context, route);
 | 
			
		||||
| 
						 | 
				
			
			@ -131,10 +130,7 @@ class _LevelState extends State<Level> {
 | 
			
		|||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    simfile = Simfile(widget.stepmaniaFolderPath);
 | 
			
		||||
    simfile!.load();
 | 
			
		||||
 | 
			
		||||
    simfile!.chartSimplest!.beats.forEach((time, noteData) {
 | 
			
		||||
    widget.simfile.chartSimplest!.beats.forEach((time, noteData) {
 | 
			
		||||
      int arrowIndex = noteData.indexOf('1');
 | 
			
		||||
      if (arrowIndex < 0 || arrowIndex > 3) {
 | 
			
		||||
        return;
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +138,7 @@ class _LevelState extends State<Level> {
 | 
			
		|||
      notes.add(Note(time: time, direction: ArrowDirection.values[arrowIndex]));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    player.play(DeviceFileSource(simfile!.audioPath!));
 | 
			
		||||
    player.play(DeviceFileSource(widget.simfile.audioPath!));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @override
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +188,7 @@ class _LevelState extends State<Level> {
 | 
			
		|||
                }
 | 
			
		||||
              },
 | 
			
		||||
            ),
 | 
			
		||||
            title: Text(widget.stepmaniaFolderPath.split('/').last),
 | 
			
		||||
            title: Text(widget.simfile.tags['TITLE']!),
 | 
			
		||||
            actions: [
 | 
			
		||||
              IconButton(
 | 
			
		||||
                  icon: Icon(Icons.close),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ 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/simfile.dart';
 | 
			
		||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
			
		||||
 | 
			
		||||
import 'level.dart';
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +19,7 @@ class LevelSelection extends StatefulWidget {
 | 
			
		|||
 | 
			
		||||
class _LevelSelectionState extends State<LevelSelection> {
 | 
			
		||||
  String? stepmaniaCoursesPath;
 | 
			
		||||
  List<FileSystemEntity> stepmaniaCoursesFolders = [];
 | 
			
		||||
  List<Simfile> stepmaniaCoursesFolders = [];
 | 
			
		||||
 | 
			
		||||
  String eSenseDeviceName = '';
 | 
			
		||||
  ESenseManager? eSenseManager;
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +110,8 @@ class _LevelSelectionState extends State<LevelSelection> {
 | 
			
		|||
        prefs.getString('stepmania_courses');
 | 
			
		||||
 | 
			
		||||
    if (stepmaniaCoursesPathSetting == null) return;
 | 
			
		||||
    List<FileSystemEntity> stepmaniaCoursesFoldersFuture = await listFilesAndFolders(stepmaniaCoursesPathSetting);
 | 
			
		||||
    List<Simfile> stepmaniaCoursesFoldersFuture =
 | 
			
		||||
        await listFilesAndFolders(stepmaniaCoursesPathSetting);
 | 
			
		||||
 | 
			
		||||
    setState(() {
 | 
			
		||||
      stepmaniaCoursesPath = stepmaniaCoursesPathSetting;
 | 
			
		||||
| 
						 | 
				
			
			@ -129,15 +131,18 @@ class _LevelSelectionState extends State<LevelSelection> {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<List<FileSystemEntity>> listFilesAndFolders(
 | 
			
		||||
      String directoryPath) async {
 | 
			
		||||
  Future<List<Simfile>> listFilesAndFolders(String directoryPath) async {
 | 
			
		||||
    final directory = Directory(directoryPath);
 | 
			
		||||
    try {
 | 
			
		||||
      // List all files and folders in the directory
 | 
			
		||||
      return directory
 | 
			
		||||
          .listSync()
 | 
			
		||||
          .where((entity) => FileSystemEntity.isDirectorySync(entity.path))
 | 
			
		||||
          .toList();
 | 
			
		||||
          .map((entity) {
 | 
			
		||||
        Simfile simfile = Simfile(entity.path);
 | 
			
		||||
        simfile.load();
 | 
			
		||||
        return simfile;
 | 
			
		||||
      }).toList();
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      print("Error reading directory: $e");
 | 
			
		||||
      return [];
 | 
			
		||||
| 
						 | 
				
			
			@ -155,10 +160,10 @@ class _LevelSelectionState extends State<LevelSelection> {
 | 
			
		|||
                    context: context,
 | 
			
		||||
                    builder: (BuildContext context) {
 | 
			
		||||
                      return ESenseConnectDialog(
 | 
			
		||||
                        deviceStatus: _deviceStatus,
 | 
			
		||||
                        connect: (String name) {
 | 
			
		||||
                          _connectToESense(name);
 | 
			
		||||
                        });
 | 
			
		||||
                          deviceStatus: _deviceStatus,
 | 
			
		||||
                          connect: (String name) {
 | 
			
		||||
                            _connectToESense(name);
 | 
			
		||||
                          });
 | 
			
		||||
                    },
 | 
			
		||||
                  ),
 | 
			
		||||
              icon: const Icon(Icons.bluetooth))
 | 
			
		||||
| 
						 | 
				
			
			@ -176,26 +181,17 @@ class _LevelSelectionState extends State<LevelSelection> {
 | 
			
		|||
            separatorBuilder: (BuildContext context, int index) =>
 | 
			
		||||
                const Divider(),
 | 
			
		||||
            itemBuilder: (context, index) {
 | 
			
		||||
              String thumbnailPath = Directory(
 | 
			
		||||
                      stepmaniaCoursesFolders[index].path)
 | 
			
		||||
                  .listSync()
 | 
			
		||||
                  .firstWhere(
 | 
			
		||||
                      (file) => file.path.toLowerCase().endsWith('banner.png'),
 | 
			
		||||
                      orElse: () => File(''))
 | 
			
		||||
                  .path;
 | 
			
		||||
              return ListTile(
 | 
			
		||||
                leading: Image.file(File(thumbnailPath)),
 | 
			
		||||
                leading: Image.file(
 | 
			
		||||
                    File(stepmaniaCoursesFolders[index].bannerPath!)),
 | 
			
		||||
                trailing: Icon(Icons.play_arrow),
 | 
			
		||||
                title:
 | 
			
		||||
                    Text(stepmaniaCoursesFolders[index].path.split('/').last),
 | 
			
		||||
                title: Text(stepmaniaCoursesFolders[index].tags["TITLE"]!),
 | 
			
		||||
                subtitle: Text('3:45'),
 | 
			
		||||
                onTap: () => Navigator.push(
 | 
			
		||||
                    context,
 | 
			
		||||
                    MaterialPageRoute(
 | 
			
		||||
                        builder: (BuildContext context) => Level(
 | 
			
		||||
                              stepmaniaFolderPath:
 | 
			
		||||
                                  stepmaniaCoursesFolders[index].path,
 | 
			
		||||
                            ))),
 | 
			
		||||
                        builder: (BuildContext context) =>
 | 
			
		||||
                            Level(stepmaniaCoursesFolders[index]))),
 | 
			
		||||
              );
 | 
			
		||||
            },
 | 
			
		||||
          );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -124,7 +124,8 @@ class Simfile {
 | 
			
		|||
    simfilePath = Directory(directoryPath)
 | 
			
		||||
        .listSync()
 | 
			
		||||
        .firstWhere((entity) => entity.path.endsWith('.sm'),
 | 
			
		||||
            orElse: () => File('')).path;
 | 
			
		||||
            orElse: () => File(''))
 | 
			
		||||
        .path;
 | 
			
		||||
 | 
			
		||||
    audioPath = Directory(directoryPath)
 | 
			
		||||
        .listSync()
 | 
			
		||||
| 
						 | 
				
			
			@ -132,6 +133,12 @@ class Simfile {
 | 
			
		|||
            orElse: () => File(''))
 | 
			
		||||
        .path;
 | 
			
		||||
 | 
			
		||||
    bannerPath = Directory(directoryPath)
 | 
			
		||||
        .listSync()
 | 
			
		||||
        .firstWhere((file) => file.path.toLowerCase().endsWith('banner.png'),
 | 
			
		||||
            orElse: () => File(''))
 | 
			
		||||
        .path;
 | 
			
		||||
 | 
			
		||||
    lines = File(simfilePath!).readAsStringSync();
 | 
			
		||||
 | 
			
		||||
    RegExp commentsRegExp = RegExp(r'//.*$');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue