From 56ade57a034b6ba71603dd27927e017caa31ce26 Mon Sep 17 00:00:00 2001 From: Rivers Cuomo Date: Wed, 31 Jul 2024 08:45:41 -0700 Subject: [PATCH] play button --- lib/helpers/utils.dart | 10 ++- lib/main.dart | 23 +++++- lib/models/job.dart | 2 +- lib/screens/home_screen.dart | 73 +++++++++++-------- ..._name_field.dart => playlist_widgets.dart} | 18 +++++ lib/widgets/spotify_style_playlist_tile.dart | 2 +- ...=> target_playlist_selection_options.dart} | 6 +- lib/widgets/widgets.dart | 3 +- 8 files changed, 93 insertions(+), 44 deletions(-) rename lib/widgets/{playlist_name_field.dart => playlist_widgets.dart} (62%) rename lib/widgets/{playlist_selection_options.dart => target_playlist_selection_options.dart} (93%) diff --git a/lib/helpers/utils.dart b/lib/helpers/utils.dart index db0c36b..5c95057 100644 --- a/lib/helpers/utils.dart +++ b/lib/helpers/utils.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'package:spotify/spotify.dart' hide Image; -import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; class Utils { static String extractPlaylistId(String playlistUrl) { @@ -22,9 +22,11 @@ class Utils { : const Icon(Icons.music_note); } - static void launchUrl(String url) async { - if (await canLaunchUrl(Uri.parse(url))) { - launchUrl(url); + static Future myLaunch(String url) async { + print('Launching URL: $url'); + final uri = Uri.parse(url); + if (await url_launcher.canLaunchUrl(uri)) { + await url_launcher.launchUrl(uri); } else { throw 'Could not launch $url'; } diff --git a/lib/main.dart b/lib/main.dart index 7886014..d7bad78 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -93,9 +93,28 @@ final spotifyThemeData = ThemeData( titleTextStyle: TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold), ), + buttonTheme: ButtonThemeData( + buttonColor: Colors.green, + textTheme: ButtonTextTheme.primary, + // padding: const EdgeInsets.all(16.0), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(25), + ), + ), + // iconButtonTheme: IconButtonThemeData( + // style: ButtonStyle( + // backgroundColor: MaterialStateProperty.all(Colors.green), + // foregroundColor: MaterialStateProperty.all(Colors.black), + // overlayColor: MaterialStateProperty.all(Colors.green[700]), + // shape: MaterialStateProperty.all(CircleBorder()), + // padding: MaterialStateProperty.all(EdgeInsets.all(12)), + // minimumSize: MaterialStateProperty.all(Size(48, 48)), + // ), + // ), textTheme: TextTheme( - titleLarge: TextStyle(color: Colors.white, fontWeight: FontWeight.bold), - bodyMedium: TextStyle(color: Colors.white70), + titleLarge: + const TextStyle(color: Colors.white, fontWeight: FontWeight.bold), + bodyMedium: const TextStyle(color: Colors.white70), // titleMedium: TextStyle(color: Colors.white54), labelMedium: TextStyle(color: Colors.grey[400]), ), diff --git a/lib/models/job.dart b/lib/models/job.dart index e0f9303..f5b834a 100644 --- a/lib/models/job.dart +++ b/lib/models/job.dart @@ -71,7 +71,7 @@ class Job { 'playlist_id': targetPlaylist.id, 'description': description, 'remove_low_energy': removeLowEnergy, - 'last_tracks': lastTracks, + 'last_track_ids': lastTracks.map((t) => t.id).toList(), 'banned_artists': bannedArtists, // 'banned_song_titles': bannedSongTitles, 'banned_tracks': bannedTracks, diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 5ed269a..a9e4ff8 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -106,8 +106,8 @@ class _HomeScreenState extends State { }); } - Widget _buildPlaylistSelectionOptions() { - return PlaylistSelectionOptions( + Widget _buildTargetPlaylistSelectionOptions() { + return TargetPlaylistSelectionOptions( onPlaylistSelected: (PlaylistSimple selectedPlaylist) { if (jobs.isEmpty) { final newJob = Job( @@ -181,7 +181,7 @@ class _HomeScreenState extends State { Column( children: [ // jobs.isEmpty || _isResettingTargetPlaylist - // ? _buildPlaylistSelectionOptions() + // ? _buildTargetPlaylistSelectionOptions() // : ExpansionTile( title: PlaylistTitle(context, targetPlaylist), @@ -190,7 +190,7 @@ class _HomeScreenState extends State { initiallyExpanded: jobs.isEmpty, children: [ - _buildPlaylistSelectionOptions(), + _buildTargetPlaylistSelectionOptions(), ], // playlist: targetPlaylist, @@ -234,6 +234,14 @@ class _HomeScreenState extends State { ? Colors.green : Colors.red, ), + trailing: IconButton( + icon: const Icon(Icons.play_arrow), + style: greenButtonStyle, + onPressed: () { + Utils.myLaunch( + targetPlaylist.externalUrls?.spotify ?? ''); + }, + ), ); }), ]), @@ -242,20 +250,33 @@ class _HomeScreenState extends State { ), ), bottomNavigationBar: jobs.isNotEmpty && jobs[0].recipe.isNotEmpty - ? Padding( + ? Container( padding: const EdgeInsets.all(16), - child: ElevatedButton( - onPressed: isProcessing ? null : _processJobs, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.green, - minimumSize: const Size(double.infinity, 50), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(25), - ), + child: SafeArea( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 300, // Adjust this value as needed + minHeight: 50, + ), + child: ElevatedButton( + onPressed: isProcessing ? null : _processJobs, + style: ElevatedButton.styleFrom( + minimumSize: const Size(200, 50), // Minimum size + padding: const EdgeInsets.symmetric(horizontal: 20), + ), + child: Text( + isProcessing + ? 'Processing...' + : 'Update Spotkin On Spotify', + textAlign: TextAlign.center, + ), + ), + ), + ], ), - child: Text(isProcessing - ? 'Processing...' - : 'Update Spotkin On Spotify'), ), ) : null, @@ -264,19 +285,7 @@ class _HomeScreenState extends State { } } -Widget playlistSubtitle(PlaylistSimple playlist, BuildContext context) { - return playlist.owner != null - ? Text( - 'Playlist • ${playlist.owner!.displayName}', - style: Theme.of(context).textTheme.labelMedium, - ) - : const SizedBox(); -} - -Text PlaylistTitle(BuildContext context, PlaylistSimple playlist) { - return Text( - playlist.name ?? 'Unknown Playlist', - style: Theme.of(context).textTheme.titleMedium, - overflow: TextOverflow.ellipsis, - ); -} +var greenButtonStyle = ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.green), + foregroundColor: MaterialStateProperty.all(Colors.black), +); diff --git a/lib/widgets/playlist_name_field.dart b/lib/widgets/playlist_widgets.dart similarity index 62% rename from lib/widgets/playlist_name_field.dart rename to lib/widgets/playlist_widgets.dart index 6cdbbea..ad20fb8 100644 --- a/lib/widgets/playlist_name_field.dart +++ b/lib/widgets/playlist_widgets.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:spotify/spotify.dart'; import 'package:spotkin_flutter/app_core.dart'; class PlaylistNameField extends StatelessWidget { @@ -27,3 +28,20 @@ class PlaylistNameField extends StatelessWidget { ); } } + +Widget playlistSubtitle(PlaylistSimple playlist, BuildContext context) { + return playlist.owner != null + ? Text( + 'Playlist • ${playlist.owner!.displayName}', + style: Theme.of(context).textTheme.labelMedium, + ) + : const SizedBox(); +} + +Text PlaylistTitle(BuildContext context, PlaylistSimple playlist) { + return Text( + playlist.name ?? 'Unknown Playlist', + style: Theme.of(context).textTheme.titleMedium, + overflow: TextOverflow.ellipsis, + ); +} diff --git a/lib/widgets/spotify_style_playlist_tile.dart b/lib/widgets/spotify_style_playlist_tile.dart index a942dc2..15a65e0 100644 --- a/lib/widgets/spotify_style_playlist_tile.dart +++ b/lib/widgets/spotify_style_playlist_tile.dart @@ -20,7 +20,7 @@ class SpotifyStylePlaylistTile extends StatelessWidget { onTap: () { final url = playlist.externalUrls!.spotify; if (url != null) { - Utils.launchUrl(url); + Utils.myLaunch(url); } }, child: Padding( diff --git a/lib/widgets/playlist_selection_options.dart b/lib/widgets/target_playlist_selection_options.dart similarity index 93% rename from lib/widgets/playlist_selection_options.dart rename to lib/widgets/target_playlist_selection_options.dart index 142d31b..805cf6c 100644 --- a/lib/widgets/playlist_selection_options.dart +++ b/lib/widgets/target_playlist_selection_options.dart @@ -2,10 +2,10 @@ import 'package:flutter/material.dart'; import 'package:spotify/spotify.dart'; import 'package:spotkin_flutter/app_core.dart'; -class PlaylistSelectionOptions extends StatelessWidget { +class TargetPlaylistSelectionOptions extends StatelessWidget { final Function(PlaylistSimple) onPlaylistSelected; - const PlaylistSelectionOptions({ + const TargetPlaylistSelectionOptions({ Key? key, required this.onPlaylistSelected, }) : super(key: key); @@ -19,7 +19,7 @@ class PlaylistSelectionOptions extends StatelessWidget { height: 24, ), Text( - 'Step 1: Select which playlist you want to use for your Spotkin', + 'Step 1: Select which playlist you want to use for Spotkin', style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center, ), diff --git a/lib/widgets/widgets.dart b/lib/widgets/widgets.dart index ddc499b..94c7a2c 100644 --- a/lib/widgets/widgets.dart +++ b/lib/widgets/widgets.dart @@ -1,5 +1,6 @@ export 'ingredient_form.dart'; export 'bottom_sheets/bottom_sheets.dart'; -export 'playlist_selection_options.dart'; +export 'playlist_widgets.dart'; +export 'target_playlist_selection_options.dart'; export 'settings_card.dart'; export 'spotify_style_playlist_tile.dart';