feat(screencast,chat): roteamento read-only, avisos de sessão e TCP privado
SessionNoticeMessage encerra abas de recebimento; abas ↑/↓; chat unifica bucket peer e conexão TCP. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
fc657345ba
commit
112b6edaeb
14 files changed
+406
-36
No files matched your search
@@ -305,8 +305,8 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
@Override
|
||||
public void onPrivateChannelReady(String peerIp) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
appendSystemLine(privateKey(peerIp), "Canal TCP privado conectado com " + peerIp + ".");
|
||||
if (privateKey(peerIp).equals(activeConversationKey)) {
|
||||
appendSystemLine(peerKey(canonicalPeerIp(peerIp)), "Canal TCP privado conectado com " + peerIp + ".");
|
||||
if (peerKey(canonicalPeerIp(peerIp)).equals(activeConversationKey)) {
|
||||
flushTranscriptToPane();
|
||||
}
|
||||
});
|
||||
@@ -315,8 +315,8 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
@Override
|
||||
public void onPrivateChannelClosed(String peerIp) {
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
appendSystemLine(privateKey(peerIp), "Canal TCP privado encerrado (" + peerIp + ").");
|
||||
if (privateKey(peerIp).equals(activeConversationKey)) {
|
||||
appendSystemLine(peerKey(canonicalPeerIp(peerIp)), "Canal TCP privado encerrado (" + peerIp + ").");
|
||||
if (peerKey(canonicalPeerIp(peerIp)).equals(activeConversationKey)) {
|
||||
flushTranscriptToPane();
|
||||
}
|
||||
});
|
||||
@@ -324,7 +324,13 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
|
||||
@Override
|
||||
public void appendPrivateLine(String peerIp, LegacyMpChatMessage message, boolean outgoing) {
|
||||
SwingUtilities.invokeLater(() -> appendLegacyLine(privateKey(peerIp), message));
|
||||
SwingUtilities.invokeLater(() -> {
|
||||
String canonical = canonicalPeerIp(peerIp);
|
||||
if (!outgoing) {
|
||||
ensurePeerTabForIncoming(canonical, message.getNome());
|
||||
}
|
||||
appendLegacyLine(peerKey(canonical), message);
|
||||
});
|
||||
}
|
||||
|
||||
private void buildUi() {
|
||||
@@ -418,8 +424,8 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
if (privateChatController != null) {
|
||||
privateChatController.openChat(user);
|
||||
}
|
||||
appendSystemLine(privateKey(PeerIpv4.fromInetAddress(user.getAddress())),
|
||||
"Canal TCP privado conectando… envie de novo em instantes.");
|
||||
appendSystemLine(peerKey(canonicalPeerIp(PeerIpv4.fromInetAddress(user.getAddress()))),
|
||||
"Canal TCP privado conectando…");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -499,7 +505,7 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
public void receiveLegacyMessage(String tipo, String nome, String ip, String text) {
|
||||
runOnEdt(() -> {
|
||||
LegacyMpChatMessage legacy = new LegacyMpChatMessage(nome, ip, tipo, text);
|
||||
String bucket = ip != null && !ip.isBlank() ? privateKey(canonicalPeerIp(ip)) : ROOM_KEY;
|
||||
String bucket = ip != null && !ip.isBlank() ? peerKey(canonicalPeerIp(ip)) : ROOM_KEY;
|
||||
appendLegacyLine(bucket, legacy);
|
||||
});
|
||||
}
|
||||
@@ -551,7 +557,7 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
}
|
||||
if (key != null && key.startsWith("peer:") && !PluginSessionKeys.PEER_DRAFT.equals(key)) {
|
||||
String tabIp = canonicalPeerIp(key.substring("peer:".length()));
|
||||
return peerKey(tabIp).equals(bucket);
|
||||
return peerKey(tabIp).equals(bucket) || privateKey(tabIp).equals(bucket);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -609,9 +615,6 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
if (ip == null || ip.isEmpty()) {
|
||||
return ROOM_KEY;
|
||||
}
|
||||
if (routing.privateTcpOn()) {
|
||||
return privateKey(ip);
|
||||
}
|
||||
return peerKey(ip);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ public class PrivateChatController {
|
||||
private final PrivateChatHost host;
|
||||
private final Map<String, TcpConnection> connections = new HashMap<>();
|
||||
private final Set<String> pendingConnections = new HashSet<>();
|
||||
private final Map<String, PendingSend> pendingTextByAddress = new HashMap<>();
|
||||
private PrivateChatUiSink uiSink;
|
||||
|
||||
public PrivateChatController(ConnectionManager connectionManager, PrivateChatHost host) {
|
||||
@@ -38,10 +39,9 @@ public class PrivateChatController {
|
||||
return;
|
||||
}
|
||||
String address = PeerIpv4.fromInetAddress(user.getAddress());
|
||||
if (connections.containsKey(address)) {
|
||||
if (uiSink != null) {
|
||||
uiSink.onPrivateChannelReady(address);
|
||||
}
|
||||
TcpConnection existing = connections.get(address);
|
||||
if (existing != null && !existing.isClosed()) {
|
||||
flushPendingSend(address, user);
|
||||
return;
|
||||
}
|
||||
if (pendingConnections.contains(address)) {
|
||||
@@ -51,6 +51,17 @@ public class PrivateChatController {
|
||||
host.openConnection(address);
|
||||
}
|
||||
|
||||
public void registerOutgoingConnection(String address, TcpConnection connection) {
|
||||
if (address == null || connection == null) {
|
||||
return;
|
||||
}
|
||||
String canonical = PeerIpv4.normalize(address);
|
||||
pendingConnections.remove(canonical);
|
||||
replaceConnection(canonical, connection, false);
|
||||
User user = new User("", connection.getAddress(), System.currentTimeMillis(), null);
|
||||
flushPendingSend(canonical, user);
|
||||
}
|
||||
|
||||
public void receiveMessage(TcpConnection connection, LegacyMpChatMessage message) {
|
||||
if (uiSink != null) {
|
||||
uiSink.appendPrivateLine(addressKey(connection), message, false);
|
||||
@@ -60,8 +71,17 @@ public class PrivateChatController {
|
||||
public void connectionReceived(TcpConnection connection) {
|
||||
String address = addressKey(connection);
|
||||
pendingConnections.remove(address);
|
||||
replaceConnection(address, connection, true);
|
||||
}
|
||||
|
||||
private void replaceConnection(String address, TcpConnection connection, boolean notifyReady) {
|
||||
TcpConnection existing = connections.get(address);
|
||||
if (existing != null && !existing.isClosed() && existing != connection) {
|
||||
return;
|
||||
}
|
||||
boolean first = existing == null || existing.isClosed();
|
||||
connections.put(address, connection);
|
||||
if (uiSink != null) {
|
||||
if (notifyReady && first && uiSink != null) {
|
||||
uiSink.onPrivateChannelReady(address);
|
||||
}
|
||||
}
|
||||
@@ -69,6 +89,8 @@ public class PrivateChatController {
|
||||
public void closeChat(TcpConnection connection) {
|
||||
String address = addressKey(connection);
|
||||
connections.remove(address);
|
||||
pendingConnections.remove(address);
|
||||
pendingTextByAddress.remove(address);
|
||||
if (uiSink != null) {
|
||||
uiSink.onPrivateChannelClosed(address);
|
||||
}
|
||||
@@ -80,9 +102,24 @@ public class PrivateChatController {
|
||||
}
|
||||
String address = PeerIpv4.fromInetAddress(user.getAddress());
|
||||
TcpConnection connection = connections.get(address);
|
||||
if (connection == null) {
|
||||
if (connection == null || connection.isClosed()) {
|
||||
if (pendingConnections.contains(address)) {
|
||||
pendingTextByAddress.put(address, new PendingSend(user, text));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return sendOnConnection(connection, address, text);
|
||||
}
|
||||
|
||||
private void flushPendingSend(String address, User user) {
|
||||
PendingSend pending = pendingTextByAddress.remove(address);
|
||||
if (pending != null) {
|
||||
sendText(user != null ? user : pending.user, pending.text);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean sendOnConnection(TcpConnection connection, String address, String text) {
|
||||
try {
|
||||
LegacyMpChatMessage message = new LegacyMpChatMessage(
|
||||
connectionManager.getUserName(),
|
||||
@@ -105,6 +142,10 @@ public class PrivateChatController {
|
||||
if (user == null || user.getAddress() == null) {
|
||||
return false;
|
||||
}
|
||||
return connections.containsKey(PeerIpv4.fromInetAddress(user.getAddress()));
|
||||
TcpConnection connection = connections.get(PeerIpv4.fromInetAddress(user.getAddress()));
|
||||
return connection != null && !connection.isClosed();
|
||||
}
|
||||
|
||||
private record PendingSend(User user, String text) {
|
||||
}
|
||||
}
|
||||
@@ -139,11 +139,12 @@ public class ChatPlugin extends Plugin implements PrivateChatHost {
|
||||
@Override
|
||||
public void openConnection(String ip) {
|
||||
try {
|
||||
connectionManager.connectPluginTcp(
|
||||
TcpConnection connection = connectionManager.connectPluginTcp(
|
||||
InetAddress.getByName(ip),
|
||||
getIdentifier(),
|
||||
getIdentifier()
|
||||
);
|
||||
privateChatController.registerOutgoingConnection(ip, connection);
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error opening connection: " + e.getMessage());
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user