Compare commits

..

7 Commits

Author SHA1 Message Date
153f634a08 Adds ability to select a specific track within an album, and fixes info view not keeping position between albums.
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-19 23:40:35 -05:00
1f6c906576 Fixes odd expander button size issue
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-15 22:29:44 -05:00
c0ead41d21 Replaces latest tag with pipeline number
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
2024-07-09 04:49:21 +00:00
e383876bb0 Updates woodpecker file for manual pipeline runs
All checks were successful
ci/woodpecker/manual/woodpecker Pipeline was successful
2024-07-01 15:35:11 -05:00
eaf6d47ba0 Updates woodpecker file again 2024-06-29 00:25:02 -05:00
56c4cf014d Updates woodpecker file with hopefully better secret stuff 2024-06-29 00:16:45 -05:00
2c10ec28aa Updates dockerignore and woodpecker files
Some checks are pending
ci/woodpecker/push/woodpecker Pipeline is running
2024-06-29 00:05:20 -05:00
7 changed files with 59 additions and 32 deletions

3
.dockerignore Normal file
View File

@@ -0,0 +1,3 @@
**/node_modules/
**/dist
.git

View File

@@ -1,6 +1,15 @@
when:
branch: main
event:
- push
- manual
steps: steps:
- name: build - name: build
image: node:18-alpine image: woodpeckerci/plugin-docker-buildx
commands: settings:
- npm install repo: git.halfbinary.net/${CI_REPO_OWNER}/prettyplayerfe
- npm run build registry: git.halfbinary.net
tags: ${CI_PIPELINE_NUMBER}
username: ${CI_REPO_OWNER}
password:
from_secret: docker_password

View File

