mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
fix: categories not showing for oauth exception, maximized window size is stored
feat: UserLibrary and UserAlbums using fl_query
This commit is contained in:
parent
3e498a4827
commit
4df917e65e
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fl_query/fl_query.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
@ -120,7 +121,9 @@ class AlbumView extends HookConsumerWidget {
|
|||||||
album.id!,
|
album.id!,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
ref.refresh(currentUserAlbumsQuery);
|
QueryBowl.of(context).refetchQueries(
|
||||||
|
[currentUserAlbumsQueryJob.queryKey],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -1,34 +1,39 @@
|
|||||||
|
import 'package:fl_query_hooks/fl_query_hooks.dart';
|
||||||
import 'package:flutter/material.dart' hide Image;
|
import 'package:flutter/material.dart' hide Image;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotube/components/Album/AlbumCard.dart';
|
import 'package:spotube/components/Album/AlbumCard.dart';
|
||||||
import 'package:spotube/components/LoaderShimmers/ShimmerPlaybuttonCard.dart';
|
import 'package:spotube/components/LoaderShimmers/ShimmerPlaybuttonCard.dart';
|
||||||
|
import 'package:spotube/provider/SpotifyDI.dart';
|
||||||
import 'package:spotube/provider/SpotifyRequests.dart';
|
import 'package:spotube/provider/SpotifyRequests.dart';
|
||||||
import 'package:spotube/utils/type_conversion_utils.dart';
|
import 'package:spotube/utils/type_conversion_utils.dart';
|
||||||
|
|
||||||
class UserAlbums extends ConsumerWidget {
|
class UserAlbums extends HookConsumerWidget {
|
||||||
const UserAlbums({Key? key}) : super(key: key);
|
const UserAlbums({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final albums = ref.watch(currentUserAlbumsQuery);
|
final albumsQuery = useQuery(
|
||||||
|
job: currentUserAlbumsQueryJob,
|
||||||
|
externalData: ref.watch(spotifyProvider),
|
||||||
|
);
|
||||||
|
|
||||||
return albums.when(
|
if (albumsQuery.isLoading || !albumsQuery.hasData) {
|
||||||
data: (data) => SingleChildScrollView(
|
return const Center(child: ShimmerPlaybuttonCard(count: 7));
|
||||||
|
}
|
||||||
|
|
||||||
|
return SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 20, // gap between adjacent chips
|
spacing: 20, // gap between adjacent chips
|
||||||
runSpacing: 20, // gap between lines
|
runSpacing: 20, // gap between lines
|
||||||
alignment: WrapAlignment.center,
|
alignment: WrapAlignment.center,
|
||||||
children: data
|
children: albumsQuery.data!
|
||||||
.map((album) =>
|
.map((album) =>
|
||||||
AlbumCard(TypeConversionUtils.simpleAlbum_X_Album(album)))
|
AlbumCard(TypeConversionUtils.simpleAlbum_X_Album(album)))
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
loading: () => const Center(child: ShimmerPlaybuttonCard(count: 7)),
|
|
||||||
error: (_, __) => const Text("Failure is the pillar of success"),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
|
import 'package:fl_query_hooks/fl_query_hooks.dart';
|
||||||
import 'package:flutter/material.dart' hide Image;
|
import 'package:flutter/material.dart' hide Image;
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/components/LoaderShimmers/ShimmerPlaybuttonCard.dart';
|
import 'package:spotube/components/LoaderShimmers/ShimmerPlaybuttonCard.dart';
|
||||||
import 'package:spotube/components/Playlist/PlaylistCard.dart';
|
import 'package:spotube/components/Playlist/PlaylistCard.dart';
|
||||||
import 'package:spotube/components/Playlist/PlaylistCreateDialog.dart';
|
import 'package:spotube/components/Playlist/PlaylistCreateDialog.dart';
|
||||||
|
import 'package:spotube/provider/SpotifyDI.dart';
|
||||||
import 'package:spotube/provider/SpotifyRequests.dart';
|
import 'package:spotube/provider/SpotifyRequests.dart';
|
||||||
|
|
||||||
class UserPlaylists extends ConsumerWidget {
|
class UserPlaylists extends HookConsumerWidget {
|
||||||
const UserPlaylists({Key? key}) : super(key: key);
|
const UserPlaylists({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final playlists = ref.watch(currentUserPlaylistsQuery);
|
final playlistsQuery = useQuery(
|
||||||
|
job: currentUserPlaylistsQueryJob,
|
||||||
return playlists.when(
|
externalData: ref.watch(spotifyProvider),
|
||||||
loading: () => const Center(child: ShimmerPlaybuttonCard(count: 7)),
|
);
|
||||||
data: (data) {
|
|
||||||
Image image = Image();
|
Image image = Image();
|
||||||
image.height = 300;
|
image.height = 300;
|
||||||
image.width = 300;
|
image.width = 300;
|
||||||
@ -25,9 +26,13 @@ class UserPlaylists extends ConsumerWidget {
|
|||||||
likedTracksPlaylist.collaborative = false;
|
likedTracksPlaylist.collaborative = false;
|
||||||
likedTracksPlaylist.public = false;
|
likedTracksPlaylist.public = false;
|
||||||
likedTracksPlaylist.id = "user-liked-tracks";
|
likedTracksPlaylist.id = "user-liked-tracks";
|
||||||
image.url =
|
image.url = "https://t.scdn.co/images/3099b3803ad9496896c43f22fe9be8c4.png";
|
||||||
"https://t.scdn.co/images/3099b3803ad9496896c43f22fe9be8c4.png";
|
|
||||||
likedTracksPlaylist.images = [image];
|
likedTracksPlaylist.images = [image];
|
||||||
|
|
||||||
|
if (playlistsQuery.isLoading || !playlistsQuery.hasData) {
|
||||||
|
return const Center(child: ShimmerPlaybuttonCard(count: 7));
|
||||||
|
}
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@ -38,12 +43,12 @@ class UserPlaylists extends ConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
const PlaylistCreateDialog(),
|
const PlaylistCreateDialog(),
|
||||||
PlaylistCard(likedTracksPlaylist),
|
PlaylistCard(likedTracksPlaylist),
|
||||||
...data.map((playlist) => PlaylistCard(playlist)).toList(),
|
...playlistsQuery.data!
|
||||||
|
.map((playlist) => PlaylistCard(playlist))
|
||||||
|
.toList(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
|
||||||
error: (_, __) => const Text("Failure is the pillar of success"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:fl_query/fl_query.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@ -51,7 +52,9 @@ class PlaylistCreateDialog extends HookConsumerWidget {
|
|||||||
description: description.text,
|
description: description.text,
|
||||||
)
|
)
|
||||||
.then((_) {
|
.then((_) {
|
||||||
ref.refresh(currentUserPlaylistsQuery);
|
QueryBowl.of(context).refetchQueries([
|
||||||
|
currentUserPlaylistsQueryJob.queryKey,
|
||||||
|
]);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:fl_query/fl_query.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
@ -146,7 +147,9 @@ class PlaylistView extends HookConsumerWidget {
|
|||||||
logger.e("FollowButton.onPressed", e, stack);
|
logger.e("FollowButton.onPressed", e, stack);
|
||||||
} finally {
|
} finally {
|
||||||
ref.refresh(query);
|
ref.refresh(query);
|
||||||
ref.refresh(currentUserPlaylistsQuery);
|
QueryBowl.of(context).refetchQueries([
|
||||||
|
currentUserPlaylistsQueryJob.queryKey,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -170,6 +170,7 @@ class _SpotubeState extends ConsumerState<Spotube> with WidgetsBindingObserver {
|
|||||||
prevSize?.height == appWindow.size.height;
|
prevSize?.height == appWindow.size.height;
|
||||||
|
|
||||||
if (localStorage == null || windowSameDimension || kIsMobile) return;
|
if (localStorage == null || windowSameDimension || kIsMobile) return;
|
||||||
|
if (appWindow.isMaximized) return;
|
||||||
localStorage!.setString(
|
localStorage!.setString(
|
||||||
LocalStorageKeys.windowSizeInfo,
|
LocalStorageKeys.windowSizeInfo,
|
||||||
jsonEncode({
|
jsonEncode({
|
||||||
|
@ -95,16 +95,18 @@ class Auth extends PersistedChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<void> loadFromLocal(Map<String, dynamic> map) {
|
FutureOr<void> loadFromLocal(Map<String, dynamic> map) async {
|
||||||
_accessToken = map["accessToken"];
|
_accessToken = map["accessToken"];
|
||||||
_expiration = map["expiration"] != null
|
_expiration = map["expiration"] != null
|
||||||
? DateTime.tryParse(map["expiration"])
|
? DateTime.tryParse(map["expiration"])
|
||||||
: _expiration;
|
: _expiration;
|
||||||
_authCookie = map["authCookie"];
|
_authCookie = map["authCookie"];
|
||||||
_restartRefresher();
|
|
||||||
if (isExpired) {
|
if (isExpired) {
|
||||||
refresh();
|
final data = await ServiceUtils.getAccessToken(authCookie!);
|
||||||
|
_accessToken = data.accessToken;
|
||||||
|
_expiration = data.expiration;
|
||||||
}
|
}
|
||||||
|
_restartRefresher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -45,16 +45,17 @@ final categoryPlaylistsQueryJob =
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final currentUserPlaylistsQuery = FutureProvider<Iterable<PlaylistSimple>>(
|
final currentUserPlaylistsQueryJob =
|
||||||
(ref) {
|
QueryJob<Iterable<PlaylistSimple>, SpotifyApi>(
|
||||||
final spotify = ref.watch(spotifyProvider);
|
queryKey: "current-user-query",
|
||||||
|
task: (_, spotify) {
|
||||||
return spotify.playlists.me.all();
|
return spotify.playlists.me.all();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
final currentUserAlbumsQuery = FutureProvider<Iterable<AlbumSimple>>(
|
final currentUserAlbumsQueryJob = QueryJob<Iterable<AlbumSimple>, SpotifyApi>(
|
||||||
(ref) {
|
queryKey: "current-user-albums",
|
||||||
final spotify = ref.watch(spotifyProvider);
|
task: (_, spotify) {
|
||||||
return spotify.me.savedAlbums().all();
|
return spotify.me.savedAlbums().all();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user