Files
lidify/CHANGELOG.md
T
Your Name b85d206547 Release v1.3.2: Fix mobile scrolling blocked by pull-to-refresh
Hotfix for v1.3.0 production issue where PullToRefresh component was
blocking all mobile scrolling.

Root Cause:
- CSS flex chain break (container uses h-full instead of flex-1)
- Touch event handlers interfering with native scroll

Fix:
Temporarily disabled PullToRefresh via early return that bypasses all
functionality while still rendering children. Feature will be properly
fixed in v1.4.

This restores normal scrolling on mobile devices across all pages.

Also includes:
- CHANGELOG.md updates for v1.3.1 and v1.3.2
- README.md typo fix
2026-01-06 21:24:17 -06:00

12 KiB

Changelog

All notable changes to Lidify will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[1.3.2] - 2025-01-07

Fixed

  • Mobile scrolling blocked by pull-to-refresh component
  • Pull-to-refresh component temporarily disabled (will be properly fixed in v1.4)

Technical Details

  • Root cause: CSS flex chain break (h-full) and touch event interference
  • Implemented early return to bypass problematic wrapper while preserving child rendering
  • TODO: Re-enable in v1.4 with proper CSS fix (flex-1 flex flex-col min-h-0)

[1.3.1] - 2025-01-07

Fixed

  • Production database schema mismatch causing SystemSettings endpoints to fail
  • Added missing downloadSource and primaryFailureFallback columns to SystemSettings table

Database Migrations

  • 20260107000000_add_download_source_columns - Idempotent migration adds missing columns with defaults

Technical Details

  • Root cause: Migration gap between squashed init migration and production database setup
  • Uses PostgreSQL IF NOT EXISTS pattern for safe deployment across all environments
  • Default values: downloadSource='soulseek', primaryFailureFallback='none'

[1.3.0] - 2026-01-06

Added

  • Multi-source download system with configurable Soulseek/Lidarr primary source and fallback options
  • Configurable enrichment speed control (1-5x concurrency) in Settings → Cache & Automation
  • Stale job cleanup button in Settings to clear stuck Discovery batches and downloads
  • Mobile touch drag support for seek sliders on all player views
  • Skip ±30s buttons for audiobooks/podcasts on mobile players
  • iOS PWA media controls support (Control Center and Lock Screen)
  • Artist name alias resolution via Last.fm (e.g., "of mice" → "Of Mice & Men")
  • Library grid now supports 8 columns on ultra-wide displays (2xl breakpoint)
  • Artist discography sorting options (Year/Date Added)
  • Enrichment failure notifications with retry/skip modal
  • Download history deduplication to prevent duplicate entries
  • Utility function for normalizing API responses to arrays (normalizeToArray) - @tombatossals
  • Keyword-based mood scoring for standard analysis mode tracks - @RustyJonez
  • Global and route-level error boundaries for better error handling
  • React Strict Mode for development quality checks
  • Next.js image optimization enabled by default
  • Mobile-aware animation rendering (GalaxyBackground disables particles on mobile)
  • Accessibility motion preferences support (prefers-reduced-motion)
  • Lazy loading for heavy components (MoodMixer, VibeOverlay, MetadataEditor)
  • Bundle analyzer tooling (npm run analyze)
  • Loading states for all 10 priority routes
  • Skip links for keyboard navigation (WCAG 2.1 AA compliance)
  • ARIA attributes on all interactive controls and navigation elements
  • Toast notifications with ARIA live regions for screen readers
  • Bull Board admin dashboard authentication (requires admin user)
  • Lidarr webhook signature verification with configurable secret
  • Encryption key validation on startup (prevents insecure defaults)
  • Session cookie security (httpOnly, sameSite=strict, secure in production)
  • Swagger API documentation authentication in production
  • JWT token expiration (24h access tokens, 30d refresh tokens)
  • JWT refresh token endpoint (/api/auth/refresh)
  • Token version validation (password changes invalidate existing tokens)
  • Download queue reconciliation on server startup (marks stale jobs as failed)
  • Redis batch operations for cache warmup (MULTI/EXEC pipelining)
  • Memory-efficient database-level shuffle (ORDER BY RANDOM() LIMIT n)
  • Dynamic import caching in queue cleaner (lazy-load pattern)
  • Database index for DownloadJob.targetMbid field
  • PWA install prompt dismissal persistence (7-day cooldown)

