Updated how mute and deafen for self works, more similar to official client behavior.

This commit is contained in:
Storm Dragon
2026-09-05 22:11:03 -04:00
parent cf9746c8de
commit 97e0dc9281
5 changed files with 111 additions and 23 deletions
+22 -6
View File
@@ -32,12 +32,13 @@ type Barnard struct {
Address string
TLSConfig tls.Config
Stream *gumbleopenal.Stream
connectionMutex sync.RWMutex
Tx bool
AutoTransmit bool // auto-start transmission on connect
Connected bool
stateMutex sync.RWMutex
Stream *gumbleopenal.Stream
connectionMutex sync.RWMutex
Tx bool
AutoTransmit bool // auto-start transmission on connect
Connected bool
unmuteOnUndeafen bool
stateMutex sync.RWMutex
Ui *uiterm.Ui
UiOutput uiterm.Textview
@@ -213,6 +214,21 @@ func (b *Barnard) isConnected() bool {
func (b *Barnard) setConnected(connected bool) {
b.stateMutex.Lock()
b.Connected = connected
if !connected {
b.unmuteOnUndeafen = false
}
b.stateMutex.Unlock()
}
func (b *Barnard) shouldUnmuteOnUndeafen() bool {
b.stateMutex.RLock()
defer b.stateMutex.RUnlock()
return b.unmuteOnUndeafen
}
func (b *Barnard) setUnmuteOnUndeafen(unmute bool) {
b.stateMutex.Lock()
b.unmuteOnUndeafen = unmute
b.stateMutex.Unlock()
}
+33
View File
@@ -150,6 +150,39 @@ func TestTransmitDoesNotStartWhileSelfMuted(t *testing.T) {
}
}
func TestSelfDeafenRestoresPriorMuteState(t *testing.T) {
tests := []struct {
name string
deafened bool
currentlyMuted bool
unmuteOnUndeafen bool
wantMuted bool
wantRememberUnmute bool
}{
{name: "deafen while unmuted", deafened: true, wantMuted: true, wantRememberUnmute: true},
{name: "deafen while already muted", deafened: true, currentlyMuted: true, wantMuted: true},
{name: "undeafen automatic mute", unmuteOnUndeafen: true},
{name: "undeafen prior mute", wantMuted: true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
muted, rememberUnmute := selfDeafenTarget(test.deafened, test.currentlyMuted, test.unmuteOnUndeafen)
if muted != test.wantMuted || rememberUnmute != test.wantRememberUnmute {
t.Fatalf("got muted=%t rememberUnmute=%t; want muted=%t rememberUnmute=%t", muted, rememberUnmute, test.wantMuted, test.wantRememberUnmute)
}
})
}
}
func TestDisconnectForgetsAutomaticDeafenMute(t *testing.T) {
b := &Barnard{}
b.setUnmuteOnUndeafen(true)
b.setConnected(false)
if b.shouldUnmuteOnUndeafen() {
t.Fatal("disconnect retained automatic deafen mute state")
}
}
func TestConcurrentSelectedUserAccess(t *testing.T) {
b := &Barnard{}
user := &gumble.User{Session: 1}
+8
View File
@@ -76,10 +76,18 @@ mutedeafen() {
[[ $notify ]] && notify "You muted and deafened yourself."
}
deafen() {
[[ $notify ]] && notify "You deafened yourself."
}
muteundeafen() {
[[ $notify ]] && notify "You undeafened yourself. Your microphone remains muted."
}
unmuteundeafen() {
[[ $notify ]] && notify "You unmuted and undeafened yourself."
}
msg() {
[[ $sound ]] && play -n synth .3 sin 1290:1490 sin 1494:1294 remix - norm -8
[[ $notify ]] && notify "$1 from $2: $3"
+16 -11
View File
@@ -9,12 +9,17 @@ import (
)
func TestSetSelfMutedAndDeafenedWritesOneCombinedState(t *testing.T) {
for _, deafened := range []bool{true, false} {
name := "undeafen"
if deafened {
name = "deafen"
}
t.Run(name, func(t *testing.T) {
tests := []struct {
name string
muted bool
deafened bool
}{
{name: "deafen", muted: true, deafened: true},
{name: "undeafen and remain muted", muted: true},
{name: "undeafen and unmute"},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
local, remote := net.Pipe()
defer local.Close()
defer remote.Close()
@@ -23,7 +28,7 @@ func TestSetSelfMutedAndDeafenedWritesOneCombinedState(t *testing.T) {
user := &User{Session: 7, client: client}
written := make(chan struct{})
go func() {
user.SetSelfMutedAndDeafened(true, deafened)
user.SetSelfMutedAndDeafened(test.muted, test.deafened)
close(written)
}()
@@ -38,11 +43,11 @@ func TestSetSelfMutedAndDeafenedWritesOneCombinedState(t *testing.T) {
if err := proto.Unmarshal(data, &state); err != nil {
t.Fatal(err)
}
if state.SelfMute == nil || !*state.SelfMute {
t.Fatalf("self mute = %v, want true", state.SelfMute)
if state.SelfMute == nil || *state.SelfMute != test.muted {
t.Fatalf("self mute = %v, want %v", state.SelfMute, test.muted)
}
if state.SelfDeaf == nil || *state.SelfDeaf != deafened {
t.Fatalf("self deafen = %v, want %v", state.SelfDeaf, deafened)
if state.SelfDeaf == nil || *state.SelfDeaf != test.deafened {
t.Fatalf("self deafen = %v, want %v", state.SelfDeaf, test.deafened)
}
<-written
})
+32 -6
View File
@@ -233,6 +233,13 @@ func (b *Barnard) setSelfMute(muted bool) {
b.UpdateGeneralStatus("cannot change self mute while disconnected", true)
return
}
if !muted && b.selfDeafened() {
b.setUnmuteOnUndeafen(false)
b.Client.Self.SetSelfMutedAndDeafened(false, false)
b.Notify("unmuteundeafen", "me", "")
b.AddOutputLine("You unmuted and undeafened yourself")
return
}
if b.selfMuted() == muted {
return
}
@@ -272,17 +279,36 @@ func (b *Barnard) setSelfDeafen(deafened bool) {
if b.selfDeafened() == deafened {
return
}
if b.isTransmitting() {
if deafened && b.isTransmitting() {
b.StopTransmission()
}
b.Client.Self.SetSelfMutedAndDeafened(true, deafened)
muted, unmuteOnUndeafen := selfDeafenTarget(deafened, b.selfMuted(), b.shouldUnmuteOnUndeafen())
b.setUnmuteOnUndeafen(unmuteOnUndeafen)
b.Client.Self.SetSelfMutedAndDeafened(muted, deafened)
if deafened {
b.Notify("mutedeafen", "me", "")
b.AddOutputLine("You muted and deafened yourself")
if unmuteOnUndeafen {
b.Notify("mutedeafen", "me", "")
b.AddOutputLine("You muted and deafened yourself")
} else {
b.Notify("deafen", "me", "")
b.AddOutputLine("You deafened yourself")
}
return
}
b.Notify("muteundeafen", "me", "")
b.AddOutputLine("You undeafened yourself; microphone remains muted")
if muted {
b.Notify("muteundeafen", "me", "")
b.AddOutputLine("You undeafened yourself; microphone remains muted")
} else {
b.Notify("unmuteundeafen", "me", "")
b.AddOutputLine("You unmuted and undeafened yourself")
}
}
func selfDeafenTarget(deafened, currentlyMuted, unmuteOnUndeafen bool) (muted, rememberUnmute bool) {
if deafened {
return true, !currentlyMuted
}
return !unmuteOnUndeafen, false
}
func (b *Barnard) toggleSelfDeafen() {