829 Commits

Author SHA1 Message Date
Timo 3392f0b3a7 docs: tighten v2.5.3 changelog wording 2026-07-02 17:16:15 +02:00
GitHub Action 72ea5d1ee9 chore(release): update versions to v2.5.3 [skip ci] 2026-07-02 14:59:12 +00:00
Timo 869c64171b Fix Disney+ force sync, seek, and HCM regressions for v2.5.3
The v2.5.2 Disney+ page-API integration leaked blob-relative <video>
time into force sync, seeks, and heartbeats when the page-API bridge
had no fresh data, so force sync on Disney+ appeared broken.

- getSyncCurrentTime/getSyncDuration now refuse native values on Disney+
  (return null/0) so stale bridge data degrades to a clean no-op instead
  of broadcasting garbage to peers. The get_current_time handler and
  episode/lobby/hcmIsLive paths are routed through the same accessor.
- Validate FORCE_SYNC_PREPARE/SEEK payloads as finite before relaying;
  the internal coercion no longer treats '' as 0.
- Stop double-routing FORCE_SYNC_PREPARE from the popup path (the
  generic popup route now covers only play/pause/seek).
- popup force-sync: exclude null/empty peer times from the jump-to-others
  median (Number(null)===0 was dragging the target to 0), guard against
  NaN end-to-end, clear the dangling reset timer on failure, and retry
  without re-injecting when the content script responds but the Disney+
  bridge has not yet delivered a finite time.
- hcmIsLive skips the native-duration live signal on Disney+ only,
  preserving YouTube/Twitch Infinity-duration live detection.

Disney-specific logic remains strictly gated to disneyplus.com; no
Netflix/YouTube/Twitch/generic path is affected.
v2.5.3
2026-07-02 16:57:48 +02:00
GitHub Action 6ccaf45f8e chore(release): update versions to v2.5.2 [skip ci] 2026-07-02 13:34:11 +00:00
Timo 1b7be23b29 Document v2.5.2 release v2.5.2 2026-07-02 15:33:47 +02:00
KoalaDev 9ec0e9dd4e Merge pull request #19 from Shik3i/codex/netflix-seek-fix
[codex] Fix Netflix and Disney+ seek handling
2026-07-02 15:29:55 +02:00
Timo 9ac8c28442 Remove Disney+ DOM scraping fallback 2026-07-02 15:08:54 +02:00
Timo 076157fef1 Sync Disney+ via the page media player API (precise time + seek)
Disney+'s <video> is blob-relative (unusable as an absolute clock) and its
scrubber aria-value freezes during playback, so DOM scraping lagged and the
+/-10s button seek could neither reach far targets nor land precisely. The
real player hangs off the <disney-web-player> custom element as
`.mediaPlayer`, exposing seek(ms) and timeline.info (playhead/duration ms).

Since the isolated content world can't read that page object, route it
through the existing MAIN-world page-API bridge (as Netflix already does):

- page-api-seek-overrides.js: register a 'disney' provider.
- background.js installPageApiSeekBridge: seek Disney via mediaPlayer.seek(),
  and post the exact playhead/duration (seconds) to the content world every
  250ms. Both are gated on provider === 'disney'; Netflix path unchanged.
- content.js: cache the pushed playhead, prefer it in getDisneyPlusTimeline
  (DOM scraping stays as fallback), and check the page-API seek first in
  seekVideo. Outcome is identical for Netflix and generic sites.

Verified live on Disney+: reported time matches the player exactly and
seek lands within ~1s of the target.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:56:02 +02:00
Timo 236da46f5d Lift the 120s cap on Disney+ relative-seek so large seeks reach target
Disney+ has no absolute seek on its blob <video>, so absolute seeks are
translated into repeated clicks of the player's relative skip button. The
click count was capped at 12 (=120s at 10s/step), so any seek further than
two minutes away silently landed short — breaking absolute-position sync
(e.g. syncing to 5:00 from far away never arrived).

Derive the step size from the matched button's own label (10s default,
some UIs use 5/15/30) and issue enough clicks to cover the full delta,
bounded at a sane maximum.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:45:12 +02:00
Timo 2fbcbc4f83 Harden Disney+ time fallback against <video> element recreation
When the control overlay (and its live time readout) is briefly absent,
the old fallback recomputed the timeline from the raw blob-relative
video.currentTime via a cached scale/start. Disney recreates the <video>
element on some play/pause transitions, which resets currentTime, so that
math produced a wildly wrong time ("loses the time" after a pause).

