diff --git a/packages/components/albums/src/album-detail.ts b/packages/components/albums/src/album-detail.ts
index b628e62..b2068e1 100644
--- a/packages/components/albums/src/album-detail.ts
+++ b/packages/components/albums/src/album-detail.ts
@@ -59,6 +59,22 @@ export class AlbumDetail extends LitElement {
padding-bottom: 1rem;
font-size: 1rem;
}
+
+ h6 {
+ margin: 0;
+ padding-bottom: 1rem;
+ font-size: 0.8rem;
+ color: var(--secondary-text-color);
+ }
+
+ div.track {
+ display: flex;
+ justify-content: space-between;
+ }
+
+ div.track > .duration {
+ color: var(--secondary-text-color);
+ }
`;
constructor() {
@@ -82,17 +98,47 @@ export class AlbumDetail extends LitElement {
? html`(${this.album.releaseYear.value})`
: nothing}
+
${this._formatAlbumDuration()}
Tracks
- ${map(this.album.tracks, (track) => html`- ${track.name}
`)}
+ ${map(
+ this.album.tracks,
+ (track) =>
+ html`
+
- ${track.name}
+ ${this._formatDuration(track.durationInSeconds)}
+ `,
+ )}
`;
}
+
+ private _formatDuration(durationInSeconds: number): string {
+ if (durationInSeconds === 0) return "";
+
+ const date = new Date(0);
+ date.setSeconds(durationInSeconds);
+ return date.toLocaleTimeString("en-US", {
+ minute: "2-digit",
+ second: "2-digit",
+ });
+ }
+
+ private _formatAlbumDuration(): string {
+ const durationInSeconds = this.album.tracks.reduce(
+ (acc, track) => acc + track.durationInSeconds,
+ 0,
+ );
+ const durationInMinutes = Math.floor(durationInSeconds / 60);
+ return `${durationInMinutes} min`;
+ }
}
@customElement("album-detail-page")
diff --git a/packages/components/ui-atoms/src/layouts/two-column.layout.ts b/packages/components/ui-atoms/src/layouts/two-column.layout.ts
index d8064e5..ec5a8cd 100644
--- a/packages/components/ui-atoms/src/layouts/two-column.layout.ts
+++ b/packages/components/ui-atoms/src/layouts/two-column.layout.ts
@@ -9,7 +9,7 @@ export class TwoColumnLayout extends LitElement {
static styles = css`
div.container {
display: flex;
- height: 100vh;
+ padding-bottom: 2rem;
}
.left-column {
diff --git a/packages/core/types/src/model/track.ts b/packages/core/types/src/model/track.ts
index b22cc3b..f0ed639 100644
--- a/packages/core/types/src/model/track.ts
+++ b/packages/core/types/src/model/track.ts
@@ -69,7 +69,6 @@ export type Track = {
/**
* Duration of the track in milliseconds. It must be greater than zero.
- * TODO: We would need to download the entire track to get this information. Consider re-adding this field when we have a way to get this information.
*/
- // durationInMilliseconds: number,
+ durationInSeconds: number;
};
diff --git a/packages/core/types/src/services/metadata-provider.ts b/packages/core/types/src/services/metadata-provider.ts
index 80ed117..828ae37 100644
--- a/packages/core/types/src/services/metadata-provider.ts
+++ b/packages/core/types/src/services/metadata-provider.ts
@@ -59,6 +59,11 @@ export type TrackMetadata = {
* Keywords to reflect the mood of the audio, e.g. 'Romantic' or 'Sad'
*/
mood?: string | undefined;
+
+ /**
+ * Length of the track in seconds.
+ */
+ lengthInSeconds?: number | undefined;
};
/**
diff --git a/packages/infrastructure/mmb-metadata-provider/index.ts b/packages/infrastructure/mmb-metadata-provider/index.ts
index e4ccb9e..4610d34 100644
--- a/packages/infrastructure/mmb-metadata-provider/index.ts
+++ b/packages/infrastructure/mmb-metadata-provider/index.ts
@@ -48,6 +48,7 @@ const mmbMetadataProvider = MetadataProvider.of({
trackNumber: metadata.common.track.no ?? undefined,
embeddedCover,
year: metadata.common.year,
+ lengthInSeconds: metadata.format.duration,
};
}),
),
diff --git a/packages/infrastructure/spotify-provider/src/apis/list-albums-api.ts b/packages/infrastructure/spotify-provider/src/apis/list-albums-api.ts
index bbbfda8..a87285b 100644
--- a/packages/infrastructure/spotify-provider/src/apis/list-albums-api.ts
+++ b/packages/infrastructure/spotify-provider/src/apis/list-albums-api.ts
@@ -120,6 +120,7 @@ const toTrackSchema = (
},
secondaryArtists: [],
trackNumber: spotifyTrack.track_number,
+ durationInSeconds: spotifyTrack.duration_ms / 1000,
});
const downloadImage = (url?: string) =>
diff --git a/packages/workers/media-provider/src/sync/file-based-sync.ts b/packages/workers/media-provider/src/sync/file-based-sync.ts
index 67b8163..67f48c7 100644
--- a/packages/workers/media-provider/src/sync/file-based-sync.ts
+++ b/packages/workers/media-provider/src/sync/file-based-sync.ts
@@ -421,5 +421,6 @@ const createTrack = (
provider: FileBasedProviderId.OneDrive /* TODO: Take from metadata. */,
fileId: file.id,
},
+ durationInSeconds: metadata.lengthInSeconds ?? 0,
};
});