Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/redesign' into new-track-list-tile
Browse files Browse the repository at this point in the history
  • Loading branch information
Chaphasilor committed Nov 9, 2024
2 parents 0957900 + 672e7ac commit 67fc3d2
Show file tree
Hide file tree
Showing 16 changed files with 344 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ class _AddToPlaylistTileState extends State<AddToPlaylistTile> {
?.playlistItemId;
itemIsIncluded = true;
});
return playlistItemId != null;
return true; // this is called before the state is updated
}
return false;
}
Expand Down
12 changes: 12 additions & 0 deletions lib/components/AlbumScreen/album_screen_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,18 @@ class _SongsSliverListState extends State<SongsSliverList> {

@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) {
Expand Down
8 changes: 6 additions & 2 deletions lib/components/ArtistScreen/artist_screen_content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ class _ArtistScreenContentState extends State<ArtistScreenContent> {
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: <Widget>[
SliverAppBar(
Expand Down Expand Up @@ -156,7 +160,7 @@ class _ArtistScreenContentState extends State<ArtistScreenContent> {
if (!isOffline &&
FinampSettingsHelper.finampSettings.showArtistsTopSongs)
SongsSliverList(
childrenForList: songs.take(5).toList(),
childrenForList: topTracks,
childrenForQueue: Future.value(songs),
showPlayCount: true,
isOnArtistScreen: true,
Expand All @@ -182,4 +186,4 @@ class _ArtistScreenContentState extends State<ArtistScreenContent> {
]);
});
}
}
}
6 changes: 3 additions & 3 deletions lib/components/Buttons/simple_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ class SimpleButton extends StatelessWidget {
color: (disabled || inactive) ? iconColor?.withOpacity(0.5) : iconColor,
weight: 1.5,
),
const SizedBox(
width: 6,
),
Text(
text,
style: TextStyle(
Expand All @@ -51,6 +48,7 @@ class SimpleButton extends StatelessWidget {
fontSize: 14,
fontWeight: FontWeight.normal,
),
textAlign: TextAlign.center,
),
];

