Fix 9 design majors: ITrackService interface, IsDescending, ArrayPool base, CliUtils, sort sentinel cleanup, content controller via TrackService, Skip property
This commit is contained in:
@@ -4,8 +4,6 @@ namespace DeepDrftWeb.Client.Common;
|
||||
|
||||
public class DarkModeSettings()
|
||||
{
|
||||
// public EventCallback<bool> IsDarkModeChanged { get; set; }
|
||||
|
||||
[PersistentState]
|
||||
public bool IsDarkMode
|
||||
{
|
||||
@@ -14,7 +12,6 @@ public class DarkModeSettings()
|
||||
{
|
||||
if (value == field) return;
|
||||
field = value;
|
||||
// IsDarkModeChanged.InvokeAsync(value);
|
||||
}
|
||||
} = false;
|
||||
}
|
||||
@@ -225,6 +225,9 @@ public class AudioInteropService : IAsyncDisposable
|
||||
return await InvokeJsAsync<AudioOperationResult>("DeepDrftAudio.disposePlayer", playerId);
|
||||
}
|
||||
|
||||
// TODO: The typeof(T) switch below requires updating whenever a new result type is added.
|
||||
// Consider introducing a shared marker interface (e.g. IAudioResult with a static factory
|
||||
// method) so InvokeJsAsync can construct the failure result generically without a type switch.
|
||||
private async Task<T> InvokeJsAsync<T>(string identifier, params object[] args)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -2,6 +2,7 @@ using DeepDrftModels.Entities;
|
||||
using DeepDrftWeb.Client.Clients;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using NetBlocks.Models;
|
||||
using System.Buffers;
|
||||
|
||||
namespace DeepDrftWeb.Client.Services;
|
||||
|
||||
@@ -135,34 +136,30 @@ public abstract class AudioPlayerService : IPlayerService, IAsyncDisposable
|
||||
|
||||
private async Task StreamAudio(TrackMediaResponse audio)
|
||||
{
|
||||
const int bufferSize = 32 * 1024;
|
||||
var rentedBuffer = ArrayPool<byte>.Shared.Rent(bufferSize);
|
||||
try
|
||||
{
|
||||
const int bufferSize = 32 * 1024;
|
||||
long totalBytesRead = 0;
|
||||
int currentBytes;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
var buffer = new byte[bufferSize];
|
||||
currentBytes = await audio.Stream.ReadAsync(buffer, 0, buffer.Length);
|
||||
|
||||
currentBytes = await audio.Stream.ReadAsync(rentedBuffer, 0, bufferSize);
|
||||
|
||||
if (currentBytes > 0)
|
||||
{
|
||||
totalBytesRead += currentBytes;
|
||||
|
||||
if (currentBytes < bufferSize)
|
||||
{
|
||||
var trimmedBuffer = new byte[currentBytes];
|
||||
Array.Copy(buffer, trimmedBuffer, currentBytes);
|
||||
buffer = trimmedBuffer;
|
||||
}
|
||||
|
||||
var appendResult = await _audioInterop.AppendAudioBlockAsync(PlayerId, buffer);
|
||||
|
||||
// Slice to actual bytes read before sending to interop
|
||||
var chunk = rentedBuffer[..currentBytes];
|
||||
|
||||
var appendResult = await _audioInterop.AppendAudioBlockAsync(PlayerId, chunk);
|
||||
if (!appendResult.Success)
|
||||
{
|
||||
throw new Exception($"Failed to append audio block: {appendResult.Error}");
|
||||
}
|
||||
|
||||
|
||||
if (audio.ContentLength > 0)
|
||||
{
|
||||
LoadProgress = Math.Min(1.0, (double)totalBytesRead / audio.ContentLength);
|
||||
@@ -170,13 +167,13 @@ public abstract class AudioPlayerService : IPlayerService, IAsyncDisposable
|
||||
}
|
||||
}
|
||||
} while (currentBytes > 0);
|
||||
|
||||
|
||||
var finalizeResult = await _audioInterop.FinalizeAudioBufferAsync(PlayerId);
|
||||
if (!finalizeResult.Success)
|
||||
{
|
||||
throw new Exception($"Failed to finalize audio buffer: {finalizeResult.Error}");
|
||||
}
|
||||
|
||||
|
||||
Duration = finalizeResult.Duration;
|
||||
LoadProgress = 1.0;
|
||||
IsLoaded = true;
|
||||
@@ -191,6 +188,10 @@ public abstract class AudioPlayerService : IPlayerService, IAsyncDisposable
|
||||
await NotifyStateChanged();
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
ArrayPool<byte>.Shared.Return(rentedBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task TogglePlayPause()
|
||||
|
||||
@@ -53,8 +53,6 @@ public class StreamingAudioPlayerService : AudioPlayerService, IStreamingPlayerS
|
||||
// Resume AudioContext immediately on track selection (user interaction) to avoid clicks later
|
||||
await _audioInterop.EnsureAudioContextReady(PlayerId);
|
||||
|
||||
// NotifyStateChanged();
|
||||
|
||||
await NotifyTrackSelected();
|
||||
|
||||
await LoadTrackStreaming(track);
|
||||
|
||||
Reference in New Issue
Block a user