domain: player/reporting ticks -> milliseconds (phase 4c)

Playback position now crosses the IPC boundary in milliseconds. Ticks
survive only inside Rust (DB storage, Jellyfin API) and at the genuine
remote-session boundary (session seek / transfer / RemoteControls).

Rust command signatures (ms in, converted to ticks internally):
- storage_update_playback_progress / _context: position_ms
- repository_report_playback_start / _progress / _stopped: position_ms
- PlaybackProgress.position_ticks -> position_ms (converted in the query)

Frontend:
- playbackReporting, playerEvents, VideoPlayer, Queue, player/[id] resume:
  seconds*1000 / durationMs/1000 instead of tick math.
- repository-client + syncService param names -> positionMs.
- Tests updated to ms fixtures/assertions.

Out of scope (legitimately ticks): NowPlayingItem, PlayState.positionTicks,
sessionSeek, playbackModeTransferToLocal, RemoteControls, SessionCard — the
remote Jellyfin session API.

Rust 456, frontend 644, check clean.
This commit is contained in:
2026-07-23 22:02:29 +02:00
parent 93d198ce21
commit ec8a7610f5
14 changed files with 88 additions and 71 deletions
+7 -3
View File
@@ -579,8 +579,9 @@ pub async fn repository_report_playback_start(
manager: State<'_, RepositoryManagerWrapper>,
handle: String,
item_id: String,
position_ticks: i64,
position_ms: i64,
) -> Result<(), String> {
let position_ticks = position_ms * 10_000;
let repo = manager.0.get(&handle).ok_or("Repository not found")?;
repo.as_ref()
.report_playback_start(&item_id, position_ticks)
@@ -595,8 +596,9 @@ pub async fn repository_report_playback_progress(
manager: State<'_, RepositoryManagerWrapper>,
handle: String,
item_id: String,
position_ticks: i64,
position_ms: i64,
) -> Result<(), String> {
let position_ticks = position_ms * 10_000;
let repo = manager.0.get(&handle).ok_or("Repository not found")?;
repo.as_ref()
.report_playback_progress(&item_id, position_ticks)
@@ -611,8 +613,10 @@ pub async fn repository_report_playback_stopped(
manager: State<'_, RepositoryManagerWrapper>,
handle: String,
item_id: String,
position_ticks: i64,
position_ms: i64,
) -> Result<(), String> {
// Milliseconds across the boundary; the Jellyfin API wants ticks.
let position_ticks = position_ms * 10_000;
let repo = manager.0.get(&handle).ok_or("Repository not found")?;
repo.as_ref()
.report_playback_stopped(&item_id, position_ticks)