feat: when selecting level show ESenseNotConnectedDialog if not connected to esense
This commit is contained in:
		
							parent
							
								
									d9403d9e98
								
							
						
					
					
						commit
						4fb6af0135
					
				| 
						 | 
					@ -1,14 +1,13 @@
 | 
				
			||||||
import 'dart:io';
 | 
					import 'dart:io';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import 'package:file_picker/file_picker.dart';
 | 
					 | 
				
			||||||
import 'package:flutter/material.dart';
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
import 'package:permission_handler/permission_handler.dart';
 | 
					import 'package:permission_handler/permission_handler.dart';
 | 
				
			||||||
import 'package:sense_the_rhythm/widgets/connection_status_button.dart';
 | 
					 | 
				
			||||||
import 'package:shared_preferences/shared_preferences.dart';
 | 
					import 'package:shared_preferences/shared_preferences.dart';
 | 
				
			||||||
 | 
					import 'package:file_picker/file_picker.dart';
 | 
				
			||||||
import 'package:sense_the_rhythm/utils/esense_input.dart';
 | 
					import 'package:sense_the_rhythm/utils/esense_input.dart';
 | 
				
			||||||
import 'package:sense_the_rhythm/utils/simfile.dart';
 | 
					import 'package:sense_the_rhythm/utils/simfile.dart';
 | 
				
			||||||
import 'package:sense_the_rhythm/widgets/esense_connect_dialog.dart';
 | 
					import 'package:sense_the_rhythm/widgets/connection_status_button.dart';
 | 
				
			||||||