The native clock advances 1:1 with real playback, so instead anchor the
last live UI position to video.currentTime and extrapolate by the elapsed
native delta. If the delta is negative or implausibly large (element
recreated / seek), freeze at the last known position rather than emitting
a garbage time.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:38:26 +02:00
Timo 8fe1c6dfbc Fix laggy Disney+ time by preferring the live "time remaining" indicator
Disney+ throttles the scrubber slider's aria-valuenow, so it can lag real
playback by several seconds (and its value snaps back when the control
overlay reappears on pause). The player's "time remaining" indicator,
however, updates live.

getDisneyPlusUiTimeline() now captures any element whose class/testid
mentions "remain", parses its clock text, and — when a reliable duration
is known — derives current = duration - remaining and prefers it over the
laggy slider value. Falls back to the previous behavior when no remaining
indicator is present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:26:53 +02:00
Timo 51da169d69 Remove temporary Media Session interceptor and Video Event Log diagnostics
Clean up the exploratory Disney+ diagnostics now that the Shadow DOM
timeline/seek integration is in place:

- Remove Proposal 1 (Media Session interceptor): the background.js
  interceptor injection and the content.js message listener capturing
  __koalaMediaSessionCapture, plus the now-unused mediaSessionPosition
  reporting in content.js and popup.js.
- Remove Proposal 3 (Video Event Log): videoEventsLog, logVideoEvent(),
  the per-video event logging listeners, and the popup.html/popup.js UI.
- Keep Proposal 2 (DOM timestamp scraper) for ongoing diagnostics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 14:18:50 +02:00
Timo a9f5c0b9bf TEMPORARY DIAGNOSTICS: Integrate querySelectorAllShadow in Disney+ specific functions 2026-07-02 13:45:36 +02:00
Timo 705fbc146b TEMPORARY DIAGNOSTICS: Upgrade DOM scraper to support Shadow DOM recursion 2026-07-02 13:42:25 +02:00
Timo 09d35f3e48 TEMPORARY DIAGNOSTICS: Implement Proposal 2 and 3 logs in Dev tools tab 2026-07-02 13:35:08 +02:00
Timo 32994aaaa5 Support dynamic Disney+ timeline offset/scale caching for accurate seek sync 2026-07-02 13:30:20 +02:00
Timo bea0f6925c Implement cached duration fallback and simulate keyboard events fallback for Disney+ seeks when controls are hidden 2026-07-02 13:27:53 +02:00
Timo 71fa6e7315 Support absolute seeks on Disney+ by automatically translating them to relative jumps 2026-07-02 13:25:11 +02:00
Timo 54b806d270 Fix Media Session listener scoping by moving it to root IIFE level in content.js 2026-07-02 13:23:14 +02:00
Timo 066d2c9407 Implement temporary Media Session interceptor diagnostics for Disney+ and restore Netflix sessionId lookup guard 2026-07-02 13:19:47 +02:00
Timo ce522e2ab7 Safeguard Netflix player session ID lookup in background.js 2026-07-02 13:01:14 +02:00
Timo 9cbeb661d6 Save baseline state with Disney+ seek adjustments and build identifier 2026-07-02 13:00:41 +02:00
Timo beda924b65 Fix DEV_SIMULATE_REMOTE_SEEK targetTime routing in background.js and add build identifier 2026-07-02 12:57:58 +02:00
KoalaDev 01762b0c2f Normalize shared tab titles 2026-07-02 10:20:25 +02:00
KoalaDev 0af22998c8 Handle target tab navigation reinjection 2026-07-02 10:02:31 +02:00
KoalaDev 52265e84eb Generalize page API seek overrides 2026-07-02 09:57:57 +02:00
KoalaDev 57cd071d58 Add hidden remote seek test controls 2026-07-02 09:50:39 +02:00
KoalaDev 8a21fbe07f Fix Netflix seek handling 2026-07-02 09:43:11 +02:00
KoalaDev 7781d418ba Merge pull request #17 from Shik3i/feat/protocol-rate-limit-vitest
feat: Protocol spec, rate limiting, vitest, and documentation
2026-07-02 00:17:01 +02:00
Timo c022f6f490 fix: harden leave room rate limiting 2026-07-02 00:14:55 +02:00
Timo 9fe83f89b2 fix: make protocol docs match implementation 2026-07-02 00:04:49 +02:00
Timo e51e8ae436 fix: move relay changelog notes to v2.5.1 2026-07-01 23:55:42 +02:00
Timo e74abd00f7 fix: keep linux optional deps in lockfile 2026-07-01 23:51:52 +02:00
Timo dab7368537 fix: repair PR verification and docs cleanup 2026-07-01 23:46:23 +02:00
Skrockle 463f871958 feat: Add protocol spec, rate limiting, vitest framework, and documentation
## Added
- **WebSocket Protocol Specification** (docs/PROTOCOL.md) - Complete reference
  for all 20+ events with payload schemas, rate limits, and edge cases
