From f772bbdbbc607b028ed8851442aa605fe59f799b Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Fri, 30 Aug 2024 14:05:11 +0800 Subject: [PATCH] :rocket Ready to launch! --- ios/Podfile.lock | 6 ++ ios/Runner.xcodeproj/project.pbxproj | 9 +- ios/Runner/Info.plist | 2 +- lib/router.dart | 6 ++ lib/screens/about.dart | 90 +++++++++++++++++++ lib/screens/settings.dart | 12 +++ linux/CMakeLists.txt | 2 +- linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + linux/my_application.cc | 4 +- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + macos/Runner.xcodeproj/project.pbxproj | 9 +- macos/Runner/Info.plist | 2 +- pubspec.lock | 66 +++++++++++++- pubspec.yaml | 6 +- web/index.html | 4 +- web/manifest.json | 4 +- windows/CMakeLists.txt | 2 +- .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + windows/runner/Runner.rc | 10 +-- windows/runner/main.cpp | 2 +- 22 files changed, 221 insertions(+), 26 deletions(-) create mode 100644 lib/screens/about.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 87d5fc6..84e11fb 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -55,6 +55,8 @@ PODS: - sqlite3/fts5 - sqlite3/perf-threadsafe - sqlite3/rtree + - url_launcher_ios (0.0.1): + - Flutter DEPENDENCIES: - audio_service (from `.symlinks/plugins/audio_service/ios`) @@ -73,6 +75,7 @@ DEPENDENCIES: - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - sqflite (from `.symlinks/plugins/sqflite/darwin`) - sqlite3_flutter_libs (from `.symlinks/plugins/sqlite3_flutter_libs/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) SPEC REPOS: trunk: @@ -112,6 +115,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/sqflite/darwin" sqlite3_flutter_libs: :path: ".symlinks/plugins/sqlite3_flutter_libs/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" SPEC CHECKSUMS: audio_service: f509d65da41b9521a61f1c404dd58651f265a567 @@ -132,6 +137,7 @@ SPEC CHECKSUMS: sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec sqlite3: 0bb0e6389d824e40296f531b858a2a0b71c0d2fb sqlite3_flutter_libs: c00457ebd31e59fa6bb830380ddba24d44fbcd3b + url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 684734b..8b626b8 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -473,7 +473,8 @@ DEVELOPMENT_TEAM = W7HPZ53V6B; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = RhythmBox; + INFOPLIST_KEY_CFBundleDisplayName = GroovyBox; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -657,7 +658,8 @@ DEVELOPMENT_TEAM = W7HPZ53V6B; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = RhythmBox; + INFOPLIST_KEY_CFBundleDisplayName = GroovyBox; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -681,7 +683,8 @@ DEVELOPMENT_TEAM = W7HPZ53V6B; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = RhythmBox; + INFOPLIST_KEY_CFBundleDisplayName = GroovyBox; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 005933c..fbc43c9 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - rhythm_box + Groovy Box CFBundlePackageType APPL CFBundleShortVersionString diff --git a/lib/router.dart b/lib/router.dart index bc1f145..30d7e2f 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -1,6 +1,7 @@ import 'package:animations/animations.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:rhythm_box/screens/about.dart'; import 'package:rhythm_box/screens/album/view.dart'; import 'package:rhythm_box/screens/auth/mobile_login.dart'; import 'package:rhythm_box/screens/explore.dart'; @@ -51,6 +52,11 @@ final router = GoRouter(routes: [ name: 'settings', builder: (context, state) => const SettingsScreen(), ), + GoRoute( + path: '/about', + name: 'about', + builder: (context, state) => const AboutScreen(), + ), ], ), ShellRoute( diff --git a/lib/screens/about.dart b/lib/screens/about.dart new file mode 100644 index 0000000..a90b41c --- /dev/null +++ b/lib/screens/about.dart @@ -0,0 +1,90 @@ +import 'package:flutter/material.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:rhythm_box/platform.dart'; +import 'package:url_launcher/url_launcher_string.dart'; + +class AboutScreen extends StatelessWidget { + const AboutScreen({super.key}); + + @override + Widget build(BuildContext context) { + const denseButtonStyle = + ButtonStyle(visualDensity: VisualDensity(vertical: -4)); + + return Material( + color: Theme.of(context).colorScheme.surface, + child: SizedBox( + width: double.infinity, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(16)), + child: Image.asset('assets/icon.png', width: 120, height: 120), + ), + const SizedBox(height: 8), + Text( + PlatformInfo.isIOS || PlatformInfo.isMacOS + ? 'GroovyBox' + : 'RhythmBox', + style: Theme.of(context).textTheme.headlineMedium, + ), + const Text( + 'Yet another Spotify third-party app', + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + const SizedBox(height: 8), + FutureBuilder( + future: PackageInfo.fromPlatform(), + builder: (context, snapshot) { + if (!snapshot.hasData) { + return const SizedBox(); + } + + return Text( + 'v${snapshot.data!.version} · ${snapshot.data!.buildNumber}', + style: const TextStyle(fontFamily: 'monospace'), + ); + }, + ), + Text('Copyright © ${DateTime.now().year} Solsynth LLC'), + const SizedBox(height: 16), + TextButton( + style: denseButtonStyle, + child: const Text('App Details'), + onPressed: () async { + final info = await PackageInfo.fromPlatform(); + + showAboutDialog( + context: context, + applicationVersion: '${info.version} (${info.buildNumber})', + applicationLegalese: 'Yet another Spotify third-party app.', + applicationIcon: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(16)), + child: + Image.asset('assets/icon.png', width: 60, height: 60), + ), + ); + }, + ), + TextButton( + style: denseButtonStyle, + child: const Text('Project Website'), + onPressed: () { + launchUrlString('https://solsynth.dev/products/rhythm-box'); + }, + ), + const SizedBox(height: 16), + const Text( + 'Open-sourced under AGPLv3', + style: TextStyle( + fontWeight: FontWeight.w300, + fontSize: 12, + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 12d4c89..9a5dc75 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:go_router/go_router.dart'; import 'package:rhythm_box/providers/auth.dart'; import 'package:rhythm_box/providers/spotify.dart'; import 'package:rhythm_box/providers/user_preferences.dart'; @@ -122,6 +123,17 @@ class _SettingsScreenState extends State { onChanged: _preferences.setNormalizeAudio, ), ), + const Divider(thickness: 0.3, height: 1), + ListTile( + contentPadding: const EdgeInsets.symmetric(horizontal: 24), + leading: const Icon(Icons.info), + title: const Text('About'), + subtitle: const Text('More information about this app'), + trailing: const Icon(Icons.chevron_right), + onTap: () async { + GoRouter.of(context).pushNamed('about'); + }, + ), ], ), ), diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 40271c0..506adc6 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -4,7 +4,7 @@ project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. -set(BINARY_NAME "rhythm_box") +set(BINARY_NAME "RhythmBox") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "dev.solsynth.rhythmBox") diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 3501420..8211dc5 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -11,6 +11,7 @@ #include #include #include +#include #include void fl_register_plugins(FlPluginRegistry* registry) { @@ -29,6 +30,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) sqlite3_flutter_libs_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin"); sqlite3_flutter_libs_plugin_register_with_registrar(sqlite3_flutter_libs_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); g_autoptr(FlPluginRegistrar) window_manager_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin"); window_manager_plugin_register_with_registrar(window_manager_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 701f5cf..abe8e61 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -8,6 +8,7 @@ list(APPEND FLUTTER_PLUGIN_LIST media_kit_libs_linux screen_retriever sqlite3_flutter_libs + url_launcher_linux window_manager ) diff --git a/linux/my_application.cc b/linux/my_application.cc index fc1f0b5..8a034e5 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -40,11 +40,11 @@ static void my_application_activate(GApplication* application) { if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "rhythm_box"); + gtk_header_bar_set_title(header_bar, "RhythmBox"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { - gtk_window_set_title(window, "rhythm_box"); + gtk_window_set_title(window, "RhythmBox"); } gtk_window_set_default_size(window, 1280, 720); diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index dff91bc..302ade2 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -18,6 +18,7 @@ import screen_retriever import shared_preferences_foundation import sqflite import sqlite3_flutter_libs +import url_launcher_macos import window_manager func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { @@ -34,5 +35,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) } diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index e7854e7..5be36b4 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -574,7 +574,8 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = RhythmBox; + INFOPLIST_KEY_CFBundleDisplayName = GroovyBox; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -707,7 +708,8 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = RhythmBox; + INFOPLIST_KEY_CFBundleDisplayName = GroovyBox; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -728,7 +730,8 @@ CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; - INFOPLIST_KEY_CFBundleDisplayName = RhythmBox; + INFOPLIST_KEY_CFBundleDisplayName = GroovyBox; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.music"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", diff --git a/macos/Runner/Info.plist b/macos/Runner/Info.plist index 4789daa..3368dbc 100644 --- a/macos/Runner/Info.plist +++ b/macos/Runner/Info.plist @@ -13,7 +13,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + Groovy Box CFBundlePackageType APPL CFBundleShortVersionString diff --git a/pubspec.lock b/pubspec.lock index ac22e32..77c64c9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1438,6 +1438,70 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" + url: "https://pub.dev" + source: hosted + version: "6.3.0" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: e35a698ac302dd68e41f73250bd9517fe3ab5fa4f18fe4647a0872db61bacbab + url: "https://pub.dev" + source: hosted + version: "6.3.10" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e + url: "https://pub.dev" + source: hosted + version: "6.3.1" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af + url: "https://pub.dev" + source: hosted + version: "3.2.0" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" + url: "https://pub.dev" + source: hosted + version: "3.2.0" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e" + url: "https://pub.dev" + source: hosted + version: "2.3.3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" + url: "https://pub.dev" + source: hosted + version: "3.1.2" uuid: dependency: "direct main" description: @@ -1544,4 +1608,4 @@ packages: version: "2.2.1" sdks: dart: ">=3.5.0 <4.0.0" - flutter: ">=3.22.0" + flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 457cef3..62b217a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -100,6 +100,7 @@ dependencies: path: packages/desktop_webview_window flutter_inappwebview: ^6.0.0 timezone: ^0.9.4 + url_launcher: ^6.3.0 dev_dependencies: flutter_test: @@ -130,9 +131,8 @@ flutter: 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 + assets: + - assets/icon.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images diff --git a/web/index.html b/web/index.html index f986a9c..34e5cf0 100644 --- a/web/index.html +++ b/web/index.html @@ -21,13 +21,13 @@ - + - rhythm_box + RhythmBox