Make Artist tappable in AlbumDetailsPage to go to the artist (#123)
* add onTapTitle to CoverSliverAppBar * untested changes * Make artist tappable to go to album artist * remove gesture detector --------- Co-authored-by: FriederHannenheim <frieder12.fml@pm.me>
This commit is contained in:
parent
9e41b35a80
commit
fd4877a159
2 changed files with 72 additions and 11 deletions
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_gen/gen_l10n/localizations.dart';
|
||||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:mucke/domain/entities/artist.dart';
|
||||
|
||||
import '../../domain/entities/album.dart';
|
||||
import '../../domain/entities/song.dart';
|
||||
|
@ -9,6 +10,7 @@ import '../l10n_utils.dart';
|
|||
import '../state/album_page_store.dart';
|
||||
import '../state/audio_store.dart';
|
||||
import '../state/music_data_store.dart';
|
||||
import '../state/navigation_store.dart';
|
||||
import '../state/settings_store.dart';
|
||||
import '../theming.dart';
|
||||
import '../utils.dart' as utils;
|
||||
|
@ -19,6 +21,7 @@ import '../widgets/exclude_level_options.dart';
|
|||
import '../widgets/like_count_options.dart';
|
||||
import '../widgets/song_bottom_sheet.dart';
|
||||
import '../widgets/song_list_tile_numbered.dart';
|
||||
import 'artist_details_page.dart';
|
||||
|
||||
class AlbumDetailsPage extends StatefulWidget {
|
||||
const AlbumDetailsPage({Key? key, required this.album}) : super(key: key);
|
||||
|
@ -48,6 +51,9 @@ class _AlbumDetailsPageState extends State<AlbumDetailsPage> {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final AudioStore audioStore = GetIt.I<AudioStore>();
|
||||
final NavigationStore navStore = GetIt.I<NavigationStore>();
|
||||
final MusicDataStore musicDataStore = GetIt.I<MusicDataStore>();
|
||||
|
||||
|
||||
return Scaffold(
|
||||
body: Material(
|
||||
|
@ -55,6 +61,7 @@ class _AlbumDetailsPageState extends State<AlbumDetailsPage> {
|
|||
builder: (BuildContext context) {
|
||||
final album = widget.album;
|
||||
final songs = store.albumSongStream.value ?? [];
|
||||
final artists = musicDataStore.artistStream.value ?? [];
|
||||
final totalDuration =
|
||||
songs.fold(const Duration(milliseconds: 0), (Duration d, s) => d + s.duration);
|
||||
final songsByDisc = _songsByDisc(store.albumSongStream.value ?? []);
|
||||
|
@ -62,6 +69,9 @@ class _AlbumDetailsPageState extends State<AlbumDetailsPage> {
|
|||
for (int i = 0; i < songsByDisc.length - 1; i++) {
|
||||
discSongNums.add(songsByDisc[i].length + discSongNums[i]);
|
||||
}
|
||||
Artist? albumArtist;
|
||||
if (artists.isNotEmpty)
|
||||
albumArtist = artists.singleWhere((a) => a.name == album.artist);
|
||||
|
||||
return Scrollbar(
|
||||
child: CustomScrollView(
|
||||
|
@ -123,6 +133,17 @@ class _AlbumDetailsPageState extends State<AlbumDetailsPage> {
|
|||
image: utils.getAlbumImage(album.albumArtPath),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
onTapSubtitle: () async {
|
||||
if (albumArtist != null)
|
||||
navStore.pushOnLibrary(
|
||||
MaterialPageRoute<Widget>(
|
||||
builder: (BuildContext context) =>
|
||||
ArtistDetailsPage(
|
||||
artist: albumArtist!,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundColor: utils.bgColor(album.color),
|
||||
button: SizedBox(
|
||||
width: 48,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
|
@ -15,6 +16,7 @@ class CoverSliverAppBar extends StatefulWidget {
|
|||
required this.cover,
|
||||
required this.backgroundColor,
|
||||
this.button,
|
||||
this.onTapSubtitle,
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
@ -24,6 +26,7 @@ class CoverSliverAppBar extends StatefulWidget {
|
|||
final Widget cover;
|
||||
final Color backgroundColor;
|
||||
final Widget? button;
|
||||
final AsyncCallback? onTapSubtitle;
|
||||
|
||||
@override
|
||||
State<CoverSliverAppBar> createState() => _CoverSliverAppBarState();
|
||||
|
@ -54,6 +57,7 @@ class _CoverSliverAppBarState extends State<CoverSliverAppBar> {
|
|||
subtitle: widget.subtitle,
|
||||
subtitle2: widget.subtitle2,
|
||||
button: widget.button,
|
||||
onTapSubtitle: widget.onTapSubtitle,
|
||||
),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.chevron_left_rounded),
|
||||
|
@ -77,6 +81,7 @@ class Header extends StatelessWidget {
|
|||
required this.cover,
|
||||
required this.backgroundColor,
|
||||
this.button,
|
||||
this.onTapSubtitle,
|
||||
}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
@ -87,6 +92,7 @@ class Header extends StatelessWidget {
|
|||
final double maxHeight;
|
||||
final double minHeight;
|
||||
final Widget? button;
|
||||
final AsyncCallback? onTapSubtitle;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -110,6 +116,7 @@ class Header extends StatelessWidget {
|
|||
title: title,
|
||||
subtitle: subtitle,
|
||||
subtitle2: subtitle2,
|
||||
onTapSubtitle: onTapSubtitle,
|
||||
),
|
||||
],
|
||||
);
|
||||
|
@ -142,6 +149,7 @@ class Header extends StatelessWidget {
|
|||
required String title,
|
||||
String? subtitle,
|
||||
String? subtitle2,
|
||||
AsyncCallback? onTapSubtitle,
|
||||
}) {
|
||||
// TODO: padding right for enabled multi select
|
||||
return Align(
|
||||
|
@ -183,17 +191,7 @@ class Header extends StatelessWidget {
|
|||
width: 10.0,
|
||||
),
|
||||
if (subtitle != null)
|
||||
Text(
|
||||
subtitle,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.fade,
|
||||
style: TextStyle(
|
||||
fontSize: Tween<double>(begin: 0, end: 16).evaluate(animation),
|
||||
color: Colors.white
|
||||
.withOpacity(Tween<double>(begin: 0, end: 1).evaluate(animation2)),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
_buildSubtitle(context, subtitle, animation, animation2, onTapSubtitle),
|
||||
if (subtitle2 != null)
|
||||
Text(
|
||||
subtitle2,
|
||||
|
@ -210,6 +208,48 @@ class Header extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
Widget _buildSubtitle(
|
||||
BuildContext context,
|
||||
String subtitle,
|
||||
Animation<double> animation,
|
||||
Animation<double> animation2,
|
||||
AsyncCallback? onTapSubtitle) {
|
||||
if (onTapSubtitle == null)
|
||||
return Text(
|
||||
subtitle,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.fade,
|
||||
style: TextStyle(
|
||||
fontSize: Tween<double>(begin: 0, end: 16).evaluate(animation),
|
||||
color: Colors.white.withOpacity(
|
||||
Tween<double>(begin: 0, end: 1).evaluate(animation2)),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
);
|
||||
return TextButton(
|
||||
onPressed: onTapSubtitle,
|
||||
style: TextButton.styleFrom(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||
minimumSize: Size.zero,
|
||||
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
backgroundColor: Colors.white24,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
side: const BorderSide(color: Colors.white24),
|
||||
)),
|
||||
child: Text(
|
||||
subtitle,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.fade,
|
||||
style: TextStyle(
|
||||
fontSize: Tween<double>(begin: 0, end: 16).evaluate(animation),
|
||||
color: Colors.white.withOpacity(
|
||||
Tween<double>(begin: 0, end: 1).evaluate(animation2)),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget _buildButton(Animation<double> animation, BuildContext context) {
|
||||
return Positioned(
|
||||
width: 96,
|
||||
|
|
Loading…
Add table
Reference in a new issue