github jordibrouwer/nextdash v1.19.4

2 hours ago

The headline is the Jellyfin widget: connect it once and it shows what was added to your media server lately with the real posters and backdrops from Jellyfin itself, so a dashboard tile looks like your library. Config → Widgets is one panel with three tabs — Your widgets, Catalogue and Custom widget — and on a wide screen the list and the open widget stand side by side. The What's new window gives a release's highlight a spotlight and opens every release since your last visit, and the weekly digest gains a part for the week's nextDash releases. A weekly digest sums up what needs you once a week: links that broke, certificates running out, container updates and bookmarks nobody opens. Status & alerts leaves Behavior for a section of its own, Config → Monitoring, with three tabs. A pasted link shows what it is before you choose where it goes. v1.19.3 leads the What's new window and brings v1.19.2, v1.19.1 and v1.18.4.1, held back before, in under it. It also carries everything prepared for v1.19.3, which was never tagged: the weekly digest and Config → Monitoring.

Monitoring

  • new — a weekly digest. Once a week the server builds one message from the health report, the container update check and usage: newly and still broken links, certificates running out, container updates (held ones left out), most opened, never opened, not opened for the stale threshold, and the Inbox count. It goes to browser notifications and the downtime alert service, on Monday at 08:00 by default in the quiet-hours zone. It waits for quiet hours to end instead of going through quietGate, and a week with nothing to say sends nothing. The due slot is the latest configured weekday and time at or before now, so a restart, a late start and a double tick all give the same answer; a digest missed while the server was off goes out once, and the very first tick only records the slot so an upgrade does not push last Monday's digest at once. State and the latest snapshot live in data/digest.json (digest.go, digest_build.go, digest_settings.go); GET /api/digest/latest serves the snapshot and POST /api/digest/test, behind the write token, sends a proof digest without moving the week's slot.
  • new — the digest on the dashboard: a card, a window and a bar. The card, Your week in nextDash, names the one or two things that matter most; Read the digest opens a window with a part per subject — what it means, the names behind the count, and a button to the view where it is dealt with (Open in Bookmarks, Work through for the broken links, Open Containers, Review, Open Inbox). After a button the digest shrinks to a bar in the corner with its progress and Next; it holds the corner so other cards wait, comes back after a reload, and goes once every part is opened or with ×. The push lands on /#digest, which opens the same window. On the day of a digest the daily review card waits (DigestNotice.holdsTheWeek). digest-notice.js, digest.css.
  • new — Config → Monitoring. Status & alerts was split into Checks and Notifications, then moved out of Behavior into a section of its own with three tabs: Checks (in this browser, on the server, how monitored bookmarks stand out), Notifications (downtime alerts, browser notifications, reminders, the weekly digest) and Schedules (maintenance windows and quiet hours). MONITORING_FROM_BEHAVIOR sends an old #config/behavior/status, checks or notifications address, a saved location, a news entry and the behaviorTab setter to the matching Monitoring tab; the loader's copy of that map is gone. The bookmarks tour, the status page hints, the Health tutorial and the container notice say Monitoring instead of Behavior → Status & alerts.
  • new — Monitoring → Notifications → Weekly digest: send it or not, the day, the hour, which parts go in, Show for the latest digest and Send for a proof one. The settings default to on (digestEnabled, digestHealth, digestUpdates, digestUsage), with missing-key entries so an existing install gets them on too.
  • fix — digest.json stays out of backups (dataNever in backup.go). It had no backup policy, which TestEveryDataFileHasABackupPolicy caught. A restore has no use for last week's digest: without the file, the next tick only records the week's slot and sends nothing.
  • fix — Send a weekly digest has an ℹ that says what the digest holds and where it goes, in six languages (digestEnabledInfoTitle, digestEnabledInfoMessage).
  • new — the weekly digest names the week's nextDash releases. A New in nextDash part, made from the same files the What's new window reads, lists every release that came out in the digest's week with the items marked as a highlight, or the release's one-line lead when nothing is marked. Its button opens What's new; it is news, so it does not count as something to work through. On by default (digestNews, digest_news.go).
  • fix — one busy host no longer starves the other checks. A monitor check took one of the round's eight slots before it waited on its host's gate, so twenty services on one IP held all eight while queued behind each other, and every other host waited; with that server offline, a large round could run past its ten minutes and drop the checks it had not reached. The host gate now comes first (health_monitor.go).
  • fix — the server log's age limit gets past a stack trace. The lines under http: panic serving carry no timestamp, so they had no age, stopped the prune once they reached the head of the ring, and kept every line behind them past the window. An unstamped line now takes the time of the line before it (log_buffer.go).

