4 Commits

Author SHA1 Message Date
cdf81f3258 Share icon packs between desktop and Android
The Android app's Material icons become a TeamSpeak-format pack shipped in
core, which the desktop offers next to the TeamSpeak packs. Android now
draws its icons from packs too and imports TeamSpeak's own zips, falling
back to the Material pack for what they lack.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 09:39:42 +00:00
941365cab0 Give the Android app its real UI
- Connect screen with an address or a bookmark, which can be added and
  removed there.
- Server screen: the channel tree with each client's status, folding
  channels, joining (asking for a password where needed) and
  subscribing from a channel's sheet; private message, poke and volume
  from a client's sheet.
- Chat: the server log, the channel and private conversations with
  their history, unread marks, BBCode and clickable client, channel and
  web links. Chat lines are the HTML the desktop shows, turned into
  styled text.
- Voice bar: mute, deafen, away, and a hold-to-talk button in
  push-to-talk mode. The microphone permission is asked for on connect.
- Settings: nickname, transmission mode, voice activation, noise
  suppression, gain control and playback volume, in effect at once.

The session's state reaches Compose as immutable snapshots: the tree
at most every 30 ms, rebuilt only when channels or clients changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 14:21:51 +00:00
b3ad3ceda0 Keep the Android connection alive in the background
The session moves from the connection screen's ViewModel into an
app-wide SessionController, and a foreground service keeps the process
running while connected:

- Its notification shows the server and status and offers Mute, Deafen
  and Disconnect.
- It declares microphone use only once the microphone is handed to the
  connection, as Android requires that permission to be granted then.
- It holds a low-latency Wi-Fi lock and a CPU wake lock, since voice
  goes out every 20 ms.
- When the system moves to another network, the session reconnects to
  where it was, as its socket stays bound to the old one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 08:28:36 +00:00
086b913c8e Add the Android app: Gradle build, Oboe audio, connection screen
android/ builds core and ts3j from the same sources as the desktop's
Maven build, so the app shares all of the client's logic:

- audio: Oboe streams behind AudioCapture/AudioPlayback, with a lock-free
  ring between the real-time callback and the blocking Java side, and
  libopus 1.5.2 built with the NDK behind OpusCodec. Speakers are mixed
  onto one stream. Capture uses the VoiceRecognition preset, leaving
  noise suppression and gain to the client's own processing.
- app: a plain connection screen to try the port out - connect,
  microphone, mute, deafen, channel chat and a log - until the real UI.

Targets Android 13 and up (minSdk 33) on arm64 and x86_64.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 08:24:21 +00:00