diff --git a/README.md b/README.md index 231823d..7d66412 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ One album per day - [ ] working buttons - [ ] link to spotify - [ ] see more (...) - - [ ] group as list/as card + - [x] group as list/as card - [ ] top left menu - [ ] widget - [ ] notification 1/day diff --git a/lib/albumCard.dart b/lib/albumCard.dart deleted file mode 100644 index d74c014..0000000 --- a/lib/albumCard.dart +++ /dev/null @@ -1,194 +0,0 @@ -import 'package:cradle/moreInfoMenu.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:dio/dio.dart'; - -class AlbumCard extends StatefulWidget { - late DateTime date; - - AlbumCard({super.key, required DateTime time}) { - date = time; - } - - @override - _AlbumCardState createState() => _AlbumCardState(time: date); -} - -class _AlbumCardState extends State { - late DateTime date; - - Image cover = Image.asset('assets/default.png', fit: BoxFit.fitWidth); - - String name = "album"; - String artist = "artist"; - String genre = "genre"; - double averageRating = 5.0; - - _AlbumCardState({required DateTime time}) { - date = time; - _getAlbumByDate(); - } - - void _getAlbumByDate() async { - Dio dio = Dio(); - String website = - 'https://cradle-api.vercel.app/album/${date.year}/${date.month}/${date.day}'; - Response apiCall = await dio.get(website); - Map result = apiCall.data; - - List genres = result['genre']; - setState(() { - cover = Image.network( - result['image'], - fit: BoxFit.fitWidth, - ); - name = result['name']; - artist = result['artist']; - genre = genres[0]; - averageRating = result['average_rating']; - }); - } - - bool _dateIsToday(DateTime date) { - DateTime timeNow = DateTime.now(); - return ((date.year == timeNow.year) && - (date.month == timeNow.month) && - (date.day == timeNow.day)); - } - - bool _dateIsYesterday(DateTime date) { - DateTime timeNow = DateTime.now(); - return ((date.year == timeNow.year) && - (date.month == timeNow.month) && - (date.day == (timeNow.day - 1))); - } - - @override - Widget build(BuildContext context) { - return SizedBox( - width: MediaQuery.of(context).size.width - 32, - height: MediaQuery.of(context).size.height / 2, - child: Card( - elevation: 0, - color: Theme.of(context).colorScheme.surfaceVariant, - child: Column( - children: [ - Expanded( - flex: 55, - child: ClipRRect( - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(12), - topRight: Radius.circular(12), - ), - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: cover, - )), - ), - Expanded( - flex: 45, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.only(left: 8, top: 8), - child: Text(name, - maxLines: 1, - style: Theme.of(context) - .textTheme - .headlineSmall), - ), - Padding( - padding: - const EdgeInsets.only(right: 8, left: 8), - child: Text( - (_dateIsToday(date)) - ? "today" - : (_dateIsYesterday(date)) - ? "yesterday" - : "${date.day}/${date.month}/${date.year}", - style: Theme.of(context).textTheme.bodyLarge, - textAlign: TextAlign.right, - )) - ], - ), - Row( - children: [ - Padding( - padding: const EdgeInsets.only(left: 8), - child: Text( - "by $artist", - style: Theme.of(context).textTheme.bodyMedium, - ), - ) - ], - ), - Row( - children: [ - Padding( - padding: const EdgeInsets.only(left: 8), - child: ActionChip( - avatar: const Icon(Icons.music_note), - label: Text( - genre, - style: TextStyle( - color: Theme.of(context) - .colorScheme - .onSecondaryContainer), - ), - onPressed: () {}, - backgroundColor: Theme.of(context) - .colorScheme - .secondaryContainer, - ), - ), - Padding( - padding: const EdgeInsets.only(left: 8), - child: ActionChip( - avatar: SvgPicture.asset("assets/rym.svg"), - label: Text( - "$averageRating/5", - style: TextStyle( - color: Theme.of(context) - .colorScheme - .onSecondaryContainer), - ), - onPressed: () {}, - backgroundColor: Theme.of(context) - .colorScheme - .secondaryContainer, - ), - ), - ], - ), - Padding( - padding: - const EdgeInsets.only(left: 8, top: 16, right: 8), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const MoreInfoMenu(), - - // new Spacer(), - FilledButton.icon( - icon: SvgPicture.asset( - "assets/spotify.svg", - color: - Theme.of(context).colorScheme.onPrimary, - width: 18, - height: 18, - ), - onPressed: null, - label: const Text("Listen on Spotify"), - ), - ], - ), - ) - ], - )) - ], - ))); - } -} diff --git a/lib/albumCard/albumCard.dart b/lib/albumCard/albumCard.dart new file mode 100644 index 0000000..587a498 --- /dev/null +++ b/lib/albumCard/albumCard.dart @@ -0,0 +1,233 @@ +import 'package:cradle/moreInfoMenu.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:dio/dio.dart'; + +class AlbumCard extends StatefulWidget { + late DateTime date; + bool isCard; + + AlbumCard({super.key, required DateTime time, required this.isCard}) { + date = time; + } + + @override + _AlbumCardState createState() => _AlbumCardState(time: date); +} + +class _AlbumCardState extends State { + late DateTime date; + + Image cover = Image.asset('assets/default.png', fit: BoxFit.fitWidth); + String name = "album"; + String artist = "artist"; + String genre = "genre"; + double averageRating = 5.0; + + _AlbumCardState({required DateTime time}) { + date = time; + _getAlbumByDate(); + } + + void _getAlbumByDate() async { + Dio dio = Dio(); + String website = + 'https://cradle-api.vercel.app/album/${date.year}/${date.month}/${date.day}'; + Response apiCall = await dio.get(website); + Map result = apiCall.data; + + List genres = result['genre']; + setState(() { + cover = Image.network( + result['image'], + fit: BoxFit.fitWidth, + ); + name = result['name']; + artist = result['artist']; + genre = genres[0]; + averageRating = result['average_rating']; + }); + } + + bool _dateIsToday(DateTime date) { + DateTime timeNow = DateTime.now(); + return ((date.year == timeNow.year) && + (date.month == timeNow.month) && + (date.day == timeNow.day)); + } + + bool _dateIsYesterday(DateTime date) { + DateTime timeNow = DateTime.now(); + return ((date.year == timeNow.year) && + (date.month == timeNow.month) && + (date.day == (timeNow.day - 1))); + } + + @override + Widget build(BuildContext context) { + return widget.isCard ? displayAsCard(context) : displayAsList(); + } + + Widget displayAsList() { + return ListTile( + leading: cover, + title: Text(name), + subtitle: Text(artist), + trailing: Text( + (_dateIsToday(date)) + ? "today" + : (_dateIsYesterday(date)) + ? "yesterday" + : "${date.day}/${date.month}/${date.year}", + style: Theme.of(context).textTheme.labelSmall, + textAlign: TextAlign.right, + ), + style: ListTileStyle.list, + isThreeLine: true, + ); + } + + Widget displayAsCard(BuildContext context) { + return AnimatedSwitcher( + duration: const Duration(milliseconds: 250), + child: Center( + child: SizedBox( + width: MediaQuery.of(context).size.width - 32, + height: MediaQuery.of(context).size.height / 2, + child: Card( + elevation: 0, + color: Theme.of(context).colorScheme.surfaceVariant, + child: Column( + children: [ + Expanded( + flex: 55, + child: ClipRRect( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(12), + topRight: Radius.circular(12), + ), + child: SizedBox( + width: MediaQuery.of(context).size.width, + child: cover, + )), + ), + Expanded( + flex: 45, + child: Column( + children: [ + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: + const EdgeInsets.only(left: 8, top: 8), + child: Text( + name.length > 18 + ? '${name.substring(0, 15)}...' + : name, + maxLines: 1, + style: Theme.of(context) + .textTheme + .headlineSmall), + ), + Padding( + padding: const EdgeInsets.only( + right: 8, left: 8), + child: Text( + (_dateIsToday(date)) + ? "today" + : (_dateIsYesterday(date)) + ? "yesterday" + : "${date.day}/${date.month}/${date.year}", + style: Theme.of(context) + .textTheme + .bodyLarge, + textAlign: TextAlign.right, + )) + ], + ), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 8), + child: Text( + "by $artist", + style: Theme.of(context) + .textTheme + .bodyMedium, + ), + ) + ], + ), + Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 8), + child: ActionChip( + avatar: const Icon(Icons.music_note), + label: Text( + genre, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .onSecondaryContainer), + ), + onPressed: () {}, + backgroundColor: Theme.of(context) + .colorScheme + .secondaryContainer, + ), + ), + Padding( + padding: const EdgeInsets.only(left: 8), + child: ActionChip( + avatar: + SvgPicture.asset("assets/rym.svg"), + label: Text( + "$averageRating/5", + style: TextStyle( + color: Theme.of(context) + .colorScheme + .onSecondaryContainer), + ), + onPressed: () {}, + backgroundColor: Theme.of(context) + .colorScheme + .secondaryContainer, + ), + ), + ], + ), + Padding( + padding: const EdgeInsets.only( + left: 8, top: 16, right: 8), + child: Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + const MoreInfoMenu(), + + // new Spacer(), + FilledButton.icon( + icon: SvgPicture.asset( + "assets/spotify.svg", + color: Theme.of(context) + .colorScheme + .onPrimary, + width: 18, + height: 18, + ), + onPressed: null, + label: const Text("Listen on Spotify"), + ), + ], + ), + ) + ], + )) + ], + ))), + )); + } +} diff --git a/lib/main.dart b/lib/main.dart index 8095f3a..2af3815 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,4 @@ -import 'package:cradle/albumCard.dart'; +import 'package:cradle/albumCard/albumCard.dart'; import 'package:cradle/theme_manager.dart'; import 'package:flutter/material.dart'; @@ -38,6 +38,8 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { + bool isCard = true; + @override Widget build(BuildContext context) { // This method is rerun every time setState is called, for instance as done @@ -49,7 +51,7 @@ class _MyHomePageState extends State { DateTime timeNow = DateTime.now(); List albumCards = [ const SizedBox(height: 16), - AlbumCard(time: timeNow), + AlbumCard(time: timeNow, isCard: isCard), ]; DateTime deadline = DateTime.parse('2023-12-31'); @@ -70,7 +72,10 @@ class _MyHomePageState extends State { while (date.isAfter(deadline)) { date = DateTime(date.year, date.month, date.day - 1); albumCards.add(const SizedBox(height: 13)); - albumCards.add(AlbumCard(time: date)); + albumCards.add(AlbumCard( + time: date, + isCard: isCard, + )); } return Scaffold( @@ -92,31 +97,23 @@ class _MyHomePageState extends State { )), actions: [ - IconButton(onPressed: () {}, icon: const Icon(Icons.grid_view)) + IconButton( + onPressed: () { + setState(() { + isCard = !isCard; + }); + }, + icon: (!isCard) + ? const Icon(Icons.view_list) + : const Icon(Icons.grid_view)) ], ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: SingleChildScrollView( - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.center, - - children: albumCards, - ), + body: SingleChildScrollView( + child: Column( + + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: albumCards, ), ), );