@namespace MidrandBooks.Components @using Microsoft.AspNetCore.Components @using MidrandBooks.Models @if (Book != null) {
@if (!string.IsNullOrEmpty(Book.CoverUrl)) { @Book.Title } else {
AUDIO
}
Now Playing Audiobook

@Book.Title

By @Book.Author
@if (!IsMinimized) {
@foreach (var spd in Speeds) { }
@FormatSeconds(Progress) @FormatSeconds(Duration)
}
} @code { [Parameter] public BookModel? Book { get; set; } [Parameter] public bool IsPlaying { get; set; } [Parameter] public EventCallback OnPlayToggle { get; set; } [Parameter] public EventCallback OnClose { get; set; } private bool IsMinimized { get; set; } = false; private double PlaybackSpeed { get; set; } = 1.0; private double[] Speeds = new double[] { 0.75, 1.0, 1.25, 1.5 }; private double Volume { get; set; } = 0.8; private bool IsMuted { get; set; } = false; private double PreviousVolume { get; set; } = 0.8; private double Progress { get; set; } = 120; // Simulated seconds played private double Duration { get; set; } = 3600; // Simulated total seconds (1 hour) // Sleep Timer States private int? SleepTimerValue { get; set; } private int TimeLeft { get; set; } private System.Threading.Timer? SleepEngineTimer { get; set; } private void ToggleMinimize() { IsMinimized = !IsMinimized; } private void TogglePlay() { IsPlaying = !IsPlaying; OnPlayToggle.InvokeAsync(IsPlaying); } private void SetSpeed(double speed) { PlaybackSpeed = speed; } private void ToggleMute() { if (IsMuted) { Volume = PreviousVolume; IsMuted = false; } else { PreviousVolume = Volume; Volume = 0; IsMuted = true; } } private void SeekChanged(ChangeEventArgs e) { if (double.TryParse(e.Value?.ToString(), out var seekVal)) { Progress = seekVal; } } private void SkipForward() { Progress = Math.Min(Duration, Progress + 15); } private void SkipBack() { Progress = Math.Max(0, Progress - 15); } private void SetSleepTimer(int minutes) { SleepTimerValue = minutes; TimeLeft = minutes * 60; SleepEngineTimer?.Dispose(); SleepEngineTimer = new System.Threading.Timer(_ => { InvokeAsync(() => { if (TimeLeft > 1) { TimeLeft--; } else { IsPlaying = false; OnPlayToggle.InvokeAsync(false); SleepTimerValue = null; SleepEngineTimer?.Dispose(); } StateHasChanged(); }); }, null, 1000, 1000); } private void ClearSleepTimer() { SleepTimerValue = null; SleepEngineTimer?.Dispose(); } private string FormatSeconds(double totalSecs) { var hours = Math.Floor(totalSecs / 3600); var minutes = Math.Floor((totalSecs % 3600) / 60); var seconds = Math.Floor(totalSecs % 60); var formattedSecs = seconds < 10 ? $"0{seconds}" : seconds.ToString(); if (hours > 0) { var formattedMins = minutes < 10 ? $"0{minutes}" : minutes.ToString(); return $"{hours}:{formattedMins}:{formattedSecs}"; } return $"{minutes}:{formattedSecs}"; } public void Dispose() { SleepEngineTimer?.Dispose(); } }