Expand All @@ -74,6 +72,8 @@ class SimpleButton extends StatelessWidget {
),
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
alignment: WrapAlignment.center,
spacing: 6.0,
children: iconPosition == IconPosition.start
? contents
: contents.reversed.toList(),
Expand Down
39 changes: 39 additions & 0 deletions lib/components/MusicScreen/music_screen_tab_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -314,6 +318,39 @@ class _MusicScreenTabViewState extends State<MusicScreenTabView>
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
Expand Down Expand Up @@ -357,6 +394,7 @@ class _MusicScreenTabViewState extends State<MusicScreenTabView>
const FirstPageProgressIndicator(),
newPageProgressIndicatorBuilder: (_) =>
const NewPageProgressIndicator(),
noItemsFoundIndicatorBuilder: (_) => emptyListIndicator,
),
separatorBuilder: (context, index) => const SizedBox.shrink(),
)
Expand Down Expand Up @@ -387,6 +425,7 @@ class _MusicScreenTabViewState extends State<MusicScreenTabView>
const FirstPageProgressIndicator(),
newPageProgressIndicatorBuilder: (_) =>
const NewPageProgressIndicator(),
noItemsFoundIndicatorBuilder: (_) => emptyListIndicator,
),
gridDelegate: FinampSettingsHelper
.finampSettings.useFixedSizeGridTiles
Expand Down
27 changes: 24 additions & 3 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,7 @@
},
"description": "Tooltip for downloadbutton on incidental downloads, which show a lock icon. It says one of the requiring downloads."
},
"finampCollectionNames": "{itemType, select, favorites{Favorites} allPlaylists{All Playlists} fiveLatestAlbums{5 Latest Albums} allPlaylistsMetadata{Info for All Playlists} other{{itemType}} }",
"finampCollectionNames": "{itemType, select, favorites{Favorites} allPlaylists{All Playlists} fiveLatestAlbums{5 Latest Albums} allPlaylistsMetadata{Playlist Metadata} other{{itemType}} }",
"@finampCollectionNames": {
"placeholders": {
"itemType": {
Expand All @@ -1401,6 +1401,11 @@
},
"description": "Localized names of special downloadable collection representing cached images for a certain library."
},
"transcodingStreamingContainerTitle": "Select Transcoding Container",
"@transcodingStreamingContainerTitle": {
"description": "Title for the dropdown that selects the container format for transcoded streams"
},
"transcodingStreamingContainerSubtitle": "Select the segment container to use when streaming transcoded audio. Already queued tracks will not be affected.",
"downloadTranscodeEnableTitle": "Enable Transcoded Downloads",
"@downloadTranscodeEnableTitle": {
"description": "Title for Enable Transcoded Downloads dropdown"
Expand Down Expand Up @@ -1608,8 +1613,8 @@
},
"trackOfflineFavorites": "Sync all favorite statuses",
"trackOfflineFavoritesSubtitle": "This allows showing more up-to-date favorite statuses while offline. Does not download any additional files.",
"allPlaylistsInfoSetting": "Show all playlists offline",
"allPlaylistsInfoSettingSubtitle": "Sync metadata for all playlists to show partially downloaded playlists offline",
"allPlaylistsInfoSetting": "Download Playlist Metadata",
"allPlaylistsInfoSettingSubtitle": "Sync metadata for all playlists to improve your playlist experience",
"downloadFavoritesSetting": "Download all favorites",
"downloadAllPlaylistsSetting": "Download all playlists",
"fiveLatestAlbumsSetting": "Download 5 latest albums",
Expand Down Expand Up @@ -1792,5 +1797,21 @@
"showCoversOnAlbumScreenSubtitle": "Show album covers for each track separately on the album screen.",
"@showCoversOnAlbumScreenSubtitle": {
"description": "Subtitle for the setting that controls if album covers are shown for each track separately on the album 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"
}
}
14 changes: 13 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@ import 'services/jellyfin_api_helper.dart';
import 'services/locale_helper.dart';
import 'services/music_player_background_task.dart';
import 'services/theme_mode_helper.dart';
import 'services/ui_overlay_setter_observer.dart';
import 'setup_logging.dart';

void main() async {
// If the app has failed, this is set to true. If true, we don't attempt to run the main app since the error app has started.
bool hasFailed = false;
try {
await setupLogging();
await _setupEdgeToEdgeOverlayStyle();
await setupHive();
_migrateDownloadLocations();
_migrateSortOptions();
Expand Down Expand Up @@ -120,6 +122,15 @@ void main() async {
}
}

Future<void> _setupEdgeToEdgeOverlayStyle() async {
if (Platform.isAndroid) {
await SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(systemNavigationBarColor: Colors.transparent));
final binding = WidgetsFlutterBinding.ensureInitialized();
binding.addObserver(UIOverlaySetterObserver());
}
}

