From e6699735a68763787a74941b3402007738683c03 Mon Sep 17 00:00:00 2001 From: Iván Ávalos Date: Sun, 23 Apr 2023 17:24:03 -0600 Subject: Initial WIP for practice 6 --- lib/screens/album_detail_screen.dart | 130 +++++++++++++++++++++++++++++++++++ lib/screens/albums_screen.dart | 70 +++++++++++++++++++ lib/screens/dashboard_screen.dart | 7 ++ 3 files changed, 207 insertions(+) create mode 100644 lib/screens/album_detail_screen.dart create mode 100644 lib/screens/albums_screen.dart (limited to 'lib/screens') diff --git a/lib/screens/album_detail_screen.dart b/lib/screens/album_detail_screen.dart new file mode 100644 index 0000000..478c0b6 --- /dev/null +++ b/lib/screens/album_detail_screen.dart @@ -0,0 +1,130 @@ +import 'package:flutter/material.dart'; +import 'package:pmsna1/models/album.dart'; +import 'package:pmsna1/models/artist.dart'; +import 'package:pmsna1/network/music_api.dart'; +import 'package:pmsna1/widgets/album_placeholder.dart'; +import 'package:pmsna1/widgets/responsive.dart'; + +class AlbumDetailScreen extends StatefulWidget { + const AlbumDetailScreen({super.key}); + + @override + State createState() => _AlbumDetailScreenState(); +} + +class _AlbumDetailScreenState extends State { + MusicApi? api; + Album? album; + + @override + void initState() { + super.initState(); + api = MusicApi(); + } + + Widget getArtistCard(Artist artist, BuildContext context) => Card( + margin: const EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 2.0), + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + artist.name, + style: Theme.of(context) + .typography + .englishLike + .bodyLarge + ?.copyWith(color: Theme.of(context).colorScheme.onSurface), + ), + const SizedBox(height: 4.0), + Text(artist.disambiguation), + ], + ), + ), + ); + + // Widget getLeft() => Image.network(album!.coverUri.toString()); + Widget getLeft() => const SizedBox.shrink(); + + Widget getRight() => Column( + children: [ + ListTile( + title: const Text('Fecha de lanzamiento'), + subtitle: Text(album!.firstReleaseDate), + ), + ListTile( + title: const Text('Tipo'), + subtitle: Text(album!.primaryType), + ), + ListTile( + title: const Text('Artistas'), + subtitle: FutureBuilder( + future: api!.getAlbumArtists(album!.id), + initialData: const [], + builder: (context, snapshot) => snapshot.hasData + ? ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: snapshot.data?.length, + itemBuilder: (context, index) { + Artist artist = snapshot.data![index]; + return getArtistCard(artist, context); + }) + : snapshot.hasError + ? const Text('Ocurrió un error') + : const CircularProgressIndicator(), + ), + ) + ], + ); + + @override + Widget build(BuildContext context) { + album = ModalRoute.of(context)?.settings.arguments as Album?; + if (album == null) return const Placeholder(); + + Image cover = Image.network( + album!.coverUri.toString(), + fit: BoxFit.cover, + alignment: Alignment.center, + errorBuilder: (context, error, stackTrace) => const AlbumPlaceholder(400), + loadingBuilder: (context, child, loadingProgress) => + loadingProgress == null ? child : const AlbumPlaceholder(400), + ); + + return Scaffold( + body: NestedScrollView( + headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => + [ + SliverAppBar( + expandedHeight: 400.0, + pinned: true, + flexibleSpace: FlexibleSpaceBar( + title: Text(album!.title, + style: TextStyle( + backgroundColor: + Theme.of(context).colorScheme.primaryContainer, + color: Theme.of(context).colorScheme.onPrimaryContainer, + )), + background: cover, + ), + ) + ], + body: SingleChildScrollView( + child: Responsive( + mobile: Column(children: [getLeft(), getRight()]), + tablet: Row(children: [ + Expanded(child: getLeft()), + Expanded(child: getRight()), + ]), + desktop: Row(children: [ + Expanded(child: getLeft()), + Expanded(child: getRight()), + ]), + ), + ), + ), + ); + } +} diff --git a/lib/screens/albums_screen.dart b/lib/screens/albums_screen.dart new file mode 100644 index 0000000..d376e35 --- /dev/null +++ b/lib/screens/albums_screen.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; +import 'package:pmsna1/models/album.dart'; +import 'package:pmsna1/network/music_api.dart'; +import 'package:pmsna1/widgets/album_item.dart'; +import 'package:pmsna1/widgets/responsive.dart'; + +import '../widgets/loading_modal_widget.dart'; + +class AlbumsScreen extends StatefulWidget { + const AlbumsScreen({super.key}); + + @override + State createState() => _AlbumsScreenState(); +} + +class _AlbumsScreenState extends State { + MusicApi? musicApi; + + @override + void initState() { + super.initState(); + musicApi = MusicApi(); + } + + Widget getGridForCount( + int count, + int itemCount, + Widget Function(BuildContext, int) itemBuilder, + ) { + return MasonryGridView.builder( + gridDelegate: SliverSimpleGridDelegateWithFixedCrossAxisCount( + crossAxisCount: count, + ), + itemCount: itemCount, + itemBuilder: itemBuilder, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('Música (Alvvays)')), + body: FutureBuilder( + future: musicApi!.getAlvvaysAlbums(), + builder: (context, AsyncSnapshot?> snapshot) { + int itemCount = snapshot.data != null ? snapshot.data!.length : 0; + itemBuilder(BuildContext context, int index) { + return AlbumItem(snapshot.data![index]); + } + + if (snapshot.hasData) { + return Responsive( + mobile: getGridForCount(2, itemCount, itemBuilder), + tablet: getGridForCount(3, itemCount, itemBuilder), + desktop: getGridForCount(4, itemCount, itemBuilder), + ); + } else if (snapshot.hasError) { + print(snapshot.error); + return const Center( + child: Text('Ocurrió un error'), + ); + } else { + return const LoadingModal(); + } + }, + ), + ); + } +} diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart index 03b84e7..914749c 100644 --- a/lib/screens/dashboard_screen.dart +++ b/lib/screens/dashboard_screen.dart @@ -51,6 +51,13 @@ class DashboardScreen extends StatelessWidget { Navigator.of(context).pushNamed('/events'); }, ), + ListTile( + title: const Text('Música'), + leading: const Icon(Icons.music_note), + onTap: () { + Navigator.of(context).pushNamed('/albums'); + }, + ), ListTile( title: const Text('Tema'), trailing: SegmentedButton( -- cgit v1.2.3