aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--components/buffer.js75
-rw-r--r--components/member-list.js19
-rw-r--r--components/membership.js15
-rw-r--r--lib/irc.js20
-rw-r--r--style.css2
6 files changed, 98 insertions, 38 deletions
diff --git a/README.md b/README.md
index 65a033b..e11229b 100644
--- a/README.md
+++ b/README.md
@@ -45,8 +45,8 @@ gamja can be configured via a [configuration file] and via [URL parameters].
## Contributing
-Send patches on the [mailing list], report bugs on the [issue tracker]. Discuss
-in [#soju on Libera Chat].
+Send patches on [Codeberg] or on the [mailing list], report bugs on the
+[issue tracker]. Discuss in [#soju on Libera Chat].
## License
@@ -55,6 +55,7 @@ AGPLv3, see LICENSE.
Copyright (C) 2020 The gamja Contributors
[gamja]: https://sr.ht/~emersion/gamja/
+[Codeberg]: https://codeberg.org/emersion/gamja
[mailing list]: https://lists.sr.ht/~emersion/public-inbox
[issue tracker]: https://todo.sr.ht/~emersion/gamja
[Parcel]: https://parceljs.org
diff --git a/components/buffer.js b/components/buffer.js
index 3112a57..3b160e3 100644
--- a/components/buffer.js
+++ b/components/buffer.js
@@ -196,11 +196,80 @@ class LogLine extends Component {
break;
case "MODE":
target = msg.params[0];
+ let modeStr = msg.params[1];
+
+ let user = html`${createNick(msg.prefix.name)}`;
+
+ // TODO: use irc.forEachChannelModeUpdate()
+ if (buf.type == BufferType.CHANNEL && modeStr.length === 2 && server.cm(buf.name) === server.cm(target)) {
+ let plusMinus = modeStr[0];
+ let mode = modeStr[1];
+ let arg = msg.params[2];
+
+ let verb;
+ switch (mode) {
+ case "b":
+ verb = plusMinus === "+" ? "added" : "removed";
+ content = html`${user} has ${verb} a ban on ${arg}`;
+ break;
+ case "e":
+ verb = plusMinus === "+" ? "added" : "removed";
+ content = html`${user} has ${verb} a ban exemption on ${arg}`;
+ break;
+ case "l":
+ if (plusMinus === "+") {
+ content = html`${user} has set the channel user limit to ${arg}`;
+ } else {
+ content = html`${user} has unset the channel user limit`;
+ }
+ break;
+ case "i":
+ verb = plusMinus === "+" ? "marked": "unmarked";
+ content = html`${user} has ${verb} as invite-only`;
+ break;
+ case "m":
+ verb = plusMinus === "+" ? "marked": "unmarked";
+ content = html`${user} has ${verb} as moderated`;
+ break;
+ case "s":
+ verb = plusMinus === "+" ? "marked": "unmarked";
+ content = html`${user} has ${verb} as secret`;
+ break;
+ case "t":
+ verb = plusMinus === "+" ? "locked": "unlocked";
+ content = html`${user} has ${verb} the channel topic`;
+ break;
+ case "n":
+ verb = plusMinus === "+" ? "allowed": "denied";
+ content = html`${user} has ${verb} external messages to this channel`;
+ break;
+ }
+ if (content) {
+ break;
+ }
+
+ // Channel membership modes
+ let membership;
+ for (let prefix in irc.STD_MEMBERSHIP_MODES) {
+ if (irc.STD_MEMBERSHIP_MODES[prefix] === mode) {
+ membership = irc.STD_MEMBERSHIP_NAMES[prefix];
+ break;
+ }
+ }
+ if (membership && arg) {
+ let verb = plusMinus === "+" ? "granted" : "revoked";
+ let preposition = plusMinus === "+" ? "to" : "from";
+ content = html`
+ ${user} has ${verb} ${membership} privileges ${preposition} ${createNick(arg)}
+ `;
+ break;
+ }
+ }
+
content = html`
- * ${createNick(msg.prefix.name)} sets mode ${msg.params.slice(1).join(" ")}
+ ${user} sets mode ${msg.params.slice(1).join(" ")}
`;
- // TODO: case-mapping
- if (buf.name !== target) {
+ if (server.cm(buf.name) !== server.cm(target)) {
content = html`${content} on ${target}`;
}
break;
diff --git a/components/member-list.js b/components/member-list.js
index 283892d..f539f76 100644
--- a/components/member-list.js
+++ b/components/member-list.js
@@ -22,25 +22,6 @@ class MemberItem extends Component {
}
render() {
- // XXX: If we were feeling creative we could generate unique colors for
- // each item in ISUPPORT CHANMODES. But I am not feeling creative.
- const membmap = {
- "~": "owner",
- "&": "admin",
- "@": "op",
- "%": "halfop",
- "+": "voice",
- };
- const membclass = membmap[this.props.membership[0]] || "";
- let membership = "";
- if (this.props.membership) {
- membership = html`
- <span class="membership ${membclass}" title=${membclass}>
- ${this.props.membership}
- </span>
- `;
- };
-
let title;
let user = this.props.user;
let classes = ["nick"];
diff --git a/components/membership.js b/components/membership.js
index 36b3d73..9f7b4c3 100644
--- a/components/membership.js
+++ b/components/membership.js
@@ -1,21 +1,14 @@
import { html, Component } from "../lib/index.js";
-
-// XXX: If we were feeling creative we could generate unique colors for
-// each item in ISUPPORT CHANMODES. But I am not feeling creative.
-const names = {
- "~": "owner",
- "&": "admin",
- "@": "op",
- "%": "halfop",
- "+": "voice",
-};
+import * as irc from "../lib/irc.js";
export default function Membership(props) {
if (!this.props.value) {
return null;
}
- const name = names[this.props.value[0]] || "";
+ // XXX: If we were feeling creative we could generate unique colors for
+ // each item in ISUPPORT CHANMODES. But I am not feeling creative.
+ const name = irc.STD_MEMBERSHIP_NAMES[this.props.value[0]] || "";
return html`
<span class="membership ${name}" title=${name}>
${this.props.value}
diff --git a/lib/irc.js b/lib/irc.js
index dafa99b..11ea578 100644
--- a/lib/irc.js
+++ b/lib/irc.js
@@ -74,8 +74,24 @@ export const ERR_SASLTOOLONG = "905";
export const ERR_SASLABORTED = "906";
export const ERR_SASLALREADY = "907";
-export const STD_MEMBERSHIPS = "~&@%+";
-export const STD_CHANTYPES = "#&+!";
+export const STD_MEMBERSHIP_NAMES = {
+ "~": "owner",
+ "&": "admin",
+ "@": "operator",
+ "%": "halfop",
+ "+": "voice",
+};
+
+export const STD_MEMBERSHIP_MODES = {
+ "~": "q",
+ "&": "a",
+ "@": "o",
+ "%": "h",
+ "+": "v",
+};
+
+const STD_MEMBERSHIPS = "~&@%+";
+const STD_CHANTYPES = "#&+!";
const tagEscapeMap = {
";": "\\:",
diff --git a/style.css b/style.css
index bbb08d4..4ed7089 100644
--- a/style.css
+++ b/style.css
@@ -302,7 +302,7 @@ button.danger:hover {
.membership.admin {
color: blue;
}
-.membership.op {
+.membership.operator {
color: var(--green);
}
.membership.halfop {