Widgets

  • fix — a label typed right after Save is no longer wiped. Save repainted the panel, then redrew it once more when the dashboard's blocks came back, replacing what was typed in between; that second redraw is skipped while config is on screen (dashboard-config-widgets.js).
  • new — a Jellyfin widget with the real posters from your server. The tile shows what was added lately the way Jellyfin itself does: each film and series with its own poster, an episode under its series poster (an episode's own still is 16:9 and reads badly in a 2:3 frame), and in the hero layout the newest item large on its backdrop. The pictures are the ones in your library, fetched from Jellyfin by the server at quality 85 and the width the tile needs, so the tile looks like a shelf of your own media rather than a list of titles.
  • new — the Jellyfin set-up connects first and asks after. Fill in the address and the API key and press Connect (POST /api/widgets/jellyfin/setup, denied in demo mode): the server tries both and says Connected to {name} ({version}), then fills the choices below it with who the tile reads as and the libraries that exist, so nothing has to be typed by id. Then pick the libraries (anime is usually a library of its own, so libraries rather than item types), a layout — list, strip, hero or grid — whether a click opens the item in Jellyfin or a detail view, whether watched items are hidden, how many rows and how often it refreshes (a minute at least). How wide the tile is comes from a container query, so a two-column tile on a phone reads as the one-column version. The API key is an ordinary widget credential (X-Emby-Token) and never comes back to the browser: the server fetches the list (GET /api/widgets/jellyfin) and the posters (GET /api/widgets/jellyfin/image), which only proxies a picture the last answer named. One answer per widget on its own TTL; a failure keeps the last good answer and says how old it is. Posters are kept in data/jellyfin-images/, named by server, item, kind and tag, capped at 200 MB and trimmed oldest-first (evictImagesIn, shared with the preview cache), and left out of backups. A page template carries the server address as a variable and drops the user and libraries, which name nobody on another server (widgets_jellyfin.go, widgets_jellyfin_route.go, widgets_jellyfin_images.go, dashboard-widget-jellyfin.js, dashboard-config-widget-jellyfin.js, dashboard-widget-jellyfin.css).
  • new — Config → Widgets has three tabs: Your widgets, Catalogue and Custom widget. The Catalogue is every kind on one page with a small drawing of what it shows, made of example figures rather than a live render so it opens fast; group chips narrow the cards without a refetch. The Custom widget tab explains the one kind that is a capability rather than a report. A widget added from either lands on Your widgets to be filled in (dashboard-config-widget-catalogue.js).
  • new — the Types tab folds into the Catalogue. A stored or linked types tab lands on the Catalogue; the Unraid section's Add opens the catalogue on that kind, and the widgets tutorial and search commands say so. The orphaned Types strings are gone from all six locales.
  • new — Your widgets is one panel of one-line rows with a shared detail view. One function draws a widget's detail for both places it can stand, so the two can never offer different controls.
  • new — list and detail side by side on a wide screen. Wide or narrow is measured on the section's own width, not the window's, with 40 px of slack so a width on the line does not flip back and forth; it repaints only when the answer changes. Wide, one widget is always open beside the list — the chosen one, or the first shown once that one is gone after a delete, move or search. Moving between the layouts keeps the field being typed in, with its uncommitted value.
  • fix — renaming a widget no longer takes the caret away. A rename fires when you leave the title, so the config redraw that followed took the caret out of the field you had just moved to; the dashboard's blocks now refresh with keepConfig.
  • fix — a negative size or line speed scales like a positive one. A custom widget's Size and Rate formats stepped on the value rather than its magnitude, so a negative change read -5000000 B without a decimals setting and -4.77 MB with one (formatByteSize, formatBitRate).

Config

  • fix — the sub-tab strips stay on one line and scroll. A section with many tabs wrapped them onto a second row on a narrow screen. The strip now scrolls sideways, keeps the active tab in view and fades the side where there is more (syncSubtabStrips, config-view.css).
  • fix — Structure is no longer marked new in the section list.
  • fix — the new badge moves from Containers and Unraid to Widgets (NEW_SECTIONS).
  • fix — a redraw keeps the focus on the control it replaced. Appearance draws again by itself when the colour document or the surface meta arrives, and each redraw swapped the focused control for a copy and left the focus on the page. A settings jump that had just reached its control lost it, and the tab strip stopped answering the arrow keys. The redraw now hands the focus to the matching control in the new markup.
  • fix — a link to a section waits for the section before drawing it. An address such as #config/widgets drew the section before its file had loaded, so the heading changed while the body of the previous section stayed under it. It now waits for the file, as picking the section from the list already did.

Dashboard

  • new — the paste choice shows what the pasted link is. While you choose between bookmark and Inbox, a card shows the site's favicon, domain, title, description and picture, from the same /api/bookmark-preview answer the hover card draws, with the local copy of the picture. A slow answer never lands in a later modal, and a missing picture is asked for once more (dashboard-paste-choice.js).
  • fix — four corner cards are gone: the Widgets layout invitation, the Fresh offer, the pointer to the feature overview and the offer to check unchecked bookmarks (widgets-layout-notice.js, fresh-notice.js, features-notice.js, unchecked-bookmarks-notice.js, their specs, their strings in six languages and their rows in Config → Show again). Fresh, its tutorial and POST /api/health/check-mode-all stay.
  • fix — a block's grip can be dragged with the mouse again under a header style other than the theme's. The grip was sized in em against a font size of 0, so it was zero wide and the icon after it took every click (category-header.css).
  • fix — cancelling a block move no longer takes the focus back from the title. Escape on a block you were carrying put the focus back on its handle two frames later, whatever you had done in between, so Shift+Tab to the title and Enter folded nothing. The focus now returns only when the redraw dropped it.

Containers

  • fix — the disk prune questions use the singular for one: Remove 1 stopped container, 1 untagged image, 1 image no container uses, in six languages.
  • fix — a recreated container answers what the old one announced. docker compose up --force-recreate (or a pull) destroys the container and starts a new one under the same name; the destroy event wiped the notifier's memory of the unhealthy or stopped unexpectedly it had sent, so no healthy again / running again followed, the open alert stayed in notify-open.json and reminders said still has a problem about a container that ran fine. The watch is now kept while a notice is outstanding (docker_notify.go).

What's new

  • new — a spotlight for the highlight. An item a release marks as highlight gets room at the top: its picture or a short silent looping recording (the still with motion turned down), a short title of its own, the explanation and a button to where the change lives (link, linkLabel, a hash route such as #config/monitoring/notifications). Other new changes are one row each with their section in front and the detail folded; fixes are one line each, opened with a native disclosure; shortcuts keep their own block. When the release the window opens on marks nothing, its first new change stands in. Media lives under static/data/whats-new/media/. v1.19.3's weekly digest is the first spotlight, with a screenshot and a recording (whats-new-modal.js, modal.css).
  • new — every release since your last visit opens. The window opens each release newer than the last one you saw, the newest with the big version as its headline, and says Since your last visit: n releases, x new and y fixed. Older releases stay as rows under Earlier.

Bookmarks

  • fix — the icon menu marks what was saved while the panel has focus. A Use letter save that landed while the pencil had the focus left the menu marking Automatic until the panel was redrawn for another reason. The panel that is kept on a redraw now has its icon menu brought up to date in place.

Tag suggestions

  • fix — the catalogue also knows a subdomain by its parent domain. docs.docker.com, wiki.archlinux.org and en.wikipedia.org were passed over because the shipped file names docker.com, archlinux.org and wikipedia.org; the lookup now tries the host and then each parent down to two labels. A domain and its subdomains are one row under the catalogue's site, so turning it down holds for all of them.

Docs

  • docs — Help follows v1.19.4, in six languages: Widgets → Adding one names the three tabs and the side-by-side layout, The kinds counts thirty-one and adds What is new to watch? with Jellyfin, Weekly digest names the New in nextDash part and its switch, and Version describes the spotlight and every release since your last visit. Checks & health and the tipMaintBulkCheck tip no longer point at the removed corner card; they send unchecked bookmarks through the Bookmarks view instead.
  • docs — MANUAL §4, §12.1, §12.4, §15.1, §15.2, §15.3, §17.1, §17.7 and §17.8: the four removed corner cards are gone from the list, Config → Widgets has its three tabs and the wide layout, Jellyfin has a row and a set-up paragraph, the digest has its news part, and What's new its spotlight, the releases since your last visit and the All / New only / section chips.
  • docs — translations of the v1.19.4 strings, which only had an English fallback in the code: the Widgets tabs and Catalogue, the Custom widget tab, the Jellyfin settings and tile, the digest's New in nextDash part and its switch, and the What's new window's spotlight, chips and Ko-fi card — 100 keys in en.json, nl, de, fr, es and zh. The Jellyfin set-up errors now have fixed keys (widgetJellyfinError*) instead of one built from the server's error text.
  • docs — README and MANUAL: the README names the Jellyfin widget and counts thirty-one widget kinds, the Unraid screenshot caption points at Widgets → Catalogue, and the MANUAL's Find settings picture is described under Monitoring › Schedules.
  • docs — 498 unused locale strings removed from en, nl, de, fr, es and zh (366 in dashboard, 132 in config): keys no file, template or test names in any form. Nothing on screen changes.
  • docs — Help → Config gets a Monitoring panel and Help → Monitoring a Weekly digest panel, in six languages; Help → Behavior lists four tabs, and every Help panel and tip that named Behavior → Status & alerts names the Monitoring tab now. Help → Config says the tab strips scroll on a narrow screen.
  • docs — both new Help articles open with a picture, like every other: the config map with its tabs for Monitoring, and a week becoming one message on your devices for the weekly digest (HELP_PANEL_ART, tests/config-setting-art.spec.js).
  • docs — MANUAL §12.1, §12.4, §12.5, §12.8, §14.9, §17.1, §17.2 and §17.5 describe Monitoring and its three tabs, and §12.4 the weekly digest; Get told mentions it. §5.3 describes the preview in the paste choice, and the README's alerts line mentions the weekly digest.
  • docs — translations of the weekly digest card, window, bar and settings, and of the five strings that pointed to Behavior → Status & alerts (the Health tutorial, the bookmarks tour, two status page hints and the container notice), in nl, de, fr, es and zh. The orphaned config.behaviorTabStatusAlerts is gone from those five, so validate:locale-parity is green again.
  • docs — Config → Overview and About → News & features gain two v1.19.4 entries, the weekly digest and the Monitoring section, in six languages (overview-features.json).

Tests

  • tests — digest_test.go, digest_build_test.go and digest_settings_test.go cover the due slot, the first tick, quiet hours, an empty week and the snapshot; tests/digest-notice.spec.js the card, window and bar; tests/digest-config.spec.js the settings panel. tests/config-tabs.spec.js covers the Monitoring tabs, old Behavior addresses and saved places, and the scrolling strips; the specs that opened Behavior → Status & alerts open Monitoring. tests/dashboard-paste-preview.spec.js, tests/dashboard-block-move.spec.js and tests/docker-disk.spec.js cover the preview, the grip and the singular questions.
  • tests — tests/config-widget-panel.spec.js waits on signals instead of a 6 s sleep, which was hiding the Save race. tests/config-help-health.spec.js counts ten panels on Help → Monitoring.
  • tests — the specs that still opened Behavior → Status & alerts open Monitoring. config-new-sections, config-push-notifications, config-checkbox-rows and config-backups lost their Monitoring paths when the condition-wait commits were rebased under them; they are back, with the waits kept. config-info-reset checks the three Monitoring tabs and lists the digest's five follow-on fields, config-settings-jump-index lands the uptime webhook on Monitoring. All sixteen failed in CI on the first v1.19.3 push.
  • tests — tests/dashboard-widget-jellyfin.spec.js and widgets_jellyfin_test.go, widgets_jellyfin_config_test.go, widgets_jellyfin_images_test.go and page_template_test.go cover the tile, its layouts, the setup, the cache, the image proxy and the template. tests/config-widgets-tabs.spec.js, tests/config-widgets-tab.spec.js and tests/config-widgets-wide.spec.js cover the three tabs, the rows and the side-by-side layout; widget-secret-reveal, widget-preset-address, config-widget-panel and config-unraid follow the new panel.
  • tests — tests/whats-new-spotlight.spec.js covers the spotlight and the releases since the last visit; digest_news_test.go and tests/digest-notice.spec.js the digest's news part.
  • tests — tests/whats-new-media.spec.js takes the What's new pictures and recordings through the real UI, one release at a time against a copy of the demo data, from a plan in tests/fixtures/whats-new-media/<tag>.js. The shared steps moved out of manual-screenshots.spec.js into tests/helpers/manual-shot-kit.js.
  • tests — TestContainerNotifierRecreateAnswersWhatWasTold, TestRunDueMonitorsOneSlowHostDoesNotStarveTheOthers, TestServerLogRetentionPassesUnstampedLines and two negative cases in TestCustomWidgetFormatting cover the four fixes above; each fails without its fix.
  • tests — tests/config-tag-suggestions.spec.js also covers the catalogue matching a subdomain through its parent domain, as one row.
  • tests — fixed sleeps became condition waits. About six hundred waitForTimeout calls in the e2e suite wait for the state they were really waiting for: a tab's aria-selected, a save's response, a polled value. scripts/validate-test-waits.cjs, run in CI, fails a sleep that does not say with a // comment why the clock and not a condition. A few specs that raced the What's new window, the wall clock or the scroll lock were fixed on the way, and CI keeps the Playwright browser between runs.
  • release — release-to-main.sh refuses a dev HEAD without green CI. The script scanned for vulnerabilities but ran no tests, so a red, still running or never pushed HEAD went to main as it was. It now asks gh for the CI run on that exact commit and stops unless it completed successfully; --skip-ci is the way past it, like --skip-scan.

Don't miss a new nextdash release

NewReleases is sending notifications on new releases.