add presence support

This commit is contained in:
emerson 2022-10-14 08:47:26 -04:00
parent a55837c171
commit 37e12cba8d
4 changed files with 64 additions and 1 deletions

View file

@ -1,5 +1,9 @@
# Changelog
## v0.2
### Added
- `AWAY` and `away-notify`
## v0.1.1 - 2022-02-09
- Fix `DELETEMSG` being sent to unsupporting clients
- Fix missing parameter in `900` numeric.

View file

@ -90,7 +90,7 @@ On Libera I'm `emerson`, on Matrix I'm `@emersonveenstra:matrix.org`, feel free
| Channel lists/searching | ❌ | ❌ | [#30](https://todo.sr.ht/~emerson/reflectionircd/30) |
| Encrypted rooms | ❌ | ❌ | [#20](https://todo.sr.ht/~emerson/reflectionircd/20) |
| Rich text | ❌ | ❌ | [#31](https://todo.sr.ht/~emerson/reflectionircd/31) |
| Presence | ❌ | ❌ | [#25](https://todo.sr.ht/~emerson/reflectionircd/25) Note that not all homeservers have presence enabled |
| Presence | ✅ | ✅ | Note that not all homeservers have presence enabled |
| Channel renaming <small>(IRCv3)</small> | ✅ | ❌ | [#16](https://todo.sr.ht/~emerson/reflectionircd/16) |
| Message replies <small>(IRCv3)</small> | ✅ | ✅ | Clients without support will still receive the reply message, but it won't be marked as a reply |
| Message reactions <small>(IRCv3)</small> | ✅ | ✅ ||

View file

@ -112,6 +112,9 @@ export abstract class Client {
case 'AUTHENTICATE':
this.doAUTHENTICATE(message);
break;
case 'AWAY':
this.doAWAY(message);
break;
case 'BATCH':
this.doBATCH(message);
break;
@ -187,6 +190,34 @@ export abstract class Client {
}
}
doAWAY(message: IRCMessage) {
const data = {
presence: 'online',
status_msg: ''
}
if (message.params.length === 1) {
data.presence = 'unavailable';
data.status_msg = message.params[0];
}
this.apiCall.put(`/presence/${this.user.mxid}/status`, data).then(r => {
// Returning the IRC numerics here because most servers have presence disabled anyways
if (data.presence === 'online') {
this.sendMessage(this.server.name, "305", [this.user.nick, "You are no longer marked as being away"]);
} else {
this.sendMessage(this.server.name, "306", [this.user.nick, "You have been marked as being away"]);
}
}).catch(function (error) {
if (error.response) {
console.log(error.response.data);
} else if (error.request) {
console.log(error.request);
} else {
console.log('Error', error.message);
console.log(error.config);
}
})
}
doBATCH(message: IRCMessage) {
const referenceTag = message.params[0].substring(1);
if (message.params[0].startsWith('+')) {

View file

@ -211,6 +211,9 @@ export class Server {
routeMatrixEvent(nextEvent: any, targetChannel: Channel) {
switch (nextEvent["type"]) {
case 'm.presence':
this.handleMatrixPresence(nextEvent);
break;
case 'm.reaction':
this.handleMatrixReaction(nextEvent, targetChannel);
break;
@ -279,6 +282,31 @@ export class Server {
}
}
handleMatrixPresence(event: any) {
let matrixUser = this.matrixUsers.get(event["sender"]);
// Don't bother sending if the user isn't joined to any channels yet
if (!matrixUser) {
return;
}
if (matrixUser.mxid === this.ourMatrixUser.mxid) {
return;
}
const presence = event["content"]?.["presence"];
if (!presence) {
return;
}
const status = event["content"]?.["status_msg"];
if (status === undefined) {
return;
}
if (presence === 'online') {
this.sendToAllWithCap('away-notify', matrixUser.getMask(), 'AWAY', []);
} else {
const awayMessage = (status === '') ? "user is away" : status;
this.sendToAllWithCap('away-notify', matrixUser.getMask(), 'AWAY', [awayMessage]);
}
}
handleMatrixReaction(event: any, targetChannel: Channel) {
const sourceUser = this.getOrCreateMatrixUser(event["sender"]);
this.checkForLazyJoin(event, sourceUser, targetChannel);