mirror of
https://github.com/markuryy/shark.git
synced 2025-12-12 11:41:02 +00:00
fix(dl): add progress events for tracks from new downloader
This commit is contained in:
@@ -56,10 +56,12 @@ async fn download_and_decrypt_track(
|
|||||||
track_id: String,
|
track_id: String,
|
||||||
output_path: String,
|
output_path: String,
|
||||||
is_encrypted: bool,
|
is_encrypted: bool,
|
||||||
|
window: tauri::Window,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio::fs::File;
|
use tokio::fs::File;
|
||||||
use deezer_crypto::StreamingDecryptor;
|
use deezer_crypto::StreamingDecryptor;
|
||||||
|
use tauri::Emitter;
|
||||||
|
|
||||||
// Build HTTP client
|
// Build HTTP client
|
||||||
let client = reqwest::Client::builder()
|
let client = reqwest::Client::builder()
|
||||||
@@ -79,11 +81,16 @@ async fn download_and_decrypt_track(
|
|||||||
return Err(format!("HTTP error: {}", response.status()));
|
return Err(format!("HTTP error: {}", response.status()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let total_size = response.content_length().unwrap_or(0) as f64;
|
||||||
|
|
||||||
// Open output file
|
// Open output file
|
||||||
let mut file = File::create(&output_path)
|
let mut file = File::create(&output_path)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("Failed to create output file: {}", e))?;
|
.map_err(|e| format!("Failed to create output file: {}", e))?;
|
||||||
|
|
||||||
|
let mut downloaded_bytes = 0u64;
|
||||||
|
let mut last_reported_percentage = 0u8;
|
||||||
|
|
||||||
// Stream download with optional decryption
|
// Stream download with optional decryption
|
||||||
if is_encrypted {
|
if is_encrypted {
|
||||||
let mut decryptor = StreamingDecryptor::new(&track_id);
|
let mut decryptor = StreamingDecryptor::new(&track_id);
|
||||||
@@ -93,6 +100,7 @@ async fn download_and_decrypt_track(
|
|||||||
|
|
||||||
while let Some(chunk_result) = stream.next().await {
|
while let Some(chunk_result) = stream.next().await {
|
||||||
let chunk = chunk_result.map_err(|e| format!("Download stream error: {}", e))?;
|
let chunk = chunk_result.map_err(|e| format!("Download stream error: {}", e))?;
|
||||||
|
downloaded_bytes += chunk.len() as u64;
|
||||||
|
|
||||||
// Decrypt chunk and write to file
|
// Decrypt chunk and write to file
|
||||||
let decrypted = decryptor.process(&chunk);
|
let decrypted = decryptor.process(&chunk);
|
||||||
@@ -101,6 +109,21 @@ async fn download_and_decrypt_track(
|
|||||||
.await
|
.await
|
||||||
.map_err(|e| format!("Failed to write to file: {}", e))?;
|
.map_err(|e| format!("Failed to write to file: {}", e))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Emit progress every 5%
|
||||||
|
if total_size > 0.0 {
|
||||||
|
let percentage = ((downloaded_bytes as f64 / total_size) * 100.0) as u8;
|
||||||
|
let rounded_percentage = (percentage / 5) * 5;
|
||||||
|
|
||||||
|
if rounded_percentage > last_reported_percentage || percentage == 100 {
|
||||||
|
last_reported_percentage = rounded_percentage;
|
||||||
|
let _ = window.emit("download-progress", serde_json::json!({
|
||||||
|
"downloaded": downloaded_bytes,
|
||||||
|
"total": total_size as u64,
|
||||||
|
"percentage": percentage
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write any remaining buffered data
|
// Write any remaining buffered data
|
||||||
@@ -118,9 +141,26 @@ async fn download_and_decrypt_track(
|
|||||||
|
|
||||||
while let Some(chunk_result) = stream.next().await {
|
while let Some(chunk_result) = stream.next().await {
|
||||||
let chunk = chunk_result.map_err(|e| format!("Download stream error: {}", e))?;
|
let chunk = chunk_result.map_err(|e| format!("Download stream error: {}", e))?;
|
||||||
|
downloaded_bytes += chunk.len() as u64;
|
||||||
|
|
||||||
file.write_all(&chunk)
|
file.write_all(&chunk)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| format!("Failed to write to file: {}", e))?;
|
.map_err(|e| format!("Failed to write to file: {}", e))?;
|
||||||
|
|
||||||
|
// Emit progress every 5%
|
||||||
|
if total_size > 0.0 {
|
||||||
|
let percentage = ((downloaded_bytes as f64 / total_size) * 100.0) as u8;
|
||||||
|
let rounded_percentage = (percentage / 5) * 5;
|
||||||
|
|
||||||
|
if rounded_percentage > last_reported_percentage || percentage == 100 {
|
||||||
|
last_reported_percentage = rounded_percentage;
|
||||||
|
let _ = window.emit("download-progress", serde_json::json!({
|
||||||
|
"downloaded": downloaded_bytes,
|
||||||
|
"total": total_size as u64,
|
||||||
|
"percentage": percentage
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export async function downloadTrack(
|
|||||||
retryCount: number = 0,
|
retryCount: number = 0,
|
||||||
decryptionTrackId?: string
|
decryptionTrackId?: string
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
|
const { listen } = await import('@tauri-apps/api/event');
|
||||||
// Generate paths
|
// Generate paths
|
||||||
const paths = generateTrackPath(track, musicFolder, format, false);
|
const paths = generateTrackPath(track, musicFolder, format, false);
|
||||||
|
|
||||||
@@ -60,16 +61,28 @@ export async function downloadTrack(
|
|||||||
// Use the provided decryption track ID (for fallback tracks) or the original track ID
|
// Use the provided decryption track ID (for fallback tracks) or the original track ID
|
||||||
const trackIdForDecryption = decryptionTrackId ? decryptionTrackId.toString() : track.id.toString();
|
const trackIdForDecryption = decryptionTrackId ? decryptionTrackId.toString() : track.id.toString();
|
||||||
|
|
||||||
// Download and decrypt in Rust backend (streaming, no memory accumulation)
|
// Set up progress listener
|
||||||
console.log('Downloading and decrypting track in Rust backend...');
|
const unlisten = await listen<DownloadProgress>('download-progress', (event) => {
|
||||||
await invoke('download_and_decrypt_track', {
|
if (onProgress) {
|
||||||
url: downloadURL,
|
onProgress(event.payload);
|
||||||
trackId: trackIdForDecryption,
|
}
|
||||||
outputPath: paths.tempPath,
|
|
||||||
isEncrypted: isCrypted
|
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Download and decryption complete!');
|
try {
|
||||||
|
// Download and decrypt in Rust backend (streaming, no memory accumulation)
|
||||||
|
console.log('Downloading and decrypting track in Rust backend...');
|
||||||
|
await invoke('download_and_decrypt_track', {
|
||||||
|
url: downloadURL,
|
||||||
|
trackId: trackIdForDecryption,
|
||||||
|
outputPath: paths.tempPath,
|
||||||
|
isEncrypted: isCrypted
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Download and decryption complete!');
|
||||||
|
} finally {
|
||||||
|
// Clean up event listener
|
||||||
|
unlisten();
|
||||||
|
}
|
||||||
|
|
||||||
// Get user settings
|
// Get user settings
|
||||||
const appSettings = get(settings);
|
const appSettings = get(settings);
|
||||||
|
|||||||
Reference in New Issue
Block a user