Abstretta uses JavaScript in several key places to provide the kind of interactivity that makes the system easier to use. Up to now, it’s been plain old jQuery (https://jquery.org/) code. The resulting code worked fine, but I wasn’t quite happy with the performance. Also, because there was a lot of asynchronous things happening, I had to bypass Rails’ built-in TurboLinks functionality - which also hurt overall responsiveness.

So over the holiday break (time off? wuzzat?) I recoded all the JavaScript code using StimulusJS (https://www.stimulusjs.org). StimulusJS is written by the folks at Basecamp, still owned by DHH (https://twitter.com/dhh) who created Rails. So StimulusJS integrates perfectly with the TurboLinks page-load lifecycle making things faster and less glitchy.

Another advantage is that StimulusJS makes it easy to componentize wide-scoped functionality and apply it only when needed. For instance, Abstretta uses timeago.js (https://timeago.org/) to render relative timestamps. With StimulusJS this gets rolled into a controller as:

(() => {
  stimulus.register("timeago", class extends Stimulus.Controller {

    connect() {
      console.log("-=> timeago_controller connected");

      $("time.timeago").timeago();
      $(".timeago_content").fadeIn('slow');

      (function run_timeago() {
        setTimeout(function() {
          $("time.timeago").timeago();
        }, 60000);
      })();

    }

    initialize() {

      jQuery.timeago.settings.strings["en"] = {
        prefixAgo: null,
        prefixFromNow: null,
        suffixAgo: "",
        suffixFromNow: "",
        seconds: "<1m",
        minute: "1m",
        minutes: "%dm",
        hour: "1h",
        hours: "%dh",
        day: "1d",
        days: "%dd",
        month: "1mo",
        months: "%dmo",
        year: "1yr",
        years: "%dyr",
        wordSeparator: " ",
        numbers: []
      };

    }

  });
  console.log("-=> timeago_controller loaded");
})()

Then to use JavaScript-generated relative timestamps, that update every minute just attach it to the surrounding container like:

<div data-controller="timeago">
  Yadda yadda yadda
</div>

The next big step in the JavaScript code will be upgrading the Rails stack to 5.1 and putting in WebPacker support. That will give even better responsiveness - close to what you get from a native App.