Connect to several servers at once on Android, in a denser TeamSpeak-like layout

The server name in the top bar opens the servers the app is on, "Connect…" for
another one and "Disconnect from current". Only one server captures with the
microphone at a time, handed over by core's Sessions as on the desktop; a
server without it shows a button to bring it there. Push-to-talk, the floating
button and the level meter follow the server holding it.

Each server has its own controller (session, tree, chats, network recovery);
the app-wide one keeps what they share. Private message notifications carry
their server, as client ids repeat across servers.

The layout follows TeamSpeak's own: 26 dp tree rows with smaller icons and
text, a lower top bar, and no tabs — the chat is a button in the bottom bar,
whose buttons keep fixed places around the push-to-talk button's space.
Holding the mute button switches between push-to-talk and voice activation.

A server that drops the connection now lets go of the microphone too, so a
reconnect cannot capture alongside the server that took it over meanwhile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 16:08:36 +00:00
parent 9f2e5087ce
commit 9b1aa45611
12 changed files with 941 additions and 575 deletions

View File

@@ -89,9 +89,15 @@ public final class Sessions {
assignMicrophoneIfFree();
}
/** A disconnected session cannot capture; the microphone moves on if it had it. */
/**
* A disconnected session cannot capture; the microphone moves on if it had it. The session
* lets go of it too, or a reconnect would capture alongside whoever holds it by then.
*/
public void disconnected(ServerSession session) {
if (microphoneOwner == session) microphoneOwner = null;
if (microphoneOwner == session) {
microphoneOwner = null;
handover.execute(() -> session.setMicrophoneActive(false));
}
assignMicrophoneIfFree();
}