Skip to content

Commit

Permalink
Add album list screen
Browse files Browse the repository at this point in the history
  • Loading branch information
up2code committed May 7, 2024
1 parent 150a218 commit 76f2c3c
Show file tree
Hide file tree
Showing 7 changed files with 227 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:vocadb_app/src/features/albums/presentation/albums_list/albums_list_params_state.dart';
import 'package:vocadb_app/src/features/albums/presentation/widgets/dropdown_album_sort.dart';
import 'package:vocadb_app/src/features/albums/presentation/widgets/dropdown_album_type.dart';
import 'package:vocadb_app/src/features/tags/presentation/tag_widgets/tag_input.dart';

class AlbumsFilterScreen extends StatelessWidget {
const AlbumsFilterScreen(
{super.key, this.onSortChanged, this.onAlbumTypesChanged});

final Function(String?)? onAlbumTypesChanged;

final Function(String?)? onSortChanged;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Filter'),
),
body: Consumer(
builder: (context, ref, child) {
final state = ref.watch(albumsListParamsStateProvider);

return ListView(
children: [
DropdownAlbumType(
value: state.discTypes ?? '',
onChanged: (value) =>
onAlbumTypesChanged?.call(value) ??
ref
.read(albumsListParamsStateProvider.notifier)
.updateDiscTypes(value!),
),
DropdownAlbumSort(
value: 'Name',
onChanged: (value) =>
onAlbumTypesChanged?.call(value) ??
ref
.read(albumsListParamsStateProvider.notifier)
.updateSort(value!),
),
const Divider(),
const TagInput(),
],
);
},
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:vocadb_app/src/features/albums/domain/albums_list_params.dart';
import 'package:vocadb_app/src/features/settings/data/user_settings_repository.dart';

class AlbumsListParamsState extends StateNotifier<AlbumsListParams> {
AlbumsListParamsState({String lang = 'Default'})
: super(AlbumsListParams(lang: lang));
void updateDiscTypes(String? value) =>
state = state.copyWith(discTypes: value);
void updateQuery(String value) => state = state.copyWith(query: value);
void updateSort(String value) => state = state.copyWith(sort: value);
void clearQuery() => state = state.copyWith(query: null);
}

final albumsListParamsStateProvider = StateNotifierProvider.autoDispose<
AlbumsListParamsState, AlbumsListParams>((ref) {
final preferredLang = ref.watch(userSettingsRepositoryProvider
.select((value) => value.currentPreferredLang));
return AlbumsListParamsState(lang: preferredLang);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:vocadb_app/src/common_widgets/async_value_widget.dart';
import 'package:vocadb_app/src/common_widgets/search_appbar.dart';
import 'package:vocadb_app/src/features/albums/data/album_repository.dart';
import 'package:vocadb_app/src/features/albums/domain/album.dart';
import 'package:vocadb_app/src/features/albums/presentation/albums_list/album_list_view.dart';
import 'package:vocadb_app/src/features/albums/presentation/albums_list/albums_list_params_state.dart';
import 'package:vocadb_app/src/routing/app_route_context.dart';

class AlbumsListScreen extends ConsumerWidget {
const AlbumsListScreen({super.key, this.onSelectAlbum});

static const filterKey = Key('icon-filter-key');

final Function(Album)? onSelectAlbum;

@override
Widget build(BuildContext context, WidgetRef ref) {
return Scaffold(
appBar: SearchAppBar(
titleText: 'Albums',
actions: [
IconButton(
key: filterKey,
icon: const Icon(Icons.tune),
onPressed: () => context.goAlbumsListFilterScreen(),
),
],
onSubmitted: (value) {
ref.read(albumsListParamsStateProvider.notifier).updateQuery(value);
},
onCleared: () {
ref.read(albumsListParamsStateProvider.notifier).clearQuery();
},
),
body: Consumer(builder: ((context, ref, child) {
final value = ref.watch(albumsListProvider);
return AsyncValueWidget(
value: value,
data: (data) {
return AlbumListView(
albums: data,
onSelect: (artist) => onSelectAlbum?.call(artist),
);
});
})),
);
}
}

// State
final albumsListProvider = FutureProvider.autoDispose<List<Album>>((ref) {
final params = ref.watch(albumsListParamsStateProvider);
final albumRepository = ref.watch(albumRepositoryProvider);
return albumRepository.fetchAlbums(params: params);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:vocadb_app/src/common_widgets/dropdown_tile.dart';

class DropdownAlbumSort extends StatelessWidget {
const DropdownAlbumSort({super.key, required this.value, this.onChanged});

static const dropdownKey = Key('dropdown-album-sort-key');

final String value;

final Function(String?)? onChanged;

@override
Widget build(BuildContext context) {
return DropdownTile(
dropdownButtonKey: dropdownKey,
value: value,
label: 'Sort',
onChanged: onChanged,
items: const [
DropdownMenuItem<String>(
value: 'Name',
child: Text('Name'),
),
DropdownMenuItem<String>(
value: 'AdditionDate',
child: Text('Addition date'),
),
DropdownMenuItem<String>(
value: 'ReleaseDate',
child: Text('Release date'),
),
DropdownMenuItem<String>(
value: 'RatingAverage',
child: Text('Rating average'),
),
DropdownMenuItem<String>(
value: 'RatingTotal',
child: Text('Total score'),
),
DropdownMenuItem<String>(
value: 'CollectionCount',
child: Text('Collection count'),
),
],
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class HomeScreen extends StatelessWidget {
ShortcutMenuButton(
title: 'Albums',
iconData: Icons.album,
onPressed: () {},
onPressed: () {
context.goAlbumSearchScreen();
},
),
ShortcutMenuButton(
title: 'Tags',
Expand Down
9 changes: 9 additions & 0 deletions lib/src/routing/app_route_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ extension AppRouteContext on BuildContext {

}

Future<void> goAlbumSearchScreen() async {
goNamed(AppRoute.albumsList.name);

}

Future<void> goSongSearchScreen() async {
goNamed(AppRoute.songsList.name);

Expand All @@ -47,6 +52,10 @@ extension AppRouteContext on BuildContext {
goNamed(AppRoute.songsListFilter.name);
}

Future<void> goAlbumsListFilterScreen() async {
goNamed(AppRoute.albumsListFilter.name);
}

Future<void> goEntryDetail(Entry entry) async {
String entryType = entry.entryType;
switch (entryType) {
Expand Down
42 changes: 38 additions & 4 deletions lib/src/routing/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:vocadb_app/src/features/albums/domain/album.dart';
import 'package:vocadb_app/src/features/albums/presentation/album_detail_screen/album_detail_screen.dart';
import 'package:vocadb_app/src/features/albums/presentation/albums_list/albums_list_filter_screen.dart';
import 'package:vocadb_app/src/features/albums/presentation/albums_list/albums_list_screen.dart';
import 'package:vocadb_app/src/features/songs/presentation/songs_list_screen/songs_list_filter_screen.dart';
import 'package:vocadb_app/src/features/songs/presentation/songs_list_screen/songs_list_screen.dart';
import 'package:vocadb_app/src/features/users/presentation/user_albums_screen/user_albums_filter_screen.dart';
Expand Down Expand Up @@ -40,6 +42,8 @@ enum AppRoute {
songsList,
songsListFilter,
albumDetail,
albumsList,
albumsListFilter,
artistDetail,
artistsList,
artistsListFilter,
Expand Down Expand Up @@ -87,6 +91,7 @@ final goRouterProvider = Provider.autoDispose<GoRouter>(
name: AppRoute.home.name,
builder: (context, state) => const MainScreen(),
routes: [
//// Songs
GoRoute(
path: 'S',
name: AppRoute.songsList.name,
Expand Down Expand Up @@ -115,6 +120,8 @@ final goRouterProvider = Provider.autoDispose<GoRouter>(
),
],
),

//// Artists
GoRoute(
path: 'Ar',
name: AppRoute.artistsList.name,
Expand Down Expand Up @@ -143,14 +150,37 @@ final goRouterProvider = Provider.autoDispose<GoRouter>(
),
],
),

GoRoute(
path: 'A/:id',
name: AppRoute.albumDetail.name,
path: 'A',
name: AppRoute.albumsList.name,
builder: (context, state) {
final albumId = state.pathParameters['id']!;
return AlbumDetailScreen(album: Album(id: int.parse(albumId)));
return AlbumsListScreen(onSelectAlbum: (album) {
context.goAlbumDetail(album);
});
},
routes: [
GoRoute(
path: 'Filter',
name: AppRoute.albumsListFilter.name,
pageBuilder: (context, state) => MaterialPage(
key: state.pageKey,
fullscreenDialog: true,
child: const AlbumsFilterScreen(),
),
),
GoRoute(
path: ':id',
name: AppRoute.albumDetail.name,
builder: (context, state) {
final albumId = state.pathParameters['id']!;
return AlbumDetailScreen(album: Album(id: int.parse(albumId)));
},
),
],
),

//// Tags
GoRoute(
path: 'T/:id',
name: AppRoute.tagDetail.name,
Expand All @@ -159,6 +189,8 @@ final goRouterProvider = Provider.autoDispose<GoRouter>(
return TagDetailScreen(tagId: tagId);
},
),

//// Release events
GoRoute(
path: 'E/:id',
name: AppRoute.releaseEventDetail.name,
Expand All @@ -167,6 +199,8 @@ final goRouterProvider = Provider.autoDispose<GoRouter>(
return ReleaseEventDetailScreen(releaseEventId: releaseEventId);
},
),

//// Personal
GoRoute(
path: 'MySongs',
name: AppRoute.userRatedSongs.name,
Expand Down

0 comments on commit 76f2c3c

Please sign in to comment.