11import { useCallback , useEffect , useState } from 'react' ;
22import { toast } from 'sonner' ;
33import { useAuth } from '@/app/contexts/auth-context' ;
4- import { fetchMediaThumbnailDataUrl } from '@/app/features/media/utils/media-thumbnail' ;
5- import { useHomeAssistant , useI18n } from '@/app/hooks' ;
4+ import { useI18n } from '@/app/hooks' ;
65import { homeAssistantService } from '@/app/services/home-assistant.service' ;
7- import { homeAssistantSelectors } from '@/app/stores/selectors' ;
86import {
97 resolveHomeAssistantAbsoluteUrl ,
108 resolveHomeAssistantProxyUrl ,
@@ -41,18 +39,16 @@ export function useMediaCardController({
4139 initialPositionUpdatedAt,
4240} : UseMediaCardControllerParams ) {
4341 const { config : authConfig } = useAuth ( ) ;
44- const connected = useHomeAssistant ( homeAssistantSelectors . connected ) ;
45- const connection = useHomeAssistant ( homeAssistantSelectors . connection ) ;
4642 const { t } = useI18n ( ) ;
4743 const [ state , setState ] = useState ( initialState ) ;
4844 const [ volume , setVolume ] = useState ( initialVolume ) ;
4945 const [ isMuted , setIsMuted ] = useState ( initialMuted ) ;
46+ const [ previousVolume , setPreviousVolume ] = useState ( initialVolume > 0 ? initialVolume : 50 ) ;
5047 const [ isOpen , setIsOpen ] = useState ( false ) ;
5148 const [ elapsedSeconds , setElapsedSeconds ] = useState ( initialElapsedSeconds ?? 0 ) ;
5249 const [ durationSeconds , setDurationSeconds ] = useState ( initialDurationSeconds ?? 0 ) ;
5350 const [ failedArtworkUrl , setFailedArtworkUrl ] = useState < string | null > ( null ) ;
5451 const [ resolvedAlbumArt , setResolvedAlbumArt ] = useState < string | null > ( null ) ;
55- const [ thumbnailAlbumArt , setThumbnailAlbumArt ] = useState < string | null > ( null ) ;
5652 const artworkRequestKey = [ entityId , artworkKey ] . filter ( Boolean ) . join ( '::' ) ;
5753 const fallbackArtwork = entityPicture
5854 ? import . meta. env . DEV
@@ -66,11 +62,14 @@ export function useMediaCardController({
6662
6763 useEffect ( ( ) => {
6864 setVolume ( initialVolume ) ;
65+ if ( initialVolume > 0 ) {
66+ setPreviousVolume ( initialVolume ) ;
67+ }
6968 } , [ initialVolume ] ) ;
7069
7170 useEffect ( ( ) => {
72- setIsMuted ( initialMuted ) ;
73- } , [ initialMuted ] ) ;
71+ setIsMuted ( initialMuted || initialVolume === 0 ) ;
72+ } , [ initialMuted , initialVolume ] ) ;
7473
7574 useEffect ( ( ) => {
7675 setElapsedSeconds ( initialElapsedSeconds ?? 0 ) ;
@@ -82,58 +81,22 @@ export function useMediaCardController({
8281
8382 useEffect ( ( ) => {
8483 if ( ! artworkRequestKey ) {
85- setThumbnailAlbumArt ( null ) ;
8684 setResolvedAlbumArt (
8785 isFailedArtworkCandidate ( fallbackArtwork , failedArtworkUrl ) ? null : fallbackArtwork
8886 ) ;
8987 return ;
9088 }
91-
92- let cancelled = false ;
93-
94- void ( async ( ) => {
95- if ( ! connected || ! connection ) {
96- if ( ! cancelled ) {
97- setResolvedAlbumArt (
98- isFailedArtworkCandidate ( fallbackArtwork , failedArtworkUrl ) ? null : fallbackArtwork
99- ) ;
100- }
101- return ;
102- }
103-
104- const thumbnailDataUrl = await fetchMediaThumbnailDataUrl ( entityId , connection ) . catch (
105- ( ) => null
106- ) ;
107- if ( thumbnailDataUrl && ! isFailedArtworkCandidate ( thumbnailDataUrl , failedArtworkUrl ) ) {
108- if ( cancelled ) {
109- return ;
110- }
111-
112- setThumbnailAlbumArt ( thumbnailDataUrl ) ;
113- setResolvedAlbumArt ( thumbnailDataUrl ) ;
114- return ;
115- }
116-
117- if ( ! cancelled ) {
118- setThumbnailAlbumArt ( null ) ;
119- setResolvedAlbumArt (
120- isFailedArtworkCandidate ( fallbackArtwork , failedArtworkUrl ) ? null : fallbackArtwork
121- ) ;
122- }
123- } ) ( ) ;
124-
125- return ( ) => {
126- cancelled = true ;
127- } ;
128- } , [ artworkRequestKey , connected , connection , entityId , failedArtworkUrl , fallbackArtwork ] ) ;
89+ setResolvedAlbumArt (
90+ isFailedArtworkCandidate ( fallbackArtwork , failedArtworkUrl ) ? null : fallbackArtwork
91+ ) ;
92+ } , [ artworkRequestKey , failedArtworkUrl , fallbackArtwork ] ) ;
12993
13094 useEffect ( ( ) => {
13195 if ( ! artworkRequestKey ) {
13296 return ;
13397 }
13498
13599 setFailedArtworkUrl ( null ) ;
136- setThumbnailAlbumArt ( null ) ;
137100 } , [ artworkRequestKey ] ) ;
138101
139102 const isPlaying = state === 'playing' ;
@@ -193,24 +156,45 @@ export function useMediaCardController({
193156 const toggleMute = useCallback ( ( ) => {
194157 const nextMuted = ! isMuted ;
195158 setIsMuted ( nextMuted ) ;
159+ if ( nextMuted ) {
160+ const nextPreviousVolume = volume > 0 ? volume : previousVolume ;
161+ setPreviousVolume ( nextPreviousVolume ) ;
162+ setVolume ( 0 ) ;
163+ void runAction (
164+ ( ) => homeAssistantService . setMediaPlayerVolume ( entityId , 0 ) ,
165+ t ( 'media.feedback.updateVolumeFailed' )
166+ ) ;
167+ return ;
168+ }
169+
170+ const restoredVolume = previousVolume > 0 ? previousVolume : 50 ;
171+ setVolume ( restoredVolume ) ;
196172 void runAction (
197- ( ) => homeAssistantService . setMediaPlayerMute ( entityId , nextMuted ) ,
173+ ( ) => homeAssistantService . setMediaPlayerVolume ( entityId , restoredVolume ) ,
198174 t ( 'media.feedback.updateVolumeFailed' )
199175 ) ;
200- } , [ entityId , isMuted , runAction , t ] ) ;
176+ } , [ entityId , isMuted , previousVolume , runAction , t , volume ] ) ;
201177
202178 const handleVolumeChange = useCallback (
203179 ( nextVolume : number ) => {
204180 setVolume ( nextVolume ) ;
181+ if ( nextVolume > 0 ) {
182+ setPreviousVolume ( nextVolume ) ;
183+ }
184+
205185 if ( nextVolume > 0 && isMuted ) {
206186 setIsMuted ( false ) ;
207- void runAction ( async ( ) => {
208- await homeAssistantService . setMediaPlayerMute ( entityId , false ) ;
209- await homeAssistantService . setMediaPlayerVolume ( entityId , nextVolume ) ;
210- } , t ( 'media.feedback.updateVolumeFailed' ) ) ;
187+ void runAction (
188+ ( ) => homeAssistantService . setMediaPlayerVolume ( entityId , nextVolume ) ,
189+ t ( 'media.feedback.updateVolumeFailed' )
190+ ) ;
211191 return ;
212192 }
213193
194+ if ( nextVolume === 0 ) {
195+ setIsMuted ( true ) ;
196+ }
197+
214198 void runAction (
215199 ( ) => homeAssistantService . setMediaPlayerVolume ( entityId , nextVolume ) ,
216200 t ( 'media.feedback.updateVolumeFailed' )
@@ -252,7 +236,6 @@ export function useMediaCardController({
252236
253237 return {
254238 albumArt : resolvedAlbumArt ,
255- thumbnailAlbumArt,
256239 closeDialog,
257240 durationSeconds,
258241 elapsedSeconds,
0 commit comments