Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3852e83a3c |
@@ -500,10 +500,16 @@ class _AlbumDetailsScreenState extends State<AlbumDetailsScreen> with SingleTick
|
|||||||
void _navigateToArtist() {
|
void _navigateToArtist() {
|
||||||
// Navigate to the first artist if available
|
// Navigate to the first artist if available
|
||||||
if (widget.album.artists != null && widget.album.artists!.isNotEmpty) {
|
if (widget.album.artists != null && widget.album.artists!.isNotEmpty) {
|
||||||
|
final artist = widget.album.artists!.first;
|
||||||
|
final maProvider = context.read<MusicAssistantProvider>();
|
||||||
|
final imageUrl = maProvider.getImageUrl(artist, size: 256);
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ArtistDetailsScreen(artist: widget.album.artists!.first),
|
builder: (context) => ArtistDetailsScreen(
|
||||||
|
artist: artist,
|
||||||
|
initialImageUrl: imageUrl,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,11 +15,13 @@ import '../utils/page_transitions.dart';
|
|||||||
class ArtistDetailsScreen extends StatefulWidget {
|
class ArtistDetailsScreen extends StatefulWidget {
|
||||||
final Artist artist;
|
final Artist artist;
|
||||||
final String? heroTagSuffix;
|
final String? heroTagSuffix;
|
||||||
|
final String? initialImageUrl;
|
||||||
|
|
||||||
const ArtistDetailsScreen({
|
const ArtistDetailsScreen({
|
||||||
super.key,
|
super.key,
|
||||||
required this.artist,
|
required this.artist,
|
||||||
this.heroTagSuffix,
|
this.heroTagSuffix,
|
||||||
|
this.initialImageUrl,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -44,12 +46,14 @@ class _ArtistDetailsScreenState extends State<ArtistDetailsScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_isFavorite = widget.artist.favorite ?? false;
|
_isFavorite = widget.artist.favorite ?? false;
|
||||||
|
// Use initial image URL immediately for smooth hero animation
|
||||||
|
_artistImageUrl = widget.initialImageUrl;
|
||||||
_loadArtistAlbums();
|
_loadArtistAlbums();
|
||||||
_loadArtistDescription();
|
_loadArtistDescription();
|
||||||
_refreshFavoriteStatus();
|
_refreshFavoriteStatus();
|
||||||
|
|
||||||
// CRITICAL FIX: Defer image loading and color extraction until after transition
|
// Defer higher-res image loading and color extraction until after transition
|
||||||
// This prevents expensive operations during hero animation
|
// But hero animation now works because we have initialImageUrl
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
Future.delayed(const Duration(milliseconds: 350), () {
|
Future.delayed(const Duration(milliseconds: 350), () {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|||||||
@@ -90,6 +90,9 @@ class LibraryArtistsScreen extends StatelessWidget {
|
|||||||
}) {
|
}) {
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
final maProvider = context.read<MusicAssistantProvider>();
|
||||||
|
// Get image URL for hero animation
|
||||||
|
final imageUrl = maProvider.getImageUrl(artist, size: 256);
|
||||||
|
|
||||||
// RepaintBoundary isolates repaints to individual tiles
|
// RepaintBoundary isolates repaints to individual tiles
|
||||||
return RepaintBoundary(
|
return RepaintBoundary(
|
||||||
@@ -116,6 +119,7 @@ class LibraryArtistsScreen extends StatelessWidget {
|
|||||||
child: ArtistDetailsScreen(
|
child: ArtistDetailsScreen(
|
||||||
artist: artist,
|
artist: artist,
|
||||||
heroTagSuffix: 'library',
|
heroTagSuffix: 'library',
|
||||||
|
initialImageUrl: imageUrl,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -312,7 +312,10 @@ class _NewLibraryScreenState extends State<NewLibraryScreen>
|
|||||||
}) {
|
}) {
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
final textTheme = Theme.of(context).textTheme;
|
final textTheme = Theme.of(context).textTheme;
|
||||||
|
final maProvider = context.read<MusicAssistantProvider>();
|
||||||
final suffix = '_library';
|
final suffix = '_library';
|
||||||
|
// Get image URL for hero animation
|
||||||
|
final imageUrl = maProvider.getImageUrl(artist, size: 256);
|
||||||
|
|
||||||
return RepaintBoundary(
|
return RepaintBoundary(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
@@ -322,9 +325,6 @@ class _NewLibraryScreenState extends State<NewLibraryScreen>
|
|||||||
radius: 24,
|
radius: 24,
|
||||||
imageSize: 128,
|
imageSize: 128,
|
||||||
heroTag: HeroTags.artistImage + (artist.uri ?? artist.itemId) + suffix,
|
heroTag: HeroTags.artistImage + (artist.uri ?? artist.itemId) + suffix,
|
||||||
onImageLoaded: (imageUrl) {
|
|
||||||
// Store for adaptive colors on tap
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
title: Hero(
|
title: Hero(
|
||||||
tag: HeroTags.artistName + (artist.uri ?? artist.itemId) + suffix,
|
tag: HeroTags.artistName + (artist.uri ?? artist.itemId) + suffix,
|
||||||
@@ -348,6 +348,7 @@ class _NewLibraryScreenState extends State<NewLibraryScreen>
|
|||||||
child: ArtistDetailsScreen(
|
child: ArtistDetailsScreen(
|
||||||
artist: artist,
|
artist: artist,
|
||||||
heroTagSuffix: 'library',
|
heroTagSuffix: 'library',
|
||||||
|
initialImageUrl: imageUrl,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -404,6 +404,8 @@ class SearchScreenState extends State<SearchScreen> {
|
|||||||
|
|
||||||
Widget _buildArtistTile(Artist artist) {
|
Widget _buildArtistTile(Artist artist) {
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
final maProvider = context.read<MusicAssistantProvider>();
|
||||||
|
final imageUrl = maProvider.getImageUrl(artist, size: 256);
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: ArtistAvatar(
|
leading: ArtistAvatar(
|
||||||
@@ -428,7 +430,10 @@ class SearchScreenState extends State<SearchScreen> {
|
|||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => ArtistDetailsScreen(artist: artist),
|
builder: (context) => ArtistDetailsScreen(
|
||||||
|
artist: artist,
|
||||||
|
initialImageUrl: imageUrl,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class _ArtistCardState extends State<ArtistCard> {
|
|||||||
child: ArtistDetailsScreen(
|
child: ArtistDetailsScreen(
|
||||||
artist: widget.artist,
|
artist: widget.artist,
|
||||||
heroTagSuffix: widget.heroTagSuffix,
|
heroTagSuffix: widget.heroTagSuffix,
|
||||||
|
initialImageUrl: imageUrl,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user