Close a channel's web tab when the user parts or is kicked (closes #185) #192

Merged
clawbot merged 1 commits from issue-185-web-part-kick into next 2026-10-27 03:11:34 +01:00
+31 -5
View File
@@ -355,6 +355,14 @@ function App() {
.catch(() => {});
}, []);
// removeChannelTab closes a channel's tab and shows the Server tab.
const removeChannelTab = useCallback((name) => {
setTabs((prev) =>
prev.filter((t) => !(t.type === "channel" && t.name === name)),
);
setActiveTab(0);
}, []);
const processMessage = useCallback(
(msg) => {
const body = Array.isArray(msg.body) ? msg.body.join("\n") : "";
@@ -424,6 +432,13 @@ function App() {
break;
}
case "PART": {
// The user's own PART, sent from this client or another,
// closes the tab and adds no message or unread count.
if (msg.from === nickRef.current) {
removeChannelTab(msg.to);
break;
}
const reason = body ? " (" + body + ")" : "";
const text = `${msg.from} has parted ${msg.to}${reason}`;
if (msg.to) addMessage(msg.to, { ...base, text, system: true });
@@ -431,6 +446,20 @@ function App() {
break;
}
case "KICK": {
// The kicked nick is in params; the body is the reason.
const kicked = Array.isArray(msg.params) ? msg.params[0] : "";
const reason = body ? " (" + body + ")" : "";
const text = `${kicked} was kicked from ${msg.to} by ${msg.from}${reason}`;
if (msg.to) addMessage(msg.to, { ...base, text, system: true });
if (kicked === nickRef.current) {
removeChannelTab(msg.to);
} else if (msg.to && msg.to.startsWith("#")) {
refreshMembers(msg.to);
}
break;
}
case "QUIT": {
const reason = body ? " (" + body + ")" : "";
const text = `${msg.from} has quit${reason}`;
@@ -656,7 +685,7 @@ function App() {
}
}
},
[addMessage, refreshMembers],
[addMessage, refreshMembers, removeChannelTab],
);
// Long-poll loop.
@@ -865,10 +894,7 @@ function App() {
} catch (e) {
// Ignore.
}
setTabs((prev) =>
prev.filter((t) => !(t.type === "channel" && t.name === name)),
);
setActiveTab(0);
removeChannelTab(name);
};
const closeTab = (idx) => {