From 493baea0e1feffad9ebaebb9808b3652207f4e27 Mon Sep 17 00:00:00 2001 From: Oreo80 Date: Mon, 8 Jun 2026 21:07:24 +0300 Subject: [PATCH 1/2] Solve page: green passing test cases, taller console, longer AI timeout - Serialize per-test status as string (JsonStringEnumConverter) so the frontend can detect Accepted; passing test cases now render green - Enlarge console output panel; add green/red test-case box styling - Bound the Improve Solution panel to a single scrollable area - Raise AI timeout from 10s to 30s (HomeController + Solve.cshtml) Co-Authored-By: Claude Opus 4.8 --- JustBigO(Fun)/Controllers/HomeController.cs | 8 +++---- JustBigO(Fun)/Services/DockerCodeExecutor.cs | 7 +++++- JustBigO(Fun)/Views/Home/Solve.cshtml | 24 ++++++++++---------- JustBigO(Fun)/wwwroot/css/site.css | 22 +++++++++++++++--- 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/JustBigO(Fun)/Controllers/HomeController.cs b/JustBigO(Fun)/Controllers/HomeController.cs index 3d92f70..15548b0 100644 --- a/JustBigO(Fun)/Controllers/HomeController.cs +++ b/JustBigO(Fun)/Controllers/HomeController.cs @@ -169,9 +169,9 @@ public async Task AnalyzeComplexity( try { - // Gestionăm timeout-ul de 10 secunde să nu blocăm interfața. + // Gestionăm timeout-ul de 30 secunde să nu blocăm interfața. var analyzeTask = complexityAnalyzer.AnalyzeCodeAsync(model.SourceCode); - var timeoutTask = Task.Delay(TimeSpan.FromSeconds(10)); + var timeoutTask = Task.Delay(TimeSpan.FromSeconds(30)); if (await Task.WhenAny(analyzeTask, timeoutTask) == analyzeTask) { @@ -333,13 +333,13 @@ public async Task SubmitSolution( string timeO = "O(?)"; string spaceO = "O(?)"; - // 2. Dacă codul trece testele, apelăm Agentul AI cu TIMEOUT de 10 secunde + // 2. Dacă codul trece testele, apelăm Agentul AI cu TIMEOUT de 30 secunde if (isSuccess) { try { var analyzeTask = complexityAnalyzer.AnalyzeCodeAsync(model.SourceCode); - var timeoutTask = Task.Delay(TimeSpan.FromSeconds(10)); + var timeoutTask = Task.Delay(TimeSpan.FromSeconds(30)); if (await Task.WhenAny(analyzeTask, timeoutTask) == analyzeTask) { diff --git a/JustBigO(Fun)/Services/DockerCodeExecutor.cs b/JustBigO(Fun)/Services/DockerCodeExecutor.cs index 632d979..46d0b5d 100644 --- a/JustBigO(Fun)/Services/DockerCodeExecutor.cs +++ b/JustBigO(Fun)/Services/DockerCodeExecutor.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using System.Diagnostics; using System.Text.Json; +using System.Text.Json.Serialization; using System.Text; using System.Text.RegularExpressions; @@ -13,7 +14,11 @@ public class DockerCodeExecutor : ICodeExecutor private readonly IServiceScopeFactory _scopeFactory; private readonly ILogger _logger; private static readonly Encoding Utf8NoBom = new UTF8Encoding(false); - private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }; + private static readonly JsonSerializerOptions JsonOptions = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + Converters = { new JsonStringEnumConverter() } + }; public DockerCodeExecutor(IServiceScopeFactory scopeFactory, ILogger logger) { diff --git a/JustBigO(Fun)/Views/Home/Solve.cshtml b/JustBigO(Fun)/Views/Home/Solve.cshtml index 55dffbc..66c4e40 100644 --- a/JustBigO(Fun)/Views/Home/Solve.cshtml +++ b/JustBigO(Fun)/Views/Home/Solve.cshtml @@ -125,9 +125,9 @@ .replace(/"/g, '"'); } - // Functie ajutatoare pentru timeout Frontend (10 secunde) + // Functie ajutatoare pentru timeout Frontend (30 secunde) async function fetchWithTimeout(resource, options = {}) { - const { timeout = 10000 } = options; + const { timeout = 30000 } = options; const controller = new AbortController(); const id = setTimeout(() => controller.abort(), timeout); const response = await fetch(resource, { @@ -244,12 +244,12 @@ try { // Impunem limită la apelul SignalR const invokeTask = connection.invoke("TranslateCode", sourceCode, sourceLang, targetLang); - const timeoutTask = new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), 10000)); + const timeoutTask = new Promise((_, reject) => setTimeout(() => reject(new Error("Timeout")), 30000)); await Promise.race([invokeTask, timeoutTask]); } catch (err) { console.error("Translation Error: ", err); if (err.message === "Timeout") { - window.aiEditor.setValue("// Timeout: Agentul AI a depășit timpul de așteptare de 10s.\n// Platforma nu a fost blocată. Încearcă din nou mai târziu."); + window.aiEditor.setValue("// Timeout: Agentul AI a depășit timpul de așteptare de 30s.\n// Platforma nu a fost blocată. Încearcă din nou mai târziu."); } else { window.aiEditor.setValue("// Error translating code."); } @@ -278,7 +278,7 @@ sourceCode: sourceCode, language: language }), - timeout: 10000 // 10 secunde limită + timeout: 30000 // 30 secunde limită }); if ((response.redirected && response.url.includes('Login')) || response.status === 401) { @@ -291,7 +291,7 @@ hintContainer.textContent = data.hint || "No hint was returned."; } catch (err) { if (err.name === 'AbortError' || err.message === 'Timeout') { - hintContainer.innerHTML = 'Timpul de așteptare a expirat (10s). Agentul AI este momentan suprasolicitat.'; + hintContainer.innerHTML = 'Timpul de așteptare a expirat (30s). Agentul AI este momentan suprasolicitat.'; } else { hintContainer.textContent = "Error requesting hint: " + err.message; } @@ -320,7 +320,7 @@ sourceCode: sourceCode, language: language }), - timeout: 10000 + timeout: 30000 }); if ((response.redirected && response.url.includes('Login')) || response.status === 401) { @@ -351,7 +351,7 @@ consoleOutput.innerHTML = msg; } catch (err) { if (err.name === 'AbortError' || err.message === 'Timeout') { - consoleOutput.innerHTML = '
Timeout: Agentul AI a depășit timpul alocat (10s). Platforma nu a fost blocată.
'; + consoleOutput.innerHTML = '
Timeout: Agentul AI a depășit timpul alocat (30s). Platforma nu a fost blocată.
'; } else { consoleOutput.innerHTML = '
Complete current code failed: ' + err.message + '
'; } @@ -387,7 +387,7 @@ sourceCode: sourceCode, language: language }), - timeout: 10000 + timeout: 30000 }); if ((response.redirected && response.url.includes('Login')) || response.status === 401) { @@ -411,7 +411,7 @@ preCode.textContent = ''; preDs.textContent = ''; if (err.name === 'AbortError' || err.message === 'Timeout') { - preSteps.textContent = 'Timeout: Agentul AI a depășit timpul de așteptare de 10 secunde.'; + preSteps.textContent = 'Timeout: Agentul AI a depășit timpul de așteptare de 30 secunde.'; } else { preSteps.textContent = 'Error: ' + err.message; } @@ -515,7 +515,7 @@ results.forEach((r, idx) => { const isOk = r.status === 'Accepted'; html += ` -
+
Test Case #${idx + 1} ${r.status} @@ -574,7 +574,7 @@ sourceCode: sourceCode, language: document.getElementById('languageSelect').value }), - timeout: 10000 + timeout: 30000 }); if (aiResponse.ok) { diff --git a/JustBigO(Fun)/wwwroot/css/site.css b/JustBigO(Fun)/wwwroot/css/site.css index 6aeed94..f87d4aa 100644 --- a/JustBigO(Fun)/wwwroot/css/site.css +++ b/JustBigO(Fun)/wwwroot/css/site.css @@ -648,7 +648,7 @@ body { } .jbo-console-panel { - height: 180px; + height: 340px; background: rgba(15,23,42,0.96); border: 1px solid rgba(148,163,184,0.3); border-radius: 0.75rem; @@ -656,6 +656,22 @@ body { flex-direction: column; } +/* Test-case result boxes (Submit output) */ +.jbo-testcase { + border: 1px solid transparent; + background: rgba(15,23,42,0.6); +} + +.jbo-testcase--pass { + border-color: #22c55e !important; + background: rgba(34,197,94,0.12) !important; +} + +.jbo-testcase--fail { + border-color: #ef4444 !important; + background: rgba(239,68,68,0.10) !important; +} + .jbo-console-header { display: flex; justify-content: space-between; @@ -703,6 +719,8 @@ body { background: rgba(15, 23, 42, 0.85); border: 1px solid rgba(148, 163, 184, 0.25); color: #cbd5e1; + max-height: 24rem; + overflow-y: auto; } .jbo-improve-pre { @@ -715,8 +733,6 @@ body { border-radius: 0.35rem; padding: 0.5rem 0.65rem; margin: 0; - max-height: 12rem; - overflow-y: auto; color: #e2e8f0; } From 7c1ad015862e3934be0b968dcbb7aab79b0ad30f Mon Sep 17 00:00:00 2001 From: Oreo80 Date: Mon, 8 Jun 2026 21:59:33 +0300 Subject: [PATCH 2/2] README: add demo screencast link Co-Authored-By: Claude Opus 4.8 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b3c0787..a4dbda2 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ JustBigO-Fun is an ASP.NET Core 9.0 MVC platform for algorithmic challenges, inspired by sites like LeetCode. +> 🎥 **Demo (screencast):** https://youtu.be/4bKce7Ch55Y + > 📄 The application's technical documentation (features, tech stack, run instructions) is in the **[Project Documentation](#project-documentation)** section at the end of this README. ---