feat(album): display disc groups from catalog metadata

This commit is contained in:
zarzet committed 2026-09-26 23:24:12 +07:00
1 parent 6b17f06a5b
commit 06951f742a
4 files changed
+130 -5

No files matched your search

+22 -1
View File
@@ -36,6 +36,7 @@ import 'package:spotiflac_android/widgets/track_detail_actions.dart';
import 'package:spotiflac_android/widgets/selection_action_button.dart';
import 'package:spotiflac_android/widgets/selection_bottom_bar.dart';
import 'package:spotiflac_android/widgets/downloadable_cover.dart';
import 'package:spotiflac_android/widgets/disc_separator_chip.dart';
import 'package:spotiflac_android/widgets/mornye_artist_header.dart';
class _AlbumCache {
@@ -628,6 +629,14 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen>
final existingHistoryKeys = ref.watch(
downloadHistoryVisibleBatchExistsProvider(_historySnapshot.request),
);
int discNumber(Track track) {
final number = track.discNumber ?? 1;
return number > 0 ? number : 1;
}
final hasMultipleDiscs = tracks.any(
(track) => discNumber(track) > 1 || (track.totalDiscs ?? 1) > 1,
);
return SliverPadding(
padding: EdgeInsets.symmetric(horizontal: wideListInset(context)),
sliver: SliverList(
@@ -637,7 +646,7 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen>
final isInHistory = existingHistoryKeys.contains(
historyLookups[index].lookupKey,
);
return KeyedSubtree(
final row = KeyedSubtree(
key: ValueKey(selectionId),
child: StaggeredListItem(
index: index,
@@ -675,6 +684,18 @@ class _AlbumScreenState extends ConsumerState<AlbumScreen>
),
),
);
final disc = discNumber(track);
if (hasMultipleDiscs &&
(index == 0 || discNumber(tracks[index - 1]) != disc)) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
DiscSeparatorChip(discNumber: disc),
row,
],
);
}
return row;
}, childCount: tracks.length),
),
);
+6 -4
View File
@@ -490,10 +490,12 @@ class _CollectionHeaderSkeleton extends StatelessWidget {
children: [
const SkeletonBox(width: 48, height: 48, borderRadius: 24),
const SizedBox(width: 16),
SkeletonBox(
width: screenWidth * 0.45,
height: 48,
borderRadius: 24,
Flexible(
child: SkeletonBox(
width: screenWidth * 0.45,
height: 48,
borderRadius: 24,
),
),
const SizedBox(width: 16),
const SkeletonBox(width: 48, height: 48, borderRadius: 24),
+23
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:spotiflac_android/l10n/l10n.dart';
import 'package:spotiflac_android/theme/mornye_theme.dart';
/// "Disc N" chip with a trailing hairline, shown between disc groups in
/// album track lists.
@@ -11,6 +12,28 @@ class DiscSeparatorChip extends StatelessWidget {
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
if (context.isMornye) {
return Padding(
padding: const EdgeInsets.fromLTRB(20, 20, 20, 8),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Divider(
height: 1,
color: MornyeTheme.metadataDividerColor(context),
),
const SizedBox(height: 12),
Text(
context.l10n.downloadedAlbumDiscHeader(discNumber),
style: Theme.of(context).textTheme.titleSmall?.copyWith(
color: colorScheme.onSurfaceVariant,
fontWeight: FontWeight.w600,
),
),
],
),
);
}
return Padding(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 8),