Player Client and Visual Enhancements

- Redesigned audio player bar to be mobile-friendly
 - Added unloading for track switching (needs to be fixed)
 - Added IsLoading status so loading spinner isn't hanging around when it shouldn't be
 - Normalized styles with scoped files (will further reduce)
 - Layout Cleanup
 - EF fixes (migrations now function for deployment)
 - deploy script updates (new dedicated host)
This commit is contained in:
daniel-c-harvey
2025-09-12 20:37:17 -04:00
parent 73d4b0a9c5
commit 9ac2c9182a
31 changed files with 763 additions and 179 deletions
+21 -27
View File
@@ -21,7 +21,6 @@ interface AudioState {
type ProgressCallback = (currentTime: number) => void;
type EndCallback = () => void;
type LoadProgressCallback = (progress: number) => void;
interface Window {
webkitAudioContext?: typeof AudioContext;
@@ -40,7 +39,6 @@ class AudioPlayer {
private duration: number = 0;
private onProgressCallback: ProgressCallback | null = null;
private onEndCallback: EndCallback | null = null;
private onLoadProgressCallback: LoadProgressCallback | null = null;
private progressInterval: number | null = null;
private bufferChunks: Uint8Array[] = [];
private expectedSize: number = 0;
@@ -72,12 +70,6 @@ class AudioPlayer {
try {
this.bufferChunks.push(audioBlock);
this.currentSize += audioBlock.length;
if (this.expectedSize > 0 && this.onLoadProgressCallback) {
const progress = (this.currentSize / this.expectedSize) * 100;
this.onLoadProgressCallback(Math.min(progress, 100));
}
return { success: true };
} catch (error) {
return { success: false, error: (error as Error).message };
@@ -101,10 +93,6 @@ class AudioPlayer {
this.bufferChunks = [];
this.currentSize = 0;
if (this.onLoadProgressCallback) {
this.onLoadProgressCallback(100);
}
return {
success: true,
duration: this.duration,
@@ -297,8 +285,19 @@ class AudioPlayer {
this.onEndCallback = callback;
}
setOnLoadProgressCallback(callback: LoadProgressCallback): void {
this.onLoadProgressCallback = callback;
unload(): AudioResult {
try {
this.stop();
this.audioBuffer = null;
this.duration = 0;
this.bufferChunks = [];
this.currentSize = 0;
this.expectedSize = 0;
return { success: true };
} catch (error) {
return { success: false, error: (error as Error).message };
}
}
dispose(): void {
@@ -387,6 +386,14 @@ const DeepDrftAudio = {
return player.stop();
},
unload: (playerId: string): AudioResult => {
const player = audioPlayers.get(playerId);
if (!player) {
return { success: false, error: "Player not found" };
}
return player.unload();
},
seek: (playerId: string, position: number): AudioResult => {
const player = audioPlayers.get(playerId);
if (!player) {
@@ -445,19 +452,6 @@ const DeepDrftAudio = {
return { success: true };
},
setOnLoadProgressCallback: (playerId: string, dotNetObjectReference: DotNetObjectReference, methodName: string): AudioResult => {
const player = audioPlayers.get(playerId);
if (!player) {
return { success: false, error: "Player not found" };
}
player.setOnLoadProgressCallback((progress: number) => {
dotNetObjectReference.invokeMethodAsync(methodName, progress);
});
return { success: true };
},
disposePlayer: (playerId: string): AudioResult => {
const player = audioPlayers.get(playerId);
if (player) {