Skip to content

Instantly share code, notes, and snippets.

@swantzter
Created July 7, 2021 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swantzter/e78f094b3ca32f052f3a1dbccbfa8887 to your computer and use it in GitHub Desktop.
Save swantzter/e78f094b3ca32f052f3a1dbccbfa8887 to your computer and use it in GitHub Desktop.
Web IRC client idea

Goals

So, I've been trying to think of how I would like to see a web irc client built, and why

  • It should appeal to an audience who are not familiar with IRC and provide them a good introduction
  • You shouldn't need to read pages of docs to use it, show but "explain" IRC specific stuff like channel modes etc inside the client. (named modes would be cool for that)

I need to think about more goals tbh

Architecture

I'd like to split the thing into two or three parts, moving most of the IRC out of the "main thread" through workers. It's a shame SharedWorker doesn't have wider support.

This also means that hopefully, by isolating IRC state and parsing we could end up with a really solid library that could be used in other environments too, such as node.js or deno.

  1. Worker for Networking+Parsing. This worker would either be the above mentioned library, or lightly wrap it by adding WebSocket to talk to the server, and postMessage to talk with the main thread and other workers. It should handle sending and recieving messages, keeping the state up to date, pings and pongs, CAP negotiation etc, basically all the IRC, and then it should parse messages into a more JS friendly format, probably an object, perhaps for a privmsg or notice { command, source, target, message, tags, msgId, timestamp }, probably needs thought by someone who knows irc better than me. Once it's done parsing it postMessages to listening targets depending on what they're currently listening to. It could also post smaller "status updates" such as "new messages for channels A,B,C". That way say the UI would subscribe to "messages for channel X" and "global status updates", and the storage worker would subscribe to "all messages" and "channel join/parts"
  2. Worker for Storage/Persisted State. This worker would talk with some sort of storage, could be local, could be remote, could be a hybrid, for local/first impl I think it'd be interesting to look into IndexedDB (idb), there are good wrapper libraries for it ruch as the aptly named idb, that way you could index on say target and timestamp and quickly recieve messages sent in one channel between two dates. THis worker would also persist state from the IRC worker to be reused when the user returns (Nick, which channels are joined (for auto-rejoin), etc.) This worker would talk with the IRC worker through a MessageChannel. A remote storage could potentially even rely on chathistory
  3. Main thread for rendering. With the above two workers the main thread can hopefully be kept pretty free to do just UI work, leaving it responsive and fast even on low-power devices. It would "subscribe" to new messages for the buffer it's currently viewing from the IRC state Worker and thus only get a small subset of the messages, it would then only keep the messages that are currently visible on screen (and a short backlog) in memory and emulate a scrollbar that's long enough to represent how many messages there are (one way could be to put one empty element just above the rendered scrollback, give it height: calc(var(--hidden-messages) * 2rem) and content-visibility: auto when you then scroll back previous messages are requested from the storage worker for the date/time range you've scrolled to

Alternatively the Networking+Parsing Worker is merged with the Storage/Persisted State worker.

UI/UX

All right, this is specifically why I want to decouple the UI from the IRC parsing and storage, because I think the underlying IRC stuff can be useful for others and easily reused, but I would like the UI to do some Libera specific things, maybe those things could be turned off with config, or we just encourage other frontends for other uses.

Channel Groups

I want channels to be grouped by namespace, something like:

Libera Chat
  #libera
  #libera-dev
Solanum
  #solanum
----------------
Informal
  ##channel
  ##otherchannel
----------------
Direct Messages
  Swant
  SomePerson
  ABot

Collapse joins, parts and nick changes

I like how glirc does this:

Nick+ Nick2+- Nick3>Nick4 Nick5*

Inline comamnd syntax help

It's hard to know what order parameters should be, and what they are, once again I'd liek to look to glirc for something like what it does, either inline or as a "tooltip" à la slack or discord

Examples from glirc

  1. Starting to type a command (command is blue signifying there is a command starting with what I've typed)
  2. Typed an invalid command (command turns red, giving me early feedback I did something wrong)
  3. Typed a valid command (shows me placeholders for optional and required parameters, command is yellow since it requires parameters)
  4. Entered the required parameters (command turns green)
  5. This also works for /mode, I believe by using the info in RPL_MYINFO

Example from slack

I don't fully like how it shows the parameters, and I specifically dislikes that it opens another "search" window on top of your input box, but I like that it shows a list based on the fact you've typed / and filters it based on what you type next:

Example from Discord

Sorry you'll have to deal with swedish here. I like that it shows up above your normal input box, and I like that it explains what the command does with a sentence. It's also pretty beginner friendly when showing you parameters, they're visually distinct (monospace on a different background colour) and doesn't use things like <> and [] to show required/optional, instead it spells out "OPTIONAL" before the parameter if it's optional. I'm not sure how I feel about that list not showing the parameters until you hover over it or have typed out the entire command. It might actually be a pretty good idea now that I think about it, but it initially made me hesitate

@swantzter
Copy link
Author

swantzter commented Jul 7, 2021

I was also considering making bots a separate group to direct messages, not sure how, bot mode https://ircv3.net/specs/extensions/bot-mode? c2c tags? METADATA?

@progval
Copy link

progval commented Jul 7, 2021

show but "explain" IRC specific stuff like channel modes etc inside the client. (named modes would be cool for that)

I don't think named modes alone are useful. We need to specify more modes and/or make the IRCd provide documentation for them; but (all?) IRCd authors seem to dislike the former, and they can't agree on a way to do the latter.

Inline comamnd syntax help

And for bots: ircv3/ircv3-specifications#415

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment