Skip to content

Commit

Permalink
fix(auth): refresh access token timer not working
Browse files Browse the repository at this point in the history
refactor: use fl_query for spotify API instead of riverpod
  • Loading branch information
KRTirtho committed Oct 23, 2022
1 parent b5144df commit b3ac5ca
Show file tree
Hide file tree
Showing 17 changed files with 615 additions and 374 deletions.
48 changes: 13 additions & 35 deletions lib/components/Album/AlbumView.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:fl_query/fl_query.dart';
import 'package:fl_query_hooks/fl_query_hooks.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
Expand Down Expand Up @@ -57,9 +58,14 @@ class AlbumView extends HookConsumerWidget {
final SpotifyApi spotify = ref.watch(spotifyProvider);
final Auth auth = ref.watch(authProvider);

final tracksSnapshot = ref.watch(albumTracksQuery(album.id!));
final albumSavedSnapshot =
ref.watch(albumIsSavedForCurrentUserQuery(album.id!));
final tracksSnapshot = useQuery(
job: albumTracksQueryJob(album.id!),
externalData: spotify,
);
final albumSavedSnapshot = useQuery(
job: albumIsSavedForCurrentUserQueryJob(album.id!),
externalData: spotify,
);

final albumArt = useMemoized(
() => TypeConversionUtils.image_X_UrlString(
Expand All @@ -82,11 +88,11 @@ class AlbumView extends HookConsumerWidget {
routePath: "/album/${album.id}",
bottomSpace: breakpoint.isLessThanOrEqualTo(Breakpoints.md),
onPlay: ([track]) {
if (tracksSnapshot.asData?.value != null) {
if (tracksSnapshot.hasData) {
if (!isAlbumPlaying) {
playPlaylist(
playback,
tracksSnapshot.asData!.value
tracksSnapshot.data!
.map((track) =>
TypeConversionUtils.simpleTrack_X_Track(track, album))
.toList(),
Expand All @@ -95,7 +101,7 @@ class AlbumView extends HookConsumerWidget {
} else if (isAlbumPlaying && track != null) {
playPlaylist(
playback,
tracksSnapshot.asData!.value
tracksSnapshot.data!
.map((track) =>
TypeConversionUtils.simpleTrack_X_Track(track, album))
.toList(),
Expand All @@ -112,35 +118,7 @@ class AlbumView extends HookConsumerWidget {
ClipboardData(text: "https://open.spotify.com/album/${album.id}"),
);
},
heartBtn: auth.isLoggedIn
? albumSavedSnapshot.when(
data: (isSaved) {
return HeartButton(
isLiked: isSaved,
onPressed: () {
(isSaved
? spotify.me.removeAlbums(
[album.id!],
)
: spotify.me.saveAlbums(
[album.id!],
))
.whenComplete(() {
ref.refresh(
albumIsSavedForCurrentUserQuery(
album.id!,
),
);
QueryBowl.of(context).refetchQueries(
[currentUserAlbumsQueryJob.queryKey],
);
});
},
);
},
error: (error, _) => Text("Error $error"),
loading: () => const CircularProgressIndicator())
: null,
heartBtn: AlbumHeartButton(album: album),
);
}
}
160 changes: 102 additions & 58 deletions lib/components/Artist/ArtistProfile.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:fl_query/fl_query.dart';
import 'package:fl_query_hooks/fl_query_hooks.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
Expand Down Expand Up @@ -49,20 +51,28 @@ class ArtistProfile extends HookConsumerWidget {

final Playback playback = ref.watch(playbackProvider);

final artistsSnapshot = ref.watch(artistProfileQuery(artistId));
final isFollowingSnapshot =
ref.watch(currentUserFollowsArtistQuery(artistId));
final topTracksSnapshot = ref.watch(artistTopTracksQuery(artistId));

final relatedArtists = ref.watch(artistRelatedArtistsQuery(artistId));

return SafeArea(
child: Scaffold(
appBar: const PageWindowTitleBar(
leading: BackButton(),
),
body: artistsSnapshot.when<Widget>(
data: (data) {
body: HookBuilder(
builder: (context) {
final artistsQuery = useQuery(
job: artistProfileQueryJob(artistId),
externalData: spotify,
);

if (artistsQuery.isLoading || !artistsQuery.hasData) {
return const ShimmerArtistProfile();
} else if (artistsQuery.hasError) {
return Center(
child: Text(artistsQuery.error.toString()),
);
}

final data = artistsQuery.data!;

return SingleChildScrollView(
controller: parentScrollController,
padding: const EdgeInsets.all(20),
Expand Down Expand Up @@ -115,42 +125,57 @@ class ArtistProfile extends HookConsumerWidget {
Row(
mainAxisSize: MainAxisSize.min,
children: [
isFollowingSnapshot.when(
data: (isFollowing) {
return OutlinedButton(
onPressed: () async {
try {
isFollowing
? await spotify.me.unfollow(
FollowingType.artist,
[artistId],
)
: await spotify.me.follow(
FollowingType.artist,
[artistId],
);
} catch (e, stack) {
logger.e(
"FollowButton.onPressed",
e,
stack,
);
} finally {
ref.refresh(
currentUserFollowsArtistQuery(
artistId),
);
}
},
child: Text(
isFollowing ? "Following" : "Follow",
),
HookBuilder(
builder: (context) {
final isFollowingQuery = useQuery(
job: currentUserFollowsArtistQueryJob(
artistId),
externalData: spotify,
);

if (isFollowingQuery.isLoading ||
!isFollowingQuery.hasData) {
return const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(),
);
},
error: (error, stackTrace) => Container(),
loading: () =>
const CircularProgressIndicator
.adaptive()),
}

return OutlinedButton(
onPressed: () async {
try {
isFollowingQuery.data!
? await spotify.me.unfollow(
FollowingType.artist,
[artistId],
)
: await spotify.me.follow(
FollowingType.artist,
[artistId],
);
} catch (e, stack) {
logger.e(
"FollowButton.onPressed",
e,
stack,
);
} finally {
QueryBowl.of(context).refetchQueries([
currentUserFollowsArtistQueryJob(
artistId)
.queryKey,
]);
}
},
child: Text(
isFollowingQuery.data!
? "Following"
: "Follow",
),
);
},
),
IconButton(
icon: const Icon(Icons.share_rounded),
onPressed: () {
Expand Down Expand Up @@ -180,8 +205,23 @@ class ArtistProfile extends HookConsumerWidget {
],
),
const SizedBox(height: 50),
topTracksSnapshot.when(
data: (topTracks) {
HookBuilder(
builder: (context) {
final topTracksQuery = useQuery(
job: artistTopTracksQueryJob(artistId),
externalData: spotify,
);

if (topTracksQuery.isLoading || !topTracksQuery.hasData) {
return const CircularProgressIndicator.adaptive();
} else if (topTracksQuery.hasError) {
return Center(
child: Text(topTracksQuery.error.toString()),
);
}

final topTracks = topTracksQuery.data!;

final isPlaylistPlaying =
playback.playlist?.id == data.id;
playPlaylist(List<Track> tracks,
Expand Down Expand Up @@ -248,10 +288,6 @@ class ArtistProfile extends HookConsumerWidget {
}),
]);
},
error: (error, stack) =>
Text("Failed to find top tracks $error"),
loading: () => const Center(
child: CircularProgressIndicator.adaptive()),
),
const SizedBox(height: 50),
Text(
Expand All @@ -266,28 +302,36 @@ class ArtistProfile extends HookConsumerWidget {
style: Theme.of(context).textTheme.headline4,
),
const SizedBox(height: 10),
relatedArtists.when(
data: (artists) {
HookBuilder(
builder: (context) {
final relatedArtists = useQuery(
job: artistRelatedArtistsQueryJob(artistId),
externalData: spotify,
);

if (relatedArtists.isLoading || !relatedArtists.hasData) {
return const CircularProgressIndicator.adaptive();
} else if (relatedArtists.hasError) {
return Center(
child: Text(relatedArtists.error.toString()),
);
}

return Center(
child: Wrap(
spacing: 20,
runSpacing: 20,
children: artists
children: relatedArtists.data!
.map((artist) => ArtistCard(artist))
.toList(),
),
);
},
error: (error, stackTrack) =>
Text("Failed to get Artist albums $error"),
loading: () => const CircularProgressIndicator.adaptive(),
),
],
),
);
},
error: (_, __) => const Text("Life's miserable"),
loading: () => const ShimmerArtistProfile(),
),
),
);
Expand Down
21 changes: 18 additions & 3 deletions lib/components/Home/Sidebar.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:badges/badges.dart';
import 'package:bitsdojo_window/bitsdojo_window.dart';
import 'package:fl_query_hooks/fl_query_hooks.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:go_router/go_router.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
Expand All @@ -9,6 +10,7 @@ import 'package:spotube/hooks/useBreakpoints.dart';
import 'package:spotube/models/sideBarTiles.dart';
import 'package:spotube/provider/Auth.dart';
import 'package:spotube/provider/Downloader.dart';
import 'package:spotube/provider/SpotifyDI.dart';
import 'package:spotube/provider/SpotifyRequests.dart';
import 'package:spotube/provider/UserPreferences.dart';
import 'package:spotube/utils/platform.dart';
Expand Down Expand Up @@ -42,7 +44,7 @@ class Sidebar extends HookConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) {
final breakpoints = useBreakpoints();
final extended = useState(false);
final meSnapshot = ref.watch(currentUserQuery);

final auth = ref.watch(authProvider);
final downloadCount = ref.watch(
downloaderProvider.select((s) => s.currentlyRunning),
Expand Down Expand Up @@ -161,15 +163,28 @@ class Sidebar extends HookConsumerWidget {
),
SizedBox(
width: extended.value ? 256 : 80,
child: Builder(
child: HookBuilder(
builder: (context) {
final data = meSnapshot.asData?.value;
final me = useQuery(
job: currentUserQueryJob,
externalData: ref.watch(spotifyProvider),
);
final data = me.data;

final avatarImg = TypeConversionUtils.image_X_UrlString(
data?.images,
index: (data?.images?.length ?? 1) - 1,
placeholder: ImagePlaceholder.artist,
);

useEffect(() {
if (auth.isLoggedIn && !me.hasData) {
me.setExternalData(ref.read(spotifyProvider));
me.refetch();
}
return;
}, [auth.isLoggedIn, me.hasData]);

if (extended.value) {
return Padding(
padding: const EdgeInsets.all(16).copyWith(left: 0),
Expand Down
Loading

0 comments on commit b3ac5ca

Please sign in to comment.