#224 · Constant background fades, narrow durations fading out, and a timeline background
- timeline-app
- pull request
Closes #222 and #223. **Stacked on #221**: it targets that branch, so its diff shows only these changes. Merge #221 first; GitHub then retargets this PR to `main`. ### Duration background fades (#222) - **Constant fade:** each edge in view fades over **48 px**, whatever the duration's width. It used to be a quarter of the width, up to 64 px. - **Narrow durations fade out** the way the ruler's finest marks do, with a smoothstep. A background is fully opaque at 192 px wide or more (four fades), fades as the duration narrows, and is gone below 96 px (two fades), while its band still shows. ### Timeline background (#223) **Timeline-wide plugin settings.** A manifest may declare up to eight `settings` (for now, `image-url`). Their values are kept on the installed plugin (`{ manifest, enabled, settings }`), not in any event's metadata: - The core validator refuses an address that isn't HTTPS. - It drops empty values, and values for settings the manifest no longer declares (after an update, say). - `.ochx`, `.och`, Postgres and drafts store installed plugins as JSON, so the settings travel with no storage change. **`backdrop` effect.** `{ kind: 'image', setting }` shows one of the plugin's image settings behind the whole timeline. When several enabled plugins set one, the last one wins. **The Timeline background plugin.** A new official plugin, using both: - **Setting it:** the **Plugins** dialog shows a "Background image URL" field under the plugin. An invalid address is refused with a message, and clearing the field removes the image. - **Drawing:** the image covers the stage beneath every duration background (z-index 0; theirs start at 1). It turns on the halo from #221 too, and is blurred like other images on a timeline labelled sensitive. - **Exports** embed it like other images. It isn't added to the History education suite. Changing that suite would mean a new suite version; say if you want it. The plugin docs (`docs/plugins.md`), the guide and the OpenAPI description (the installed plugin's `settings`) describe all of this. ### Tests - **Unit** (`test/plugins.test.mjs`): the plugin and its settings, i.e. validation, dropped values, refused addresses, invalid manifests, and the last backdrop winning. The plugin library's second page now lists it too. - **Browser** (`test/duration-backgrounds-browser.mjs`): - the fade is 48 px; - a 96–192 px duration's opacity matches the smoothstep; - a duration under 96 px shows no image while its band remains; - the timeline background is set in the Plugins dialog: an invalid address shows the error, a valid one shows the image filling the stage beneath the duration backgrounds, and clearing it removes it. - **A test-only race.** The test's `view()` now tries again when a redraw still pending from a plugin change rewrites the bound fields between filling them and pressing Go. That happens only at test speed. - `npm test` (300) and the full Chromium browser suite pass.