Skip to content

Commit

Permalink
draft freshen up albums page
Browse files Browse the repository at this point in the history
  • Loading branch information
FriederHannenheim committed May 12, 2024
1 parent a750a52 commit cb2aadc
Show file tree
Hide file tree
Showing 5 changed files with 261 additions and 58 deletions.
86 changes: 57 additions & 29 deletions src/lib/presentation/pages/albums_page.dart
@@ -1,12 +1,16 @@
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:get_it/get_it.dart';
import 'package:mobx/mobx.dart';
import 'package:mobx/mobx.dart' as mobx;
import 'package:mucke/presentation/widgets/album_art_grid.dart';
import 'package:mucke/presentation/widgets/album_art_list.dart';

import '../../domain/entities/album.dart';
import '../state/music_data_store.dart';
import '../state/navigation_store.dart';
import '../widgets/album_art_list_tile.dart';
import 'album_details_page.dart';

class AlbumsPage extends StatefulWidget {
const AlbumsPage({Key? key}) : super(key: key);
Expand All @@ -15,8 +19,11 @@ class AlbumsPage extends StatefulWidget {
_AlbumsPageState createState() => _AlbumsPageState();
}

class _AlbumsPageState extends State<AlbumsPage> with AutomaticKeepAliveClientMixin {
final ScrollController _scrollController = ScrollController();
class _AlbumsPageState extends State<AlbumsPage>
with AutomaticKeepAliveClientMixin {
final ScrollController scrollController = ScrollController();
final Observable<bool> showAlbumGrid = Observable(false);
final Observable<String> sortingMode = Observable('name');

@override
Widget build(BuildContext context) {
Expand All @@ -28,33 +35,54 @@ class _AlbumsPageState extends State<AlbumsPage> with AutomaticKeepAliveClientMi
return Observer(builder: (_) {
print('AlbumsPage.build -> Observer.builder');
final List<Album> albums = store.albumStream.value ?? [];
return Scrollbar(
controller: _scrollController,
child: ListView.separated(
controller: _scrollController,
itemCount: albums.length,
itemBuilder: (_, int index) {
final Album album = albums[index];
return AlbumArtListTile(
title: album.title,
subtitle: album.artist,
albumArtPath: album.albumArtPath,
onTap: () {
navStore.push(
context,
MaterialPageRoute<Widget>(
builder: (BuildContext context) => AlbumDetailsPage(
album: album,
),
),
);
switch (sortingMode.value) {
case 'name':
break;
case 'artistName':
albums.sort((a,b) => a.artist.compareTo(b.artist));
break;
case 'random':
albums.shuffle(Random());
break;
}
return CustomScrollView(
slivers: [
SliverAppBar(
floating: true,
leading: IconButton(
onPressed: () {
showAlbumGrid.toggle();
},
);
},
separatorBuilder: (BuildContext context, int index) => const SizedBox(
height: 4.0,
icon: Icon(showAlbumGrid.value ? Icons.list : Icons.grid_view),
),
actions: [
DropdownButton(
value: sortingMode.value,
items: const [
DropdownMenuItem(value: 'name', child: Text('name')),
DropdownMenuItem(value: 'artistName', child: Text('artistName')),
DropdownMenuItem(value: 'random', child: Text('random')),
],
onChanged: (selectedValue) {
if (selectedValue != null)
mobx.Action(() {
sortingMode.value = selectedValue;
})();
},
)
],
),
),
if (showAlbumGrid.value)
AlbumArtGrid(
albums: albums,
scrollController: scrollController,
navStore: navStore)
else
AlbumArtList(
albums: albums,
scrollController: scrollController,
navStore: navStore),
],
);
});
}
Expand Down
45 changes: 45 additions & 0 deletions src/lib/presentation/widgets/album_art_grid.dart
@@ -0,0 +1,45 @@
import 'package:flutter/material.dart';
import 'package:mucke/presentation/pages/album_details_page.dart';
import 'package:mucke/presentation/state/navigation_store.dart';
import 'package:mucke/presentation/widgets/album_art_grid_tile.dart';

import '../../domain/entities/album.dart';

class AlbumArtGrid extends StatelessWidget {
const AlbumArtGrid({
Key? key,
required this.albums,
required this.scrollController,
required this.navStore,
}) : super(key: key);

final List<Album> albums;
final ScrollController scrollController;
final NavigationStore navStore;

@override
Widget build(BuildContext context) {
return SliverGrid.builder(
itemCount: albums.length,
gridDelegate:
const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
itemBuilder: (_, int index) {
final Album album = albums[index];
return AlbumArtGridTile(
title: album.title,
subtitle: album.artist,
albumArtPath: album.albumArtPath,
onTap: () {
navStore.push(
context,
MaterialPageRoute<Widget>(
builder: (BuildContext context) => AlbumDetailsPage(
album: album,
),
),
);
});
},
);
}
}
69 changes: 69 additions & 0 deletions src/lib/presentation/widgets/album_art_grid_tile.dart
@@ -0,0 +1,69 @@
import 'package:flutter/material.dart';

import '../theming.dart';
import '../utils.dart' as utils;

class AlbumArtGridTile extends StatelessWidget {
const AlbumArtGridTile({
Key? key,
required this.title,
required this.subtitle,
required this.onTap,
this.albumArtPath,
this.highlight = false,
}) : super(key: key);

final String title;
final String subtitle;
final String? albumArtPath;
final Function onTap;
final bool highlight;

@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap(),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 0, horizontal: 20),
child: Column(
children: [
SizedBox(
width: 128,
height: 128,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4.0),
boxShadow: const [
BoxShadow(
color: Colors.black54,
blurRadius: 8,
offset: Offset(0, 2),
),
],
),
clipBehavior: Clip.antiAlias,
child: Image(
image: utils.getAlbumImage(albumArtPath),
fit: BoxFit.cover,
),
),
),
const Padding(padding: EdgeInsets.symmetric(vertical: 3, horizontal: 0)),
Text(
title,
style: const TextStyle(fontWeight: FontWeight.bold),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
subtitle,
style: TEXT_SMALL_SUBTITLE.copyWith(color: Colors.white),
maxLines: 1,
overflow: TextOverflow.ellipsis,
)
],
),
),
);
}
}
37 changes: 37 additions & 0 deletions src/lib/presentation/widgets/album_art_list.dart
@@ -0,0 +1,37 @@
import 'package:flutter/material.dart';
import 'package:mucke/presentation/state/navigation_store.dart';

import '../../domain/entities/album.dart';
import 'album_art_list_tile.dart';

class AlbumArtList extends StatelessWidget {
const AlbumArtList({
Key? key,
required this.albums,
required this.scrollController,
required this.navStore,
}) : super(key: key);

final List<Album> albums;
final ScrollController scrollController;
final NavigationStore navStore;

@override
Widget build(BuildContext context) {
return SliverList.separated(
itemCount: albums.length,
itemBuilder: (_, int index) {
final Album album = albums[index];
return AlbumArtListTile(
title: album.title,
subtitle: album.artist,
albumArtPath: album.albumArtPath,
onTap: () {},
);
},
separatorBuilder: (BuildContext context, int index) => const SizedBox(
height: 4.0,
),
);
}
}

0 comments on commit cb2aadc

Please sign in to comment.