BenDMyers / showmy.chat

On-demand themed Twitch chat overlay generator

Home Page:https://showmy.chat

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Configuration for showing the "n" most recent messages

BenDMyers opened this issue · comments

Need

Some users would only like to display the n latest messages - especially in the case of large, obtrusive themes such as animalese and cards. This can be handled theme-level — for instance, cards currently displays the five most recent messages using :nth-last-child:

[data-twitch-message]:nth-last-child(n+5) {
	opacity: 0;
	transform: rotateX(-90deg);
	transition:
		opacity var(--animation-duration) ease-in,
		transform var(--animation-duration) ease-in;
}

However, this isn't ideal, because it hardcodes the number of messages that can be displayed, and it does so in a way that requires some weird CSS overrides to change.

showmy.chat should provide a query parameter through which users can specify how many of the most recent messages to display. If this query parameter is not provided, then the default behavior should be to show all messages — this way, users strictly opt in to only showing a subset of their messages.

Suggested API

  • Configuration should be strictly optional. If query parameter is not provided, all messages are shown.
    • In homepage URL builder, if user does not opt in to only displaying the n latest messages, don't add the query parameter to the built URL at all
  • Query parameter name could be showLatestMessages, and its expected value should be an integer greater than zero.
    • If value is not an integer greater than zero, query parameter is ignored.
  • Deletion should be handled in the JavaScript, and outdated messages should be completely deleted, rather than hidden. Rationale:
    • If outdated messages are hidden with CSS solutions, then when a mod deletes a message, previously-hidden outdated messages could become visible again
    • Some folks may be using the n latest feature to reduce the number of DOM elements on the page for perf reasons

Steps

  • Ensure Eleventy Serverless query parameter data can be accessed inside the handleChat script
  • Ensure if showLatestMessages query parameter has been provided, and is an integer greater than 0, scripts delete older messages
  • Add configuration to homepage URL builder
  • Remove hardcoded CSS implementation in themes (currently just cards, I think?)
  • Notify known users of cards theme of changed behavior

@ajcwebdev I know you've expressed interest in configuring the number of messages shown (and maybe in contributing to that feature?)

I'd love to know what you think about the above specs for that.

Note to whomever picks up this issue: we can split this up into two pull requests if need be.

  1. The logic for supporting the configuration query parameter
  2. Adding configuration to the homepage URL builder

Thanks for opening this issue Ben; this will be a great addition to an already awesome library.

I like the default of showing all messages. I think most users will want an infinite scroll style where it just fills up the entire space they've allotted for chat messages. Having a query parameter to configure that behavior sounds like a good solution.

Potential solutions:

  1. The page inspects the URL and grabs the query parameters. It looks at its own query parameters and parses through them. Problem is you don't want cross side scripting attacks.
  2. Have the serverless template generate a bunch of meta tags that wouldn't appear on screen that can encode the information as attributes and then we use querySelector to get those elements and attributes.
  3. Inline script so we have access to Eleventy templating. But that may cause syntax highlighting issues.

Option two seems like the best way forward right now.

On Chance's Some Antics stream this week (timestamp 11m 37s), Chance briefly demonstrated a technique that I think could be a potential solution here — he sets a global variable equal to a stringified version of process.env:

<script
	dangerouslySetInnerHTML={{
		__html: `window.ENV = ${JSON.stringify(ENV)}`;
	}}
/>

I poked around, and it looks like Sean McPherson describes an Eleventy-ified version of this approach at https://www.seanmcp.com/articles/send-data-to-the-window-with-eleventy/

Using this and passing it the eleventy.serverless.query data object might be the cleanest approach, and it has my vote. Thoughts, @ajcwebdev?

Yeah, that's a tiny amount of code. I like it!

To get a feel for this approach I broke it down to the smallest possible steps I could think of to find a point where my understanding breaks down.

  • Add shortcode to Eleventy config with script tag
  • Expose shortcode on home page
  • Console log data passed into shortcode
  • Console log Eleventy serverless query

This happens when I get to the Eleventy serverless part, which makes sense since I've never used it before.

Add shortcode to Eleventy config with script tag

Create a shortcode called console-log-test inside .eleventy.js that returns a JavaScript <script> tag that console logs a hard coded string.

eleventyConfig.addShortcode("console-log-test", () => {
  return `<script>
    console.log('test')
  </script>`
})

Expose shortcode on home page

Include shortcode in index.html.

{% console-log-test %}

Console log data passed into shortcode

Stringify and console log data passed into shortcode.

eleventyConfig.addShortcode("console-log-data", data => {
  return `<script>
    console.log(${JSON.stringify(data)})
  </script>`
})
{% console-log-data "test-data" %}

Console log variable attached to window

Stringify data and set it to TEST_VARIABLE on the window.

eleventyConfig.addShortcode("console-log-window", data => {
  return `<script>
    window.TEST_VARIABLE = ${JSON.stringify(data)}
    console.log(TEST_VARIABLE)
  </script>`
})
{% console-log-window "window-variable-test" %}

Console log Eleventy serverless query

At this point I'm not sure how to access the eleventy.serverless.query object, and where that fits in between the shortcode definition in .eleventy.js, the shortcode itself, and the serverless function.

@ajcwebdev

The short answer is your shortcode use would look like

{% console-log-data eleventy.serverless.query %}

Eleventy supplies that eleventy object in the data cascade, so you'd access it like you would any other data property (i.e. accessing it top-level like eleventy, rather than as a property of some data object like data.eleventy.