feat(ui): abas passivas sem badges na lista lateral (v1)
Sub-abas de chat e screencast são criadas em segundo plano ao receber; D23 adiado na UI. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
1414f59a20
commit
fc657345ba
10 files changed
+89
-200
No files matched your search
@@ -4,7 +4,6 @@ import pitiupi.application.messaging.MessageDispatcher;
|
||||
import pitiupi.application.messaging.PluginTransportCatalog;
|
||||
import pitiupi.application.messaging.SendTarget;
|
||||
import pitiupi.application.messaging.TransportMode;
|
||||
import pitiupi.api.plugin.PeerActivityFocusTokens;
|
||||
import pitiupi.application.presence.UserPeerView;
|
||||
import pitiupi.chat.control.PrivateChatController;
|
||||
import pitiupi.chat.control.PrivateChatUiSink;
|
||||
@@ -69,8 +68,6 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
private PrivateChatController privateChatController;
|
||||
private PeerDraftPanel draftPanel;
|
||||
private Runnable pendingTranscriptFlush;
|
||||
private String pluginId;
|
||||
|
||||
public ChatPanel(ConnectionManager connectionManager) {
|
||||
this.connectionManager = connectionManager;
|
||||
this.routingPanel = new PluginRoutingPanel(
|
||||
@@ -102,10 +99,6 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
selectRoomSession();
|
||||
}
|
||||
|
||||
public void setPluginId(String pluginId) {
|
||||
this.pluginId = pluginId;
|
||||
}
|
||||
|
||||
private void initSessionTabs() {
|
||||
sessionTabs.addOrSelectTab(
|
||||
PluginSessionKeys.ROOM,
|
||||
@@ -152,7 +145,6 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
if (PluginSessionKeys.ROOM.equals(key)) {
|
||||
routingPanel.bindRoomSession();
|
||||
switchActiveConversation(ROOM_KEY);
|
||||
reportActivityFocusForRoom();
|
||||
return;
|
||||
}
|
||||
if (key.startsWith("peer:") && !PluginSessionKeys.PEER_DRAFT.equals(key)) {
|
||||
@@ -160,40 +152,9 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
String name = peerDisplayNames.getOrDefault(ip, ip);
|
||||
routingPanel.bindPeerSession(ip, name);
|
||||
switchActiveConversation(resolveConversationKey());
|
||||
reportActivityFocusForPeerIp(ip);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportActivityFocusForRoom() {
|
||||
if (pluginId == null) {
|
||||
return;
|
||||
}
|
||||
connectionManager.getPeerActivityFocus()
|
||||
.setFocusedChannel(pluginId, PeerActivityFocusTokens.broadcast());
|
||||
}
|
||||
|
||||
private void reportActivityFocusForPeerIp(String ip) {
|
||||
if (pluginId == null) {
|
||||
return;
|
||||
}
|
||||
connectionManager.getPeerActivityFocus()
|
||||
.setFocusedChannel(pluginId, resolvePeerFocusToken(ip));
|
||||
}
|
||||
|
||||
private String resolvePeerFocusToken(String ip) {
|
||||
String canonical = canonicalPeerIp(ip);
|
||||
for (UserPeerView view : connectionManager.getPresenceService().listPeerViews()) {
|
||||
if (view.isBroadcastTarget() || view.isSelf()) {
|
||||
continue;
|
||||
}
|
||||
if (view.getInstanceId() != null
|
||||
&& view.getInetAddress().map(PeerIpv4::fromInetAddress).orElse("").equals(canonical)) {
|
||||
return PeerActivityFocusTokens.peerInstance(view.getInstanceId());
|
||||
}
|
||||
}
|
||||
return PeerActivityFocusTokens.peerIp(canonical);
|
||||
}
|
||||
|
||||
private void openDraftPeerTab() {
|
||||
String previous = sessionTabs.selectedKey();
|
||||
if (previous != null && !PluginSessionKeys.PEER_DRAFT.equals(previous)) {
|
||||
@@ -283,6 +244,18 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
showBodyCard(CARD_MAIN);
|
||||
}
|
||||
|
||||
private void ensurePeerTabForIncoming(String ip, String displayName) {
|
||||
String canonical = canonicalPeerIp(ip);
|
||||
String resolved = SessionPeerLabels.resolveDisplayName(connectionManager, canonical, displayName);
|
||||
peerDisplayNames.put(canonical, resolved);
|
||||
String tabKey = PluginSessionKeys.peer(canonical);
|
||||
sessionTabs.addTabIfAbsent(tabKey, resolved, canonical, new JPanel(), true);
|
||||
if (tabKey.equals(sessionTabs.selectedKey())) {
|
||||
routingPanel.bindPeerSession(canonical, resolved);
|
||||
switchActiveConversation(resolveConversationKey());
|
||||
}
|
||||
}
|
||||
|
||||
private static String canonicalPeerIp(String ip) {
|
||||
return PeerIpv4.normalize(ip);
|
||||
}
|
||||
@@ -298,7 +271,6 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
}
|
||||
|
||||
public void focusGeneralRoom() {
|
||||
reportActivityFocusForRoom();
|
||||
sessionTabs.selectTab(PluginSessionKeys.ROOM);
|
||||
}
|
||||
|
||||
@@ -324,9 +296,7 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
String bucket = bucketForIncoming(message);
|
||||
if (!ROOM_KEY.equals(bucket) && message.getSenderIp() != null && !message.getSenderIp().isBlank()) {
|
||||
String canonical = canonicalPeerIp(message.getSenderIp());
|
||||
if (!sessionTabs.hasTab(PluginSessionKeys.peer(canonical))) {
|
||||
openPeerTab(canonical, message.getName());
|
||||
}
|
||||
ensurePeerTabForIncoming(canonical, message.getName());
|
||||
bucket = peerKey(canonical);
|
||||
}
|
||||
appendChatLine(bucket, message);
|
||||
@@ -569,11 +539,23 @@ public class ChatPanel extends JPanel implements PrivateChatUiSink {
|
||||
private void prependLine(String bucket, String htmlLine) {
|
||||
StringBuilder buf = transcripts.computeIfAbsent(bucket, k -> new StringBuilder());
|
||||
buf.insert(0, htmlLine + "<br>");
|
||||
if (bucket.equals(activeConversationKey)) {
|
||||
if (bucket.equals(activeConversationKey) && isSessionTabShowingBucket(bucket)) {
|
||||
scheduleFlushTranscriptToPane();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSessionTabShowingBucket(String bucket) {
|
||||
String key = sessionTabs.selectedKey();
|
||||
if (ROOM_KEY.equals(bucket)) {
|
||||
return PluginSessionKeys.ROOM.equals(key);
|
||||
}
|
||||
if (key != null && key.startsWith("peer:") && !PluginSessionKeys.PEER_DRAFT.equals(key)) {
|
||||
String tabIp = canonicalPeerIp(key.substring("peer:".length()));
|
||||
return peerKey(tabIp).equals(bucket);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void scheduleFlushTranscriptToPane() {
|
||||
if (pendingTranscriptFlush != null) {
|
||||
return;
|
||||
|
||||
@@ -2,8 +2,6 @@ package pitiupi.chat.plugin;
|
||||
|
||||
import pitiupi.api.plugin.PeerActionsRegistrar;
|
||||
import pitiupi.api.plugin.PluginWorkspace;
|
||||
import pitiupi.api.plugin.PeerActivityFocusTokens;
|
||||
import pitiupi.application.activity.PeerActivityInbox;
|
||||
import pitiupi.application.peeractions.PeerAction;
|
||||
import pitiupi.application.peeractions.PeerActionTarget;
|
||||
import pitiupi.application.peeractions.PeerTarget;
|
||||
@@ -14,8 +12,6 @@ import pitiupi.chat.control.PrivateChatHost;
|
||||
import pitiupi.chat.net.ChatMessage;
|
||||
import pitiupi.chat.net.LegacyMpChatMessage;
|
||||
import pitiupi.control.ConnectionManager;
|
||||
import pitiupi.presentation.shell.LocalUserIdentity;
|
||||
import pitiupi.presentation.shell.PeerIpv4;
|
||||
import pitiupi.control.GuiManager;
|
||||
import pitiupi.models.Messages.Message;
|
||||
import pitiupi.models.Plugin;
|
||||
@@ -42,7 +38,6 @@ public class ChatPlugin extends Plugin implements PrivateChatHost {
|
||||
this.workspace = workspace;
|
||||
this.privateChatController = new PrivateChatController(connectionManager, this);
|
||||
this.chatPanel = new ChatPanel(connectionManager);
|
||||
chatPanel.setPluginId(getIdentifier());
|
||||
chatPanel.setPrivateChatController(privateChatController);
|
||||
privateChatController.setUiSink(chatPanel);
|
||||
bindShellWorkspaceContent(chatPanel);
|
||||
@@ -108,7 +103,6 @@ public class ChatPlugin extends Plugin implements PrivateChatHost {
|
||||
@Override
|
||||
public void receiveMessage(Message message) {
|
||||
if (message instanceof ChatMessage msg && chatPanel != null) {
|
||||
recordChatActivity(msg);
|
||||
SwingUtilities.invokeLater(() -> chatPanel.receiveChatMessage(msg));
|
||||
} else if (message instanceof LegacyMpChatMessage legacy && chatPanel != null) {
|
||||
SwingUtilities.invokeLater(() -> chatPanel.receiveLegacyMessage(
|
||||
@@ -120,51 +114,6 @@ public class ChatPlugin extends Plugin implements PrivateChatHost {
|
||||
}
|
||||
}
|
||||
|
||||
private void recordChatActivity(ChatMessage msg) {
|
||||
String localName = connectionManager.getUserName();
|
||||
if (localName != null && msg.getName() != null && localName.equals(msg.getName().trim())) {
|
||||
return;
|
||||
}
|
||||
if (LocalUserIdentity.isLocalSender(connectionManager, msg.getName(), msg.getSenderIp())) {
|
||||
return;
|
||||
}
|
||||
PeerActivityInbox inbox = connectionManager.getPeerActivityInbox();
|
||||
String tag = msg.getTransportLabel();
|
||||
boolean multicast = tag != null && tag.toLowerCase().contains("multicast");
|
||||
if (multicast) {
|
||||
inbox.recordBroadcastCounted(getIdentifier(), "chat.focus", PeerActivityFocusTokens.broadcast());
|
||||
return;
|
||||
}
|
||||
String instanceId = peerInstanceIdForActivity(msg.getSenderIp());
|
||||
if (instanceId != null) {
|
||||
inbox.recordCounted(
|
||||
instanceId,
|
||||
getIdentifier(),
|
||||
"chat.peer",
|
||||
PeerActivityFocusTokens.peerInstance(instanceId)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private String peerInstanceIdForActivity(String ip) {
|
||||
if (ip == null || ip.isBlank() || connectionManager == null) {
|
||||
return null;
|
||||
}
|
||||
String needle = PeerIpv4.normalize(ip);
|
||||
if (needle.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
for (UserPeerView view : connectionManager.getPresenceService().listPeerViews()) {
|
||||
if (view.isSelf()) {
|
||||
continue;
|
||||
}
|
||||
if (view.getInetAddress().map(PeerIpv4::fromInetAddress).orElse("").equals(needle)) {
|
||||
return view.getInstanceId();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean receivePrivateConnection(TcpConnection connection) {
|
||||
SwingUtilities.invokeLater(() -> privateChatController.connectionReceived(connection));
|
||||
@@ -178,15 +127,6 @@ public class ChatPlugin extends Plugin implements PrivateChatHost {
|
||||
return true;
|
||||
}
|
||||
privateChatController.receiveMessage(connection, legacy);
|
||||
String instanceId = peerInstanceIdForActivity(PeerIpv4.fromInetAddress(connection.getAddress()));
|
||||
if (instanceId != null) {
|
||||
connectionManager.getPeerActivityInbox().recordCounted(
|
||||
instanceId,
|
||||
getIdentifier(),
|
||||
"chat.private.tcp",
|
||||
PeerActivityFocusTokens.peerInstance(instanceId)
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user