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:
@@ -33,13 +33,15 @@
|
||||
<Folder Include="wwwroot\js\" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Prevent TypeScript compilation issues during publish -->
|
||||
<!-- TypeScript configuration following Microsoft recommendations -->
|
||||
<PropertyGroup>
|
||||
<TypeScriptCompileOnSaveEnabled>false</TypeScriptCompileOnSaveEnabled>
|
||||
<TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
|
||||
<TypeScriptESModuleInterop>true</TypeScriptESModuleInterop>
|
||||
<TypeScriptAllowSyntheticDefaultImports>true</TypeScriptAllowSyntheticDefaultImports>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Only copy tsconfig.json to root output, not nested publish folders -->
|
||||
<!-- Prevent tsconfig.json from being copied to output directories -->
|
||||
<ItemGroup>
|
||||
<None Update="tsconfig.json">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
{
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2016",
|
||||
"module": "ES6", // or "ESNext"
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noEmitOnError": true,
|
||||
"removeComments": false,
|
||||
"sourceMap": true,
|
||||
"outDir": "wwwroot/js"
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
"Interop/**/*.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"bin/**/*",
|
||||
"obj/**/*"
|
||||
"obj/**/*",
|
||||
"publish/**/*"
|
||||
]
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
/* Surface Colors */
|
||||
--deepdrft-surface: rgba(255, 255, 255, 1);
|
||||
--deepdrft-surface-alpha: rgba(255, 255, 255, 0.9);
|
||||
--deepdrft-theme-background-gray: rgba(26, 26, 26, 0.5);
|
||||
|
||||
/* Theme-aware Variables (Light Mode Default) */
|
||||
--deepdrft-theme-primary: var(--deepdrft-primary);
|
||||
|
||||
Reference in New Issue
Block a user