Fixed

  • Critical: Audio analyzer crashes on libraries with non-ASCII filenames (#6)
  • Critical: Audio analyzer BrokenProcessPool after ~1900 tracks (#21)
  • Critical: Audio analyzer OOM kills with aggressive worker auto-scaling (#26)
  • Critical: Audio analyzer model downloads and volume mount conflicts (#2)
  • Radio stations playing songs from wrong decades due to remaster dates (#43)
  • Manual metadata editing failing with 500 errors (#9)
  • Active downloads not resolving after Lidarr successfully imports (#31)
  • Discovery playlist downloads failing for artists with large catalogs (#34)
  • Discovery batches stuck in "downloading" status indefinitely
  • Audio analyzer rhythm extraction failures on short/silent audio (#13)
  • "Of Mice & Men" artist name truncated to "Of Mice" during scanning
  • Edition variant albums (Remastered, Deluxe) failing with "No releases available"
  • Downloads stuck in "Lidarr #1" state for 5 minutes before failing
  • Download duplicate prevention race condition causing 10+ duplicate jobs
  • Lidarr downloads incorrectly cancelled during temporary network issues
  • Discovery Weekly track durations showing "NaN:NaN"
  • Artist name search ampersand handling ("Earth, Wind & Fire")
  • Vibe overlay display issues on mobile devices
  • Pagination scroll behavior (now scrolls to top instead of bottom)
  • LastFM API crashes when receiving single objects instead of arrays (#37) - @tombatossals
  • Mood bucket infinite loop for tracks analyzed in standard mode (#40) - @RustyJonez
  • Playlist visibility toggle not properly syncing hide/show state - @tombatossals
  • Audio player time display showing current time exceeding total duration (e.g., "58:00 / 54:34")
  • Progress bar could exceed 100% for long-form media with stale metadata
  • Enrichment P2025 errors when retrying enrichment for deleted entities
  • Download settings fallback not resetting when changing primary source
  • SeekSlider touch events bubbling to parent OverlayPlayer swipe handlers
  • Audiobook/podcast position showing 0:00 after page refresh instead of saved progress
  • Volume slider showing no visual fill indicator for current level
  • PWA install prompt reappearing after user dismissal

Changed

  • Audio analyzer default workers reduced from auto-scale to 2 (memory conservative)
  • Audio analyzer Docker memory limits: 6GB limit, 2GB reservation
  • Download status polling intervals: 5s (active) / 10s (idle) / 30s (none), previously 15s
  • Library pagination options changed to 24/40/80/200 (divisible by 8-column grid)
  • Lidarr download failure detection now has 90-second grace period (3 checks)
  • Lidarr catalog population timeout increased from 45s to 60s
  • Download notifications now use API-driven state instead of local pending state
  • Enrichment stop button now gracefully finishes current item before stopping
  • Per-album enrichment triggers immediately instead of waiting for batch completion
  • Lidarr edition variant detection now proactive (enables anyReleaseOk before first search)
  • Discovery system now uses AcquisitionService for unified album/track acquisition
  • Podcast and audiobook time display now shows time remaining instead of total duration
  • Edition variant albums automatically fall back to base title search when edition-specific search fails
  • Stale pending downloads cleaned up after 2 minutes (was indefinite)
  • Download source detection now prioritizes actual service availability over user preference

Removed

  • Artist delete buttons hidden on mobile to prevent accidental deletion
  • Audio analyzer models volume mount (shadowed built-in models)

Database Migrations Required

# Run Prisma migrations
cd backend
npx prisma migrate deploy

New Schema Fields:

  • Album.originalYear - Stores original release year (separate from remaster dates)
  • SystemSettings.enrichmentConcurrency - User-configurable enrichment speed (1-5)
  • SystemSettings.downloadSource - Primary download source selection
  • SystemSettings.primaryFailureFallback - Fallback behavior on primary source failure
  • SystemSettings.lidarrWebhookSecret - Shared secret for Lidarr webhook signature verification
  • User.tokenVersion - Version number for JWT token invalidation on password change
  • DownloadJob.targetMbid - Index added for improved query performance

Backfill Script (Optional):

# Backfill originalYear for existing albums
cd backend
npx ts-node scripts/backfill-original-year.ts

Breaking Changes

  • None - All changes are backward compatible

Security

  • Critical: Bull Board admin dashboard now requires authenticated admin user
  • Critical: Lidarr webhooks verify signature/secret before processing requests
  • Critical: Encryption key validation on startup prevents insecure defaults
  • Session cookies use secure settings in production (httpOnly, sameSite=strict, secure)
  • Swagger API documentation requires authentication in production (unless DOCS_PUBLIC=true)
  • JWT tokens have proper expiration (24h access, 30d refresh) with refresh token support
  • Password changes invalidate all existing tokens via tokenVersion increment
  • Transaction-based download job creation prevents race conditions
  • Enrichment stop control no longer bypassed by worker state
  • Download queue webhook handlers use Serializable isolation transactions
  • Webhook race conditions protected with exponential backoff retry logic

Release Notes

When deploying this update:

  1. Backup your database before running migrations
  2. Set required environment variable (if not already set):
    # Generate secure encryption key
    SETTINGS_ENCRYPTION_KEY=$(openssl rand -base64 32)
    
  3. Run npx prisma migrate deploy in the backend directory
  4. Optionally run the originalYear backfill script for era mix accuracy:
    cd backend
    npx ts-node scripts/backfill-original-year.ts
    
  5. Clear Docker volumes for audio-analyzer if experiencing model issues:
    docker volume rm lidify_audio_analyzer_models 2>/dev/null || true
    docker compose build audio-analyzer --no-cache
    
  6. Review Settings → Downloads for new multi-source download options
  7. Review Settings → Cache for new enrichment speed control
  8. Configure Lidarr webhook secret in Settings for webhook signature verification (recommended)
  9. Review Settings → Security for JWT token settings

Known Issues

  • Pre-existing TypeScript errors in spotifyImport.ts matchTrack method (unrelated to this release)
  • Simon & Garfunkel artist name may be truncated due to short second part (edge case, not blocking)

Contributors

Big thanks to everyone who contributed, tested, and helped make this release happen:

  • @tombatossals - LastFM API normalization utility (#39), playlist visibility toggle fix (#49)
  • @RustyJonez - Mood bucket standard mode keyword scoring (#47)
  • @iamiq - Audio analyzer crash reporting (#2)
  • @volcs0 - Memory pressure testing (#26)
  • @Osiriz - Long-running analysis testing (#21)
  • @hessonam - Non-ASCII character testing (#6)
  • @niles - RhythmExtractor edge case reporting (#13)
  • @TheChrisK - Metadata editor bug reporting (#9)
  • @lizar93 - Discovery playlist testing (#34)
  • @brokenglasszero - Mood tags feature verification (#35)

And all users who reported bugs, tested fixes, and provided feedback!


For detailed technical implementation notes, see docs/PENDING_DEPLOY.md.