feat: separate discs in album view when multiple are available

fixes #179
This commit is contained in:
Lei Nelissen
2024-07-21 23:48:33 +02:00
parent 7cdd01e713
commit ec4a2b6831
5 changed files with 111 additions and 78 deletions

View File

@@ -74,5 +74,6 @@
"privacy-policy": "Privacy Policy",
"sleep-timer": "Sleep timer",
"delete": "Delete",
"cancel": "Cancel"
"cancel": "Cancel",
"disc": "Disc"
}

View File

@@ -74,3 +74,4 @@ export type LocaleKeys = 'play-next'
| 'sleep-timer'
| 'delete'
| 'cancel'
| 'disc'

View File

@@ -25,6 +25,8 @@ import CoverImage from '@/components/CoverImage';
import ticksToDuration from '@/utility/ticksToDuration';
import { t } from '@/localisation';
import { SafeScrollView, useNavigationOffsets } from '@/components/SafeNavigatorView';
import { groupBy } from 'lodash';
import Divider from '@/components/Divider';
const styles = StyleSheet.create({
index: {
@@ -34,6 +36,12 @@ const styles = StyleSheet.create({
activeText: {
fontWeight: '500',
},
discContainer: {
flexDirection: 'row',
gap: 24,
alignItems: 'center',
marginBottom: 12,
}
});
const AlbumImageContainer = styled.View`
@@ -99,6 +107,18 @@ const TrackListView: React.FC<TrackListViewProps> = ({
), 0)
), [trackIds, tracks]);
// Split all tracks into trackgroups depending on their parent id (i.e. disc
// number).
const trackGroups: [string, string[]][] = useMemo(() => {
// GUARD: Only apply this rendering style for albums
if (listNumberingStyle !== 'album') {
return [['0', trackIds]];
}
const groups = groupBy(trackIds, (id) => tracks[id].ParentIndexNumber);
return Object.entries(groups);
}, [trackIds, tracks, listNumberingStyle]);
// Retrieve helpers
const getImage = useGetImage();
const playTracks = usePlayTracks();
@@ -162,7 +182,15 @@ const TrackListView: React.FC<TrackListViewProps> = ({
<WrappableButton title={shuffleButtonText} icon={Shuffle} onPress={shuffleEntity} testID="shuffle-album" />
</WrappableButtonRow>
<View style={{ marginTop: 8 }}>
{trackIds.map((trackId, i) =>
{trackGroups.map(([discNo, groupTrackIds]) => (
<View key={`disc_${discNo}`} style={{ marginBottom: 24 }}>
{trackGroups.length > 1 && (
<View style={styles.discContainer}>
<SubHeader>{t('disc')} {discNo}</SubHeader>
<Divider />
</View>
)}
{groupTrackIds.map((trackId, i) =>
<TouchableHandler
key={trackId}
id={i}
@@ -242,6 +270,8 @@ const TrackListView: React.FC<TrackListViewProps> = ({
</TrackContainer>
</TouchableHandler>
)}
</View>
))}
<Text style={{ paddingTop: 24, paddingBottom: 12, textAlign: 'center', opacity: 0.5 }}>
{t('total-duration')}{': '}{ticksToDuration(totalDuration)}
</Text>

View File

@@ -52,6 +52,7 @@ export interface AlbumTrack {
RunTimeTicks: number;
ProductionYear: number;
IndexNumber: number;
ParentIndexNumber: number;
IsFolder: boolean;
Type: 'Audio';
UserData: UserData;

View File

@@ -59,7 +59,7 @@ export async function retrieveRecentAlbums(numberOfAlbums = 24) {
export async function retrieveAlbumTracks(ItemId: string) {
const singleAlbumOptions = {
ParentId: ItemId,
SortBy: 'IndexNumber,SortName',
SortBy: 'ParentIndexNumber,IndexNumber,SortName',
};
const singleAlbumParams = new URLSearchParams(singleAlbumOptions).toString();