Future<void> _setupJellyfinApiData() async {
GetIt.instance.registerSingleton(JellyfinApiHelper());
}
Expand All @@ -140,7 +151,7 @@ Future<void> _setupDownloadsHelper() async {
final downloadsService = GetIt.instance<DownloadsService>();

if (!FinampSettingsHelper
.finampSettings.hasCompleteddownloadsServiceMigration) {
.finampSettings.hasCompletedDownloadsServiceMigration) {
await downloadsService.migrateFromHive();
FinampSettingsHelper.setHasCompleteddownloadsServiceMigration(true);
}
Expand Down Expand Up @@ -219,6 +230,7 @@ Future<void> setupHive() async {
Hive.registerAdapter(LyricsAlignmentAdapter());
Hive.registerAdapter(LyricsFontSizeAdapter());
Hive.registerAdapter(KeepScreenOnOptionAdapter());
Hive.registerAdapter(FinampSegmentContainerAdapter());
Hive.registerAdapter(FinampFeatureChipsConfigurationAdapter());
Hive.registerAdapter(FinampFeatureChipTypeAdapter());

Expand Down
36 changes: 30 additions & 6 deletions lib/models/finamp_models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ const _showStopButtonOnMediaNotificationDefault = false;
const _showSeekControlsOnMediaNotificationDefault = true;
const _keepScreenOnOption = KeepScreenOnOption.whileLyrics;
const _keepScreenOnWhilePluggedIn = true;
const _hasDownloadedPlaylistInfoDefault = false;
const _defaultTranscodingSegmentContainer =
FinampSegmentContainer.fragmentedMp4;
const _featureChipsConfigurationDefault =
FinampFeatureChipsConfiguration(enabled: true, features: [
FinampFeatureChipType.playCount,
Expand Down Expand Up @@ -167,7 +170,7 @@ class FinampSettings {
this.autoloadLastQueueOnStartup = _autoLoadLastQueueOnStartup,
this.hasCompletedBlurhashImageMigration = true,
this.hasCompletedBlurhashImageMigrationIdFix = true,
this.hasCompleteddownloadsServiceMigration = true,
this.hasCompletedDownloadsServiceMigration = true,
this.requireWifiForDownloads = false,
this.onlyShowFullyDownloaded = false,
this.showDownloadsWithUnknownLibrary = true,
Expand Down Expand Up @@ -208,7 +211,9 @@ class FinampSettings {
this.keepScreenOnOption = _keepScreenOnOption,
this.keepScreenOnWhilePluggedIn = _keepScreenOnWhilePluggedIn,
this.featureChipsConfiguration = _featureChipsConfigurationDefault,
this.showCoversOnAlbumScreen = _showCoversOnAlbumScreenDefault});
this.showCoversOnAlbumScreen = _showCoversOnAlbumScreenDefault,
this.hasDownloadedPlaylistInfo = _hasDownloadedPlaylistInfoDefault,
this.transcodingSegmentContainer = _defaultTranscodingSegmentContainer});

@HiveField(0, defaultValue: _isOfflineDefault)
bool isOffline;
Expand Down Expand Up @@ -318,7 +323,7 @@ class FinampSettings {
VolumeNormalizationMode volumeNormalizationMode;

@HiveField(34, defaultValue: false)
bool hasCompleteddownloadsServiceMigration;
bool hasCompletedDownloadsServiceMigration;

@HiveField(35, defaultValue: false)
bool requireWifiForDownloads;
Expand Down Expand Up @@ -441,10 +446,16 @@ class FinampSettings {
@HiveField(73, defaultValue: _keepScreenOnWhilePluggedIn)
bool keepScreenOnWhilePluggedIn;

@HiveField(74, defaultValue: _featureChipsConfigurationDefault)
@HiveField(74, defaultValue: _hasDownloadedPlaylistInfoDefault)
bool hasDownloadedPlaylistInfo;

@HiveField(75, defaultValue: _defaultTranscodingSegmentContainer)
FinampSegmentContainer transcodingSegmentContainer;

@HiveField(76, defaultValue: _featureChipsConfigurationDefault)
FinampFeatureChipsConfiguration featureChipsConfiguration;

@HiveField(75, defaultValue: _showCoversOnAlbumScreenDefault)
@HiveField(77, defaultValue: _showCoversOnAlbumScreenDefault)
bool showCoversOnAlbumScreen;

static Future<FinampSettings> create() async {
Expand Down Expand Up @@ -2250,6 +2261,19 @@ enum KeepScreenOnOption {
}

@HiveType(typeId: 73)
enum FinampSegmentContainer {
@HiveField(0)
mpegTS("ts"),
@HiveField(1)
fragmentedMp4("mp4");

const FinampSegmentContainer(this.container);

/// The container to use to transport the segments
final String container;
}

@HiveType(typeId: 74)
enum FinampFeatureChipType {
@HiveField(0)
playCount,
Expand Down Expand Up @@ -2327,7 +2351,7 @@ enum FinampFeatureChipType {
}

@JsonSerializable()
@HiveType(typeId: 74)
@HiveType(typeId: 75)
class FinampFeatureChipsConfiguration {
const FinampFeatureChipsConfiguration({
required this.enabled,
Expand Down
Loading

0 comments on commit 67fc3d2

Please sign in to comment.