mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
refactor: more elegant playlist create button
This commit is contained in:
parent
92a418c8a8
commit
6535345c1c
@ -6,6 +6,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
|
|
||||||
import 'package:spotify/spotify.dart';
|
import 'package:spotify/spotify.dart';
|
||||||
import 'package:spotube/collections/spotube_icons.dart';
|
import 'package:spotube/collections/spotube_icons.dart';
|
||||||
|
import 'package:spotube/components/playlist/playlist_create_dialog.dart';
|
||||||
import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart';
|
import 'package:spotube/components/shared/shimmers/shimmer_playbutton_card.dart';
|
||||||
import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart';
|
import 'package:spotube/components/shared/fallbacks/anonymous_fallback.dart';
|
||||||
import 'package:spotube/components/playlist/playlist_card.dart';
|
import 'package:spotube/components/playlist/playlist_card.dart';
|
||||||
@ -82,22 +83,32 @@ class UserPlaylists extends HookConsumerWidget {
|
|||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
Padding(
|
||||||
onChanged: (value) => searchText.value = value,
|
padding: const EdgeInsets.all(10),
|
||||||
decoration: const InputDecoration(
|
child: TextField(
|
||||||
hintText: "Filter your playlists...",
|
onChanged: (value) => searchText.value = value,
|
||||||
prefixIcon: Icon(SpotubeIcons.filter),
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Filter your playlists...",
|
||||||
|
prefixIcon: Icon(SpotubeIcons.filter),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
|
||||||
if (playlistsQuery.isLoading || !playlistsQuery.hasData)
|
if (playlistsQuery.isLoading || !playlistsQuery.hasData)
|
||||||
const Center(child: ShimmerPlaybuttonCard(count: 7))
|
const Center(child: ShimmerPlaybuttonCard(count: 7))
|
||||||
else
|
else
|
||||||
Wrap(
|
Wrap(
|
||||||
runSpacing: 10,
|
runSpacing: 10,
|
||||||
children: playlists
|
alignment: WrapAlignment.center,
|
||||||
.map((playlist) => PlaylistCard(playlist))
|
children: [
|
||||||
.toList(),
|
Row(
|
||||||
|
children: const [
|
||||||
|
SizedBox(width: 10),
|
||||||
|
PlaylistCreateDialog(),
|
||||||
|
SizedBox(width: 10),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
...playlists.map((playlist) => PlaylistCard(playlist))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -13,110 +13,98 @@ class PlaylistCreateDialog extends HookConsumerWidget {
|
|||||||
Widget build(BuildContext context, ref) {
|
Widget build(BuildContext context, ref) {
|
||||||
final spotify = ref.watch(spotifyProvider);
|
final spotify = ref.watch(spotifyProvider);
|
||||||
|
|
||||||
return SizedBox(
|
return FilledButton.tonalIcon(
|
||||||
width: 200,
|
style: FilledButton.styleFrom(
|
||||||
child: TextButton(
|
foregroundColor: Theme.of(context).colorScheme.primary,
|
||||||
onPressed: () {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return HookBuilder(builder: (context) {
|
|
||||||
final playlistName = useTextEditingController();
|
|
||||||
final description = useTextEditingController();
|
|
||||||
final public = useState(false);
|
|
||||||
final collaborative = useState(false);
|
|
||||||
final client = useQueryClient();
|
|
||||||
final navigator = Navigator.of(context);
|
|
||||||
|
|
||||||
onCreate() async {
|
|
||||||
if (playlistName.text.isEmpty) return;
|
|
||||||
final me = await spotify.me.get();
|
|
||||||
await spotify.playlists.createPlaylist(
|
|
||||||
me.id!,
|
|
||||||
playlistName.text,
|
|
||||||
collaborative: collaborative.value,
|
|
||||||
public: public.value,
|
|
||||||
description: description.text,
|
|
||||||
);
|
|
||||||
await client
|
|
||||||
.getQuery(
|
|
||||||
"current-user-playlists",
|
|
||||||
)
|
|
||||||
?.refresh();
|
|
||||||
navigator.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text("Create a Playlist"),
|
|
||||||
actions: [
|
|
||||||
OutlinedButton(
|
|
||||||
child: const Text("Cancel"),
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FilledButton(
|
|
||||||
onPressed: onCreate,
|
|
||||||
child: const Text("Create"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
content: Container(
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
constraints: const BoxConstraints(maxWidth: 500),
|
|
||||||
child: ListView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
children: [
|
|
||||||
TextField(
|
|
||||||
controller: playlistName,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
hintText: "Name of the playlist",
|
|
||||||
labelText: "Playlist Name",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
TextField(
|
|
||||||
controller: description,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
hintText: "Description...",
|
|
||||||
),
|
|
||||||
keyboardType: TextInputType.multiline,
|
|
||||||
maxLines: 5,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
CheckboxListTile(
|
|
||||||
title: const Text("Public"),
|
|
||||||
value: public.value,
|
|
||||||
onChanged: (val) => public.value = val ?? false,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
CheckboxListTile(
|
|
||||||
title: const Text("Collaborative"),
|
|
||||||
value: collaborative.value,
|
|
||||||
onChanged: (val) =>
|
|
||||||
collaborative.value = val ?? false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
style: ButtonStyle(
|
|
||||||
padding: MaterialStateProperty.all(
|
|
||||||
const EdgeInsets.symmetric(vertical: 100),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: const [
|
|
||||||
Icon(SpotubeIcons.addFilled, size: 40),
|
|
||||||
Text("Create Playlist", style: TextStyle(fontSize: 20)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
icon: const Icon(SpotubeIcons.addFilled),
|
||||||
|
label: const Text("Create Playlist"),
|
||||||
|
onPressed: () {
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return HookBuilder(builder: (context) {
|
||||||
|
final playlistName = useTextEditingController();
|
||||||
|
final description = useTextEditingController();
|
||||||
|
final public = useState(false);
|
||||||
|
final collaborative = useState(false);
|
||||||
|
final client = useQueryClient();
|
||||||
|
final navigator = Navigator.of(context);
|
||||||
|
|
||||||
|
onCreate() async {
|
||||||
|
if (playlistName.text.isEmpty) return;
|
||||||
|
final me = await spotify.me.get();
|
||||||
|
await spotify.playlists.createPlaylist(
|
||||||
|
me.id!,
|
||||||
|
playlistName.text,
|
||||||
|
collaborative: collaborative.value,
|
||||||
|
public: public.value,
|
||||||
|
description: description.text,
|
||||||
|
);
|
||||||
|
await client
|
||||||
|
.getQuery(
|
||||||
|
"current-user-playlists",
|
||||||
|
)
|
||||||
|
?.refresh();
|
||||||
|
navigator.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return AlertDialog(
|
||||||
|
title: const Text("Create a Playlist"),
|
||||||
|
actions: [
|
||||||
|
OutlinedButton(
|
||||||
|
child: const Text("Cancel"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FilledButton(
|
||||||
|
onPressed: onCreate,
|
||||||
|
child: const Text("Create"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
content: Container(
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
constraints: const BoxConstraints(maxWidth: 500),
|
||||||
|
child: ListView(
|
||||||
|
shrinkWrap: true,
|
||||||
|
children: [
|
||||||
|
TextField(
|
||||||
|
controller: playlistName,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Name of the playlist",
|
||||||
|
labelText: "Playlist Name",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
TextField(
|
||||||
|
controller: description,
|
||||||
|
decoration: const InputDecoration(
|
||||||
|
hintText: "Description...",
|
||||||
|
),
|
||||||
|
keyboardType: TextInputType.multiline,
|
||||||
|
maxLines: 5,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
CheckboxListTile(
|
||||||
|
title: const Text("Public"),
|
||||||
|
value: public.value,
|
||||||
|
onChanged: (val) => public.value = val ?? false,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 10),
|
||||||
|
CheckboxListTile(
|
||||||
|
title: const Text("Collaborative"),
|
||||||
|
value: collaborative.value,
|
||||||
|
onChanged: (val) => collaborative.value = val ?? false,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user