This release bundles five accumulated development versions (1.12.20 → 1.13.2) into one shipped build. The headline themes are category management improvements, a filesystem scanner that fixes cross-platform migrations, import folder UX, and a redesigned Prerolls library filter bar.
Highlights
Category management — closer to what Issue #29 asks for
The legacy "primary category" concept has been retired from the user-visible UI:
- "Remove from Category" is now always enabled. No more "Cannot remove primary here" disabled button.
- Deleting a category is one step. No reassignment workaround, no "category must be empty" error. The delete removes the grouping from every preroll that had it, disables targeting schedules, clears fallback references, and deletes holiday presets — all in one transaction. Prerolls that lose their last category become uncategorized and remain in NeXroll; their files on disk are never touched.
- New
Uncategorizedfilter on the Prerolls page Category dropdown surfaces prerolls with zero categories. Useful for cleanup after a category delete, or for finding files the new filesystem scanner picked up but couldn't categorize. - Startup migration backfills the
preroll_categoriesmany-to-many table from the legacycategory_idcolumn. Idempotent. The column itself stays populated for backward compat with the rest of the codebase; full retirement is deferred to a future release. GET /categories/{id}/delete-impactendpoint returns affected preroll/schedule counts so the UI can show an informed confirmation dialog before deletion.
Filesystem scanner — cross-platform migration is now one click
Restoring a JSON backup from Windows to Docker (or vice versa) used to leave every preroll row pointing at a path that didn't exist on the target machine, breaking thumbnails, video serving, and Plex apply. The new scanner walks PREROLLS_DIR, matches files to existing database rows by category folder + filename, and rewrites paths to the real on-disk locations. Missing thumbnails are regenerated. Files that exist on disk with no database row are added automatically.
The scanner runs:
- At startup (
NEXROLL_SCAN_ON_STARTUP=0to disable on huge libraries) - Automatically after a JSON restore — the restore response surfaces scan stats in the UI toast
- On demand via the new Rescan Files button on the Backup & Restore page, backed by
POST /prerolls/rescan
This means a Windows → Docker migration is now: install Docker NeXroll, restore the JSON backup, copy your prerolls into the mounted volume, click Rescan. The endpoint reports paths relinked, thumbnails generated, new files found, and files still missing.
Import Folder UX overhaul
The "Import Folder" workflow no longer forces a category pick:
- Category is optional. Default is "— Auto / leave uncategorized —".
- Auto-categorize from subfolders (on by default). A file at
/import/Christmas/intro.mp4lands in the "Christmas" category if one exists. - Create missing categories (opt-in). New categories are created on the fly for unrecognized subfolder names.
- No more silent "Default" bucket. Files NeXroll can't resolve land uncategorized and appear in the new filter.
- Per-category preview in dry-run results:
Christmas: 12 Halloween: 8 (uncategorized): 3.
Preroll Library filter bar redesign
The Library page's filter row had dated styling and a vestigial Apply button for filters that were already applying client-side:
- Search dominates the top row, View toggle separated at the right edge
- Filters move to a second row with consistent sizing (Category 220 px min, Status 170 px min, per-page selector pushed right)
- Apply button removed — auto-apply, pagination resets on any filter change
- Active filter chips below the bar with per-chip remove and Clear all
- Status emoji prefixes and uppercase letter-spaced labels removed
Bug Fix: Currently Showing Tile Shows Category Name Instead of Schedule Name After Upgrade
Users upgrading from versions before v1.12.17 had active_category populated in their DB but no active_schedule_id. The dashboard tile briefly displayed the category name instead of the schedule name until the next scheduler tick. The /settings/active-category endpoint now adds a fallback: when active_schedule_id is unset but active_category is populated, it looks up the most recently run active schedule whose primary category matches and uses its name.
API Changes
POST /prerolls/map-root— new fieldsauto_categorize_from_folders(defaulttrue) andcreate_missing_categories(defaultfalse). Response now includesper_categoryarray; legacycategoryfield replaced byforced_category(nullable).GET /categories/{id}/delete-impact— new endpoint, returns affected counts.DELETE /categories/{id}— response shape changed: returnsremoved_m2m,cleared_primary,disabled_schedules,cleared_fallback_schedules,removed_holiday_presetsinstead of the v1.12.20 reassignment counts. No longer accepts or returns adefault_category_id.POST /prerolls/rescan— new endpoint, returns scan stats.
Deferred to Future Release (Issue #29 Phase 2)
Per Issue #29, additional structural work is not in this release:
- Flat file storage (new uploads still go to per-category subfolders)
- Removal of the
category_idcolumn from theprerollstable - Conversion of every remaining backend filter query from
category_id == Xto m2m - Removal of the "primary" star picker from the preroll edit modal
These will land in v1.13.x once v1.13.2 has been validated in the field.
Install
Windows: download NeXroll_Installer.exe below.
Docker: rebuild your image from this tag, or wait for the auto-published :latest.