Skip to content

Commit

Permalink
refactor out current playing context, create controls hook
Browse files Browse the repository at this point in the history
  • Loading branch information
IkeHunter committed Jan 4, 2025
1 parent 05cadea commit 4c043cd
Show file tree
Hide file tree
Showing 13 changed files with 195 additions and 182 deletions.
73 changes: 49 additions & 24 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useContext, useEffect } from 'react'
import { useCallback, useContext, useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { Outlet } from 'react-router-dom'
import { SPOTIFY_AUTH_CHECK_MS } from './config'
Expand All @@ -8,38 +8,69 @@ import {
SpotifyPlayerProvider,
Theme,
} from './context'
import { CurrentlyPlayingProvider } from './context/CurrentlyPlayingContext'
import {
authenticateLink,
checkLinkAuth,
doPlayerAction,
fetchCurrentlyPlaying,
fetchNextTracks,
incrementLiveProgress,
selectCurrentJukebox,
selectPlayerState,
selectSpotifyAuth,
setNextTracks,
setPlayerState,
updatePlayerState,
} from './store'
import { uniqueId } from './utils'

export const App = () => {
const spotifyAuth = useSelector(selectSpotifyAuth)
const currentJukebox = useSelector(selectCurrentJukebox)
const storePlayerState = useSelector(selectPlayerState)
const [initialized, setInitialized] = useState(false)

const [timer, setTimer] = useState<NodeJS.Timeout | null>(null)

const {
emitMessage,
onEvent,
isConnected: socketIsConnected,
} = useContext(SocketContext)

useEffect(() => {
setTimeout(() => {
setInitialized(true)
}, 60 * 1000)
}, [])

/**
* ======================== *
* Spotify Track State Sync *
* ======================== *
*/
useEffect(() => {
if (timer) clearInterval(timer)
if (storePlayerState?.is_playing) {
const t = setInterval(() => {
incrementLiveProgress()
}, 1000)

setTimer(t)
}

return () => {
if (timer) clearInterval(timer)
}
}, [
storePlayerState?.current_track,
storePlayerState?.is_playing,
storePlayerState?.progress,
])

// Triggers when receive spotify credentials from server
useEffect(() => {
if (!spotifyAuth) return
if (!spotifyAuth || !initialized) return

const timer = setInterval(async () => {
await checkLinkAuth()
Expand All @@ -64,7 +95,7 @@ export const App = () => {
})

onEvent<IPlayerAction>('player-action', (data) => {
updatePlayerState(data)
doPlayerAction(data)
})

onEvent<ITrackMeta[]>('track-queue-update', (data) => {
Expand All @@ -74,24 +105,20 @@ export const App = () => {

// Primary function that runs when Spotify Player changes
const handlePlayerTrackChange = useCallback(
(state: {
currentTrack: ITrack
position: number
isPlaying: boolean
nextTracks: ITrack[]
changedTracks: boolean
}) => {
const { currentTrack, position, isPlaying, nextTracks, changedTracks } =
state

emitMessage<IPlayerAuxUpdate>('player-aux-update', {
jukebox_id: currentJukebox!.id,
current_track: currentTrack,
progress: position,
is_playing: isPlaying,
default_next_tracks: nextTracks,
changed_tracks: changedTracks,
(state?: IPlayerAuxUpdate) => {
if (!state) {
emitMessage('player-aux-update', {})
return
}

updatePlayerState({
...state,
current_track: state.current_track && {
...state.current_track,
queue_id: uniqueId(),
},
})
emitMessage<IPlayerAuxUpdate>('player-aux-update', state)
},
[currentJukebox],
)
Expand All @@ -104,9 +131,7 @@ export const App = () => {
jukebox={currentJukebox}
onPlayerStateChange={handlePlayerTrackChange}
>
<CurrentlyPlayingProvider>
<Outlet />
</CurrentlyPlayingProvider>
<Outlet />
</SpotifyPlayerProvider>
</KeyboardProvider>
</Theme>
Expand Down
6 changes: 2 additions & 4 deletions src/apps/admin/pages/Overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ import './Overview.scss'
import FallbackImg from 'src/assets/img/jukeboxImage.png'
import Disk from 'src/assets/svg/Disk.svg?react'

import { useContext } from 'react'
import { useSelector } from 'react-redux'
import { AudioPlayer, TrackList } from 'src/components'
import { TrackActivity } from 'src/components/track-list/TrackActivity'
import { CurrentlyPlayingContext } from 'src/context/CurrentlyPlayingContext'
import { selectNextTracks } from 'src/store/jukebox'
import { selectCurrentTrack, selectNextTracks } from 'src/store/jukebox'

export const Overview = () => {
const queuedTracks = useSelector(selectNextTracks)
const { currentTrack } = useContext(CurrentlyPlayingContext)
const currentTrack = useSelector(selectCurrentTrack)

return (
<>
Expand Down
15 changes: 9 additions & 6 deletions src/apps/admin/pages/SpotifyPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { useSelector } from 'react-redux'
import { AudioPlayer, Form, FormSelectGroup, FormSubmit } from 'src/components'
import { REACT_ENV } from 'src/config'
import { SpotifyPlayerContext } from 'src/context'
import { CurrentlyPlayingContext } from 'src/context/CurrentlyPlayingContext'
import { authenticateLink } from 'src/store'
import { selectJukeboxLinks } from 'src/store/jukebox'
import {
selectCurrentTrack,
selectJukeboxLinks,
selectNextTracks,
} from 'src/store/jukebox'
import { formatDuration } from 'src/utils'
import { SpotifyPlayerAccount } from '../components/SpotifyPlayer/SpotifyPlayerAccount'
import { SpotifyPlayerDetail } from '../components/SpotifyPlayer/SpotifyPlayerDetail'
Expand All @@ -14,10 +17,10 @@ import './SpotifyPlayer.scss'

export const SpotifyPlayer = () => {
const jukeboxLinks = useSelector(selectJukeboxLinks)
const { currentTrack } = useContext(CurrentlyPlayingContext)
const currentTrack = useSelector(selectCurrentTrack)
const nextTracks = useSelector(selectNextTracks)

const {
nextTracks: playerNextTracks,
deviceIsActive: isActive,
spotifyIsConnected: isConnected,
connectDevice,
Expand Down Expand Up @@ -109,11 +112,11 @@ export const SpotifyPlayer = () => {
<div className="next-track-container">
<SpotifyPlayerInfo title="Next Tracks" />
</div>
{playerNextTracks.length > 0 && (
{nextTracks.length > 0 && (
<>
<h2 className="song-queue__title">Next Up</h2>
<ol>
{playerNextTracks.map((track) => (
{nextTracks.map((track) => (
<li className="track-list-track" key={track.id}>
{/* TODO: Make different set of styles for track list */}
{!track && <p>No track specified.</p>}
Expand Down
13 changes: 8 additions & 5 deletions src/components/audio-player/AudioPlayer.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/**
* @fileoverview Audio Player Component
*/
import { useContext, useEffect, useRef, useState } from 'react'
import { CurrentlyPlayingContext } from 'src/context/CurrentlyPlayingContext'
import { useEffect, useRef, useState } from 'react'
import { useSelector } from 'react-redux'
import { usePlayerControls } from 'src/hooks'
import { selectLiveProgress, selectPlayerState } from 'src/store'
import './AudioPlayer.scss'
import { Controls } from './Controls'
import { ProgressBar } from './ProgressBar'
Expand All @@ -15,9 +17,10 @@ import './ProgressBar.scss'
*/
export const AudioPlayer = (props: { disableControls?: boolean }) => {
const { disableControls } = props
const playerState = useSelector(selectPlayerState)
const liveProgress = useSelector(selectLiveProgress)

const {
playerState,
liveProgress,
play,
pause,
setProgress,
Expand All @@ -26,7 +29,7 @@ export const AudioPlayer = (props: { disableControls?: boolean }) => {
togglePlay,
like,
repeat,
} = useContext(CurrentlyPlayingContext)
} = usePlayerControls()

// Refs
const containerRef = useRef<HTMLDivElement>(null)
Expand Down
104 changes: 0 additions & 104 deletions src/context/CurrentlyPlayingContext.tsx

This file was deleted.

Loading

0 comments on commit 4c043cd

Please sign in to comment.