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>
Vendor libopus binaries under the desktop module's resources at JNA's
platform resource paths (linux-x86-64/libopus.so, win32-x86-64/opus.dll,
etc.), sourced from the checksum-verified club.minnced:opus-java-natives
1.1.1 artifact with the Windows lib renamed to JNA's mapped name.
Native.load("opus") still prefers a system libopus but now falls back to
the bundled copy, so the shaded uber-JAR runs with no external Opus
install on Linux (x86-64/x86/aarch64/arm), Windows (x86-64/x86) and
Intel macOS.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add ServicesResourceTransformer so overlapping service-provider files
(e.g. java.security.Provider) are concatenated rather than clobbered,
future-proofing the single executable JAR build.
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>