feat: generate haiku from image

Regs: OPS-85 OPS-84
This commit is contained in:
Christoph J. Scherr 2025-03-23 18:12:19 +01:00
parent 96e081fff1
commit 2c1e1e1488
No known key found for this signature in database
GPG key ID: 9EB784BB202BB7BB
3 changed files with 87 additions and 70 deletions

View file

@ -11,6 +11,7 @@ const yesButton = document.getElementById("yes-button");
const noButton = document.getElementById("no-button"); const noButton = document.getElementById("no-button");
const generatingHaikuBox = document.getElementById("generating-haiku-box"); const generatingHaikuBox = document.getElementById("generating-haiku-box");
const generatedHaikuBox = document.getElementById("generated-haiku-box"); const generatedHaikuBox = document.getElementById("generated-haiku-box");
let haiku_prompt = "";
let imageUploaded = false; let imageUploaded = false;
function handleFileSelect(event) { function handleFileSelect(event) {
@ -80,10 +81,10 @@ function handleSubmit() {
}) })
.then((data) => { .then((data) => {
// Extract top result and display it // Extract top result and display it
if (data.results && data.results.length > 0) { if (data.description) {
const topResult = data.results[0]; haiku_prompt = data.description;
document.getElementById("ai-response").textContent = document.getElementById("ai-response").textContent =
`${topResult.label} (${Math.round(topResult.confidence * 100)}% confidence)`; `Recognized: ${haiku_prompt}`;
} else { } else {
document.getElementById("ai-response").textContent = document.getElementById("ai-response").textContent =
"Could not identify the image"; "Could not identify the image";
@ -102,23 +103,30 @@ function handleSubmit() {
}, 600); }, 600);
} }
} }
function handleYesClick() { function handleYesClick() {
// Hide response box // Hide response box
responseBox.classList.add("opacity-0"); responseBox.classList.add("opacity-0");
// Show generating haiku box first responseBox.textContent = "🤖 AI is thinking...";
setTimeout(() => { responseBox.classList.remove("opacity-0");
responseBox.classList.add("hidden");
generatingHaikuBox.classList.remove("hidden");
// After a delay, hide generating box and show result fetch("/api/v1/haiku", {
setTimeout(() => { method: "POST",
generatingHaikuBox.classList.add("hidden"); headers: {
generatedHaikuBox.classList.remove("hidden"); "Content-Type": "application/json",
}, 3000); // Show loading animation for 3 seconds before revealing the haiku },
}, 500); // Wait for response box fade out body: JSON.stringify({ prompt: haiku_prompt }),
})
.then((response) => response.text())
.then((data) => {
let id = parseInt(data, 10);
window.location.href = "/haiku/" + id;
})
.catch((error) => {
responseBox.textContent = "Error: " + error.message;
});
} }
function handleNoClick() { function handleNoClick() {
// Reset everything // Reset everything
removeImage(); removeImage();

View file

@ -1,9 +1,13 @@
{% extends "base.html" %} {% extends "base.html" %} {% block content %}
<div
{% block content %} class="flex flex-col items-center justify-center min-h-screen bg-violet-900 text-white p-6"
<div class="flex flex-col items-center justify-center min-h-screen bg-violet-900 text-white p-6"> >
<div class="bg-white text-gray-900 p-8 rounded-xl shadow-lg max-w-lg w-full text-center transform transition duration-300 hover:scale-105"> <div
<h1 class="text-3xl font-bold text-violet-700 mb-4">Very 1337 prompt input</h1> class="bg-white text-gray-900 p-8 rounded-xl shadow-lg max-w-lg w-full text-center transform transition duration-300 hover:scale-105"
>
<h1 class="text-3xl font-bold text-violet-700 mb-4">
Very 1337 prompt input
</h1>
<div class="flex flex-col gap-4"> <div class="flex flex-col gap-4">
<input <input
type="text" type="text"
@ -22,14 +26,19 @@
</div> </div>
</div> </div>
<div id="response-box" class="mt-8 bg-white text-gray-900 p-6 rounded-lg shadow-lg max-w-lg w-full text-center opacity-0 transition-opacity duration-500 ease-in-out"> <div
id="response-box"
class="mt-8 bg-white text-gray-900 p-6 rounded-lg shadow-lg max-w-lg w-full text-center opacity-0 transition-opacity duration-500 ease-in-out"
>
<h2 class="text-2xl font-semibold text-violet-700">Response:</h2> <h2 class="text-2xl font-semibold text-violet-700">Response:</h2>
<p id="ai-response" class="text-lg text-gray-700 mt-2 italic">Waiting for input...</p> <p id="ai-response" class="text-lg text-gray-700 mt-2 italic">
Waiting for input...
</p>
</div> </div>
</div> </div>
<script> <script>
document.getElementById("submit-btn").addEventListener("click", function() { document.getElementById("submit-btn").addEventListener("click", function () {
let userInput = document.getElementById("user-input").value; let userInput = document.getElementById("user-input").value;
let responseBox = document.getElementById("response-box"); let responseBox = document.getElementById("response-box");
let responseText = document.getElementById("ai-response"); let responseText = document.getElementById("ai-response");
@ -39,8 +48,9 @@ document.getElementById("submit-btn").addEventListener("click", function() {
if (userInput.trim() === "") { if (userInput.trim() === "") {
responseText.textContent = "Please enter a prompt!"; responseText.textContent = "Please enter a prompt!";
} } else if (userInput.length > 100) {
else if (userInput.trim() === "amogus") { responseText.textContent = "Input must under 100 characters long!";
} else if (userInput.trim() === "amogus") {
responseText.textContent = "🤖 AI is thinking..."; responseText.textContent = "🤖 AI is thinking...";
responseBox.classList.remove("opacity-0"); responseBox.classList.remove("opacity-0");
@ -48,27 +58,26 @@ document.getElementById("submit-btn").addEventListener("click", function() {
setTimeout(() => { setTimeout(() => {
responseText.textContent = "Sus imposter ඞ"; responseText.textContent = "Sus imposter ඞ";
}, 1500); }, 1500);
} } else {
else {
responseText.textContent = "🤖 AI is thinking..."; responseText.textContent = "🤖 AI is thinking...";
responseBox.classList.remove("opacity-0"); responseBox.classList.remove("opacity-0");
fetch('/api/v1/haiku', { fetch("/api/v1/haiku", {
method: 'POST', method: "POST",
headers: { headers: {
'Content-Type': 'application/json' "Content-Type": "application/json",
}, },
body: JSON.stringify({ 'prompt': userInput }) body: JSON.stringify({ prompt: userInput }),
}) })
.then(response => response.text()) .then((response) => response.text())
.then(data => { .then((data) => {
let id = parseInt(data, 10); let id = parseInt(data, 10);
window.location.href = "/haiku/" + id; window.location.href = "/haiku/" + id;
}) })
.catch(error => { .catch((error) => {
responseText.textContent = 'Error: ' + error.message; responseText.textContent = "Error: " + error.message;
}); });
} }
}); });
</script> </script>
{% endblock %} {% endblock %}

View file

@ -97,14 +97,14 @@
</p> </p>
<div class="flex justify-center space-x-4"> <div class="flex justify-center space-x-4">
<button <button
id="yes-button" id="yesButton"
type="button" type="button"
class="mt-6 bg-violet-600 hover:bg-violet-700 text-white font-bold py-2 px-4 rounded transition duration-300" class="mt-6 bg-violet-600 hover:bg-violet-700 text-white font-bold py-2 px-4 rounded transition duration-300"
> >
Generate Haiku Generate Haiku
</button> </button>
<button <button
id="no-button" id="noButton"
type="button" type="button"
class="mt-6 bg-violet-600 hover:bg-violet-700 text-white font-bold py-2 px-4 rounded transition duration-300" class="mt-6 bg-violet-600 hover:bg-violet-700 text-white font-bold py-2 px-4 rounded transition duration-300"
> >