Adds support for whole album information consumption. Cleans up track number calculation.
This commit is contained in:
parent
0bd4992ed6
commit
f6921b7025
@ -1,39 +1,33 @@
|
|||||||
import {useEffect, useState} from "react";
|
import {useState} from "react";
|
||||||
import hostName from "./Config.ts";
|
import hostName from "./Config.ts";
|
||||||
import {TrackInfo} from "./TrackInfo.tsx";
|
import {AlbumInfo} from "./AlbumInfo.ts";
|
||||||
|
|
||||||
interface AlbumPlayerProps {
|
interface AlbumPlayerProps {
|
||||||
albumHash: string
|
albumHash: string,
|
||||||
|
albumInfo: AlbumInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) {
|
export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) {
|
||||||
const [trackNum, setTrackNum] = useState(1)
|
const [trackNum, setTrackNum] = useState<number>(0)
|
||||||
const [trackInfo, setTrackInfo] = useState<TrackInfo>()
|
const [isAlbumOver, setIsAlbumOver] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (props.albumHash) {
|
|
||||||
let fetched = fetch(`${hostName}/track/${props.albumHash}/${trackNum}`)
|
|
||||||
fetched.then(response => {
|
|
||||||
if (response.ok) {
|
|
||||||
response.json().then(body => {
|
|
||||||
setTrackInfo(body)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, [props.albumHash, trackNum])
|
|
||||||
|
|
||||||
|
let album = props.albumInfo
|
||||||
function handleNextTrack() {
|
function handleNextTrack() {
|
||||||
setTrackNum(trackNum+1)
|
if(!isAlbumOver && trackNum+1 === props.albumInfo.trackList.length) {
|
||||||
|
setIsAlbumOver(true)
|
||||||
|
} else {
|
||||||
|
setTrackNum(trackNum+1)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(props.albumHash) {
|
if(props.albumHash && album) {
|
||||||
|
console.log(album)
|
||||||
return (
|
return (
|
||||||
<div className={"player"}>
|
<div className={"player"}>
|
||||||
<div>{trackInfo?.artist ?? ""} - {trackInfo?.trackTitle ?? ""}</div>
|
<div>{album.trackList[trackNum].trackArtist} - {album.trackList[trackNum].trackTitle}</div>
|
||||||
<audio title={trackInfo?.trackTitle} controls={true} autoPlay={true} preload={"metadata"}
|
<audio title={album.trackList[trackNum].trackTitle} controls={true} autoPlay={true} preload={"metadata"}
|
||||||
src={`${hostName}/music/album/${props.albumHash}/${trackNum}`}
|
src={`${hostName}/music/album/${props.albumHash}/track/${trackNum}`}
|
||||||
onEnded={handleNextTrack} />
|
onEnded={handleNextTrack} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
5
src/AlbumTrackInfo.ts
Normal file
5
src/AlbumTrackInfo.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export interface AlbumTrackInfo {
|
||||||
|
trackNumber: number,
|
||||||
|
trackArtist: string,
|
||||||
|
trackTitle: string
|
||||||
|
}
|
||||||
23
src/App.tsx
23
src/App.tsx
@ -1,18 +1,20 @@
|
|||||||
import React, {useEffect, useState} from 'react'
|
import React, {useEffect, useState} from 'react'
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import {AlbumInfo} from "./AlbumInfo.ts"
|
import {AlbumMetadata} from "./AlbumMetadata.ts"
|
||||||
import PhotoContainer from "./PhotoContainer.tsx";
|
import PhotoContainer from "./PhotoContainer.tsx";
|
||||||
import AlbumPlayer from "./AlbumPlayer.tsx";
|
import AlbumPlayer from "./AlbumPlayer.tsx";
|
||||||
import hostName from "./Config.ts";
|
import hostName from "./Config.ts";
|
||||||
|
import {AlbumInfo} from "./AlbumInfo.ts";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [albums, setAlbums] = useState(Array<AlbumInfo>)
|
const [albums, setAlbums] = useState(Array<AlbumMetadata>)
|
||||||
const [selectedAlbum, setSelectedAlbum] = useState("")
|
const [selectedAlbum, setSelectedAlbum] = useState("")
|
||||||
|
const [albumInfo, setAlbumInfo] = useState<AlbumInfo>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let fetched = fetch(`${hostName}/albums`)
|
let fetched = fetch(`${hostName}/album`)
|
||||||
fetched.then(response => {
|
fetched.then(response => {
|
||||||
if(response.ok) {
|
if(response.ok) {
|
||||||
response.json().then( body =>
|
response.json().then( body =>
|
||||||
@ -22,6 +24,19 @@ function App() {
|
|||||||
})
|
})
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (selectedAlbum) {
|
||||||
|
let fetched = fetch(`${hostName}/album/${selectedAlbum}`)
|
||||||
|
fetched.then(response => {
|
||||||
|
if (response.ok) {
|
||||||
|
response.json().then(body =>
|
||||||
|
setAlbumInfo(body)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [selectedAlbum])
|
||||||
|
|
||||||
function handleAlbumClick(event: React.MouseEvent<HTMLElement>) {
|
function handleAlbumClick(event: React.MouseEvent<HTMLElement>) {
|
||||||
setSelectedAlbum(event.currentTarget.id)
|
setSelectedAlbum(event.currentTarget.id)
|
||||||
}
|
}
|
||||||
@ -29,7 +44,7 @@ function App() {
|
|||||||
return (
|
return (
|
||||||
<div className={"gallery"}>
|
<div className={"gallery"}>
|
||||||
<PhotoContainer imageList={albums} albumClickHandler={handleAlbumClick}/>
|
<PhotoContainer imageList={albums} albumClickHandler={handleAlbumClick}/>
|
||||||
<AlbumPlayer albumHash={selectedAlbum} key={selectedAlbum}/>
|
{albumInfo ? <AlbumPlayer albumHash={selectedAlbum} albumInfo={albumInfo} key={selectedAlbum}/> : <div></div> }
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import {AlbumInfo} from "./AlbumInfo.ts";
|
import {AlbumMetadata} from "./AlbumMetadata.ts";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import hostName from "./Config.ts";
|
import hostName from "./Config.ts";
|
||||||
|
|
||||||
interface PhotoContainerProps {
|
interface PhotoContainerProps {
|
||||||
imageList: AlbumInfo[],
|
imageList: AlbumMetadata[],
|
||||||
albumClickHandler: (event: React.MouseEvent<HTMLElement>) => void
|
albumClickHandler: (event: React.MouseEvent<HTMLElement>) => void
|
||||||
}
|
}
|
||||||
export default function PhotoContainer(props: PhotoContainerProps) {
|
export default function PhotoContainer(props: PhotoContainerProps) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user