Channels carry a channel_icon_id just like groups do; track it on
ChannelNode from the channel list and the create/edit events, and paint it
in the same right-aligned strip that already carries a client's group
icons. Spacers keep their bare look.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Download the icons a server advertises for its groups over the file
transfer channel, cache them under the config directory, and draw them as
a badge strip on each client's row, right-aligned against the tree's
visible edge like the TeamSpeak client does. Groups without a custom icon
fall back to the bundled default set.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Capture and playback now go through AudioCapture/AudioPlayback interfaces
with two implementations: PipeWire, used for the system default and for
every pw: device when a session is reachable, and Java Sound for the raw
ALSA devices and other platforms. The PipeWire binding is FFM-based
(PipeWireLibrary, PipeWireSession, PipeWireStream, SpaPod) and enumerates
the graph's real devices, so each stream shows up separately in volume
mixers.
Lines are opened with a negotiated channel count instead of a fixed mono
format: OPUS_MUSIC transmits the stereo capture as-is, OPUS_VOICE keeps
transmitting the mono downmix so the pre-processing chain and VAD still
see a single channel. Java Sound enumeration asks only for "a mixer that
can capture/play" so the PipeWire and PulseAudio ALSA plugins are no
longer hidden by their narrow format lists.
The Java Sound classes are renamed to Desktop* to match what they now
are, and JUnit plus a SpaPod round-trip test are wired into the build.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Clients can be dragged into a channel and channels re-parented or
reordered, with an insertion line (or a row outline, for "into this
channel") showing where the drop lands.
Channel positions come from channel_order, which is the id of the
channel above rather than an index, so siblings are now ordered by
walking that chain and the neighbour links are repaired locally on
create, move and delete -- the server only announces the channel
that changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Wheel events on the tab strip step through the open connections,
clamped at the ends. The content area is excluded so the tree and chat
keep their own scrolling.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ServerTabPane replaces ServerTabBar: the views live in a JTabbedPane
whose strip sits under the toolbar, with the native tab shapes and the
same look as the chat tabs. Each tab carries its server name, the
microphone marker and a close glyph. With a single connection the
server view is mounted directly, so the strip appears only once a
second server is open.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Each connection now lives in its own ServerTab with its own tree, info
and chat views plus its own mic-mute, deafen, away and commander state.
MainFrame keeps only the shell (menus, toolbar, status bar) and shows
one tab at a time; the tab bar below the toolbar appears once a second
server is open.
Incoming voice from every connection mixes into the same output — each
connection already renders one line per speaker. Capture is exclusive:
a connection only opens the microphone while it holds it, and a toolbar
button moves it to the visible tab. The mic follows a disconnect to
another connected tab, and push-to-talk drives whoever holds it.
Startup bookmarks are no longer mutually exclusive: every flagged
bookmark opens its own tab.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replace the modal add/edit form with a master/detail dialog: bookmark
list on the left, the selected bookmark's settings on the right. Edits
are flushed back into the bookmark when the selection changes or the
dialog closes.
Bookmarks gain a "connect on startup" flag (only one at a time, since
the client holds a single connection); MainFrame connects to it once
the window is up.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replace the chat target dropdown with a tab strip along the bottom of the
chat panel: a Server and a Channel tab plus one closable tab per private
chat, each with its own log and an unread marker.
Render logs and channel/client descriptions as HTML through a new BBCode
renderer in core, supporting b/i/u/s, color, size, url, center and lists,
with auto-linked bare URLs. Input is escaped and tag values validated, so
server-supplied text cannot inject markup or unsafe schemes.
Sender names and TeamSpeak's own client:// links open the same context menu
as the server tree (menus extracted into ClientMenu/ChannelMenu); channel://
links open the channel menu. Links are styled by CSS class: identities bold
in the author colour, other TS protocols plain, and links leaving the client
underlined so they cannot be mistaken for an identity.
Dragging a client or channel out of the tree yields the TS3 link BBCode.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Bookmarks can store a channel to join on connect, given either as a
"/"-separated path or a channel id, plus an optional channel password.
"Add bookmark" offers to remember the channel you are currently in.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Manage several TeamSpeak identities like the official client instead of
using one auto-generated identity file.
- IdentityStore/IdentityEntry keep each identity as a TeamSpeak-format INI
in ~/.ts3jclient/identities, so files interchange with the TS3 client;
supports create, import, export, rename, remove and a cancellable
security-level search. A legacy identity.ini is migrated in on first load.
- Settings hold the default identity; bookmarks may pin their own, falling
back to the default when unset.
- TeamspeakConnection now connects with the identity it is handed.
- Swing: Tools -> Identities manager, plus an identity drop-down in the
connect and bookmark forms.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add file up/downloads and directory operations for channel file
repositories, reachable from a channel's right-click "Browse files".
Core (com.ts3client.net.filetransfer):
- FileTransferManager drives the TS3 file protocol on the ts3j socket.
ftinitupload/ftinitdownload results arrive out-of-band as
notifystartupload/notifystartdownload (success) or
notifystatusfiletransfer (failure) events, not as command responses,
so negotiation correlates them by clientftfid via a CompletableFuture.
The byte phase opens a raw TCP socket, sends the ftkey, then streams.
- FileTransfer: observable per-transfer handle (state, progress, cancel).
- RemoteFile: UI-facing listing DTO, keeping core free of ts3j API types.
TeamspeakConnection exposes list/mkdir/delete/rename and up/download and
manages the manager's lifecycle. Swing FileBrowserDialog provides the
browser UI with a live per-transfer progress strip.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Swing desktop client (core/desktop/swing Maven modules) built on the
ts3j protocol library, included as a submodule. Native Opus voice with
voice-activation detection, push-to-talk, and audio pre-processing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>