jaw-sh / stream-nexus

Unified multicast stream chat overlay.
26 stars 7 forks source link

Render chat messages in fragments #23

Closed y-a-t-s closed 8 months ago

y-a-t-s commented 8 months ago

This renders messages reasonably safely by splitting them into fragments around emotes. I want to avoid all use of |safe because sanitation should never be assumed. This means I'll have to mess with username rendering because of role/sub tier badges as well.

Still a very early WIP. Making a draft PR for tracking and discussion.

fixes #21

y-a-t-s commented 8 months ago

Messages are now split up into Fragment objects, similar to nodes on an AST. Basically what every other parser does for an IR, except this is linear and not a tree.

y-a-t-s commented 8 months ago

Kick support is done. It works well in testing.

jaw-sh commented 8 months ago

I really, really wish you had talked to me before putting in all this work, because I don't know what this does and I'm going to have to review it to understand it.

y-a-t-s commented 8 months ago

It basically uses the existing emote regex to split the messages into chunks. Those chunks are stored in Fragment objects with an identifier for either EMOTE or TEXT. More fragment types can be added as needed. The Fragments work like nodes in trees used by most parsers, which tokenize and identify the node type (i.e. EMOTE or TEXT).

EMOTE fragments are required to have a valid URL as its associated value.

TEXT fragments are treated as plaintext, getting escaped by Askama.

We can use loops, like discussed in #21, to assemble the message body by rendering the chunks sequentially. EMOTE fragments get their url and id values put into an <img> tag and rendered properly. TEXT fragments just get rendered as escaped message text. I moved some of the template stuff to Askama macros to better re-use the rendering templates.

Using fragments like this lets us be sure that we only render the HTML we expect to. The |e in the templates ensures all HTML stuff in plaintext gets escaped.

I apologize for not communicating enough before starting this. I will be sure to check in next time.