COVID 19, 7 Day Tracker

Hello folks,

I’ve been very impressed by the samples shared here, so I thought I’d contribute one of my own. It’s yet another COVID-19 7 day incidence widget: I don’t purport to take credit for the basic code, as that was cribbed from a widget shared on Twitter (if anybody knows the original author: please get in touch, so I can credit them). The reason I still share it here is that I improved it by implementing a few practices and patterns others might find useful in widget development. Among them are:

  • Adaptive support for different widget sizes, dark mode and accessibilty text settings.
  • Robust handling of messy parameters and variance in returned data.
  • Fully internationalised for German and English, using my i18n module.
  • Uses system display formats for numbers and dates.
  • Caching of data for offline refresh cycles (with indicator of stale data).
  • Data handling decoupled from widget building for adaptability.
  • Easy in-script configuration through an object.
  • Optional debug logging.

The localisation and decoupled structure mean that, although the widget currently pulls German data from (obviously) a German service, it can easily be adapted to other data sources by modifying two short functions.

As the code is a bit long, I’ll just point you to the Github repository.

Your script doesn’t work…

You also need to download the i18n mode here linked above.

I did it and saved it as script in Scriptable „Localization“…

Mmh, maybe I need to make some modifications in the script to point it to this…?:thinking:

Yes, you do. Loading external modules through Scriptable’s importModule() function requires you

  1. to have downloaded the module you want to load into Scriptable (you’ve found out that already) and
  2. to use the name of the downloaded module (you can omit the “.js“ file extension) as the argument to importModule().

That means that if you have renamed my module to “Localization”, the correct code would now be:

const { Localization } = importModule('Localization')

Note the left hand name in the assigment and the file name need bear no relationship. The module exports a class called “Localization”, and the assignment in braces tells the code to retrieve it directly from the imported module. You could also grab everything the module exports by doing this:

const localize = importModule('Localization')
// ...
const l8n = new localize.Localization(strings)

but my module exports exactly one thing, and the former syntax (known as a destructuring assignment) is nicer to work with.

Oh, i see…