diff --git a/lib/components/AlbumScreen/album_screen_content.dart b/lib/components/AlbumScreen/album_screen_content.dart index 80f53e01..bee56f48 100644 --- a/lib/components/AlbumScreen/album_screen_content.dart +++ b/lib/components/AlbumScreen/album_screen_content.dart @@ -163,6 +163,18 @@ class _SongsSliverListState extends State { @override Widget build(BuildContext context) { + if (widget.childrenForList.isEmpty) { + return SliverToBoxAdapter( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0), + child: Text( + AppLocalizations.of(context)!.emptyTopTracksList, + style: Theme.of(context).textTheme.bodyMedium, + textAlign: TextAlign.center, + ), + ), + ); + } return SliverList( delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { diff --git a/lib/components/ArtistScreen/artist_screen_content.dart b/lib/components/ArtistScreen/artist_screen_content.dart index 3c53840c..cfc081b5 100644 --- a/lib/components/ArtistScreen/artist_screen_content.dart +++ b/lib/components/ArtistScreen/artist_screen_content.dart @@ -112,6 +112,10 @@ class _ArtistScreenContentState extends State { builder: (context, snapshot) { var songs = snapshot.data?.elementAtOrNull(0) ?? []; var albums = snapshot.data?.elementAtOrNull(1) ?? []; + var topTracks = songs + .takeWhile((s) => (s.userData?.playCount ?? 0) > 0) + .take(5) + .toList(); return CustomScrollView(slivers: [ SliverAppBar( @@ -156,10 +160,7 @@ class _ArtistScreenContentState extends State { if (!isOffline && FinampSettingsHelper.finampSettings.showArtistsTopSongs) SongsSliverList( - childrenForList: songs - .takeWhile((s) => (s.userData?.playCount ?? 0) > 0) - .take(5) - .toList(), + childrenForList: topTracks, childrenForQueue: Future.value(songs), showPlayCount: true, isOnArtistScreen: true, diff --git a/lib/components/MusicScreen/music_screen_tab_view.dart b/lib/components/MusicScreen/music_screen_tab_view.dart index cab555e5..dffe0cd2 100644 --- a/lib/components/MusicScreen/music_screen_tab_view.dart +++ b/lib/components/MusicScreen/music_screen_tab_view.dart @@ -2,13 +2,17 @@ import 'dart:async'; import 'dart:math'; import 'package:collection/collection.dart'; +import 'package:finamp/components/Buttons/cta_medium.dart'; +import 'package:finamp/components/Buttons/simple_button.dart'; import 'package:finamp/services/finamp_user_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; +import 'package:flutter_tabler_icons/flutter_tabler_icons.dart'; import 'package:get_it/get_it.dart'; import 'package:hive/hive.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import '../../models/finamp_models.dart'; import '../../models/jellyfin_models.dart'; @@ -314,6 +318,39 @@ class _MusicScreenTabViewState extends State refreshHash = newRefreshHash; } + final emptyListIndicator = Padding( + padding: + const EdgeInsets.symmetric(vertical: 16.0, horizontal: 32.0), + child: Column( + children: [ + Text( + AppLocalizations.of(context)!.emptyFilteredListTitle, + style: TextStyle( + fontSize: 24, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + Text( + AppLocalizations.of(context)!.emptyFilteredListSubtitle, + style: TextStyle( + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 8), + CTAMedium( + icon: TablerIcons.filter_x, + text: AppLocalizations.of(context)!.resetFiltersButton, + onPressed: () { + FinampSettingsHelper.setOnlyShowFavourite(false); + FinampSettingsHelper.setOnlyShowFullyDownloaded(false); + }, + ) + ], + ), + ); + var tabContent = box.get("FinampSettings")!.contentViewType == ContentViewType.list || widget.tabContentType == TabContentType.songs @@ -357,6 +394,7 @@ class _MusicScreenTabViewState extends State const FirstPageProgressIndicator(), newPageProgressIndicatorBuilder: (_) => const NewPageProgressIndicator(), + noItemsFoundIndicatorBuilder: (_) => emptyListIndicator, ), separatorBuilder: (context, index) => const SizedBox.shrink(), ) @@ -387,6 +425,7 @@ class _MusicScreenTabViewState extends State const FirstPageProgressIndicator(), newPageProgressIndicatorBuilder: (_) => const NewPageProgressIndicator(), + noItemsFoundIndicatorBuilder: (_) => emptyListIndicator, ), gridDelegate: FinampSettingsHelper .finampSettings.useFixedSizeGridTiles diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 6aaf8d0c..8130a13b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -1773,5 +1773,21 @@ "showFeatureChipsToggleSubtitle": "Show advanced track info like codec, bit rate, and more on the player screen.", "@showFeatureChipsToggleSubtitle": { "description": "Subtitle for the setting that controls if the feature chips showing advanced track info are shown on the player screen" + }, + "emptyTopTracksList": "You haven't listened to any track by this artist yet.", + "@emptyTopTracksList": { + "description": "Message shown as a placeholder when the top tracks list for an artist is empty" + }, + "emptyFilteredListTitle": "No items found", + "@emptyFilteredListTitle": { + "description": "Message shown when a list of items is filtered and no items match the filter" + }, + "emptyFilteredListSubtitle": "No items match the filter. Try turning off the filter or changing the search term.", + "@emptyFilteredListSubtitle": { + "description": "Message shown when a list of items is filtered and no items match the filter" + }, + "resetFiltersButton": "Reset filters", + "@resetFiltersButton": { + "description": "Button to reset filters on a list of items" } }