diff --git a/README.md b/README.md
index c66fa9c..a91010c 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,8 @@ That said, it is usable for basic chatting.
| Channel topics | ✅ | ❌ ||
| Channel powers | ❌ | ❌ ||
| Encrypted rooms | ❌ | ❌ ||
-| Message replies (IRCv3) | ❌ | ❌ ||
+| Channel renaming (IRCv3) | 🟨 | ❌ | Only when the canonical alias changes |
+| Message replies (IRCv3) | ✅ | ❌ ||
| Message reactions (IRCv3) | ❌ | ❌ ||
| Chat history (IRCv3) | ❌ | ❌ ||
| Multiline messages (IRCv3) | ❌ | ❌ ||
diff --git a/src/Channel.ts b/src/Channel.ts
index c1f0755..a9f0af0 100644
--- a/src/Channel.ts
+++ b/src/Channel.ts
@@ -43,6 +43,25 @@ export class Channel {
return opStatus;
}
+ updateRoomName(newNameEvent: any) {
+ const newName: string = newNameEvent["content"]["alias"];
+ if (!newName || newName === this.name)
+ return;
+ const oldName = this.name;
+ this.name = newName;
+ this.ircUsers.forEach((user, username) => {
+ user.getClients().forEach(client => {
+ if (client.enabledCaps.has("draft/channel-rename")) {
+ client.sendMessage(this.server.name, "RENAME", [oldName, this.name, "New channel name set"], new Map());
+ }
+ else {
+ client.sendMessage(this.server.name, "PART", [oldName, "Renaming channel"], new Map());
+ this.joinNewIRCClient(client, new Map());
+ }
+ })
+ })
+ }
+
joinNewIRCClient(client: Client, passedTags: Map) {
if (!client.user)
return;
@@ -126,6 +145,9 @@ export class Channel {
return;
switch (event["type"]) {
+ case 'm.room.canonical_alias':
+ this.updateRoomName(event);
+ break;
case 'm.room.guest_access':
this.handleMatrixGuestAccess(event);
break;
@@ -166,7 +188,6 @@ export class Channel {
case 'm.room.bot.options':
case 'm.room.pinned_events':
case 'm.room.tombstone':
- case 'm.room.canonical_alias':
case 'm.room.server_acl':
case 'org.matrix.room.preview_urls':
break;
diff --git a/src/Client.ts b/src/Client.ts
index 862f744..03e156b 100644
--- a/src/Client.ts
+++ b/src/Client.ts
@@ -23,6 +23,7 @@ export class Client {
["account-tag", ""],
["batch", ""],
["draft/chathistory", ""],
+ ["draft/channel-rename", ""],
["echo-message", ""],
["draft/event-playback", ""],
["extended-join", ""],
@@ -190,11 +191,13 @@ export class Client {
if (this.user === null)
return;
if (rooms['join']) {
+ const joinedRooms: Set = new Set();
for (const roomId of Object.keys(rooms.join)) {
const targetChannel = this.server.getOrCreateIRCChannel(roomId);
- this.user.channels.add(targetChannel);
+ joinedRooms.add(targetChannel);
rooms.join[roomId].state.events.forEach((nextEvent: any) => targetChannel.routeMatrixEvent(nextEvent));
}
+ joinedRooms.forEach(c => {if (this.user !== null) this.user.channels.add(c)});
}
if (this.user === null)
return;
diff --git a/src/IRCUser.ts b/src/IRCUser.ts
index f48a80a..455f44c 100644
--- a/src/IRCUser.ts
+++ b/src/IRCUser.ts
@@ -44,6 +44,10 @@ export class IRCUser {
return `${this.nick}!${this.ident}@${this.hostname}`;
}
+ getClients(): Set {
+ return this.clients;
+ }
+
addClient(client: Client, passedTags: Map) {
this.clients.add(client);
if (this.nextBatch !== "") {