Feature Request: small, tiny countdown on the user input “Yes”

I call that flicker a feature, @Nige_S. :grinning: You wouldn't want a macro user to miss the countdown, right?


Recently I revised my go-to countdown timer to momentarily flash a green background when it first appears (or is reset) because I want to draw attention to it. (Call it a colorful flicker. :grinning:)

Also when it's about to expire, it's background changes to yellow. That gives me plently of time to click the Reset button if I need more time.

Timer


As I'm sure you know, stuff like this is remarkably easy with the Custom HTML Prompt action:

( Custom HTLM Prompt configuration )
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <style type="text/css">
    body {
      margin-top: 5px;
      margin-bottom: 0;
      background: #ebebeb;
      font-family: Sans-Serif;
      color: red;
    }
    h1 {
      margin-top: 0;
      margin-bottom: 2px;
      font-size: 24px;
    }
    @keyframes FlashGreen {
      to {
        background-color: lightgreen;
        color: black;
      }
    }
    .color_invert {
      animation-name: FlashGreen;
      animation-duration: 0.5s;
      animation-timing-function: ease-out;
      animation-delay: 0;
      animation-iteration-count: 1;
      animation-direction: alternate-reverse;
    }
    .yellow_background {
      background-color: yellow;
      color: red;
    }
  </style>
</head>
<body data-kmwindowid="Archive MD5 Tamper" data-kmwindow="0, 0,250,60">
  <div>
    <h1 id="countdown" style="text-align: center; vertical-align: middle;">Time</h1>
  </div>
  <form method="post">
    <div style="text-align: center; vertical-align: middle;">
      <button name="CANCEL" type="button" onclick="DismissAndCancelMacro()">Cancel</button>&nbsp;&nbsp;
      <button name="RESET" type="button" onclick="ResetCountdown()">Reset</button>&nbsp;&nbsp;
      <button name="RESTART" type="button" onclick="DismissAndRestartMacro()">Restart</button>
    </div>
  </form>
  <script>
    StartCountdown();

    function KMInit() {
      document.title = window.KeyboardMaestro.GetVariable("local_CountdownTitle");

      var timeinterval = setInterval(function() {
        SetCountdown();
        if (!SetCountdown()) {
          clearInterval(timeinterval);
          window.KeyboardMaestro.SetVariable("local_CountdownStatus", 'expired');
          window.close();
        }
      }, 1000);
    }

    function StartCountdown() {
      window.endTime = Date.parse(new Date()) + window.KeyboardMaestro.GetVariable("local__Wait") * 1000;
      SetCountdown();
      TimedUseOfBodyClass('color_invert', 400);
      document.body.classList.remove('yellow_background');
    }

    function DismissAndCancelMacro() {
      window.KeyboardMaestro.Cancel('Cancel');
    }

    function ResetCountdown() {
      StartCountdown();
      TimedUseOfBodyClass('color_invert', 400);
      document.body.classList.remove('yellow_background');
    }

    function DismissAndRestartMacro() {
      window.KeyboardMaestro.Submit('Restart');
    }

    function SetCountdown() {
      var countdown = document.getElementById("countdown");
      var t = window.endTime - Date.parse(new Date());
      if (t < 0) {
        t = 0;
      }
      var seconds = Math.floor((t / 1000) % 60);
      var minutes = Math.floor((t / 1000 / 60) % 60);
      countdown.innerHTML = minutes + ':' + ("0" + seconds).slice(-2);

      if (t <= 5000 && t > 0) {
        document.body.classList.add('yellow_background');
      }

      return t > 0;
    }

    function TimedUseOfBodyClass(theClass, milliseconds) {
      document.body.classList.add(theClass);
      window.setTimeout(function() {
        document.body.classList.remove(theClass);
      }, milliseconds);
    }

    document.addEventListener("keydown", function(event) {
      if (event.key === "Escape") {
        DismissAndCancelMacro();
      }
    });

  </script>
</body>
</html>


Attribution: The HTML/JavaScript code was adapted from: Simplistic Countdown Timer, by @troy. In turn, that code was adapted from Keyboard Maestro Actions that @perternlewis supplied in this post.