flutter provider replaced with flutter_riverpod

This commit is contained in:
Kingkor Roy Tirtho 2022-02-11 10:44:16 +06:00
parent 88b201b24b
commit d05ec0099d
26 changed files with 472 additions and 484 deletions

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Album/AlbumView.dart'; import 'package:spotube/components/Album/AlbumView.dart';
import 'package:spotube/components/Shared/PlaybuttonCard.dart'; import 'package:spotube/components/Shared/PlaybuttonCard.dart';
@ -9,13 +9,13 @@ import 'package:spotube/helpers/simple-track-to-track.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class AlbumCard extends StatelessWidget { class AlbumCard extends ConsumerWidget {
final Album album; final Album album;
const AlbumCard(this.album, {Key? key}) : super(key: key); const AlbumCard(this.album, {Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, ref) {
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
bool isPlaylistPlaying = playback.currentPlaylist != null && bool isPlaylistPlaying = playback.currentPlaylist != null &&
playback.currentPlaylist!.id == album.id; playback.currentPlaylist!.id == album.id;
@ -34,7 +34,7 @@ class AlbumCard extends StatelessWidget {
)); ));
}, },
onPlaybuttonPressed: () async { onPlaybuttonPressed: () async {
SpotifyApi spotify = context.read<SpotifyDI>().spotifyApi; SpotifyApi spotify = ref.read(spotifyProvider);
if (isPlaylistPlaying) return; if (isPlaylistPlaying) return;
List<Track> tracks = (await spotify.albums.getTracks(album.id!).all()) List<Track> tracks = (await spotify.albums.getTracks(album.id!).all())
.map((track) => simpleTrackToTrack(track, album)) .map((track) => simpleTrackToTrack(track, album))

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
import 'package:spotube/components/Shared/TracksTableView.dart'; import 'package:spotube/components/Shared/TracksTableView.dart';
@ -8,7 +8,7 @@ import 'package:spotube/helpers/simple-track-to-track.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class AlbumView extends StatelessWidget { class AlbumView extends ConsumerWidget {
final AlbumSimple album; final AlbumSimple album;
const AlbumView(this.album, {Key? key}) : super(key: key); const AlbumView(this.album, {Key? key}) : super(key: key);
@ -31,11 +31,11 @@ class AlbumView extends StatelessWidget {
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, ref) {
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
var isPlaylistPlaying = playback.currentPlaylist?.id == album.id; var isPlaylistPlaying = playback.currentPlaylist?.id == album.id;
SpotifyApi spotify = context.watch<SpotifyDI>().spotifyApi; SpotifyApi spotify = ref.watch(spotifyProvider);
return Scaffold( return Scaffold(
body: FutureBuilder<Iterable<TrackSimple>>( body: FutureBuilder<Iterable<TrackSimple>>(
future: spotify.albums.getTracks(album.id!).all(), future: spotify.albums.getTracks(album.id!).all(),

View File

@ -1,12 +1,12 @@
import 'package:flutter/material.dart' hide Page; import 'package:flutter/material.dart' hide Page;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:provider/provider.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Album/AlbumCard.dart'; import 'package:spotube/components/Album/AlbumCard.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class ArtistAlbumView extends StatefulWidget { class ArtistAlbumView extends ConsumerStatefulWidget {
final String artistId; final String artistId;
final String artistName; final String artistName;
const ArtistAlbumView( const ArtistAlbumView(
@ -16,10 +16,10 @@ class ArtistAlbumView extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
State<ArtistAlbumView> createState() => _ArtistAlbumViewState(); ConsumerState<ArtistAlbumView> createState() => _ArtistAlbumViewState();
} }
class _ArtistAlbumViewState extends State<ArtistAlbumView> { class _ArtistAlbumViewState extends ConsumerState<ArtistAlbumView> {
final PagingController<int, Album> _pagingController = final PagingController<int, Album> _pagingController =
PagingController<int, Album>(firstPageKey: 0); PagingController<int, Album>(firstPageKey: 0);
@ -39,10 +39,9 @@ class _ArtistAlbumViewState extends State<ArtistAlbumView> {
_fetchPage(int pageKey) async { _fetchPage(int pageKey) async {
try { try {
SpotifyDI data = context.read<SpotifyDI>(); SpotifyApi spotifyApi = ref.watch(spotifyProvider);
Page<Album> albums = await data.spotifyApi.artists Page<Album> albums =
.albums(widget.artistId) await spotifyApi.artists.albums(widget.artistId).getPage(8, pageKey);
.getPage(8, pageKey);
var items = albums.items!.toList(); var items = albums.items!.toList();

View File

@ -1,7 +1,7 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Album/AlbumCard.dart'; import 'package:spotube/components/Album/AlbumCard.dart';
import 'package:spotube/components/Artist/ArtistAlbumView.dart'; import 'package:spotube/components/Artist/ArtistAlbumView.dart';
@ -14,7 +14,7 @@ import 'package:spotube/helpers/zero-pad-num-str.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class ArtistProfile extends StatefulWidget { class ArtistProfile extends ConsumerStatefulWidget {
final String artistId; final String artistId;
const ArtistProfile(this.artistId, {Key? key}) : super(key: key); const ArtistProfile(this.artistId, {Key? key}) : super(key: key);
@ -22,10 +22,10 @@ class ArtistProfile extends StatefulWidget {
_ArtistProfileState createState() => _ArtistProfileState(); _ArtistProfileState createState() => _ArtistProfileState();
} }
class _ArtistProfileState extends State<ArtistProfile> { class _ArtistProfileState extends ConsumerState<ArtistProfile> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SpotifyApi spotify = context.watch<SpotifyDI>().spotifyApi; SpotifyApi spotify = ref.watch(spotifyProvider);
return Scaffold( return Scaffold(
appBar: const PageWindowTitleBar( appBar: const PageWindowTitleBar(
leading: BackButton(), leading: BackButton(),
@ -134,7 +134,7 @@ class _ArtistProfileState extends State<ArtistProfile> {
return const Center( return const Center(
child: CircularProgressIndicator.adaptive()); child: CircularProgressIndicator.adaptive());
} }
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
var isPlaylistPlaying = var isPlaylistPlaying =
playback.currentPlaylist?.id == snapshot.data?.id; playback.currentPlaylist?.id == snapshot.data?.id;
playPlaylist(List<Track> tracks, {Track? currentTrack}) { playPlaylist(List<Track> tracks, {Track? currentTrack}) {

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart' hide Page; import 'package:flutter/material.dart' hide Page;
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Playlist/PlaylistCard.dart'; import 'package:spotube/components/Playlist/PlaylistCard.dart';
import 'package:spotube/components/Playlist/PlaylistGenreView.dart'; import 'package:spotube/components/Playlist/PlaylistGenreView.dart';
@ -51,14 +51,15 @@ class _CategoryCardState extends State<CategoryCard> {
], ],
), ),
), ),
Consumer<SpotifyDI>( Consumer(
builder: (context, data, child) { builder: (context, ref, child) {
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
return FutureBuilder<Iterable<PlaylistSimple>>( return FutureBuilder<Iterable<PlaylistSimple>>(
future: widget.playlists == null future: widget.playlists == null
? (widget.category.id != "user-featured-playlists" ? (widget.category.id != "user-featured-playlists"
? data.spotifyApi.playlists ? spotifyApi.playlists
.getByCategoryId(widget.category.id!) .getByCategoryId(widget.category.id!)
: data.spotifyApi.playlists.featured) : spotifyApi.playlists.featured)
.getPage(4, 0) .getPage(4, 0)
.then((value) => value.items ?? []) .then((value) => value.items ?? [])
: Future.value(widget.playlists), : Future.value(widget.playlists),

View File

@ -3,8 +3,8 @@ import 'dart:io';
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart' hide Page; import 'package:flutter/material.dart' hide Page;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:oauth2/oauth2.dart' show AuthorizationException; import 'package:oauth2/oauth2.dart' show AuthorizationException;
import 'package:spotify/spotify.dart' hide Image, Player, Search; import 'package:spotify/spotify.dart' hide Image, Player, Search;
@ -33,14 +33,14 @@ List<String> spotifyScopes = [
"playlist-read-collaborative" "playlist-read-collaborative"
]; ];
class Home extends StatefulWidget { class Home extends ConsumerStatefulWidget {
const Home({Key? key}) : super(key: key); const Home({Key? key}) : super(key: key);
@override @override
_HomeState createState() => _HomeState(); _HomeState createState() => _HomeState();
} }
class _HomeState extends State<Home> { class _HomeState extends ConsumerState<Home> {
final PagingController<int, Category> _pagingController = final PagingController<int, Category> _pagingController =
PagingController(firstPageKey: 0); PagingController(firstPageKey: 0);
@ -63,7 +63,7 @@ class _HomeState extends State<Home> {
DateTime? expiration = DateTime? expiration =
expirationStr != null ? DateTime.parse(expirationStr) : null; expirationStr != null ? DateTime.parse(expirationStr) : null;
try { try {
Auth authProvider = context.read<Auth>(); Auth auth = ref.read(authProvider);
if (clientId != null && clientSecret != null) { if (clientId != null && clientSecret != null) {
SpotifyApi spotifyApi = SpotifyApi( SpotifyApi spotifyApi = SpotifyApi(
@ -78,7 +78,7 @@ class _HomeState extends State<Home> {
); );
SpotifyApiCredentials credentials = await spotifyApi.getCredentials(); SpotifyApiCredentials credentials = await spotifyApi.getCredentials();
if (credentials.accessToken?.isNotEmpty ?? false) { if (credentials.accessToken?.isNotEmpty ?? false) {
authProvider.setAuthState( auth.setAuthState(
clientId: clientId, clientId: clientId,
clientSecret: clientSecret, clientSecret: clientSecret,
accessToken: accessToken:
@ -91,8 +91,8 @@ class _HomeState extends State<Home> {
} }
_pagingController.addPageRequestListener((pageKey) async { _pagingController.addPageRequestListener((pageKey) async {
try { try {
SpotifyDI data = context.read<SpotifyDI>(); SpotifyApi spotifyApi = ref.read(spotifyProvider);
Page<Category> categories = await data.spotifyApi.categories Page<Category> categories = await spotifyApi.categories
.list(country: "US") .list(country: "US")
.getPage(15, pageKey); .getPage(15, pageKey);
@ -113,10 +113,10 @@ class _HomeState extends State<Home> {
_pagingController.error = e; _pagingController.error = e;
} }
}); });
} on AuthorizationException catch (e) { } on AuthorizationException catch (_) {
if (clientId != null && clientSecret != null) { if (clientId != null && clientSecret != null) {
oauthLogin( oauthLogin(
context, ref.read(authProvider),
clientId: clientId, clientId: clientId,
clientSecret: clientSecret, clientSecret: clientSecret,
); );
@ -136,8 +136,9 @@ class _HomeState extends State<Home> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Auth authProvider = Provider.of<Auth>(context); Auth auth = ref.watch(authProvider);
if (!authProvider.isLoggedIn) { SpotifyApi spotify = ref.watch(spotifyProvider);
if (!auth.isLoggedIn) {
return const Login(); return const Login();
} }
@ -199,10 +200,8 @@ class _HomeState extends State<Home> {
style: Theme.of(context).textTheme.headline4), style: Theme.of(context).textTheme.headline4),
]), ]),
), ),
trailing: trailing: FutureBuilder<User>(
Consumer<SpotifyDI>(builder: (context, data, widget) { future: spotify.me.get(),
return FutureBuilder<User>(
future: data.spotifyApi.me.get(),
builder: (context, snapshot) { builder: (context, snapshot) {
var avatarImg = imageToUrlString(snapshot.data?.images, var avatarImg = imageToUrlString(snapshot.data?.images,
index: (snapshot.data?.images?.length ?? 1) - 1); index: (snapshot.data?.images?.length ?? 1) - 1);
@ -229,8 +228,7 @@ class _HomeState extends State<Home> {
IconButton( IconButton(
icon: const Icon(Icons.settings_outlined), icon: const Icon(Icons.settings_outlined),
onPressed: () { onPressed: () {
Navigator.of(context) Navigator.of(context).push(MaterialPageRoute(
.push(MaterialPageRoute(
builder: (context) { builder: (context) {
return const Settings(); return const Settings();
}, },
@ -240,8 +238,7 @@ class _HomeState extends State<Home> {
), ),
); );
}, },
); ),
}),
), ),
// contents of the spotify // contents of the spotify
if (_selectedIndex == 0) if (_selectedIndex == 0)

View File

@ -1,18 +1,18 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:provider/provider.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Artist/ArtistCard.dart'; import 'package:spotube/components/Artist/ArtistCard.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class UserArtists extends StatefulWidget { class UserArtists extends ConsumerStatefulWidget {
const UserArtists({Key? key}) : super(key: key); const UserArtists({Key? key}) : super(key: key);
@override @override
State<UserArtists> createState() => _UserArtistsState(); ConsumerState<UserArtists> createState() => _UserArtistsState();
} }
class _UserArtistsState extends State<UserArtists> { class _UserArtistsState extends ConsumerState<UserArtists> {
final PagingController<String, Artist> _pagingController = final PagingController<String, Artist> _pagingController =
PagingController(firstPageKey: ""); PagingController(firstPageKey: "");
@ -22,8 +22,8 @@ class _UserArtistsState extends State<UserArtists> {
WidgetsBinding.instance?.addPostFrameCallback((timestamp) { WidgetsBinding.instance?.addPostFrameCallback((timestamp) {
_pagingController.addPageRequestListener((pageKey) async { _pagingController.addPageRequestListener((pageKey) async {
try { try {
SpotifyDI data = context.read<SpotifyDI>(); SpotifyApi spotifyApi = ref.read(spotifyProvider);
CursorPage<Artist> artists = await data.spotifyApi.me CursorPage<Artist> artists = await spotifyApi.me
.following(FollowingType.artist) .following(FollowingType.artist)
.getPage(15, pageKey); .getPage(15, pageKey);
@ -51,10 +51,10 @@ class _UserArtistsState extends State<UserArtists> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SpotifyDI data = context.watch<SpotifyDI>(); SpotifyApi spotifyApi = ref.watch(spotifyProvider);
return FutureBuilder<CursorPage<Artist>>( return FutureBuilder<CursorPage<Artist>>(
future: data.spotifyApi.me.following(FollowingType.artist).first(), future: spotifyApi.me.following(FollowingType.artist).first(),
builder: (context, snapshot) { builder: (context, snapshot) {
if (!snapshot.hasData) { if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator.adaptive()); return const Center(child: CircularProgressIndicator.adaptive());

View File

@ -1,18 +1,18 @@
import 'package:flutter/material.dart' hide Image; import 'package:flutter/material.dart' hide Image;
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Playlist/PlaylistCard.dart'; import 'package:spotube/components/Playlist/PlaylistCard.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class UserPlaylists extends StatelessWidget { class UserPlaylists extends ConsumerWidget {
const UserPlaylists({Key? key}) : super(key: key); const UserPlaylists({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context, ref) {
SpotifyDI data = context.watch<SpotifyDI>(); SpotifyApi spotifyApi = ref.watch(spotifyProvider);
return FutureBuilder<Iterable<PlaylistSimple>>( return FutureBuilder<Iterable<PlaylistSimple>>(
future: data.spotifyApi.playlists.me.all(), future: spotifyApi.playlists.me.all(),
builder: (context, snapshot) { builder: (context, snapshot) {
if (!snapshot.hasData) { if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator.adaptive()); return const Center(child: CircularProgressIndicator.adaptive());

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/components/Shared/Hyperlink.dart'; import 'package:spotube/components/Shared/Hyperlink.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
@ -8,14 +8,14 @@ import 'package:spotube/models/LocalStorageKeys.dart';
import 'package:spotube/provider/Auth.dart'; import 'package:spotube/provider/Auth.dart';
import 'package:spotube/provider/UserPreferences.dart'; import 'package:spotube/provider/UserPreferences.dart';
class Login extends StatefulWidget { class Login extends ConsumerStatefulWidget {
const Login({Key? key}) : super(key: key); const Login({Key? key}) : super(key: key);
@override @override
_LoginState createState() => _LoginState(); _LoginState createState() => _LoginState();
} }
class _LoginState extends State<Login> { class _LoginState extends ConsumerState<Login> {
String clientId = ""; String clientId = "";
String clientSecret = ""; String clientSecret = "";
String accessToken = ""; String accessToken = "";
@ -28,7 +28,8 @@ class _LoginState extends State<Login> {
_fieldError = true; _fieldError = true;
}); });
} }
await oauthLogin(context, clientId: clientId, clientSecret: clientSecret); await oauthLogin(ref.read(authProvider),
clientId: clientId, clientSecret: clientSecret);
} catch (e) { } catch (e) {
print("[Login.handleLogin] $e"); print("[Login.handleLogin] $e");
} }
@ -36,8 +37,7 @@ class _LoginState extends State<Login> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<Auth>( Auth authState = ref.watch(authProvider);
builder: (context, authState, child) {
return Scaffold( return Scaffold(
appBar: const PageWindowTitleBar(), appBar: const PageWindowTitleBar(),
body: SingleChildScrollView( body: SingleChildScrollView(
@ -107,13 +107,12 @@ class _LoginState extends State<Login> {
onPressed: () async { onPressed: () async {
await handleLogin(authState); await handleLogin(authState);
UserPreferences preferences = UserPreferences preferences =
context.read<UserPreferences>(); ref.read(userPreferencesProvider);
SharedPreferences localStorage = SharedPreferences localStorage =
await SharedPreferences.getInstance(); await SharedPreferences.getInstance();
preferences.setGeniusAccessToken(accessToken); preferences.setGeniusAccessToken(accessToken);
await localStorage.setString( await localStorage.setString(
LocalStorageKeys.geniusAccessToken, LocalStorageKeys.geniusAccessToken, accessToken);
accessToken);
setState(() { setState(() {
accessToken = ""; accessToken = "";
}); });
@ -128,7 +127,5 @@ class _LoginState extends State<Login> {
), ),
), ),
); );
},
);
} }
} }

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Settings.dart'; import 'package:spotube/components/Settings.dart';
import 'package:spotube/helpers/artist-to-string.dart'; import 'package:spotube/helpers/artist-to-string.dart';
@ -7,20 +7,20 @@ import 'package:spotube/helpers/getLyrics.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/UserPreferences.dart'; import 'package:spotube/provider/UserPreferences.dart';
class Lyrics extends StatefulWidget { class Lyrics extends ConsumerStatefulWidget {
const Lyrics({Key? key}) : super(key: key); const Lyrics({Key? key}) : super(key: key);
@override @override
State<Lyrics> createState() => _LyricsState(); ConsumerState<Lyrics> createState() => _LyricsState();
} }
class _LyricsState extends State<Lyrics> { class _LyricsState extends ConsumerState<Lyrics> {
Map<String, String> _lyrics = {}; Map<String, String> _lyrics = {};
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
UserPreferences userPreferences = context.watch<UserPreferences>(); UserPreferences userPreferences = ref.watch(userPreferencesProvider);
bool hasToken = (userPreferences.geniusAccessToken != null || bool hasToken = (userPreferences.geniusAccessToken != null ||
(userPreferences.geniusAccessToken?.isNotEmpty ?? false)); (userPreferences.geniusAccessToken?.isNotEmpty ?? false));

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:just_audio/just_audio.dart'; import 'package:just_audio/just_audio.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Shared/DownloadTrackButton.dart'; import 'package:spotube/components/Shared/DownloadTrackButton.dart';
@ -10,18 +11,17 @@ import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/helpers/search-youtube.dart'; import 'package:spotube/helpers/search-youtube.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart';
class Player extends StatefulWidget { class Player extends ConsumerStatefulWidget {
const Player({Key? key}) : super(key: key); const Player({Key? key}) : super(key: key);
@override @override
_PlayerState createState() => _PlayerState(); _PlayerState createState() => _PlayerState();
} }
class _PlayerState extends State<Player> with WidgetsBindingObserver { class _PlayerState extends ConsumerState<Player> with WidgetsBindingObserver {
late AudioPlayer player; late AudioPlayer player;
bool _isPlaying = false; bool _isPlaying = false;
bool _shuffled = false; bool _shuffled = false;
@ -111,7 +111,7 @@ class _PlayerState extends State<Player> with WidgetsBindingObserver {
} }
void _movePlaylistPositionBy(int pos) { void _movePlaylistPositionBy(int pos) {
Playback playback = context.read<Playback>(); Playback playback = ref.read(playbackProvider);
if (playback.currentTrack != null && playback.currentPlaylist != null) { if (playback.currentTrack != null && playback.currentPlaylist != null) {
int index = playback.currentPlaylist!.trackIds int index = playback.currentPlaylist!.trackIds
.indexOf(playback.currentTrack!.id!) + .indexOf(playback.currentTrack!.id!) +
@ -198,8 +198,9 @@ class _PlayerState extends State<Player> with WidgetsBindingObserver {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
color: Theme.of(context).backgroundColor, color: Theme.of(context).backgroundColor,
child: Consumer<Playback>( child: Consumer(
builder: (context, playback, widget) { builder: (context, ref, widget) {
Playback playback = ref.watch(playbackProvider);
if (playback.currentPlaylist != null && if (playback.currentPlaylist != null &&
playback.currentTrack != null) { playback.currentTrack != null) {
_playTrack(playback.currentTrack!, playback); _playTrack(playback.currentTrack!, playback);
@ -348,10 +349,11 @@ class _PlayerState extends State<Player> with WidgetsBindingObserver {
DownloadTrackButton( DownloadTrackButton(
track: playback.currentTrack, track: playback.currentTrack,
), ),
Consumer<SpotifyDI>(builder: (context, data, widget) { Consumer(builder: (context, ref, widget) {
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
return FutureBuilder<bool>( return FutureBuilder<bool>(
future: playback.currentTrack?.id != null future: playback.currentTrack?.id != null
? data.spotifyApi.tracks.me ? spotifyApi.tracks.me
.containsOne(playback.currentTrack!.id!) .containsOne(playback.currentTrack!.id!)
: Future.value(false), : Future.value(false),
initialData: false, initialData: false,
@ -367,7 +369,7 @@ class _PlayerState extends State<Player> with WidgetsBindingObserver {
onPressed: () { onPressed: () {
if (!isLiked && if (!isLiked &&
playback.currentTrack?.id != null) { playback.currentTrack?.id != null) {
data.spotifyApi.tracks.me spotifyApi.tracks.me
.saveOne( .saveOne(
playback.currentTrack!.id!) playback.currentTrack!.id!)
.then((value) => setState(() {})); .then((value) => setState(() {}));

View File

@ -1,13 +1,13 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:spotube/helpers/zero-pad-num-str.dart'; import 'package:spotube/helpers/zero-pad-num-str.dart';
import 'package:spotube/models/GlobalKeyActions.dart'; import 'package:spotube/models/GlobalKeyActions.dart';
import 'package:spotube/provider/UserPreferences.dart'; import 'package:spotube/provider/UserPreferences.dart';
import 'package:provider/provider.dart';
class PlayerControls extends StatefulWidget { class PlayerControls extends ConsumerStatefulWidget {
final Stream<Duration> positionStream; final Stream<Duration> positionStream;
final bool isPlaying; final bool isPlaying;
final Duration duration; final Duration duration;
@ -38,7 +38,7 @@ class PlayerControls extends StatefulWidget {
_PlayerControlsState createState() => _PlayerControlsState(); _PlayerControlsState createState() => _PlayerControlsState();
} }
class _PlayerControlsState extends State<PlayerControls> { class _PlayerControlsState extends ConsumerState<PlayerControls> {
StreamSubscription? _timePositionListener; StreamSubscription? _timePositionListener;
late List<GlobalKeyActions> _hotKeys = []; late List<GlobalKeyActions> _hotKeys = [];
@ -88,7 +88,7 @@ class _PlayerControlsState extends State<PlayerControls> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
UserPreferences preferences = context.watch<UserPreferences>(); UserPreferences preferences = ref.watch(userPreferencesProvider);
_configureHotKeys(preferences); _configureHotKeys(preferences);
return Container( return Container(

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Playlist/PlaylistView.dart'; import 'package:spotube/components/Playlist/PlaylistView.dart';
import 'package:spotube/components/Shared/PlaybuttonCard.dart'; import 'package:spotube/components/Shared/PlaybuttonCard.dart';
@ -7,17 +7,17 @@ import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class PlaylistCard extends StatefulWidget { class PlaylistCard extends ConsumerStatefulWidget {
final PlaylistSimple playlist; final PlaylistSimple playlist;
const PlaylistCard(this.playlist, {Key? key}) : super(key: key); const PlaylistCard(this.playlist, {Key? key}) : super(key: key);
@override @override
_PlaylistCardState createState() => _PlaylistCardState(); _PlaylistCardState createState() => _PlaylistCardState();
} }
class _PlaylistCardState extends State<PlaylistCard> { class _PlaylistCardState extends ConsumerState<PlaylistCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
bool isPlaylistPlaying = playback.currentPlaylist != null && bool isPlaylistPlaying = playback.currentPlaylist != null &&
playback.currentPlaylist!.id == widget.playlist.id; playback.currentPlaylist!.id == widget.playlist.id;
return PlaybuttonCard( return PlaybuttonCard(
@ -33,13 +33,13 @@ class _PlaylistCardState extends State<PlaylistCard> {
}, },
onPlaybuttonPressed: () async { onPlaybuttonPressed: () async {
if (isPlaylistPlaying) return; if (isPlaylistPlaying) return;
SpotifyDI data = context.read<SpotifyDI>(); SpotifyApi spotifyApi = ref.read(spotifyProvider);
List<Track> tracks = (widget.playlist.id != "user-liked-tracks" List<Track> tracks = (widget.playlist.id != "user-liked-tracks"
? await data.spotifyApi.playlists ? await spotifyApi.playlists
.getTracksByPlaylistId(widget.playlist.id!) .getTracksByPlaylistId(widget.playlist.id!)
.all() .all()
: await data.spotifyApi.tracks.me.saved : await spotifyApi.tracks.me.saved
.all() .all()
.then((tracks) => tracks.map((e) => e.track!))) .then((tracks) => tracks.map((e) => e.track!)))
.toList(); .toList();

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
import 'package:spotube/components/Playlist/PlaylistCard.dart'; import 'package:spotube/components/Playlist/PlaylistCard.dart';
@ -33,16 +33,18 @@ class _PlaylistGenreViewState extends State<PlaylistGenreView> {
style: Theme.of(context).textTheme.headline4, style: Theme.of(context).textTheme.headline4,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
Consumer<SpotifyDI>( Consumer(
builder: (context, data, child) => Expanded( builder: (context, ref, child) {
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
return Expanded(
child: SingleChildScrollView( child: SingleChildScrollView(
child: FutureBuilder<Iterable<PlaylistSimple>>( child: FutureBuilder<Iterable<PlaylistSimple>>(
future: widget.playlists == null future: widget.playlists == null
? (widget.genreId != "user-featured-playlists" ? (widget.genreId != "user-featured-playlists"
? data.spotifyApi.playlists ? spotifyApi.playlists
.getByCategoryId(widget.genreId) .getByCategoryId(widget.genreId)
.all() .all()
: data.spotifyApi.playlists.featured.all()) : spotifyApi.playlists.featured.all())
: Future.value(widget.playlists), : Future.value(widget.playlists),
builder: (context, snapshot) { builder: (context, snapshot) {
if (snapshot.hasError) { if (snapshot.hasError) {
@ -65,7 +67,8 @@ class _PlaylistGenreViewState extends State<PlaylistGenreView> {
); );
}), }),
), ),
), );
},
) )
], ],
), ),

View File

@ -1,20 +1,20 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotube/components/Shared/PageWindowTitleBar.dart'; import 'package:spotube/components/Shared/PageWindowTitleBar.dart';
import 'package:spotube/components/Shared/TracksTableView.dart'; import 'package:spotube/components/Shared/TracksTableView.dart';
import 'package:spotube/helpers/image-to-url-string.dart'; import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class PlaylistView extends StatefulWidget { class PlaylistView extends ConsumerStatefulWidget {
final PlaylistSimple playlist; final PlaylistSimple playlist;
const PlaylistView(this.playlist, {Key? key}) : super(key: key); const PlaylistView(this.playlist, {Key? key}) : super(key: key);
@override @override
_PlaylistViewState createState() => _PlaylistViewState(); _PlaylistViewState createState() => _PlaylistViewState();
} }
class _PlaylistViewState extends State<PlaylistView> { class _PlaylistViewState extends ConsumerState<PlaylistView> {
playPlaylist(Playback playback, List<Track> tracks, {Track? currentTrack}) { playPlaylist(Playback playback, List<Track> tracks, {Track? currentTrack}) {
currentTrack ??= tracks.first; currentTrack ??= tracks.first;
var isPlaylistPlaying = playback.currentPlaylist?.id != null && var isPlaylistPlaying = playback.currentPlaylist?.id != null &&
@ -36,17 +36,17 @@ class _PlaylistViewState extends State<PlaylistView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
SpotifyApi spotifyApi = ref.watch(spotifyProvider);
var isPlaylistPlaying = playback.currentPlaylist?.id != null && var isPlaylistPlaying = playback.currentPlaylist?.id != null &&
playback.currentPlaylist?.id == widget.playlist.id; playback.currentPlaylist?.id == widget.playlist.id;
return Consumer<SpotifyDI>(builder: (_, data, __) {
return Scaffold( return Scaffold(
body: FutureBuilder<Iterable<Track>>( body: FutureBuilder<Iterable<Track>>(
future: widget.playlist.id != "user-liked-tracks" future: widget.playlist.id != "user-liked-tracks"
? data.spotifyApi.playlists ? spotifyApi.playlists
.getTracksByPlaylistId(widget.playlist.id) .getTracksByPlaylistId(widget.playlist.id)
.all() .all()
: data.spotifyApi.tracks.me.saved : spotifyApi.tracks.me.saved
.all() .all()
.then((tracks) => tracks.map((e) => e.track!)), .then((tracks) => tracks.map((e) => e.track!)),
builder: (context, snapshot) { builder: (context, snapshot) {
@ -101,6 +101,5 @@ class _PlaylistViewState extends State<PlaylistView> {
); );
}), }),
); );
});
} }
} }

View File

@ -1,5 +1,5 @@
import 'package:flutter/material.dart' hide Page; import 'package:flutter/material.dart' hide Page;
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Album/AlbumCard.dart'; import 'package:spotube/components/Album/AlbumCard.dart';
import 'package:spotube/components/Artist/ArtistCard.dart'; import 'package:spotube/components/Artist/ArtistCard.dart';
@ -11,14 +11,14 @@ import 'package:spotube/helpers/zero-pad-num-str.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart'; import 'package:spotube/provider/SpotifyDI.dart';
class Search extends StatefulWidget { class Search extends ConsumerStatefulWidget {
const Search({Key? key}) : super(key: key); const Search({Key? key}) : super(key: key);
@override @override
State<Search> createState() => _SearchState(); ConsumerState<Search> createState() => _SearchState();
} }
class _SearchState extends State<Search> { class _SearchState extends ConsumerState<Search> {
late TextEditingController _controller; late TextEditingController _controller;
String searchTerm = ""; String searchTerm = "";
@ -31,7 +31,7 @@ class _SearchState extends State<Search> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
SpotifyApi spotify = context.watch<SpotifyDI>().spotifyApi; SpotifyApi spotify = ref.watch(spotifyProvider);
return Expanded( return Expanded(
child: Column( child: Column(
@ -80,7 +80,7 @@ class _SearchState extends State<Search> {
} else if (!snapshot.hasData && searchTerm.isEmpty) { } else if (!snapshot.hasData && searchTerm.isEmpty) {
return Container(); return Container();
} }
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
List<AlbumSimple> albums = []; List<AlbumSimple> albums = [];
List<Artist> artists = []; List<Artist> artists = [];
List<Track> tracks = []; List<Track> tracks = [];

View File

@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/components/Settings/SettingsHotkeyTile.dart'; import 'package:spotube/components/Settings/SettingsHotkeyTile.dart';
import 'package:spotube/components/Shared/Hyperlink.dart'; import 'package:spotube/components/Shared/Hyperlink.dart';
@ -10,14 +9,14 @@ import 'package:spotube/models/LocalStorageKeys.dart';
import 'package:spotube/provider/Auth.dart'; import 'package:spotube/provider/Auth.dart';
import 'package:spotube/provider/UserPreferences.dart'; import 'package:spotube/provider/UserPreferences.dart';
class Settings extends StatefulWidget { class Settings extends ConsumerStatefulWidget {
const Settings({Key? key}) : super(key: key); const Settings({Key? key}) : super(key: key);
@override @override
_SettingsState createState() => _SettingsState(); _SettingsState createState() => _SettingsState();
} }
class _SettingsState extends State<Settings> { class _SettingsState extends ConsumerState<Settings> {
TextEditingController? _textEditingController; TextEditingController? _textEditingController;
String? _geniusAccessToken; String? _geniusAccessToken;
@ -40,7 +39,7 @@ class _SettingsState extends State<Settings> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
UserPreferences preferences = context.watch<UserPreferences>(); UserPreferences preferences = ref.watch(userPreferencesProvider);
return Scaffold( return Scaffold(
appBar: PageWindowTitleBar( appBar: PageWindowTitleBar(
@ -151,7 +150,7 @@ class _SettingsState extends State<Settings> {
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
Builder(builder: (context) { Builder(builder: (context) {
var auth = context.read<Auth>(); Auth auth = ref.watch(authProvider);
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [

View File

@ -1,6 +1,6 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Album/AlbumView.dart'; import 'package:spotube/components/Album/AlbumView.dart';
import 'package:spotube/components/Shared/LinkText.dart'; import 'package:spotube/components/Shared/LinkText.dart';
@ -9,7 +9,7 @@ import 'package:spotube/helpers/image-to-url-string.dart';
import 'package:spotube/helpers/zero-pad-num-str.dart'; import 'package:spotube/helpers/zero-pad-num-str.dart';
import 'package:spotube/provider/Playback.dart'; import 'package:spotube/provider/Playback.dart';
class TracksTableView extends StatelessWidget { class TracksTableView extends ConsumerWidget {
final void Function(Track currentTrack)? onTrackPlayButtonPressed; final void Function(Track currentTrack)? onTrackPlayButtonPressed;
final List<Track> tracks; final List<Track> tracks;
const TracksTableView(this.tracks, {Key? key, this.onTrackPlayButtonPressed}) const TracksTableView(this.tracks, {Key? key, this.onTrackPlayButtonPressed})
@ -97,8 +97,8 @@ class TracksTableView extends StatelessWidget {
} }
@override @override
Widget build(BuildContext context) { Widget build(context, ref) {
Playback playback = context.watch<Playback>(); Playback playback = ref.watch(playbackProvider);
TextStyle tableHeadStyle = TextStyle tableHeadStyle =
const TextStyle(fontWeight: FontWeight.bold, fontSize: 16); const TextStyle(fontWeight: FontWeight.bold, fontSize: 16);
return Expanded( return Expanded(

View File

@ -1,5 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Home.dart'; import 'package:spotube/components/Home.dart';
@ -9,7 +7,7 @@ import 'package:spotube/provider/Auth.dart';
const redirectUri = "http://localhost:4304/auth/spotify/callback"; const redirectUri = "http://localhost:4304/auth/spotify/callback";
Future<void> oauthLogin(BuildContext context, Future<void> oauthLogin(Auth auth,
{required String clientId, required String clientSecret}) async { {required String clientId, required String clientSecret}) async {
try { try {
String? accessToken; String? accessToken;
@ -50,7 +48,7 @@ Future<void> oauthLogin(BuildContext context,
clientSecret, clientSecret,
); );
Provider.of<Auth>(context, listen: false).setAuthState( auth.setAuthState(
clientId: clientId, clientId: clientId,
clientSecret: clientSecret, clientSecret: clientSecret,
accessToken: accessToken, accessToken: accessToken,

View File

@ -1,20 +1,15 @@
import 'package:bitsdojo_window/bitsdojo_window.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotify/spotify.dart';
import 'package:spotube/components/Home.dart'; import 'package:spotube/components/Home.dart';
import 'package:spotube/models/LocalStorageKeys.dart'; import 'package:spotube/models/LocalStorageKeys.dart';
import 'package:spotube/provider/Auth.dart';
import 'package:spotube/provider/Playback.dart';
import 'package:spotube/provider/SpotifyDI.dart';
import 'package:spotube/provider/UserPreferences.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await hotKeyManager.unregisterAll(); await hotKeyManager.unregisterAll();
runApp(MyApp()); runApp(const ProviderScope(child: MyApp()));
doWhenWindowReady(() { doWhenWindowReady(() {
appWindow.minSize = const Size(900, 700); appWindow.minSize = const Size(900, 700);
appWindow.size = const Size(900, 700); appWindow.size = const Size(900, 700);
@ -25,6 +20,8 @@ void main() async {
} }
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
static _MyAppState? of(BuildContext context) => static _MyAppState? of(BuildContext context) =>
context.findAncestorStateOfType<_MyAppState>(); context.findAncestorStateOfType<_MyAppState>();
@override @override
@ -72,50 +69,7 @@ class _MyAppState extends State<MyApp> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MultiProvider( return MaterialApp(
providers: [
ChangeNotifierProvider<Auth>(create: (context) => Auth()),
ChangeNotifierProvider<SpotifyDI>(create: (context) {
Auth authState = Provider.of<Auth>(context, listen: false);
return SpotifyDI(
SpotifyApi(
SpotifyApiCredentials(
authState.clientId,
authState.clientSecret,
accessToken: authState.accessToken,
refreshToken: authState.refreshToken,
expiration: authState.expiration,
scopes: spotifyScopes,
),
onCredentialsRefreshed: (credentials) async {
SharedPreferences localStorage =
await SharedPreferences.getInstance();
localStorage.setString(
LocalStorageKeys.refreshToken,
credentials.refreshToken!,
);
localStorage.setString(
LocalStorageKeys.accessToken,
credentials.accessToken!,
);
localStorage.setString(
LocalStorageKeys.clientId, credentials.clientId!);
localStorage.setString(
LocalStorageKeys.clientSecret,
credentials.clientSecret!,
);
},
),
);
}),
ChangeNotifierProvider<Playback>(create: (context) => Playback()),
ChangeNotifierProvider<UserPreferences>(
create: (context) {
return UserPreferences();
},
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: 'Spotube', title: 'Spotube',
theme: ThemeData( theme: ThemeData(
@ -204,7 +158,6 @@ class _MyAppState extends State<MyApp> {
), ),
themeMode: _themeMode, themeMode: _themeMode,
home: const Home(), home: const Home(),
),
); );
} }
} }

View File

@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class Auth with ChangeNotifier { class Auth with ChangeNotifier {
String? _clientId; String? _clientId;
@ -52,3 +53,5 @@ class Auth with ChangeNotifier {
notifyListeners(); notifyListeners();
} }
} }
var authProvider = ChangeNotifierProvider<Auth>((ref) => Auth());

View File

@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
class CurrentPlaylist { class CurrentPlaylist {
@ -77,4 +78,4 @@ class Playback extends ChangeNotifier {
} }
} }
var x = Playback(); var playbackProvider = ChangeNotifierProvider<Playback>((_) => Playback());

View File

@ -1,10 +1,36 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotify/spotify.dart'; import 'package:spotify/spotify.dart';
import 'package:spotube/components/Home.dart';
import 'package:spotube/models/LocalStorageKeys.dart';
import 'package:spotube/provider/Auth.dart';
class SpotifyDI extends ChangeNotifier { var spotifyProvider = Provider<SpotifyApi>((ref) {
SpotifyApi _spotifyApi; Auth authState = ref.watch(authProvider);
return SpotifyApi(
SpotifyDI(this._spotifyApi); SpotifyApiCredentials(
authState.clientId,
SpotifyApi get spotifyApi => _spotifyApi; authState.clientSecret,
} accessToken: authState.accessToken,
refreshToken: authState.refreshToken,
expiration: authState.expiration,
scopes: spotifyScopes,
),
onCredentialsRefreshed: (credentials) async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
localStorage.setString(
LocalStorageKeys.refreshToken,
credentials.refreshToken!,
);
localStorage.setString(
LocalStorageKeys.accessToken,
credentials.accessToken!,
);
localStorage.setString(LocalStorageKeys.clientId, credentials.clientId!);
localStorage.setString(
LocalStorageKeys.clientSecret,
credentials.clientSecret!,
);
},
);
});

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:hotkey_manager/hotkey_manager.dart'; import 'package:hotkey_manager/hotkey_manager.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:spotube/models/LocalStorageKeys.dart'; import 'package:spotube/models/LocalStorageKeys.dart';
@ -110,3 +111,5 @@ class UserPreferences extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
} }
var userPreferencesProvider = ChangeNotifierProvider((_) => UserPreferences());

View File

@ -195,6 +195,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.4" version: "1.0.4"
flutter_riverpod:
dependency: "direct main"
description:
name: flutter_riverpod
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -338,13 +345,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.1" version: "2.8.1"
nested:
dependency: transitive
description:
name: nested
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
oauth2: oauth2:
dependency: transitive dependency: transitive
description: description:
@ -457,13 +457,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.2.4" version: "4.2.4"
provider: riverpod:
dependency: "direct main" dependency: transitive
description: description:
name: provider name: riverpod
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "6.0.1" version: "1.0.3"
rxdart: rxdart:
dependency: transitive dependency: transitive
description: description:
@ -574,6 +574,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0" version: "1.10.0"
state_notifier:
dependency: transitive
description:
name: state_notifier
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.2+1"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:

View File

@ -37,7 +37,6 @@ dependencies:
cached_network_image: ^3.2.0 cached_network_image: ^3.2.0
html: ^0.15.0 html: ^0.15.0
http: ^0.13.4 http: ^0.13.4
provider: ^6.0.1
shared_preferences: ^2.0.11 shared_preferences: ^2.0.11
spotify: ^0.6.0 spotify: ^0.6.0
url_launcher: ^6.0.17 url_launcher: ^6.0.17
@ -50,6 +49,7 @@ dependencies:
path: ^1.8.0 path: ^1.8.0
path_provider: ^2.0.8 path_provider: ^2.0.8
collection: ^1.15.0 collection: ^1.15.0
flutter_riverpod: ^1.0.3
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: