From 3fea16e5d1c8dcf30625b2a2ed85bd5588d4a02d Mon Sep 17 00:00:00 2001 From: CyberDotPy <56804602+aceeedev@users.noreply.github.com> Date: Sun, 6 Aug 2023 11:03:28 -0700 Subject: [PATCH] Fixed auth issues and styling Reformatted track view page again (fixed title from getting cutoff, button style, and wrapped text) and made calendar page start at bottom when necessary --- .vscode/settings.json | 1 + lib/backend/spotify_api/auth.dart | 4 ++- lib/pages/calendar_page.dart | 10 +++--- lib/styles.dart | 2 +- lib/utils/get_new_daily_track.dart | 33 +++---------------- lib/utils/get_recommendation_seeds.dart | 5 ++- ...equest_access_token_without_auth_code.dart | 31 +++++++++++++++++ lib/widgets/artist_selector.dart | 4 ++- lib/widgets/developer_settings_widgets.dart | 9 ++--- lib/widgets/genre_selector.dart | 8 +++-- lib/widgets/spotify_attribute_widget.dart | 31 ++++++++--------- lib/widgets/track_selector.dart | 3 +- lib/widgets/track_view_widget.dart | 10 +++--- 13 files changed, 87 insertions(+), 64 deletions(-) create mode 100644 lib/utils/request_access_token_without_auth_code.dart diff --git a/.vscode/settings.json b/.vscode/settings.json index 9fd99df..b8526bd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,7 @@ { "cSpell.words": [ "acousticness", + "appcheck", "cupertino", "Danceability", "Instrumentalness", diff --git a/lib/backend/spotify_api/auth.dart b/lib/backend/spotify_api/auth.dart index 5e2a065..9b03343 100644 --- a/lib/backend/spotify_api/auth.dart +++ b/lib/backend/spotify_api/auth.dart @@ -128,7 +128,7 @@ Future requestAccessToken(String? authCode) async { } } -Future getBrandNewAccessToken(String authCode) async { +Future getBrandNewAccessToken(String authCode) async { final url = Uri.https('accounts.spotify.com', '/api/token'); final form = { 'code': authCode, @@ -154,6 +154,8 @@ Future getBrandNewAccessToken(String authCode) async { await db.Auth.instance.saveAccessToken(newAccessToken); return newAccessToken; + } else if (response.statusCode == 400) { + return null; } else { throw Exception('Response code was not 200, was ${response.statusCode}'); } diff --git a/lib/pages/calendar_page.dart b/lib/pages/calendar_page.dart index a86f6d7..193cc9d 100644 --- a/lib/pages/calendar_page.dart +++ b/lib/pages/calendar_page.dart @@ -92,12 +92,14 @@ class _CalendarPageState extends State { // flip daily tracks and months since ListView starts at bottom // and is reversed - dailyTracksByMonth = dailyTracksByMonth.reversed.toList(); - monthsBetweenFirstDailyTrackAndNow = - monthsBetweenFirstDailyTrackAndNow.reversed.toList(); + if (monthsBetweenFirstDailyTrackAndNow.length > 2) { + dailyTracksByMonth = dailyTracksByMonth.reversed.toList(); + monthsBetweenFirstDailyTrackAndNow = + monthsBetweenFirstDailyTrackAndNow.reversed.toList(); + } return ListView.builder( - reverse: true, + reverse: monthsBetweenFirstDailyTrackAndNow.length > 2, itemCount: monthsBetweenFirstDailyTrackAndNow.length, itemBuilder: (context, index) => Column( children: [ diff --git a/lib/styles.dart b/lib/styles.dart index 7563740..b93fb9c 100644 --- a/lib/styles.dart +++ b/lib/styles.dart @@ -74,7 +74,7 @@ class Styles { MaterialColor get accentColor => _accentColor; // buttons - static const _unselectedElevation = 1.5; + static const _unselectedElevation = 2.0; static final _selectedColor = _secondaryColor[900]; static const _selectedElevation = 0.1; static final _shadowColor = _secondaryColor[200]; diff --git a/lib/utils/get_new_daily_track.dart b/lib/utils/get_new_daily_track.dart index 3846583..88774cd 100644 --- a/lib/utils/get_new_daily_track.dart +++ b/lib/utils/get_new_daily_track.dart @@ -3,9 +3,7 @@ import 'package:daily_spotify/models/daily_track.dart'; import 'package:daily_spotify/backend/spotify_api/spotify_api.dart'; import 'package:daily_spotify/backend/database_manager.dart' as db; import 'package:daily_spotify/utils/get_recommendation_seeds.dart'; -import 'package:daily_spotify/widgets/custom_scaffold.dart'; -import 'package:daily_spotify/widgets/frame_widget.dart'; -import 'package:daily_spotify/widgets/spotify_login.dart'; +import 'package:daily_spotify/utils/request_access_token_without_auth_code.dart'; /// Returns a new unique [DailyTrack]. Also saves the daily track to the /// database. @@ -15,39 +13,16 @@ import 'package:daily_spotify/widgets/spotify_login.dart'; /// /// Takes in the parameter [today] which is a [DateTime] and is used as the date /// of the daily track. -Future getNewDailyTrack( +Future getNewDailyTrack( BuildContext context, DateTime today) async { - // generate new recommendations - AccessToken? accessToken = await requestAccessToken(null); - - // request user auth if expired - if (accessToken == null) { - String? authCode = await requestUserAuth(); - - await Navigator.of(context).pushReplacement(MaterialPageRoute( - builder: (context) => CustomScaffold( - body: Frame( - showLogo: true, - child: SpotifyLogin( - inSetup: false, - authCode: authCode, - ), - )))); - - if (authCode == null) { - return null; - } - await getBrandNewAccessToken(authCode); - - accessToken = await requestAccessToken(authCode); - } + AccessToken accessToken = await requestAccessTokenWithoutAuthCode(context); List initialSeedArtists = await db.Config.instance.getArtistConfig(); List initialSeedGenres = await db.Config.instance.getGenreConfig(); List initialSeedTracks = await db.Config.instance.getTrackConfig(); Map seeds = await getRecommendationSeeds( - initialSeedArtists, initialSeedGenres, initialSeedTracks); + context, initialSeedArtists, initialSeedGenres, initialSeedTracks); Recommendation recommendation = await getRecommendations( accessToken: accessToken!, diff --git a/lib/utils/get_recommendation_seeds.dart b/lib/utils/get_recommendation_seeds.dart index ed5bd8c..2df2d2e 100644 --- a/lib/utils/get_recommendation_seeds.dart +++ b/lib/utils/get_recommendation_seeds.dart @@ -1,7 +1,9 @@ import 'dart:math'; import 'package:daily_spotify/backend/spotify_api/spotify_api.dart'; +import 'package:daily_spotify/utils/request_access_token_without_auth_code.dart'; import 'package:daily_spotify/utils/filter_by_genre.dart'; import 'package:daily_spotify/utils/default_config.dart'; +import 'package:flutter/material.dart'; /// Returns curated [Future>] of the recommendation seeds /// to be used in [getRecommendations]. @@ -11,6 +13,7 @@ import 'package:daily_spotify/utils/default_config.dart'; /// 'seedGenres': List /// 'seedTracks': List Future>> getRecommendationSeeds( + BuildContext context, List artistList, List genreList, List trackList) async { @@ -21,7 +24,7 @@ Future>> getRecommendationSeeds( List seedGenres = []; List seedTracks = []; - AccessToken? accessToken = await requestAccessToken(null); + AccessToken accessToken = await requestAccessTokenWithoutAuthCode(context); // artist seed if (getMoreRecent == 0 || artistList.isEmpty) { diff --git a/lib/utils/request_access_token_without_auth_code.dart b/lib/utils/request_access_token_without_auth_code.dart new file mode 100644 index 0000000..f7d51db --- /dev/null +++ b/lib/utils/request_access_token_without_auth_code.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; +import 'package:daily_spotify/backend/spotify_api/spotify_api.dart'; +import 'package:daily_spotify/widgets/custom_scaffold.dart'; +import 'package:daily_spotify/widgets/frame_widget.dart'; +import 'package:daily_spotify/widgets/spotify_login.dart'; + +Future requestAccessTokenWithoutAuthCode( + BuildContext context) async { + AccessToken? accessToken = await requestAccessToken(null); + + // request user auth if expired + if (accessToken == null) { + String? authCode = await requestUserAuth(); + + await Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => CustomScaffold( + body: Frame( + showLogo: true, + child: SpotifyLogin( + inSetup: false, + authCode: authCode, + ), + )))); + + await getBrandNewAccessToken(authCode!); + + accessToken = await requestAccessToken(authCode); + } + + return accessToken!; +} diff --git a/lib/widgets/artist_selector.dart b/lib/widgets/artist_selector.dart index 5790e10..d6a078c 100644 --- a/lib/widgets/artist_selector.dart +++ b/lib/widgets/artist_selector.dart @@ -6,6 +6,7 @@ import 'package:daily_spotify/backend/spotify_api/auth.dart' as spotify_auth; import 'package:daily_spotify/backend/database_manager.dart' as db; import 'package:daily_spotify/widgets/card_view_widget.dart'; import 'package:daily_spotify/widgets/loading_indicator_widget.dart'; +import 'package:daily_spotify/utils/request_access_token_without_auth_code.dart'; import 'package:daily_spotify/utils/default_config.dart'; import 'package:daily_spotify/styles.dart'; @@ -53,7 +54,8 @@ class _ArtistSelectorState extends State { // check to make sure artist list was already generated from genre selector if (initiallyEmpty) { - AccessToken? accessToken = await spotify_auth.requestAccessToken(null); + AccessToken accessToken = + await requestAccessTokenWithoutAuthCode(context); List artistList = await getUserTopItems(accessToken: accessToken!, type: Artist); diff --git a/lib/widgets/developer_settings_widgets.dart b/lib/widgets/developer_settings_widgets.dart index afcc8a5..afffefa 100644 --- a/lib/widgets/developer_settings_widgets.dart +++ b/lib/widgets/developer_settings_widgets.dart @@ -5,6 +5,7 @@ import 'package:intl/intl.dart'; import 'package:daily_spotify/backend/spotify_api/spotify_api.dart'; import 'package:daily_spotify/backend/database_manager.dart' as db; import 'package:daily_spotify/models/daily_track.dart'; +import 'package:daily_spotify/utils/request_access_token_without_auth_code.dart'; import 'package:daily_spotify/utils/get_recommendation_seeds.dart'; import 'package:daily_spotify/utils/get_new_daily_track.dart'; @@ -21,7 +22,7 @@ class DeveloperSettingsWidgets extends StatelessWidget { return Column( children: [ TextButton( - onPressed: () async => generateANewRecommendation(), + onPressed: () async => generateANewRecommendation(context), child: const Text('Generate a new recommendation')), TextButton( onPressed: () async => generateNewDailyTracks(context), @@ -39,15 +40,15 @@ class DeveloperSettingsWidgets extends StatelessWidget { ); } - Future generateANewRecommendation() async { - AccessToken? accessToken = await requestAccessToken(null); + Future generateANewRecommendation(BuildContext context) async { + AccessToken accessToken = await requestAccessTokenWithoutAuthCode(context); List initialSeedArtists = await db.Config.instance.getArtistConfig(); List initialSeedGenres = await db.Config.instance.getGenreConfig(); List initialSeedTracks = await db.Config.instance.getTrackConfig(); Map seeds = await getRecommendationSeeds( - initialSeedArtists, initialSeedGenres, initialSeedTracks); + context, initialSeedArtists, initialSeedGenres, initialSeedTracks); Recommendation recommendation = await getRecommendations( accessToken: accessToken!, diff --git a/lib/widgets/genre_selector.dart b/lib/widgets/genre_selector.dart index 32b70ff..9b3dc93 100644 --- a/lib/widgets/genre_selector.dart +++ b/lib/widgets/genre_selector.dart @@ -6,6 +6,7 @@ import 'package:daily_spotify/backend/spotify_api/auth.dart' as spotify_auth; import 'package:daily_spotify/backend/spotify_api/spotify_api.dart'; import 'package:daily_spotify/backend/database_manager.dart' as db; import 'package:daily_spotify/providers/setup_provider.dart'; +import 'package:daily_spotify/utils/request_access_token_without_auth_code.dart'; import 'package:daily_spotify/utils/filter_by_genre.dart'; import 'package:daily_spotify/styles.dart'; @@ -53,7 +54,7 @@ class _GenreSelectorState extends State { } Future getAndAddGenres() async { - AccessToken? accessToken = await spotify_auth.requestAccessToken(null); + AccessToken accessToken = await requestAccessTokenWithoutAuthCode(context); List artistList = await getUserTopItems(accessToken: accessToken!, type: Artist); @@ -178,7 +179,10 @@ class _GenreButtonState extends State { style: widget.selected ? Styles().selectedElevatedButtonStyle : Styles().unselectedElevatedButtonStyle, - child: Text(widget.genre.replaceAll('-', ' '))), + child: Text( + widget.genre.replaceAll('-', ' '), + style: Styles().subtitleText, + )), ); } } diff --git a/lib/widgets/spotify_attribute_widget.dart b/lib/widgets/spotify_attribute_widget.dart index 3f7be74..96801fc 100644 --- a/lib/widgets/spotify_attribute_widget.dart +++ b/lib/widgets/spotify_attribute_widget.dart @@ -7,23 +7,24 @@ class SpotifyAttribute extends StatelessWidget { @override Widget build(BuildContext context) { return Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, children: [ - Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Text( - 'Any and all metadata and cover art data is provided by Spotify and their respective services.', - textAlign: TextAlign.center, - style: Styles().defaultText, - ), + Text( + 'Any and all metadata and cover art data is provided by ', + style: Styles().defaultText, ), - Padding( - padding: const EdgeInsets.all(12.0), - child: Image.asset( - 'assets/Spotify_Logo_RGB_Green.png', - height: 24.0, - ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Image.asset( + 'assets/Spotify_Logo_RGB_Green.png', + height: 24.0, + ), + Text( + ' and their respective services.', + style: Styles().defaultText, + ), + ], ) ], ); diff --git a/lib/widgets/track_selector.dart b/lib/widgets/track_selector.dart index eef9ea8..1b43df3 100644 --- a/lib/widgets/track_selector.dart +++ b/lib/widgets/track_selector.dart @@ -6,6 +6,7 @@ import 'package:daily_spotify/backend/spotify_api/auth.dart' as spotify_auth; import 'package:daily_spotify/backend/database_manager.dart' as db; import 'package:daily_spotify/widgets/card_view_widget.dart'; import 'package:daily_spotify/widgets/loading_indicator_widget.dart'; +import 'package:daily_spotify/utils/request_access_token_without_auth_code.dart'; import 'package:daily_spotify/utils/default_config.dart'; import 'package:daily_spotify/styles.dart'; @@ -55,7 +56,7 @@ class _TrackSelectorState extends State { } Future?> getItemList() async { - AccessToken? accessToken = await spotify_auth.requestAccessToken(null); + AccessToken accessToken = await requestAccessTokenWithoutAuthCode(context); List trackList = await getUserTopItems(accessToken: accessToken!, type: Track); diff --git a/lib/widgets/track_view_widget.dart b/lib/widgets/track_view_widget.dart index be86590..8d09862 100644 --- a/lib/widgets/track_view_widget.dart +++ b/lib/widgets/track_view_widget.dart @@ -22,7 +22,7 @@ class TrackView extends StatelessWidget { final Track track; final Color averageColorOfImage; - static const List flexValues = [4, 50, 20, 10]; + static const List flexValues = [4, 46, 20, 7]; @override Widget build(BuildContext context) { @@ -36,7 +36,7 @@ class TrackView extends StatelessWidget { 0.0, 0.3, 0.4, - 0.75, + 0.7, ], colors: [ Styles().backgroundColor, @@ -72,11 +72,13 @@ class TrackView extends StatelessWidget { track.name, style: Styles().titleText, textAlign: TextAlign.center, + softWrap: true, ), Text( track.getArtists(), style: Styles().subtitleText, textAlign: TextAlign.center, + softWrap: true, ), ], ), @@ -101,9 +103,7 @@ class TrackView extends StatelessWidget { await openSong(track.spotifyHref); } }, - style: Styles().unselectedElevatedButtonStyle.copyWith( - fixedSize: - MaterialStateProperty.all(const Size(150, 25))), + style: Styles().unselectedElevatedButtonStyle, child: Row( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min,