Skip to content

Commit 5f04cd7

Browse files
scytoclaude
andcommitted
Fix group mute icon and compatibility with protocol-synced players
- Pass isGroupMuted(player) explicitly to getVolumeIconComponent so the icon reflects aggregate group mute state correctly - Pass individual child mute state (!!childPlayer.volume_muted) for child player icons instead of computing group state - Skip members with null volume_muted in isGroupMuted (players that don't support mute control) - Only disable mute button for non-group players when mute_control is PLAYER_CONTROL_NONE Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 13ec301 commit 5f04cd7

3 files changed

Lines changed: 18 additions & 6 deletions

File tree

src/components/VolumeControl.vue

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,18 @@
4545
:disabled="
4646
!player.available ||
4747
player.powered == false ||
48-
player.mute_control == PLAYER_CONTROL_NONE
48+
(player.group_members.length === 0 &&
49+
player.mute_control == PLAYER_CONTROL_NONE)
4950
"
5051
@click.stop="handlePlayerMuteToggle(player)"
5152
>
5253
<component
5354
:is="
54-
getVolumeIconComponent(player, mainDisplayVolume)
55+
getVolumeIconComponent(
56+
player,
57+
mainDisplayVolume,
58+
isGroupMuted(player),
59+
)
5560
"
5661
:size="22"
5762
/>
@@ -187,6 +192,7 @@
187192
getVolumeIconComponent(
188193
childPlayer,
189194
childDisplayVolumes[childPlayer.player_id],
195+
!!childPlayer.volume_muted,
190196
)
191197
"
192198
:size="22"

src/layouts/default/PlayerOSD/PlayerControlBtn/VolumeBtn.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ import { PlayerFeature } from "@/plugins/api/interfaces";
111111
import { getBreakpointValue } from "@/plugins/breakpoint";
112112
import { store } from "@/plugins/store";
113113
import { getVolumeIconComponent } from "@/helpers/utils";
114+
import { isGroupMuted } from "@/plugins/api/helpers";
114115
import { Volume2 } from "lucide-vue-next";
115116
import { computed, ref } from "vue";
116117
import PlayerVolume from "../PlayerVolume.vue";
@@ -147,7 +148,7 @@ const displayVolume = ref(
147148
const volumeIconComponent = computed(() => {
148149
const player = store.activePlayer;
149150
if (!player) return Volume2;
150-
return getVolumeIconComponent(player, displayVolume.value);
151+
return getVolumeIconComponent(player, displayVolume.value, isGroupMuted(player));
151152
});
152153
</script>
153154

src/plugins/api/helpers.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,14 +177,19 @@ export const isGroupMuted = function (player: Player): boolean {
177177
if (!player.group_members.length) {
178178
return !!player.volume_muted;
179179
}
180-
// For group players, only show muted if ALL members are muted
180+
// For group players, only show muted if ALL mute-capable members are muted.
181+
// Members with volume_muted == null/undefined don't support mute and are skipped.
182+
let hasMuteCapableMembers = false;
181183
for (const memberId of player.group_members) {
182184
const member = api?.players[memberId];
183-
if (member && member.available && !member.volume_muted) {
185+
if (!member || !member.available) continue;
186+
if (member.volume_muted == null) continue;
187+
hasMuteCapableMembers = true;
188+
if (!member.volume_muted) {
184189
return false;
185190
}
186191
}
187-
return true;
192+
return hasMuteCapableMembers;
188193
};
189194

190195
export const handlePlayerMuteToggle = function (player: Player) {

0 commit comments

Comments
 (0)