Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 89 additions & 20 deletions FrontApp/Pages/SubirArchivo.razor
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,110 @@

<PageTitle>Subir Archivo - NubeCasera</PageTitle>



<div class="container-fluid">
<h1 class="text-center">Subir Archivo</h1>
</div>
@* <div class="container">
<div>Seleccionar Archivo: </div>
<InputFile OnChange="SubirArchivoMetodo"/>
</div> *@

</div>

<div class="mb-3">
<label for="formFileMultiple" class="form-label">Seleccionar archivos:</label>
<InputFile class="form-control" OnChange="SubirArchivoMetodo" multiple/>
<!-- <InputFile class="form-control" OnChange="SubirArchivoMetodo" multiple /> -->
<InputFile class="form-control" OnChange="ArchivosSeleccionados" multiple />

Comment on lines 15 to +18

</div>

@if (archivosSeleccionados != null && archivosSeleccionados.Count > 0)
{
<div class="alert alert-info">
<strong>Archivos Seleccionados:</strong> @archivosSeleccionados.Count
<ul>
@foreach (var archivo in archivosSeleccionados)
{
<li>@archivo.Name (@(archivo.Size / 1024) KB)</li>
}
</ul>
</div>

<button class="btn btn-primary" @onclick="SubirArchivos" disabled="@subiendoArchivo">
@if (subiendoArchivo)
{
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
<span>Subiendo...</span>
}
else
{
<span>Subir Archivos</span>
}

</button>
}

@if (subiendoArchivo)
{
<div class="progress mt-3">
<div class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar"
style="width: @(progresoActual)%"
aria-valuenow="@progresoActual"
aria-valuemin="0"
aria-valuemax="100">
@progresoActual%
</div>
</div>
}

@code {
[Parameter]
public Guid? CategoriaId { get; set; }

// este codigo, recibe 1 IFormFile por request, se enfoca en el loop
// se puede optimizar modificando o creando un endpoint recibiendo
// List<IFormFile>.
public async Task SubirArchivoMetodo(InputFileChangeEventArgs e)
// Variables para la barra de progreso
private int progresoActual = 0;
private bool subiendoArchivo = false;

// variable para guardar los archivos seleccionados
private IReadOnlyList<IBrowserFile>? archivosSeleccionados;

// obtiene los archivos seleccionados y los guarda en la variable archivosSeleccionados
private void ArchivosSeleccionados(InputFileChangeEventArgs e)
{
archivosSeleccionados = e.GetMultipleFiles();
}

public async Task SubirArchivos()
{
var archivos = e.GetMultipleFiles();
if (archivosSeleccionados == null || archivosSeleccionados.Count == 0)return;
const long MaxFileSize = 5L * 1024L * 1024L * 1024L;

foreach (var archivo in archivos)
// Mostrar la barra de progreso
subiendoArchivo = true;
progresoActual = 0;

try
{
foreach (var archivo in archivosSeleccionados)
{
await ArchivoService.SubirArchivoAsync(
archivo,
CategoriaId ?? Guid.Empty,
MaxFileSize,
(porcentaje) =>
{
progresoActual = porcentaje;
StateHasChanged(); // Actualizar la UI
}
);
}
}
catch (Exception ex)
{
// Manejar errores (por ejemplo, mostrar un mensaje)
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
await using var stream = archivo.OpenReadStream(maxAllowedSize: MaxFileSize);
// IBrowserFile file, Guid IdCategoria, long maxAllowedSize
await ArchivoService.SubirArchivoAsync(archivo, CategoriaId ?? Guid.Empty, MaxFileSize);
// Ocultar la barra al terminar (éxito o error)
subiendoArchivo = false;
progresoActual = 0;
}
Navigation.NavigateTo("/archivos");

}
}
15 changes: 12 additions & 3 deletions FrontApp/Servicios/ArchivoService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,16 @@ namespace Front.Servicios
public class ArchivoService : IArchivoService
{
private readonly HttpClient _httpClient;

//public Action<int>? OnProgresoActualizado;

public ArchivoService(HttpClient httpClient)
Comment on lines 12 to 16
{
_httpClient = httpClient;
}



public async Task<List<ArchivoReferenciaDTO>> ObtenerArchivosAsync(Guid? categoriaId = null)
{
var url = categoriaId.HasValue
Expand All @@ -38,8 +43,8 @@ public async Task EliminarArchivoAsync(Guid id)
response.EnsureSuccessStatusCode();
}

#region working on!
public async Task SubirArchivoAsync(IBrowserFile file, Guid IdCategoria, long maxAllowedSize)

public async Task SubirArchivoAsync(IBrowserFile file, Guid IdCategoria, long maxAllowedSize, Action<int> OnProgresoActualizado)
{
const int chunkSize = 4 * 1024 * 1024; // 4 MB por chunk
var IdSubida = Guid.NewGuid().ToString();
Expand Down Expand Up @@ -78,14 +83,18 @@ public async Task SubirArchivoAsync(IBrowserFile file, Guid IdCategoria, long ma
// importante: pedir que el browser use streaming si esta disponible
req.SetBrowserRequestStreamingEnabled(true);

// porcentaje de carga de chunks, para actualizar la barra de progreso
int porcentaje = (int)((chunkIndex + 1) * 100.0 / chunksTotales);
OnProgresoActualizado?.Invoke(porcentaje);

using var resp = await _httpClient.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
resp.EnsureSuccessStatusCode();
chunkIndex++;
Comment on lines +86 to 92
}
}


#endregion


public string ObtenerUrlDescarga(Guid id)
{
Expand Down
2 changes: 1 addition & 1 deletion FrontApp/Servicios/IArchivoService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Front.Servicios
{
public interface IArchivoService
{
Task SubirArchivoAsync(IBrowserFile file, Guid IdCategoria, long maxAllowedSize);
Task SubirArchivoAsync(IBrowserFile file, Guid IdCategoria, long maxAllowedSize, Action<int> OnProgresoActualizado);
Task<List<ArchivoReferenciaDTO>> ObtenerArchivosAsync(Guid? categoriaId = null);
Task<ArchivoReferenciaDTO> ObtenerArchivoAsync(Guid id);
Task<List<ArchivoReferenciaDTO>> BuscarArchivosAsync(string? q, Guid? categoriaId = null);
Expand Down