Remove the separate Play and Info buttons from the CollageHero featured
item. All collage items (including the featured one) are now uniform
<a href> links that navigate to the detail page.
- CollageHero: remove hasResumePosition prop, play/info emits, and
associated play button logic
- App.vue: remove @play and @info bindings from CollageHero
- Delete unused HeroSection.vue component and its styles
MediaCard, MediaRow, CollageHero, HeroSection, and MediaDetail cast
cards now render as <a> tags with real hrefs. Modified clicks
(ctrl+click, middle-click) navigate natively, enabling open-in-new-tab
and link copying. Plain left-clicks continue through the existing
showDetail flow for side-effects like focus-state saving.
When typing in the search bar on a detail page, navigating to search
results would trigger restoreFocusForPage(), which focused the 'last
viewed' card and interrupted typing. Skip focus restoration whenever
the search input is currently the active element.
The clip-path slant on collage slices previously varied with the number
of posters (hard-coded 10% steps). Express the slant as a percentage
of each slice's own width so the horizontal offset always equals the
fixed 5% container overlap, giving a constant angle for any count >= 2.
- Remove vite-plugin-pwa and all service worker code. The app no longer
registers a service worker; legacy SWs are unregistered on load.
- Move snapshot parsing (thousands of sync Path.exists() calls) into a
thread pool via asyncio.to_thread() so the health check responds
immediately on startup.
- Wrap aiopathlib AsyncPath.iterdir() (sync os.scandir under the hood)
in asyncio.to_thread() in scanner and scanning modules so directory
walks do not monopolize the event loop.
- Add root_id to Torrent type for per-torrent root tracking
- Merge movies: combine all torrents, keep best metadata, sort by quality
- Merge series: combine seasons/episodes/torrents across roots
- Torrents are quality-sorted (resolution, HDR, DV, Atmos) across all roots
- App.vue play/openFolder use torrent-specific root_id when available
Items with the same content hash from multiple roots are now shown as a
single card. When duplicates exist, the item with the best metadata
(info, cover, backdrop, showreels, torrent count) is displayed.
- Change header icon from folder to settings cog
- Replace roots dropdown panel with full-screen settings overlay
- Keep media roots as the only setting section for now
- Remove legacy endpoints: /api/change-folder, /api/index, /api/scan, /api/status,
/api/playback/resume-positions
- Remove legacy global scanner module-level API from hivescan/scanner.py
- Defer all filesystem validation to background task in server lifespan (macOS-safe)
- CLI and winmain pass raw paths via MEDIAHIVE_ROOTS; no pre-startup validation
- Enforce POSIX paths everywhere (as_posix(), no backslash leakage)
- Remove MEDIAHIVE_PATH and MEDIAHIVE_DEFER_INITIAL_ROOT env vars
- Update frontend api.ts to use per-root resume positions
- Update docs/API.md and docs/multi-index-plan.md
- Fix Python 2 style except clauses in hivescan/utils.py and scanning.py
The :global() pseudo-class in Vue scoped SFC styles was being mangled
by the Vue compiler, producing broken CSS that applied properties like
z-index and opacity directly to the <html> element and dropped the
intended component selectors entirely.
Replace the html[data-mouse-active] / html[data-pointer-visible] data
attribute approach with plain CSS classes (mouse-active, pointer-visible)
toggled on document.documentElement. In Vue scoped styles, prefixing a
selector with html.mouse-active or html:not(.mouse-active) compiles
correctly — the html part stays global while the component selector
receives the scoped attribute — avoiding :global() entirely.
This keeps all component styles inside <style scoped> and fixes the
layout breakage caused by the original commit.
- Grid layout: poster/releases left, cast spanning center+right top, versions center, metadata right
- Cast gallery moved to wider center column with photo-card grid (2:3 aspect, text overlay)
- Full cast now stored in index (removed 10-item truncation)
- Cast gender field added to metadata model, TMDB client, indexer, and frontend types
- Gender-specific cast placeholder SVGs (male suit silhouette, female portrait)
- Synopsis text moved from left poster box into right metadata card
- Format badge backgrounds made opaque (res/qual/codec/audio solid colors)
- Releases list moved under poster image in left column
- Cast photo and character font sizes reduced for compact display
- mediahive/winmain.py: pywebview launcher with threaded uvicorn backend,
- scripts/winbuild.py: build script — downloads ffmpeg, runs PyInstaller, makes zip
- mediahive/config.py: TOML config persistence in %APPDATA%/mediahive/
- server.py: POST /api/change-folder switches media root
- showreel.py: suppress console windows for ffmpeg subprocesses on Windows
- protocol.py: add ChangeFolderRequest struct