Keep each server's session state in core
What a server tab knows beyond its views - the connection lifecycle, title and status, the identity used, the microphone/speaker/away and commander flags, chat sending and the channel lookups - moves from the Swing ServerTab and ServerTabSelfState into core's ServerSession, so another frontend gets the same behaviour without copying it. ServerSession also takes over what the Swing event bridge decided on its own: clearing the model on disconnect, naming the tab after the server, showing senders under their contact names, and the chat's system lines. The bridge now only updates views. SelfState moves along, while its icons stay with the tray. A server switch no longer needs to queue behind the UI thread: the disconnect is reported synchronously, so the session is free again by the time it reconnects. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
package com.ts3client.ui;
|
||||
|
||||
import com.ts3client.session.SelfState;
|
||||
import com.ts3client.ui.tray.AwtTray;
|
||||
import com.ts3client.ui.tray.TrayBackend;
|
||||
import com.ts3client.ui.tray.X11Tray;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JMenuItem;
|
||||
@@ -76,7 +78,7 @@ final class TrayController {
|
||||
// -Dts3j.tray=awt|x11 pins the backend; by default the transparent one is
|
||||
// tried first and AWT's picks up whatever it leaves.
|
||||
String choice = System.getProperty("ts3j.tray", "auto");
|
||||
IntFunction<Image> initial = size -> SelfState.DISCONNECTED.icon(size).getImage();
|
||||
IntFunction<Image> initial = size -> icon(SelfState.DISCONNECTED, size).getImage();
|
||||
TrayBackend backend = choice.equals("awt") ? null : X11Tray.create(listener, initial);
|
||||
if (backend == null && !choice.equals("x11")) {
|
||||
backend = AwtTray.create(listener, buildAwtMenu(), initial);
|
||||
@@ -93,7 +95,7 @@ final class TrayController {
|
||||
if (newState == state && newTooltip.equals(tooltip)) return;
|
||||
state = newState;
|
||||
tooltip = newTooltip;
|
||||
tray.setIcon(size -> newState.icon(size).getImage());
|
||||
tray.setIcon(size -> icon(newState, size).getImage());
|
||||
tray.setTooltip(newTooltip);
|
||||
}
|
||||
|
||||
@@ -101,13 +103,28 @@ final class TrayController {
|
||||
void refreshIcon() {
|
||||
if (tray == null || state == null) return;
|
||||
SelfState current = state;
|
||||
tray.setIcon(size -> current.icon(size).getImage());
|
||||
tray.setIcon(size -> icon(current, size).getImage());
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
if (tray != null) tray.dispose();
|
||||
}
|
||||
|
||||
/** The icon a state is drawn with, from the active icon pack. */
|
||||
private static ImageIcon icon(SelfState state, int size) {
|
||||
return switch (state) {
|
||||
case DISCONNECTED -> Icons.app(size);
|
||||
case DEAFENED -> Icons.speakerMuted(size);
|
||||
case MIC_MUTED -> Icons.micMuted(size);
|
||||
case MIC_LOCAL_MUTED -> Icons.micLocalMuted(size);
|
||||
case AWAY -> Icons.clientAway(size);
|
||||
case COMMANDER_TALKING -> Icons.clientCommanderTalking(size);
|
||||
case COMMANDER -> Icons.clientCommander(size);
|
||||
case TALKING -> Icons.clientTalking(size);
|
||||
case IDLE -> Icons.clientIdle(size);
|
||||
};
|
||||
}
|
||||
|
||||
// ---- menus ----
|
||||
|
||||
/** The menu for AWT's icon, which shows one of its own. */
|
||||
|
||||
Reference in New Issue
Block a user