Name the server and channel chat tabs after where we are
Both carry an icon now, as the private chats do. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,8 +58,11 @@ public final class ChatPanel extends JPanel {
|
||||
private final JTextField input = new JTextField();
|
||||
private final SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss");
|
||||
|
||||
private final Tab serverTab = new Tab(Target.SERVER, 0, "Server");
|
||||
private final Tab channelTab = new Tab(Target.CHANNEL, 0, "Channel");
|
||||
private static final String NO_SERVER = "Server";
|
||||
private static final String NO_CHANNEL = "Channel";
|
||||
|
||||
private final Tab serverTab = new Tab(Target.SERVER, 0, NO_SERVER, Icons.server());
|
||||
private final Tab channelTab = new Tab(Target.CHANNEL, 0, NO_CHANNEL, Icons.channelChat());
|
||||
/** Private chats keyed by the peer's client id. */
|
||||
private final Map<Integer, Tab> privateTabs = new LinkedHashMap<>();
|
||||
/** Static-content tabs (e.g. a moved-out description), keyed by caller-chosen id. */
|
||||
@@ -116,6 +119,16 @@ public final class ChatPanel extends JPanel {
|
||||
});
|
||||
}
|
||||
|
||||
/** Names the server tab after the server we are on; blank falls back to "Server". */
|
||||
public void setServerName(String name) {
|
||||
edt(() -> serverTab.setTitle(name == null || name.isBlank() ? NO_SERVER : name));
|
||||
}
|
||||
|
||||
/** Names the channel tab after the channel we are in; blank falls back to "Channel". */
|
||||
public void setChannelName(String name) {
|
||||
edt(() -> channelTab.setTitle(name == null || name.isBlank() ? NO_CHANNEL : name));
|
||||
}
|
||||
|
||||
public void setInputEnabled(boolean enabled) {
|
||||
input.setEnabled(enabled);
|
||||
}
|
||||
@@ -218,7 +231,7 @@ public final class ChatPanel extends JPanel {
|
||||
private Tab privateTab(int clientId, String nickname) {
|
||||
Tab tab = privateTabs.get(clientId);
|
||||
if (tab == null) {
|
||||
tab = new Tab(Target.PRIVATE, clientId, nickname);
|
||||
tab = new Tab(Target.PRIVATE, clientId, nickname, Icons.privateChat());
|
||||
privateTabs.put(clientId, tab);
|
||||
addTab(tab, true);
|
||||
}
|
||||
@@ -285,7 +298,7 @@ public final class ChatPanel extends JPanel {
|
||||
|
||||
final Target target;
|
||||
final int clientId;
|
||||
final String title;
|
||||
private String title;
|
||||
final JEditorPane log = HtmlStyles.pane("font-family:sans-serif; font-size:11px; margin:4px 6px;");
|
||||
final JScrollPane scroll;
|
||||
/** Set for a static-content tab (e.g. a moved-out description); null for a conversation. */
|
||||
@@ -294,8 +307,8 @@ public final class ChatPanel extends JPanel {
|
||||
private final Icon icon;
|
||||
private JLabel titleLabel;
|
||||
|
||||
Tab(Target target, int clientId, String title) {
|
||||
this(target, clientId, title, null, null, null);
|
||||
Tab(Target target, int clientId, String title, Icon icon) {
|
||||
this(target, clientId, title, icon, null, null);
|
||||
}
|
||||
|
||||
/** A static-content tab: no send target, closing it runs {@code onClose}. */
|
||||
@@ -369,6 +382,15 @@ public final class ChatPanel extends JPanel {
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Renames the tab in place — the server and channel tabs follow where we are. */
|
||||
void setTitle(String title) {
|
||||
if (title.equals(this.title)) return;
|
||||
this.title = title;
|
||||
int index = tabs.indexOfComponent(scroll);
|
||||
if (index >= 0) tabs.setTitleAt(index, title);
|
||||
if (titleLabel != null) titleLabel.setText(title);
|
||||
}
|
||||
|
||||
void setUnread(boolean unread) {
|
||||
if (titleLabel == null) return;
|
||||
titleLabel.setFont(unread ? Theme.uiBold() : Theme.uiFont());
|
||||
|
||||
@@ -114,6 +114,18 @@ public final class Icons {
|
||||
return subscribed ? new String[]{base + "_SUBSCRIBED", base} : new String[]{base};
|
||||
}
|
||||
|
||||
/** The chat tab for the current channel. */
|
||||
public static ImageIcon channelChat() {
|
||||
ImageIcon icon = of("CHANNEL_CHAT");
|
||||
return icon != null ? icon : channel(true);
|
||||
}
|
||||
|
||||
/** The chat tab of a private conversation. */
|
||||
public static ImageIcon privateChat() {
|
||||
ImageIcon icon = ofAny("PLAYER_CHAT", "NEW_CHAT");
|
||||
return icon != null ? icon : clientIdle();
|
||||
}
|
||||
|
||||
// ---- client status icons ----
|
||||
|
||||
public static ImageIcon clientIdle() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.ts3client.ui;
|
||||
|
||||
import com.ts3client.net.ChannelNode;
|
||||
import com.ts3client.net.ClientEntry;
|
||||
import com.ts3client.net.ConnectionListener;
|
||||
import com.ts3client.net.TeamspeakConnection;
|
||||
|
||||
@@ -50,6 +52,14 @@ final class ServerTabConnectionEvents implements ConnectionListener {
|
||||
this.treeActions = treeActions;
|
||||
}
|
||||
|
||||
/** Name of the channel we are in, or null while that is not known yet. */
|
||||
private String currentChannelName() {
|
||||
ClientEntry self = conn.getModel().getClient(conn.getSelfClientId());
|
||||
if (self == null) return null;
|
||||
ChannelNode ch = conn.getModel().getChannel(self.channelId);
|
||||
return ch == null ? null : ch.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatus(String text) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
@@ -80,6 +90,8 @@ final class ServerTabConnectionEvents implements ConnectionListener {
|
||||
chatPanel.setInputEnabled(false);
|
||||
chatPanel.closePrivateChats();
|
||||
chatPanel.closeNoteTabs();
|
||||
chatPanel.setServerName(null);
|
||||
chatPanel.setChannelName(null);
|
||||
chatPanel.appendSystem("Disconnected" + (reason == null || reason.isEmpty() ? "." : ": " + reason));
|
||||
host.tabDisconnected(tab);
|
||||
});
|
||||
@@ -96,6 +108,10 @@ final class ServerTabConnectionEvents implements ConnectionListener {
|
||||
listener.setTitle(name);
|
||||
host.tabUpdated(tab);
|
||||
}
|
||||
if (conn.isConnected()) {
|
||||
chatPanel.setServerName(name);
|
||||
chatPanel.setChannelName(currentChannelName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user