@page "/" @inject HttpClient Http @inject YouTubeService YouTubeService @inject PersistenceService PersistenceService @inject NavigationManager NavigationManager @using VideoStudy.Shared @using System.Net.Http.Json @using System.Text.Json @using System.Threading VideoStudy

VideoStudy

Transforme vídeos em guias de estudo com IA

@if (isProcessing || currentStep > 0) { } @if (logs.Count > 0) {
Log de execução @logs.Count eventos @(showLogs ? "▼" : "▶")
@if (showLogs) {
@foreach (var log in logs) {
[@log.Timestamp.ToString("HH:mm:ss")] @log.Message
}
}
} @if (!string.IsNullOrEmpty(generatedPdfPath)) { }
@code { private bool isProcessing = false; private int progress = 0; private int currentStep = 0; private string statusMessage = "Pronto"; private bool showLogs = false; private List logs = new(); private string videoUrl = string.Empty; private string selectedLanguage = "pt"; private string? userContext; private VideoInfo? currentVideoInfo; private string? generatedPdfPath; private class LogEntry { public DateTime Timestamp { get; set; } = DateTime.Now; public string Message { get; set; } = string.Empty; } private void ToggleLogs() => showLogs = !showLogs; private void AddLog(string message, int? eventProgress = null) { logs.Insert(0, new LogEntry { Message = message }); if (logs.Count > 100) logs.RemoveAt(logs.Count - 1); if (eventProgress.HasValue) progress = eventProgress.Value; StateHasChanged(); } private async Task HandleVideoUrlChanged(string url) { videoUrl = url; try { AddLog($"Buscando informações: {url}"); currentVideoInfo = await YouTubeService.GetVideoInfoAsync(url); if (currentVideoInfo != null) AddLog($"Encontrado: {currentVideoInfo.Title}"); } catch (Exception ex) { AddLog($"Erro ao buscar vídeo: {ex.Message}"); } } private async Task StartAnalysis() { isProcessing = true; progress = 0; currentStep = 0; generatedPdfPath = null; logs.Clear(); showLogs = true; CancellationTokenSource? cts = null; try { cts = new CancellationTokenSource(); var token = cts.Token; currentStep = 1; statusMessage = "Iniciando análise..."; AddLog("Enviando para o servidor...", 5); var request = new AnalysisRequest { VideoUrl = videoUrl, Mode = "fast", Language = "en", OutputLanguage = selectedLanguage, DurationSeconds = currentVideoInfo?.Duration.TotalSeconds ?? 0, UserContext = string.IsNullOrWhiteSpace(userContext) ? null : userContext.Trim() }; var httpRequest = new HttpRequestMessage(HttpMethod.Post, "api/analyze") { Content = JsonContent.Create(request) }; using var response = await Http.SendAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead, token); response.EnsureSuccessStatusCode(); var stream = response.Content.ReadFromJsonAsAsyncEnumerable( new JsonSerializerOptions { PropertyNameCaseInsensitive = true }, token); await foreach (var ev in stream.WithCancellation(token)) { if (ev == null) continue; if (ev.IsError) throw new Exception(ev.Message); AddLog(ev.Message, ev.ProgressPercentage); statusMessage = ev.Message; StateHasChanged(); if (ev.Result != null) { AddLog("Análise concluída!", 100); if (ev.Result.PdfData != null && ev.Result.PdfData.Length > 0) { AddLog("Salvando PDF na biblioteca...", 100); var session = await PersistenceService.SaveSessionAsync( ev.Result.PdfData, ev.Result.DocumentTitle, videoUrl); generatedPdfPath = session.FilePath; AddLog($"PDF salvo em: {session.FilePath}", 100); await Task.Delay(2000); NavigationManager.NavigateTo("library"); } break; } } } catch (Exception ex) { AddLog($"Erro: {ex.Message}"); statusMessage = "Erro na análise"; } finally { isProcessing = false; cts?.Dispose(); } } }