Commit Graph

2 Commits

Author SHA1 Message Date
alexei.dolgolyov 61cdce9b60 feat(foreground): track topmost process + browser page title
Lint & Test / test (push) Failing after 8s
Adds cross-platform foreground-window tracking and exposes it over REST
(/api/foreground) and the existing WebSocket feed.

- foreground_service.py: Windows probe via ctypes (HANDLE-correct argtypes
  to avoid 64-bit handle truncation); macOS via AppKit; Linux via Xlib
  (Wayland returns unavailable). TTL cache + per-platform fallback.
- browser_url_service.py: when foreground is a recognised browser, extract
  the page title from the window title (browser-name suffix stripped) and
  surface `is_browser` + `browser_page_title`. Optional UIA-based URL
  extraction behind MEDIA_SERVER_BROWSER_UIA env flag (off by default —
  Chromium browsers keep their accessibility tree dormant otherwise).
- websocket_manager: poll foreground every 1s inside the existing status
  loop, broadcast `foreground` on connect and `foreground_update` on
  change. Diff only on user-visible fields to avoid geometry spam.
- WebUI: new editorial card rendered under the monitor list on the
  Display tab — process name, window title, fullscreen/minimized/monitor
  chips, browser block when applicable, exe path, PID, started-ago,
  geometry, platform. 16px inter-section gap matches Settings cadence.
- i18n: 25 new keys added to both en.json and ru.json.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-05-18 03:11:59 +03:00
alexei.dolgolyov 2a474ea52c fix(player): redesign cleanup pass — sleeve, tonearm, AGC, dead code
Production-readiness pass before merging the Studio Reference redesign
to master.

Audio (backend):
- Reset AGC `_spectrum_ref` envelope on `start()` so a long silent gap
  between sessions doesn't make the first new transients clip at the
  ceiling. Annotated the trade-off (loud transient lifts reference for
  a few seconds afterwards — the price of real loudness).
- Add `tests/test_audio_analyzer.py` with 10 cases: bin-edge layout,
  AGC attack/release asymmetry, lifecycle reset. Skips numpy-dependent
  cases when numpy isn't installed; CI has it.

Vinyl mode dead code removed:
- The toggle button was dropped during the sleeve refactor but the JS
  state, 2 s `setInterval`, `beforeunload` handler, and `applyVinylMode`
  call (commented out in app.js) all stayed. Now properly excised from
  player.js + app.js + window.* exports.
- Stripped the matching `.album-art-container.vinyl*` CSS block and its
  `vinylSpin` keyframes (~95 LoC).

Sleeve + tonearm fixes:
- Removed the duplicate `.now-playing .vinyl-stage` / `.vinyl-label` /
  `.tonearm` block that was overriding the new `.vinyl-stage` rules by
  source order — the uncommitted tonearm geometry never took effect
  because the stale clone won the cascade.
- Tightened tonearm to 36% × 36% at right:-6%, top:26% so the SVG
  bounding box stays right of the sleeve (sleeve right edge ~68%).
  Needle now lands on the visible disc grooves at both rest and
  playing rotations and never overlaps the cover.
- Removed sleeve `transform: rotate(-2.5deg)` + the matching mobile
  `-1.8deg` override; sleeve now sits flat and squared-off.
- Removed the 1px inset hairline on the sleeve and the 1px outline +
  inset highlight on the album art — cleaner, no semitransparent
  border noise.
- Album art inset 5% to expose a cardstock margin around the print
  (using explicit width/height — `inset` shorthand triggered the CSS
  replaced-element rule that uses the image's intrinsic size and blew
  out the grid track).

Mobile + misc:
- Removed mobile tonearm overrides at 720px and 420px — they were
  calibrated for the pre-sleeve geometry and put the needle back over
  the cover on phones; desktop geometry is proportional and works.
- Added `<meta name="mobile-web-app-capable">` alongside the legacy
  Apple variant to silence the deprecation warning in Chromium.
- Replaced the "PRIMARY" badge on display cards with a copper star
  icon (translation key still drives title + aria-label).
- `.gitattributes` with `* text=auto eol=lf` so Windows checkouts stop
  nagging "LF will be replaced by CRLF".

Annotations:
- "REF · 24" record-label catalogue mark marked as intentional non-i18n
  decoration in index.html.

CI: ruff clean, pytest 7 passed + 3 numpy-skipped (all 10 run on CI).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 14:39:20 +03:00