feat: add mute and unmute functionality to player service; update CompactPlayer and Player components to utilize new methods
This commit is contained in:
@@ -27,10 +27,10 @@ export function CompactPlayer({ className }: CompactPlayerProps) {
|
|||||||
status: 'stopped',
|
status: 'stopped',
|
||||||
mode: 'continuous',
|
mode: 'continuous',
|
||||||
volume: 80,
|
volume: 80,
|
||||||
|
previous_volume: 50,
|
||||||
position: 0
|
position: 0
|
||||||
})
|
})
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [previousVolume, setPreviousVolume] = useState(50)
|
|
||||||
|
|
||||||
// Load initial state
|
// Load initial state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -58,12 +58,6 @@ export function CompactPlayer({ className }: CompactPlayerProps) {
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
// Initialize previous volume when state loads
|
|
||||||
useEffect(() => {
|
|
||||||
if (state.volume > 0 && previousVolume <= 0) {
|
|
||||||
setPreviousVolume(state.volume)
|
|
||||||
}
|
|
||||||
}, [state.volume, previousVolume])
|
|
||||||
|
|
||||||
const executeAction = useCallback(async (action: () => Promise<void | MessageResponse>, actionName: string) => {
|
const executeAction = useCallback(async (action: () => Promise<void | MessageResponse>, actionName: string) => {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
@@ -96,13 +90,12 @@ export function CompactPlayer({ className }: CompactPlayerProps) {
|
|||||||
const handleVolumeToggle = useCallback(() => {
|
const handleVolumeToggle = useCallback(() => {
|
||||||
if (state.volume === 0) {
|
if (state.volume === 0) {
|
||||||
// Unmute
|
// Unmute
|
||||||
executeAction(() => playerService.setVolume(previousVolume), 'unmute')
|
executeAction(playerService.unmute, 'unmute')
|
||||||
} else {
|
} else {
|
||||||
// Mute
|
// Mute
|
||||||
setPreviousVolume(state.volume)
|
executeAction(playerService.mute, 'mute')
|
||||||
executeAction(() => playerService.setVolume(0), 'mute')
|
|
||||||
}
|
}
|
||||||
}, [previousVolume, state.volume, executeAction])
|
}, [state.volume, executeAction])
|
||||||
|
|
||||||
// Don't show if no current sound
|
// Don't show if no current sound
|
||||||
if (!state.current_sound) {
|
if (!state.current_sound) {
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
status: 'stopped',
|
status: 'stopped',
|
||||||
mode: 'continuous',
|
mode: 'continuous',
|
||||||
volume: 80,
|
volume: 80,
|
||||||
|
previous_volume: 50,
|
||||||
position: 0
|
position: 0
|
||||||
})
|
})
|
||||||
const [displayMode, setDisplayMode] = useState<PlayerDisplayMode>(() => {
|
const [displayMode, setDisplayMode] = useState<PlayerDisplayMode>(() => {
|
||||||
@@ -67,8 +68,6 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
}, [displayMode, onPlayerModeChange])
|
}, [displayMode, onPlayerModeChange])
|
||||||
const [showPlaylist, setShowPlaylist] = useState(false)
|
const [showPlaylist, setShowPlaylist] = useState(false)
|
||||||
const [isLoading, setIsLoading] = useState(false)
|
const [isLoading, setIsLoading] = useState(false)
|
||||||
const [isMuted, setIsMuted] = useState(false)
|
|
||||||
const [previousVolume, setPreviousVolume] = useState(50)
|
|
||||||
|
|
||||||
// Load initial state
|
// Load initial state
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -152,23 +151,17 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
const handleVolumeChange = useCallback((volume: number[]) => {
|
const handleVolumeChange = useCallback((volume: number[]) => {
|
||||||
const newVolume = volume[0]
|
const newVolume = volume[0]
|
||||||
executeAction(() => playerService.setVolume(newVolume), 'change volume')
|
executeAction(() => playerService.setVolume(newVolume), 'change volume')
|
||||||
if (newVolume > 0 && isMuted) {
|
}, [executeAction])
|
||||||
setIsMuted(false)
|
|
||||||
}
|
|
||||||
}, [executeAction, isMuted])
|
|
||||||
|
|
||||||
const handleMute = useCallback(() => {
|
const handleMute = useCallback(() => {
|
||||||
if (isMuted) {
|
if (state.volume === 0) {
|
||||||
// Unmute
|
// Unmute
|
||||||
executeAction(() => playerService.setVolume(previousVolume), 'unmute')
|
executeAction(playerService.unmute, 'unmute')
|
||||||
setIsMuted(false)
|
|
||||||
} else {
|
} else {
|
||||||
// Mute
|
// Mute
|
||||||
setPreviousVolume(state.volume)
|
executeAction(playerService.mute, 'mute')
|
||||||
executeAction(() => playerService.setVolume(0), 'mute')
|
|
||||||
setIsMuted(true)
|
|
||||||
}
|
}
|
||||||
}, [isMuted, previousVolume, state.volume, executeAction])
|
}, [state.volume, executeAction])
|
||||||
|
|
||||||
const handleModeChange = useCallback(() => {
|
const handleModeChange = useCallback(() => {
|
||||||
const modes: PlayerMode[] = ['continuous', 'loop', 'loop_one', 'random', 'single']
|
const modes: PlayerMode[] = ['continuous', 'loop', 'loop_one', 'random', 'single']
|
||||||
@@ -460,7 +453,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
onClick={handleMute}
|
onClick={handleMute}
|
||||||
className="h-8 w-8 p-0"
|
className="h-8 w-8 p-0"
|
||||||
>
|
>
|
||||||
{isMuted || state.volume === 0 ? (
|
{state.volume === 0 ? (
|
||||||
<VolumeX className="h-4 w-4" />
|
<VolumeX className="h-4 w-4" />
|
||||||
) : (
|
) : (
|
||||||
<Volume2 className="h-4 w-4" />
|
<Volume2 className="h-4 w-4" />
|
||||||
@@ -468,7 +461,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
<div className="w-16">
|
<div className="w-16">
|
||||||
<Slider
|
<Slider
|
||||||
value={[isMuted ? 0 : state.volume]}
|
value={[state.volume]}
|
||||||
max={100}
|
max={100}
|
||||||
step={1}
|
step={1}
|
||||||
onValueChange={handleVolumeChange}
|
onValueChange={handleVolumeChange}
|
||||||
@@ -660,7 +653,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={handleMute}
|
onClick={handleMute}
|
||||||
>
|
>
|
||||||
{isMuted || state.volume === 0 ? (
|
{state.volume === 0 ? (
|
||||||
<VolumeX className="h-4 w-4" />
|
<VolumeX className="h-4 w-4" />
|
||||||
) : (
|
) : (
|
||||||
<Volume2 className="h-4 w-4" />
|
<Volume2 className="h-4 w-4" />
|
||||||
@@ -668,7 +661,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
<div className="w-24">
|
<div className="w-24">
|
||||||
<Slider
|
<Slider
|
||||||
value={[isMuted ? 0 : state.volume]}
|
value={[state.volume]}
|
||||||
max={100}
|
max={100}
|
||||||
step={1}
|
step={1}
|
||||||
onValueChange={handleVolumeChange}
|
onValueChange={handleVolumeChange}
|
||||||
@@ -676,7 +669,7 @@ export function Player({ className, onPlayerModeChange }: PlayerProps) {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<span className="text-sm text-muted-foreground w-8">
|
<span className="text-sm text-muted-foreground w-8">
|
||||||
{Math.round(isMuted ? 0 : state.volume)}%
|
{Math.round(state.volume)}%
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ export interface PlayerState {
|
|||||||
status: PlayerStatus
|
status: PlayerStatus
|
||||||
mode: PlayerMode
|
mode: PlayerMode
|
||||||
volume: number
|
volume: number
|
||||||
|
previous_volume: number
|
||||||
position: number
|
position: number
|
||||||
duration?: number
|
duration?: number
|
||||||
index?: number
|
index?: number
|
||||||
@@ -107,6 +108,20 @@ export class PlayerService {
|
|||||||
return apiClient.post<MessageResponse>('/api/v1/player/volume', { volume })
|
return apiClient.post<MessageResponse>('/api/v1/player/volume', { volume })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mute playback
|
||||||
|
*/
|
||||||
|
async mute(): Promise<MessageResponse> {
|
||||||
|
return apiClient.post<MessageResponse>('/api/v1/player/mute')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unmute playback
|
||||||
|
*/
|
||||||
|
async unmute(): Promise<MessageResponse> {
|
||||||
|
return apiClient.post<MessageResponse>('/api/v1/player/unmute')
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set playback mode
|
* Set playback mode
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user