I'm creating rust code with react that downloads files, in a test I did the download bar goes completely crazy, it keeps going back and forth

the bytes of the files are correct, I don't understand why this is happening

I have following code


test.lua

local updates = {
    { version = 1, file_name = "100MB.bin" },
    { version = 2, file_name = "1GB.bin" },
    { version = 3, file_name = "10GB.bin" }
}

return updates


use mlua::{Lua, Result as LuaResult};
use reqwest::Client;
use std::path::PathBuf;
use std::env;
use tokio::fs::{self, File};
use tokio::io::AsyncWriteExt;
use tauri::{Window, Emitter};

#[derive(serde::Serialize, Clone)] 
struct DownloadProgress {
    current_file: usize,
    total_files: usize,
    file_name: String,
    downloaded_bytes: u64,
    total_bytes: u64,
}

fn get_executable_directory() -> PathBuf {
    env::current_exe()
        .expect("Failed to get current executable path")
        .parent()
        .expect("Failed to get executable directory")
        .to_path_buf()
}

fn parse_lua_file(file_path: &str) -> LuaResult<Vec<(u32, String)>> {
    let lua = Lua::new();
    let lua_code = std::fs::read_to_string(file_path).expect("Failed to read Lua file");

    let updates: mlua::Table = lua.load(&lua_code).eval()?;
    let mut files = Vec::new();

    for pair in updates.sequence_values::<mlua::Table>() {
        let table = pair?;
        let version: u32 = table.get("version")?;
        let file_name: String = table.get("file_name")?;
        files.push((version, file_name));
    }

    Ok(files)
}

#[tauri::command]
pub async fn download_files(window: Window) -> Result<(), String> {
    // Obtém o diretório do executável
    let exe_dir = get_executable_directory();

    // Define o caminho para a pasta `patchs`
    let patchs_dir = exe_dir.join("patchs");
    
    // Verifica e cria o diretório `patchs` se ele não existir
    fs::create_dir_all(&patchs_dir).await.map_err(|e| format!("Failed to create patchs directory: {}", e))?;

    // Carrega o arquivo Lua e obtém os arquivos a serem baixados
    let lua_file_path = exe_dir.join("test.lua");
    let lua_file_path_str = lua_file_path.to_str().ok_or("Invalid file path")?;

    let files_to_download = parse_lua_file(lua_file_path_str)
        .map_err(|e| format!("Failed to parse Lua file: {}", e))?;

    let total_files = files_to_download.len();
    let client = Client::new();

    for (current_file, (_version, file_name)) in files_to_download.iter().enumerate() {
        let url = format!("https://hil-speed.hetzner.com/{}", file_name);
        
        let mut response = client
            .get(&url)
            .send()
            .await
            .map_err(|e| format!("Failed to download {}: {}", file_name, e))?;
        
        let total_bytes = response.content_length().unwrap_or(0);
        let mut downloaded_bytes = 0;

        // Define o caminho completo para o arquivo na pasta `patchs`
        let file_path = patchs_dir.join(file_name);
        let mut file = File::create(&file_path).await.map_err(|e| format!("Failed to create file {}: {}", file_name, e))?;

        // Baixa o arquivo em chunks e grava o progresso
        while let Some(chunk) = response.chunk().await.map_err(|e| format!("Failed to read chunk for {}: {}", file_name, e))? {
            downloaded_bytes += chunk.len() as u64;
            file.write_all(&chunk).await.map_err(|e| format!("Failed to write chunk for {}: {}", file_name, e))?;

            // Emite o progresso atualizado
            window.emit(
                "download-progress",
                DownloadProgress {
                    current_file: current_file + 1,
                    total_files,
                    file_name: file_name.clone(),
                    downloaded_bytes,
                    total_bytes,
                },
            ).map_err(|e| format!("Failed to send event for {}: {}", file_name, e))?;
        }
    }    
    Ok(())
}


React

import { useState, useEffect } from "react";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";

interface DownloadProgress {
  current_file: number;
  total_files: number;
  file_name: string;
  downloaded_bytes: number;
  total_bytes: number;
}

function DownloadTest() {
  const [currentFile, setCurrentFile] = useState(0);
  const [totalFiles, setTotalFiles] = useState(0);
  const [fileName, setFileName] = useState("");
  const [downloadedBytes, setDownloadedBytes] = useState(0);
  const [totalBytes, setTotalBytes] = useState(0);
  const [progressPercent, setProgressPercent] = useState(0);

  useEffect(() => {
    invoke("download_files");

    const unlisten = listen<DownloadProgress>("download-progress", (event) => {
      const data = event.payload;

      setCurrentFile(data.current_file);
      setTotalFiles(data.total_files);
      setFileName(data.file_name);
      setDownloadedBytes(data.downloaded_bytes);
      setTotalBytes(data.total_bytes);
    });

    return () => {
      unlisten.then((f) => f());
    };
  }, []);

  // Calcula a porcentagem de progresso
  useEffect(() => {
    if (totalBytes > 0) {
      setProgressPercent((downloadedBytes / totalBytes) * 100);
    }
  }, [downloadedBytes, totalBytes]);

  return (
    <div className="absolute bottom-3 rounded-lg w-[71%] h-[8%] flex flex-col justify-between items-center">
      <p className="text-[14px] font-bold text-opacity-[0.95] text-white text-center">
        Download ({currentFile} / {totalFiles}): {fileName} ({downloadedBytes} / {totalBytes} bytes)
      </p>
      <div className="w-[95%] bg-[#0E1622]/[0.95] rounded-md h-5 flex items-center">
        <div
          className="bg-[#1164CA]/[0.95] ml-1 rounded-md h-4 transition-all duration-300"
          style={{ width: `${progressPercent}%` }}
        />
      </div>
    </div>
  );
}

export default DownloadTest;


How can I fix this?