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`
  1. ${track.name}
  2. `)} + ${map( + this.album.tracks, + (track) => + html`
    +
  3. ${track.name}
  4. + ${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, }; });