@@ -35,6 +35,25 @@
transition: height 2s; transition: height 2s;
} }
.player-container {
background: rgba(0,0,0,0.5);
position: sticky;
width: 100%;
bottom:0;
}
.expander {
align-self: center;
height:.75em;
aspect-ratio: 1 / 1;
background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 500%;
}
.album-title { .album-title {
font-size: larger; font-size: larger;
} }
@@ -42,17 +61,3 @@
.bold-title { .bold-title {
font-weight: bold; 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

@@ -12,6 +12,7 @@ function App() {
const [albums, setAlbums] = useState(Array<AlbumMetadata>) const [albums, setAlbums] = useState(Array<AlbumMetadata>)
const [selectedAlbum, setSelectedAlbum] = useState("") const [selectedAlbum, setSelectedAlbum] = useState("")
const [albumInfo, setAlbumInfo] = useState<AlbumInfo>() const [albumInfo, setAlbumInfo] = useState<AlbumInfo>()
const [isShowAlbumInfo, setIsShowAlbumInfo] = useState(false)
useEffect(() => { useEffect(() => {
let fetched = fetch(`${hostName}/album`) let fetched = fetch(`${hostName}/album`)
@@ -41,10 +42,14 @@ function App() {
setSelectedAlbum(event.currentTarget.id) setSelectedAlbum(event.currentTarget.id)
} }
function handleAlbumInfoAdjust() {
setIsShowAlbumInfo(!isShowAlbumInfo)
}
return ( return (
<div className={"gallery"}> <div className={"gallery"}>
<PhotoContainer imageList={albums} albumClickHandler={handleAlbumClick}/> <PhotoContainer imageList={albums} albumClickHandler={handleAlbumClick}/>
{albumInfo ? <AlbumPlayer albumHash={selectedAlbum} albumInfo={albumInfo} key={selectedAlbum}/> : <div></div> } {albumInfo ? <AlbumPlayer handleAlbumInfoAdjust={handleAlbumInfoAdjust} isShowAlbumInfo={isShowAlbumInfo} albumHash={selectedAlbum} albumInfo={albumInfo} key={selectedAlbum}/> : <div></div> }
</div> </div>
) )
} }

View File

@@ -1,9 +1,11 @@
import {AlbumInfo} from "../models/AlbumInfo.ts"; import {AlbumInfo} from "../models/AlbumInfo.ts";
import TrackListing from "./TrackListing.tsx"; import TrackListing from "./TrackListing.tsx";
import React from "react";
interface AlbumInfoDisplayProps { interface AlbumInfoDisplayProps {
albumInfo: AlbumInfo, albumInfo: AlbumInfo,
trackNumber: number trackNumber: number,
trackClickHandler: (event: React.MouseEvent<HTMLElement>, trackNumber: number) => void
} }
export default function AlbumInfoDisplay(props: Readonly<AlbumInfoDisplayProps>) { export default function AlbumInfoDisplay(props: Readonly<AlbumInfoDisplayProps>) {
let isVarious = props.albumInfo.albumArtist.startsWith("Various") let isVarious = props.albumInfo.albumArtist.startsWith("Various")
@@ -11,7 +13,7 @@ export default function AlbumInfoDisplay(props: Readonly<AlbumInfoDisplayProps>)
return ( return (
<div> <div>
<div className={`album-title`}>{!isVarious && `${props.albumInfo.albumArtist} - `}{props.albumInfo.albumTitle}</div> <div className={`album-title`}>{!isVarious && `${props.albumInfo.albumArtist} - `}{props.albumInfo.albumTitle}</div>
<TrackListing trackList={props.albumInfo.trackList} isOneArtist={isOneArtist} trackNumber={props.trackNumber}/> <TrackListing trackClickHandler={props.trackClickHandler} trackList={props.albumInfo.trackList} isOneArtist={isOneArtist} trackNumber={props.trackNumber}/>
</div> </div>
) )
} }

View File

@@ -1,4 +1,4 @@
import {useEffect, useState} from "react"; import React, {useEffect, useState} from "react";
import hostName from "../Config.ts"; import hostName from "../Config.ts";
import {AlbumInfo} from "../models/AlbumInfo.ts"; import {AlbumInfo} from "../models/AlbumInfo.ts";
import AlbumInfoDisplay from "./AlbumInfoDisplay.tsx"; import AlbumInfoDisplay from "./AlbumInfoDisplay.tsx";
@@ -9,12 +9,13 @@ import minimize from '/minimize-2.svg'
interface AlbumPlayerProps { interface AlbumPlayerProps {
albumHash: string, albumHash: string,
albumInfo: AlbumInfo albumInfo: AlbumInfo
handleAlbumInfoAdjust: () => void,
isShowAlbumInfo: boolean
} }
export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) { export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) {
const [trackNum, setTrackNum] = useState<number>(0) const [trackNum, setTrackNum] = useState<number>(0)
const [isAlbumOver, setIsAlbumOver] = useState(false) const [isAlbumOver, setIsAlbumOver] = useState(false)
const [isShowAlbumInfo, setIsShowAlbumInfo] = useState(false)
let album = props.albumInfo let album = props.albumInfo
@@ -30,16 +31,16 @@ export default function AlbumPlayer(props: Readonly<AlbumPlayerProps>) {
} }
} }
function handleAlbumInfoAdjust() { function handleTrackClick(_: React.MouseEvent<HTMLElement>, trackNumber: number) {
setIsShowAlbumInfo(!isShowAlbumInfo) setTrackNum(trackNumber)
} }
if(props.albumHash && album) { if(props.albumHash && album) {
console.log(album) console.log(album)
return ( return (
<div className={"player"}> <div className={"player-container"}>
<div className={`expander`} onClick={handleAlbumInfoAdjust} id={"maximizer"}>{isShowAlbumInfo ? <img src={minimize} alt={'minimize song text'}/> : <img src={maximize} alt={'show full album information'}/>}</div> <div className={`expander`} onClick={props.handleAlbumInfoAdjust} id={"maximizer"}>{props.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} />} <div>{props.isShowAlbumInfo ? <AlbumInfoDisplay albumInfo={props.albumInfo} trackNumber={trackNum} trackClickHandler={handleTrackClick} /> : <TrackInfoDisplay artist={album.trackList[trackNum].trackArtist} track={album.trackList[trackNum].trackTitle} />}</div>
<audio title={album.trackList[trackNum].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}/track/${trackNum}`} src={`${hostName}/music/album/${props.albumHash}/track/${trackNum}`}
onEnded={handleNextTrack} /> onEnded={handleNextTrack} />

View File

@@ -1,9 +1,11 @@
import {AlbumTrackInfo} from "../models/AlbumTrackInfo.ts"; import {AlbumTrackInfo} from "../models/AlbumTrackInfo.ts";
import React from "react";
interface TrackListingProps { interface TrackListingProps {
trackList: AlbumTrackInfo[], trackList: AlbumTrackInfo[],
isOneArtist: boolean, isOneArtist: boolean,
trackNumber: number trackNumber: number,
trackClickHandler: (event: React.MouseEvent<HTMLElement>, trackNumber: number) => void
} }
export default function TrackListing(props: Readonly<TrackListingProps>) { export default function TrackListing(props: Readonly<TrackListingProps>) {
return ( return (
@@ -12,7 +14,7 @@ export default function TrackListing(props: Readonly<TrackListingProps>) {
let rawKeyString = `${track.trackNumber}${track.trackArtist}${track.trackTitle}` let rawKeyString = `${track.trackNumber}${track.trackArtist}${track.trackTitle}`
let isCurrentTrack = index===props.trackNumber let isCurrentTrack = index===props.trackNumber
return ( return (
<div key={rawKeyString} className={ isCurrentTrack ? `bold-title` : ``}>{track.trackNumber}. {!props.isOneArtist && `${track.trackArtist} - `}{track.trackTitle}</div> <div onClick={(e) => props.trackClickHandler(e, index)} key={rawKeyString} className={ isCurrentTrack ? `bold-title` : ``}>{track.trackNumber}. {!props.isOneArtist && `${track.trackArtist} - `}{track.trackTitle}</div>
) )
})} })}
</div> </div>