summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrangerot <purple@orangerot.dev>2024-12-23 02:08:45 +0100
committerOrangerot <purple@orangerot.dev>2024-12-23 02:08:45 +0100
commitd397b62b5b6f6db45a2cc0ae6ca4e03ff04c54b2 (patch)
tree4874d7b28bdc051a83af24cfa4a9ed947b147213
parent9aaf00e6275616f4ff3086b0fb4ae98c2036c4fb (diff)
feat: import song directory and display them with banner
-rw-r--r--android/settings.gradle2
-rw-r--r--lib/level_selection.dart121
-rw-r--r--pubspec.lock167
-rw-r--r--pubspec.yaml69
4 files changed, 264 insertions, 95 deletions
diff --git a/android/settings.gradle b/android/settings.gradle
index b9e43bd..a42444d 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -18,7 +18,7 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
- id "com.android.application" version "8.1.0" apply false
+ id "com.android.application" version "8.2.1" apply false
id "org.jetbrains.kotlin.android" version "1.8.22" apply false
}
diff --git a/lib/level_selection.dart b/lib/level_selection.dart
index a5a9c32..cc79911 100644
--- a/lib/level_selection.dart
+++ b/lib/level_selection.dart
@@ -1,40 +1,109 @@
+import 'dart:io';
+
+import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
+import 'package:shared_preferences/shared_preferences.dart';
import 'level.dart';
-class LevelSelection extends StatelessWidget {
- final List<String> _musicList = [
- "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
- "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",
- "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-3.mp3",
- ];
+class LevelSelection extends StatefulWidget {
+ const LevelSelection({super.key});
+
+ @override
+ State<LevelSelection> createState() => _LevelSelectionState();
+}
+
+class _LevelSelectionState extends State<LevelSelection> {
+ String? stepmaniaCoursesPath;
+ List<FileSystemEntity> stepmaniaCoursesFolders = [];
+
+ @override
+ void initState() {
+ super.initState();
+ loadFolderPath();
+ }
+
+ Future<void> loadFolderPath() async {
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ final String? stepmaniaCoursesPathSetting =
+ prefs.getString('stepmania_courses');
+
+ if (stepmaniaCoursesPathSetting == null) return;
+ setState(() {
+ stepmaniaCoursesPath = stepmaniaCoursesPathSetting;
+ });
+ setState(() async {
+ stepmaniaCoursesFolders =
+ await listFilesAndFolders(stepmaniaCoursesPathSetting);
+ });
+ }
+
+ Future<void> selectFolder() async {
+ String? selectedFolder = await FilePicker.platform.getDirectoryPath();
- final List<String> _coverArtList = [
- "https://cdn.pixabay.com/photo/2020/05/19/13/48/cartoon-5190942_960_720.jpg",
- "https://cdn.pixabay.com/photo/2020/05/19/13/35/cartoon-5190860_960_720.jpg",
- "https://cdn.pixabay.com/photo/2020/10/23/17/52/fox-5679446_960_720.png",
- ];
+ if (selectedFolder != null) {
+ // Save the selected folder path
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ await prefs.setString('stepmania_courses', selectedFolder);
+
+ loadFolderPath();
+ }
+ }
+
+ Future<List<FileSystemEntity>> 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();
+ } catch (e) {
+ print("Error reading directory: $e");
+ return [];
+ }
+ }
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Sense the Rhythm')),
- body: ListView.separated(
- itemCount: _musicList.length,
- separatorBuilder: (BuildContext context, int index) => const Divider(),
- itemBuilder: (context, index) {
- return ListTile(
- leading: Image.network(_coverArtList[index]),
- trailing: Icon(Icons.play_arrow),
- title: Text('Track ${index + 1}'),
- subtitle: Text('3:45'),
- onTap: () => Navigator.push(context,
- MaterialPageRoute(builder: (BuildContext context) => Level())),
+ 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) {
+ 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)),
+ trailing: Icon(Icons.play_arrow),
+ title:
+ Text(stepmaniaCoursesFolders[index].path.split('/').last),
+ subtitle: Text('3:45'),
+ onTap: () => Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (BuildContext context) => Level())),
+ );
+ },
);
- },
- ),
- floatingActionButton:
- FloatingActionButton(onPressed: () => {}, child: Icon(Icons.add)),
+ }
+ }),
+ floatingActionButton: FloatingActionButton(
+ onPressed: () => {selectFolder()}, child: Icon(Icons.add)),
);
}
}
diff --git a/pubspec.lock b/pubspec.lock
index 538c560..2dcd104 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -41,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.19.0"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.3.4+2"
cupertino_icons:
dependency: "direct main"
description:
@@ -57,6 +65,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.3"
+ file:
+ dependency: transitive
+ description:
+ name: file
+ sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.0.1"
+ file_picker:
+ dependency: "direct main"
+ description:
+ name: file_picker
+ sha256: c2376a6aae82358a9f9ccdd7d1f4006d08faa39a2767cce01031d9f593a8bd3b
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.1.6"
flutter:
dependency: "direct main"
description: flutter
@@ -70,11 +102,24 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.0"
+ flutter_plugin_android_lifecycle:
+ dependency: transitive
+ description:
+ name: flutter_plugin_android_lifecycle
+ sha256: "615a505aef59b151b46bbeef55b36ce2b6ed299d160c51d84281946f0aa0ce0e"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.24"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
leak_tracker:
dependency: transitive
description:
@@ -139,6 +184,102 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.0"
+ path_provider_linux:
+ dependency: transitive
+ description:
+ name: path_provider_linux
+ sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.1"
+ path_provider_platform_interface:
+ dependency: transitive
+ description:
+ name: path_provider_platform_interface
+ sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.2"
+ path_provider_windows:
+ dependency: transitive
+ description:
+ name: path_provider_windows
+ sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.0"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.6"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.8"
+ shared_preferences:
+ dependency: "direct main"
+ description:
+ name: shared_preferences
+ sha256: "3c7e73920c694a436afaf65ab60ce3453d91f84208d761fbd83fc21182134d93"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.4"
+ shared_preferences_android:
+ dependency: transitive
+ description:
+ name: shared_preferences_android
+ sha256: "02a7d8a9ef346c9af715811b01fbd8e27845ad2c41148eefd31321471b41863d"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.0"
+ shared_preferences_foundation:
+ dependency: transitive
+ description:
+ name: shared_preferences_foundation
+ sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.5.4"
+ shared_preferences_linux:
+ dependency: transitive
+ description:
+ name: shared_preferences_linux
+ sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.1"
+ shared_preferences_platform_interface:
+ dependency: transitive
+ description:
+ name: shared_preferences_platform_interface
+ sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.1"
+ shared_preferences_web:
+ dependency: transitive
+ description:
+ name: shared_preferences_web
+ sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.2"
+ shared_preferences_windows:
+ dependency: transitive
+ description:
+ name: shared_preferences_windows
+ sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.4.1"
sky_engine:
dependency: transitive
description: flutter
@@ -208,6 +349,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "14.3.0"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: "8b338d4486ab3fbc0ba0db9f9b4f5239b6697fcee427939a40e720cbb9ee0a69"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.9.0"
+ xdg_directories:
+ dependency: transitive
+ description:
+ name: xdg_directories
+ sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
sdks:
dart: ">=3.6.0 <4.0.0"
- flutter: ">=3.18.0-18.0.pre.54"
+ flutter: ">=3.24.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 00137d4..b364c4c 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,89 +1,24 @@
name: sense_the_rhythm
description: "A new Flutter project."
-# The following line prevents the package from being accidentally published to
-# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
-# The following defines the version and build number for your application.
-# A version number is three numbers separated by dots, like 1.2.43
-# followed by an optional build number separated by a +.
-# Both the version and the builder number may be overridden in flutter
-# build by specifying --build-name and --build-number, respectively.
-# In Android, build-name is used as versionName while build-number used as versionCode.
-# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
-# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
-# Read more about iOS versioning at
-# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-# In Windows, build-name is used as the major, minor, and patch parts
-# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: ^3.6.0
-# Dependencies specify other packages that your package needs in order to work.
-# To automatically upgrade your package dependencies to the latest versions
-# consider running `flutter pub upgrade --major-versions`. Alternatively,
-# dependencies can be manually updated by changing the version numbers below to
-# the latest version available on pub.dev. To see which dependencies have newer
-# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
-
- # The following adds the Cupertino Icons font to your application.
- # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
+ shared_preferences: ^2.3.4
+ file_picker: ^8.1.6
dev_dependencies:
flutter_test:
sdk: flutter
-
- # The "flutter_lints" package below contains a set of recommended lints to
- # encourage good coding practices. The lint set provided by the package is
- # activated in the `analysis_options.yaml` file located at the root of your
- # package. See that file for information about deactivating specific lint
- # rules and activating additional ones.
flutter_lints: ^5.0.0
-# For information on the generic Dart part of this file, see the
-# following page: https://dart.dev/tools/pub/pubspec
-
-# The following section is specific to Flutter packages.
flutter:
-
- # The following line ensures that the Material Icons font is
- # included with your application, so that you can use the icons in
- # the material Icons class.
uses-material-design: true
- # To add assets to your application, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
-
- # An image asset can refer to one or more resolution-specific "variants", see
- # https://flutter.dev/to/resolution-aware-images
-
- # For details regarding adding assets from package dependencies, see
- # https://flutter.dev/to/asset-from-package
-
- # To add custom fonts to your application, add a fonts section here,
- # in this "flutter" section. Each entry in this list should have a
- # "family" key with the font family name, and a "fonts" key with a
- # list giving the asset and other descriptors for the font. For
- # example:
- # fonts:
- # - family: Schyler
- # fonts:
- # - asset: fonts/Schyler-Regular.ttf
- # - asset: fonts/Schyler-Italic.ttf
- # style: italic
- # - family: Trajan Pro
- # fonts:
- # - asset: fonts/TrajanPro.ttf
- # - asset: fonts/TrajanPro_Bold.ttf
- # weight: 700
- #
- # For details regarding fonts from package dependencies,
- # see https://flutter.dev/to/font-from-package