songs.dart 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import 'dart:convert';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/widgets.dart';
  4. import 'package:http/http.dart' as http;
  5. import '../config.dart';
  6. import '../types/song.dart';
  7. import './spinner.dart';
  8. class Songs extends StatefulWidget {
  9. final String artist;
  10. final String album;
  11. final void Function(int) onSelect;
  12. Songs({
  13. @required this.artist, // can be an empty string
  14. @required this.album, // can be an empty string
  15. @required this.onSelect,
  16. });
  17. @override
  18. _SongsWidgetState createState() => _SongsWidgetState(
  19. artist: this.artist,
  20. album: this.album,
  21. onSelect: this.onSelect,
  22. );
  23. }
  24. Future<List<Song>> fetchSongs(String artist) async {
  25. final response = await http.get(Uri.https(config['apiUrl'], '/songs', {
  26. 'artist': artist,
  27. }));
  28. if (response.statusCode != 200) {
  29. throw Exception('Failed to load songs');
  30. }
  31. List<Song> songs = [];
  32. var responseJson = jsonDecode(response.body)['songs'];
  33. for (var i = 0; i < responseJson.length; i++) {
  34. songs.add(Song.fromJson(responseJson[i]));
  35. }
  36. return songs;
  37. }
  38. class _SongsWidgetState extends State<Songs> {
  39. final String artist;
  40. final String album;
  41. Future<List<Song>> songs;
  42. final void Function(int) onSelect;
  43. _SongsWidgetState({
  44. @required this.artist,
  45. @required this.album,
  46. @required this.onSelect,
  47. });
  48. @override
  49. void initState() {
  50. super.initState();
  51. songs = fetchSongs(this.artist);
  52. }
  53. @override
  54. Widget build(BuildContext context) {
  55. return FutureBuilder<List<Song>>(
  56. future: songs,
  57. builder: (context, snapshot) {
  58. if (snapshot.hasData) {
  59. var filteredAlbums = this.album == null
  60. ? snapshot.data
  61. : snapshot.data.where((song) => song.album == this.album);
  62. return ListView(
  63. padding: EdgeInsets.only(left: 8, right: 8),
  64. children: filteredAlbums.map<Widget>((song) => Container(
  65. height: 40,
  66. color: Colors.white,
  67. child: Align(
  68. alignment: Alignment.centerLeft,
  69. child: TextButton(
  70. child: Text("${song.track} - ${song.title.length == 0 ? 'Untitled Track' : song.title}"),
  71. onPressed: () {
  72. onSelect(song.id);
  73. },
  74. style: TextButton.styleFrom(
  75. textStyle: TextStyle(fontSize: 18, fontStyle: FontStyle.normal),
  76. primary: Colors.black,
  77. ),
  78. ),
  79. ),
  80. )).toList(),
  81. );
  82. }
  83. if (snapshot.hasError) {
  84. return Text("${snapshot.error}");
  85. }
  86. return CenterSpinner();
  87. },
  88. );
  89. }
  90. }