- **LEAVE_ROOM Rate Limiting** - 10 requests/socket/minute to prevent abuse
- **Vitest Testing Framework** - Modern test setup with coverage reporting
- **Host Control Mode Documentation** - Consolidated EN documentation
  (docs/host-control-mode.md) with references to internal implementation

## Changed
- **Graceful Shutdown** - Socket.IO clients properly disconnected during
  server shutdown (server/index.js)
- **CI Workflow** - Added test step with continue-on-error for gradual rollout
- **README** - Added protocol documentation link
- **CHANGELOG** - Updated with all new features and improvements

## Moved
- Internal documentation moved to docs/internal/ for better organization
- Host Control Mode docs consolidated from 4 files to 1 comprehensive guide

## Technical Details
- Protocol spec: 495 lines, covers all events from shared/constants.js
- Rate limiter: Follows existing pattern (checkAuthRate, checkEventRate)
- Vitest: 6 tests for rate limiter, all passing
- Documentation: Host Control Mode doc includes edge cases, testing checklist,
  architecture decisions
2026-07-01 23:27:30 +02:00
GitHub Action 1f5196e1e6 chore(release): update versions to v2.5.1 [skip ci] 2026-07-01 17:48:39 +00:00
Timo 003741a63f docs: add devops.md detailing release workflow v2.5.1 2026-07-01 19:47:31 +02:00
KoalaDev e644ab33cd Merge pull request #15 from Shik3i/codex/issue-13-title-privacy
feat(extension): add title privacy controls and settings
2026-07-01 19:43:46 +02:00
Timo 9006ebbc67 docs: remove temporary branch planning document 2026-07-01 19:40:57 +02:00
Timo e40017f053 Move privacy settings under username 2026-07-01 19:26:25 +02:00
Timo fa7eea54d8 Split tab and media title privacy controls 2026-07-01 19:21:38 +02:00
KoalaDev 04d2360814 Remove plan for splitting large JavaScript files
Removed the plan to split large JavaScript files into smaller modules due to prioritization changes.
2026-07-01 19:16:42 +02:00
Timo 29aba936ce Clarify tab and media title privacy setting 2026-07-01 18:58:39 +02:00
Timo 4bae88e107 Fix title privacy popup import 2026-07-01 18:50:09 +02:00
Skrockle 3e4b97b11a Fix: Remove redundant TITLE_PRIVACY_MODES array in popup.js
- Remove duplicate local TITLE_PRIVACY_MODES array definition
- Use Object.values(TITLE_PRIVACY_MODES).includes() for validation instead
- Keeps single source of truth in title-privacy.js

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-01 18:37:25 +02:00
Timo e555906553 fix(extension): harden title privacy edge cases 2026-06-29 13:43:10 +02:00
Timo 4f1335242c feat(extension): add shared title privacy modes 2026-06-29 13:35:34 +02:00
GitHub Action e683466bf0 chore(release): update versions to v2.5.0 [skip ci] 2026-06-29 10:58:06 +00:00
KoalaDev 788a3331d3 Merge pull request #14 from Shik3i/feature/host-control-mode
Prepare v2.5.0 host control release
v2.5.0
2026-06-29 12:55:57 +02:00
Timo 2d9b7bc099 Ignore Claude local files 2026-06-29 12:52:22 +02:00