@@ -11,7 +11,7 @@ const getPlayerVol = (sourceId, zones) => {
1111 let n = 0 ;
1212 for ( const i of getSourceZones ( sourceId , zones ) ) {
1313 n += 1 ;
14- vol += i . vol_f ;
14+ vol += i . vol_f + i . vol_f_overflow ; // Add buffer to retain proper relative space when doing an action that would un-overload the slider
1515 }
1616
1717 const avg = vol / n ;
@@ -27,22 +27,23 @@ export const applyPlayerVol = (vol, zones, sourceId, apply) => {
2727 let delta = vol - getPlayerVol ( sourceId , zones ) ;
2828
2929 for ( let i of getSourceZones ( sourceId , zones ) ) {
30- let set_pt = Math . max ( 0 , Math . min ( 1 , i . vol_f + delta ) ) ;
31- apply ( i . id , set_pt ) ;
30+ apply ( i . id , i . vol_f + delta ) ;
3231 }
3332} ;
3433
35- // cumulativeDelta reflects the amount of movement that the
36- let cumulativeDelta = 0 ;
34+ // cumulativeDelta reflects the amount of movement that the volume bar has had that has gone unreflected in the backend
35+ let cumulativeDelta = 0.0 ;
36+ let previous_delta = null ;
3737let sendingPacketCount = 0 ;
3838
3939// main volume slider on player and volume slider on player card
4040const CardVolumeSlider = ( { sourceId } ) => {
4141 const zones = useStatusStore ( ( s ) => s . status . zones ) ;
4242 const setZonesVol = useStatusStore ( ( s ) => s . setZonesVol ) ;
4343 const setZonesMute = useStatusStore ( ( s ) => s . setZonesMute ) ;
44+ const setSystemState = useStatusStore ( ( s ) => s . setSystemState ) ;
4445
45- // needed to ensure that polling doesn't cause the delta volume to be made inacurrate during volume slider interactions
46+ // needed to ensure that polling doesn't cause the delta volume to be made inaccurate during volume slider interactions
4647 const skipNextUpdate = useStatusStore ( ( s ) => s . skipNextUpdate ) ;
4748
4849 const value = getPlayerVol ( sourceId , zones ) ;
@@ -52,32 +53,42 @@ const CardVolumeSlider = ({ sourceId }) => {
5253 setZonesMute ( false , zones , sourceId ) ;
5354 } ;
5455
55- function setPlayerVol ( vol , val ) {
56- cumulativeDelta += vol - val ;
57-
58- if ( sendingPacketCount <= 0 ) {
56+ function setPlayerVol ( force = false ) {
57+ if ( sendingPacketCount <= 0 || force ) { // Sometimes slide and release interactions can send the same request twice, this check helps prevent that from doubling the intended change
5958 sendingPacketCount += 1 ;
6059
6160 const delta = cumulativeDelta ;
62-
63- fetch ( "/api/zones" , {
64- method : "PATCH" ,
65- headers : {
66- "Content-type" : "application/json" ,
67- } ,
68- body : JSON . stringify ( {
69- zones : getSourceZones ( sourceId , zones ) . map ( ( z ) => z . id ) ,
70- update : { vol_delta_f : cumulativeDelta , mute : false } ,
71- } ) ,
72- } ) . then ( ( ) => {
73- // NOTE: This used to just set cumulativeDelta to 0
74- // that would skip all accumulated delta from fetch start to backend response time
75- // causing jittering issues
76- cumulativeDelta -= delta ;
61+ if ( previous_delta !== delta ) {
62+ previous_delta = delta ;
63+
64+ fetch ( "/api/zones" , {
65+ method : "PATCH" ,
66+ headers : {
67+ "Content-type" : "application/json" ,
68+ } ,
69+ body : JSON . stringify ( {
70+ zones : getSourceZones ( sourceId , zones ) . map ( ( z ) => z . id ) ,
71+ update : { vol_delta_f : delta , mute : false } ,
72+ } ) ,
73+ } ) . then ( ( ) => {
74+ // NOTE: This used to just set cumulativeDelta to 0
75+ // that would skip all accumulated delta from fetch start to backend response time
76+ // causing jittering issues
77+ if ( force ) {
78+ cumulativeDelta = 0.0 ; // If you force push a change, do not store any unrecognized changes
79+ } else {
80+ cumulativeDelta -= delta ; // If this is a normal change, there is likely a change coming up and setting to zero would lose part of that upcoming delta
81+ }
82+ sendingPacketCount -= 1 ;
83+ // In many similar requests we instantly consume the response by doing something like this:
84+ // if(res.ok){res.json().then(s=> setSystemState(s));}
85+ // This cannot be done here due to how rapid fire the requests can be when sliding the slider rather than just tapping it
86+ } ) ;
87+ } else {
7788 sendingPacketCount -= 1 ;
78- } ) ;
89+ }
7990 }
80- } ;
91+ }
8192
8293 const mute = getSourceZones ( sourceId , zones )
8394 . map ( ( z ) => z . mute )
@@ -95,6 +106,8 @@ const CardVolumeSlider = ({ sourceId }) => {
95106 zones : getSourceZones ( sourceId , zones ) . map ( ( z ) => z . id ) ,
96107 update : { mute : mute } ,
97108 } ) ,
109+ } ) . then ( res => {
110+ if ( res . ok ) { res . json ( ) . then ( s => setSystemState ( s ) ) ; }
98111 } ) ;
99112 } ;
100113
@@ -107,9 +120,9 @@ const CardVolumeSlider = ({ sourceId }) => {
107120 setVol = { ( val , force ) => {
108121 // Cannot use value directly as that changes during the request when setValue() is called
109122 // Cannot call setValue() as a .then() after the request as that causes the ui to feel unresponsive and choppy
110- let current_val = value ;
111- setPlayerVol ( val , current_val ) ;
123+ cumulativeDelta += Math . round ( ( val - value ) * 1000 ) / 1000 ;
112124 setValue ( val ) ;
125+ setPlayerVol ( force ) ;
113126 skipNextUpdate ( ) ;
114127 } }
115128 disabled = { getSourceZones ( sourceId , zones ) == 0 }
0 commit comments