diff --git a/lib/api/spotify.dart b/lib/api/spotify.dart index 8b4979d..d0cfed1 100644 --- a/lib/api/spotify.dart +++ b/lib/api/spotify.dart @@ -1,5 +1,6 @@ import 'package:freezer/api/deezer.dart'; import 'package:freezer/api/importer.dart'; +import 'package:freezer/settings.dart'; import 'package:html/parser.dart'; import 'package:html/dom.dart' as dom; import 'package:http/http.dart' as http; @@ -141,6 +142,24 @@ class SpotifyAPIWrapper { SpotifyApi spotify; User me; + //Try authorize with saved credentials + Future trySaved() async { + print(settings.spotifyCredentials); + if (settings.spotifyClientId == null || settings.spotifyClientSecret == null || settings.spotifyCredentials == null) return false; + final credentials = SpotifyApiCredentials( + settings.spotifyClientId, + settings.spotifyClientSecret, + accessToken: settings.spotifyCredentials.accessToken, + refreshToken: settings.spotifyCredentials.refreshToken, + scopes: settings.spotifyCredentials.scopes, + expiration: settings.spotifyCredentials.expiration + ); + spotify = SpotifyApi(credentials); + me = await spotify.me.get(); + await _save(); + return true; + } + Future authorize(String clientId, String clientSecret) async { //Spotify SpotifyApiCredentials credentials = SpotifyApiCredentials(clientId, clientSecret); @@ -171,6 +190,24 @@ class SpotifyAPIWrapper { //Create spotify spotify = SpotifyApi.fromAuthCodeGrant(grant, responseUri); me = await spotify.me.get(); + + //Save + await _save(); + } + + Future _save() async { + //Save credentials + final spotifyCredentials = await spotify.getCredentials(); + final saveCredentials = SpotifyCredentialsSave( + accessToken: spotifyCredentials.accessToken, + refreshToken: spotifyCredentials.refreshToken, + scopes: spotifyCredentials.scopes, + expiration: spotifyCredentials.expiration + ); + settings.spotifyClientSecret = spotifyCredentials.clientId; + settings.spotifyClientSecret = spotifyCredentials.clientSecret; + settings.spotifyCredentials = saveCredentials; + await settings.save(); } //Cancel authorization @@ -180,4 +217,4 @@ class SpotifyAPIWrapper { _server = null; } } -} \ No newline at end of file +} diff --git a/lib/main.dart b/lib/main.dart index ece22d9..06af517 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -358,42 +358,47 @@ class _MainScreenState extends State focusNode: FocusNode(), onKey: _handleKey(navigationBarFocusNode, screenFocusNode), child: Scaffold( - bottomNavigationBar: FocusScope( - node: navigationBarFocusNode, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - PlayerBar(), - BottomNavigationBar( - backgroundColor: Theme.of(context).bottomAppBarColor, - currentIndex: _selected, - onTap: (int s) async { - //Pop all routes until home screen - while (navigatorKey.currentState.canPop()) { - await navigatorKey.currentState.maybePop(); - } + bottomNavigationBar: + FocusScope( + node: navigationBarFocusNode, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + PlayerBar(), + BottomNavigationBar( + backgroundColor: Theme.of(context).bottomAppBarColor, + currentIndex: _selected, + onTap: (int s) async { + //Pop all routes until home screen + while (navigatorKey.currentState.canPop()) { + await navigatorKey.currentState.maybePop(); + } - await navigatorKey.currentState.maybePop(); - setState(() { - _selected = s; - }); + await navigatorKey.currentState.maybePop(); + setState(() { + _selected = s; + }); - //Fix statusbar - SystemChrome.setSystemUIOverlayStyle( - SystemUiOverlayStyle( - statusBarColor: Colors.transparent)); - }, - selectedItemColor: Theme.of(context).primaryColor, - items: [ - BottomNavigationBarItem( - icon: Icon(Icons.home), label: 'Home'.i18n), - BottomNavigationBarItem( - icon: Icon(Icons.search), - label: 'Search'.i18n, - ), - BottomNavigationBarItem( - icon: Icon(Icons.library_music), - label: 'Library'.i18n) + //Fix statusbar + SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + )); + }, + selectedItemColor: Theme.of(context).primaryColor, + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Home'.i18n), + BottomNavigationBarItem( + icon: Icon(Icons.search), + label: 'Search'.i18n, + ), + BottomNavigationBarItem( + icon: Icon(Icons.library_music), + label: 'Library'.i18n + ) + ], + ) ], ) ], diff --git a/lib/settings.dart b/lib/settings.dart index 64a8087..640248e 100644 --- a/lib/settings.dart +++ b/lib/settings.dart @@ -144,6 +144,8 @@ class Settings { String spotifyClientId; @JsonKey(defaultValue: null) String spotifyClientSecret; + @JsonKey(defaultValue: null) + SpotifyCredentialsSave spotifyCredentials; Settings({this.downloadPath, this.arl}); @@ -344,4 +346,27 @@ class Settings { enum AudioQuality { MP3_128, MP3_320, FLAC, ASK } +<<<<<<< HEAD enum Themes { Light, Dark, Deezer, Black } +======= +enum Themes { + Light, + Dark, + Deezer, + Black +} + +@JsonSerializable() +class SpotifyCredentialsSave { + String accessToken; + String refreshToken; + List scopes; + DateTime expiration; + + SpotifyCredentialsSave({this.accessToken, this.refreshToken, this.scopes, this.expiration}); + + //JSON + factory SpotifyCredentialsSave.fromJson(Map json) => _$SpotifyCredentialsSaveFromJson(json); + Map toJson() => _$SpotifyCredentialsSaveToJson(this); +} +>>>>>>> main/master diff --git a/lib/settings.g.dart b/lib/settings.g.dart index 13d1d4b..275cd86 100644 --- a/lib/settings.g.dart +++ b/lib/settings.g.dart @@ -78,7 +78,11 @@ Settings _$SettingsFromJson(Map json) { ..lastFMUsername = json['lastFMUsername'] as String ..lastFMPassword = json['lastFMPassword'] as String ..spotifyClientId = json['spotifyClientId'] as String - ..spotifyClientSecret = json['spotifyClientSecret'] as String; + ..spotifyClientSecret = json['spotifyClientSecret'] as String + ..spotifyCredentials = json['spotifyCredentials'] == null + ? null + : SpotifyCredentialsSave.fromJson( + json['spotifyCredentials'] as Map); } Map _$SettingsToJson(Settings instance) => { @@ -123,6 +127,7 @@ Map _$SettingsToJson(Settings instance) => { 'lastFMPassword': instance.lastFMPassword, 'spotifyClientId': instance.spotifyClientId, 'spotifyClientSecret': instance.spotifyClientSecret, + 'spotifyCredentials': instance.spotifyCredentials, }; T _$enumDecode( @@ -170,3 +175,24 @@ const _$ThemesEnumMap = { Themes.Deezer: 'Deezer', Themes.Black: 'Black', }; + +SpotifyCredentialsSave _$SpotifyCredentialsSaveFromJson( + Map json) { + return SpotifyCredentialsSave( + accessToken: json['accessToken'] as String, + refreshToken: json['refreshToken'] as String, + scopes: (json['scopes'] as List)?.map((e) => e as String)?.toList(), + expiration: json['expiration'] == null + ? null + : DateTime.parse(json['expiration'] as String), + ); +} + +Map _$SpotifyCredentialsSaveToJson( + SpotifyCredentialsSave instance) => + { + 'accessToken': instance.accessToken, + 'refreshToken': instance.refreshToken, + 'scopes': instance.scopes, + 'expiration': instance.expiration?.toIso8601String(), + }; diff --git a/lib/ui/importer_screen.dart b/lib/ui/importer_screen.dart index 5b8077b..cc2c4a8 100644 --- a/lib/ui/importer_screen.dart +++ b/lib/ui/importer_screen.dart @@ -326,6 +326,18 @@ class _SpotifyImporterV2State extends State { void initState() { _clientId = settings.spotifyClientId; _clientSecret = settings.spotifyClientSecret; + + //Try saved + spotify = SpotifyAPIWrapper(); + spotify.trySaved().then((r) { + if (r) { + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => SpotifyImporterV2Main(spotify) + )); + } + }); + + super.initState(); } diff --git a/pubspec.yaml b/pubspec.yaml index 00c224b..3a3d863 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.6.10+1 +version: 0.6.11+1 environment: sdk: ">=2.8.0 <3.0.0"