Adds ability to display all album tracks. Also rearranges files to be more organized by type.

This commit is contained in:
aarbit 2024-06-10 23:27:39 -05:00
parent 368da13d3d
commit 639673a1c0
13 changed files with 92 additions and 11 deletions

1
public/maximize-2.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" y1="3" x2="14" y2="10"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>

After

Width:  |  Height:  |  Size: 400 B

1
public/minimize-2.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-minimize-2"><polyline points="4 14 10 14 10 20"></polyline><polyline points="20 10 14 10 14 4"></polyline><line x1="14" y1="10" x2="21" y2="3"></line><line x1="3" y1="21" x2="10" y2="14"></line></svg>

After

Width:  |  Height:  |  Size: 404 B

View File

@ -28,8 +28,30 @@
.player {
background: rgba(0,0,0,0.5);
position: -webkit-sticky;
position: sticky;
width: 100%;
bottom:0;
}
transition: height 2s;
}
.album-title {
font-size: larger;
}
.bold-title {
font-weight: bold;
}
.expander {
position: absolute;
height: 8vmin;
width: 8vmin;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%;
margin-top: 1vmin;
margin-left: 5vmin;
display: flex;
justify-content: center;
align-items: center;
font-size: 500%;
}

View File

@ -1,10 +1,10 @@
import React, {useEffect, useState} from 'react'
import './App.css'
import {AlbumMetadata} from "./AlbumMetadata.ts"
import PhotoContainer from "./PhotoContainer.tsx";
import AlbumPlayer from "./AlbumPlayer.tsx";
import {AlbumMetadata} from "./models/AlbumMetadata.ts"
import PhotoContainer from "./components/PhotoContainer.tsx";
import AlbumPlayer from "./components/AlbumPlayer.tsx";
import hostName from "./Config.ts";
import {AlbumInfo} from "./AlbumInfo.ts";
import {AlbumInfo} from "./models/AlbumInfo.ts";

View File

@ -0,0 +1,17 @@
import {AlbumInfo} from "../models/AlbumInfo.ts";
import TrackListing from "./TrackListing.tsx";
interface AlbumInfoDisplayProps {
albumInfo: AlbumInfo,
trackNumber: number
}
export default function AlbumInfoDisplay(props: Readonly<AlbumInfoDisplayProps>) {
let isVarious = props.albumInfo.albumArtist.startsWith("Various")
let isOneArtist = props.albumInfo.albumArtist === props.albumInfo.trackList[0].trackArtist
return (
<div>
<div className={`album-title`}>{!isVarious && `${props.albumInfo.albumArtist} - `}{props.albumInfo.albumTitle}</div>
<TrackListing trackList={props.albumInfo.trackList} isOneArtist={isOneArtist} trackNumber={props.trackNumber}/>
</div>
)
}

View File

@ -1,6 +1,10 @@
import {useState} from "react";
import hostName from "./Config.ts";
import {AlbumInfo} from "./AlbumInfo.ts";
import hostName from "../Config.ts";
import {AlbumInfo} from "../models/AlbumInfo.ts";
import AlbumInfoDisplay from "./AlbumInfoDisplay.tsx";
import TrackInfoDisplay from "./TrackInfoDisplay.tsx";
import maximize from '/maximize-2.svg'
import minimize from '/minimize-2.svg'
interface AlbumPlayerProps {
albumHash: string,
@ -10,6 +14,7 @@ interface AlbumPlayerProps {
export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) {
const [trackNum, setTrackNum] = useState<number>(0)
const [isAlbumOver, setIsAlbumOver] = useState(false)
const [isShowAlbumInfo, setIsShowAlbumInfo] = useState(false)
let album = props.albumInfo
function handleNextTrack() {
@ -18,14 +23,18 @@ export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) {
} else {
setTrackNum(trackNum+1)
}
}
function handleAlbumInfoAdjust() {
setIsShowAlbumInfo(!isShowAlbumInfo)
}
if(props.albumHash && album) {
console.log(album)
return (
<div className={"player"}>
<div>{album.trackList[trackNum].trackArtist} - {album.trackList[trackNum].trackTitle}</div>
<div className={`expander`} onClick={handleAlbumInfoAdjust} id={"maximizer"}>{isShowAlbumInfo ? <img src={minimize} alt={'minimize song text'}/> : <img src={maximize} alt={'show full album information'}/>}</div>
{isShowAlbumInfo ? <AlbumInfoDisplay albumInfo={props.albumInfo} trackNumber={trackNum} /> : <TrackInfoDisplay artist={album.trackList[trackNum].trackArtist} track={album.trackList[trackNum].trackTitle} />}
<audio title={album.trackList[trackNum].trackTitle} controls={true} autoPlay={true} preload={"metadata"}
src={`${hostName}/music/album/${props.albumHash}/track/${trackNum}`}
onEnded={handleNextTrack} />

View File

@ -1,6 +1,6 @@
import {AlbumMetadata} from "./AlbumMetadata.ts";
import {AlbumMetadata} from "../models/AlbumMetadata.ts";
import React from "react";
import hostName from "./Config.ts";
import hostName from "../Config.ts";
interface PhotoContainerProps {
imageList: AlbumMetadata[],

View File

@ -0,0 +1,11 @@
interface TrackInfoDisplayProps {
artist: string,
track: string
}
export default function TrackInfoDisplay(props: Readonly<TrackInfoDisplayProps>) {
return (
<div>
<div className={`album-title`}>{`${props.artist} - `}{props.track}</div>
</div>
)
}

View File

@ -0,0 +1,20 @@
import {AlbumTrackInfo} from "../models/AlbumTrackInfo.ts";
interface TrackListingProps {
trackList: AlbumTrackInfo[],
isOneArtist: boolean,
trackNumber: number
}
export default function TrackListing(props: Readonly<TrackListingProps>) {
return (
<div>
{props.trackList.map((track, index) => {
let rawKeyString = `${track.trackNumber}${track.trackArtist}${track.trackTitle}`
let isCurrentTrack = index===props.trackNumber
return (
<div key={rawKeyString} className={ isCurrentTrack ? `bold-title` : ``}>{track.trackNumber}. {!props.isOneArtist && `${track.trackArtist} - `}{track.trackTitle}</div>
)
})}
</div>
)
}