import 'package:sense_the_rhythm/screens/level.dart';
 | 
					import 'package:sense_the_rhythm/widgets/level_list_entry.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LevelSelection extends StatefulWidget {
 | 
					class LevelSelection extends StatefulWidget {
 | 
				
			||||||
  const LevelSelection({super.key});
 | 
					  const LevelSelection({super.key});
 | 
				
			||||||
| 
						 | 
					@ -133,17 +132,7 @@ class _LevelSelectionState extends State<LevelSelection> {
 | 
				
			||||||
                      const Divider(),
 | 
					                      const Divider(),
 | 
				
			||||||
                  itemBuilder: (context, index) {
 | 
					                  itemBuilder: (context, index) {
 | 
				
			||||||
                    Simfile simfile = stepmaniaCoursesFoldersFiltered[index];
 | 
					                    Simfile simfile = stepmaniaCoursesFoldersFiltered[index];
 | 
				
			||||||
                    return ListTile(
 | 
					                    return LevelListEntry(simfile: simfile);
 | 
				
			||||||
                      leading: Image.file(File(simfile.bannerPath!)),
 | 
					 | 
				
			||||||
                      trailing: Icon(Icons.play_arrow),
 | 
					 | 
				
			||||||
                      title: Text(simfile.tags["TITLE"]!),
 | 
					 | 
				
			||||||
                      subtitle: Text('3:45'),
 | 
					 | 
				
			||||||
                      onTap: () => Navigator.push(
 | 
					 | 
				
			||||||
                          context,
 | 
					 | 
				
			||||||
                          MaterialPageRoute(
 | 
					 | 
				
			||||||
                              builder: (BuildContext context) =>
 | 
					 | 
				
			||||||
                                  Level(simfile))),
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
                  },
 | 
					                  },
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
              ),
 | 
					              ),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ class ESenseInput {
 | 
				
			||||||
  static final instance = ESenseInput._();
 | 
					  static final instance = ESenseInput._();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ESenseManager eSenseManager = ESenseManager('unknown');
 | 
					  ESenseManager eSenseManager = ESenseManager('unknown');
 | 
				
			||||||
  ValueNotifier<String> deviceStatus = ValueNotifier('');
 | 
					  ValueNotifier<String> deviceStatus = ValueNotifier('Disconnected');
 | 
				
			||||||
  StreamSubscription? subscription;
 | 
					  StreamSubscription? subscription;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  String eSenseDeviceName = '';
 | 
					  String eSenseDeviceName = '';
 | 
				
			||||||
| 
						 | 
					@ -58,23 +58,23 @@ class ESenseInput {
 | 
				
			||||||
      connected = false;
 | 
					      connected = false;
 | 
				
			||||||
      switch (event.type) {
 | 
					      switch (event.type) {
 | 
				
			||||||
        case ConnectionType.connected:
 | 
					        case ConnectionType.connected:
 | 
				
			||||||
          deviceStatus.value = 'connected';
 | 
					          deviceStatus.value = 'Connected';
 | 
				
			||||||
          connected = true;
 | 
					          connected = true;
 | 
				
			||||||
          _startListenToSensorEvents();
 | 
					          _startListenToSensorEvents();
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case ConnectionType.unknown:
 | 
					        case ConnectionType.unknown:
 | 
				
			||||||
          deviceStatus.value = 'unknown';
 | 
					          deviceStatus.value = 'Unknown';
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case ConnectionType.disconnected:
 | 
					        case ConnectionType.disconnected:
 | 
				
			||||||
          deviceStatus.value = 'disconnected';
 | 
					          deviceStatus.value = 'Disconnected';
 | 
				
			||||||
          sampling = false;
 | 
					          sampling = false;
 | 
				
			||||||
          _pauseListenToSensorEvents();
 | 
					          _pauseListenToSensorEvents();
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case ConnectionType.device_found:
 | 
					        case ConnectionType.device_found:
 | 
				
			||||||
          deviceStatus.value = 'device_found';
 | 
					          deviceStatus.value = 'Device_found';
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case ConnectionType.device_not_found:
 | 
					        case ConnectionType.device_not_found:
 | 
				
			||||||
          deviceStatus.value = 'device_not_found';
 | 
					          deviceStatus.value = 'Device_not_found';
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
| 
						 | 
					@ -155,11 +155,11 @@ class ESenseInput {
 | 
				
			||||||
      print('Trying to connect to eSense device namend \'$deviceName\'');
 | 
					      print('Trying to connect to eSense device namend \'$deviceName\'');
 | 
				
			||||||
      eSenseDeviceName = deviceName;
 | 
					      eSenseDeviceName = deviceName;
 | 
				
			||||||
      eSenseManager.deviceName = deviceName;
 | 
					      eSenseManager.deviceName = deviceName;
 | 
				
			||||||
      connected = await eSenseManager.connect();
 | 
					      bool connecting = await eSenseManager.connect();
 | 
				
			||||||
      print(
 | 
					      print(
 | 
				
			||||||
          'Trying to connect to eSense device namend \'${eSenseManager.deviceName}\'');
 | 
					          'Trying to connect to eSense device namend \'${eSenseManager.deviceName}\'');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      deviceStatus.value = connected ? 'connecting...' : 'connection failed';
 | 
					      deviceStatus.value = connecting ? 'connecting...' : 'connection failed';
 | 
				
			||||||
      print(deviceStatus.value);
 | 
					      print(deviceStatus.value);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										34
									
								
								lib/widgets/esense_not_connected_dialog.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								lib/widgets/esense_not_connected_dialog.dart
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,34 @@
 | 
				
			||||||
 | 
					import 'package:flutter/material.dart';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ESenseNotConnectedDialog extends StatelessWidget {
 | 
				
			||||||
 | 
					  const ESenseNotConnectedDialog(
 | 
				
			||||||
 | 
					      {super.key, required this.onCancel, required this.onContinue});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final VoidCallback onCancel;
 | 
				
			||||||
 | 
					  final VoidCallback onContinue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @override
 | 
				
			||||||
 | 
					  Widget build(BuildContext context) {
 | 
				
			||||||
 | 
					    return AlertDialog(
 | 
				
			||||||
 | 
					      title: const Text("ESense not connected"),
 | 
				
			||||||
 | 
					      content: const Text(
 | 
				
			||||||
 | 
					          "You will only be able to play with the arrow keys of an external keyboard. "),
 | 
				
			||||||
 | 
					      actions: <Widget>[
 | 
				
			||||||
 | 
					        TextButton(
 | 
				
			||||||
 | 
					          onPressed: () {
 | 
				
			||||||
 | 
					            Navigator.pop(context, 'Cancel');
 | 
				
			||||||
 | 
					            onCancel();
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          child: const Text('Connect to ESense'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        TextButton(
 | 
				
			||||||
 | 
					          onPressed: () {
 | 
				
			||||||
 | 
					            Navigator.pop(context, 'Cancel');
 | 
				
			||||||
 | 
					            onContinue();
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          child: const Text('Continue anyway'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										68
									
								
								lib/widgets/level_list_entry.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								lib/widgets/level_list_entry.dart
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					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';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LevelListEntry extends StatelessWidget {
 | 
				
			||||||
 | 
					  const LevelListEntry({
 | 
				
			||||||
 | 
					    super.key,
 | 
				
			||||||
 | 
					    required this.simfile,
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  final Simfile simfile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void navigateToLevel(BuildContext context) {
 | 
				
			||||||
 | 
					    Navigator.push(context,
 | 
				
			||||||
 | 
					        MaterialPageRoute(builder: (BuildContext context) => Level(simfile)));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void openESenseConnectDialog(context) {
 | 
				
			||||||
 | 
					    showDialog(
 | 
				
			||||||
 | 
					      context: context,
 | 
				
			||||||
 | 
					      builder: (BuildContext context) {
 | 
				
			||||||
 | 
					        return ESenseConnectDialog(
 | 
				
			||||||
 | 
					            deviceStatus: ESenseInput.instance.deviceStatus,
 | 
				
			||||||
 | 
					            connect: (String name) {
 | 
				
			||||||
 | 
					              ESenseInput.instance.connectToESense(name);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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"]!),
 | 
				
			||||||
 | 
					      subtitle: Text('3:45'),
 | 
				
			||||||
 | 
					      onTap: () {
 | 
				
			||||||
 | 
					        tapHandler(context);
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in a new issue