mirror of
https://github.com/senju1337/senju.git
synced 2025-12-23 23:39:27 +00:00
Merge pull request #27 from senju1337/feat/OPS-55
Feat/OPS-55 add frontend for image to haiku
This commit is contained in:
commit
33aaac5f3b
5 changed files with 228 additions and 2 deletions
|
|
@ -2,7 +2,7 @@
|
|||
name = "senju"
|
||||
version = "0.1.0"
|
||||
description = "API / Webservice for Phrases/Words/Kanji/Haiku"
|
||||
authors = [{ name = "Christoph J. Scherr", email = "software@cscherr.de" }]
|
||||
authors = [{ name = "Christoph J. Scherr", email = "software@cscherr.de" },{name = "Moritz Marquard", email="mrmarquard@protonmail.com"}]
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
|
|
|
|||
|
|
@ -53,6 +53,14 @@ def prompt_view():
|
|||
)
|
||||
|
||||
|
||||
@app.route("/scan")
|
||||
def scan_view():
|
||||
return render_template(
|
||||
"scan.html",
|
||||
title="Image scanning"
|
||||
)
|
||||
|
||||
|
||||
@app.route("/api/v1/haiku", methods=['POST'])
|
||||
def generate_haiku():
|
||||
if request.method == 'POST':
|
||||
|
|
|
|||
|
|
@ -43,6 +43,11 @@
|
|||
{% if request.endpoint == 'prompt_view' %} bg-gray-900 text-white {% else %} text-gray-300 hover:bg-gray-700 hover:text-white {% endif %}">
|
||||
Haiku generation
|
||||
</a>
|
||||
<a href="{{ url_for('scan_view') }}"
|
||||
class="rounded-md px-3 py-2 text-sm font-medium
|
||||
{% if request.endpoint == 'scan_view' %} bg-gray-900 text-white {% else %} text-gray-300 hover:bg-gray-700 hover:text-white {% endif %}">
|
||||
Image scanning
|
||||
</a>
|
||||
<a href="#"
|
||||
class="rounded-md px-3 py-2 text-sm font-medium text-gray-300 hover:bg-gray-700 hover:text-white">
|
||||
Information
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{% extends "base.html" %}
|
||||
{% block content %}
|
||||
<h1 class="text-center">yo mama</h1>
|
||||
<h1 class="text-center"></h1>
|
||||
{% endblock %}
|
||||
|
|
|
|||
213
senju/templates/scan.html
Normal file
213
senju/templates/scan.html
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Image Upload with Preview</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<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 mb-8">
|
||||
|
||||
<h1 class="text-3xl font-bold text-violet-700 mb-4">Upload your image</h1>
|
||||
<!-- File Upload container-->
|
||||
<div id="upload-area" class="flex items-center justify-center w-full">
|
||||
<label for="dropzone-file" class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 dark:hover:bg-gray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
|
||||
<div class="flex flex-col items-center justify-center pt-5 pb-6">
|
||||
<svg class="w-8 h-8 mb-4 text-gray-500 dark:text-gray-400" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"/>
|
||||
</svg>
|
||||
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span class="font-semibold">Click to upload</span> or drag and drop</p>
|
||||
<p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF (MAX. 800x400px)</p>
|
||||
</div>
|
||||
<input id="dropzone-file" type="file" accept="image/*" class="hidden" />
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- Image Preview container-->
|
||||
<div id="image-preview" class="w-full hidden">
|
||||
<div class="relative">
|
||||
<img id="preview-img" src="" alt="Preview" class="w-full h-auto rounded-lg">
|
||||
<button id="remove-image" class="absolute top-2 right-2 bg-red-500 text-white rounded-full p-1 hover:bg-red-600" title="Remove image">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Error message -->
|
||||
<div id="error-message" class="mt-4 text-red-500 hidden">
|
||||
Please upload an image first.
|
||||
</div>
|
||||
|
||||
<button id="submit-button" type="submit" class="mt-6 bg-violet-600 hover:bg-violet-700 text-white font-bold py-2 px-4 rounded transition duration-300">
|
||||
Submit
|
||||
</button>
|
||||
</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">
|
||||
<h2 class="text-2xl font-semibold text-violet-700">AI recognized the following:</h2>
|
||||
<p id="ai-response" class="text-lg text-gray-700 mt-2 italic">Waiting for input...</p>
|
||||
<div class="flex justify-center space-x-4">
|
||||
<button id="yes-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">
|
||||
Generate Haiku
|
||||
</button>
|
||||
<button id="no-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">
|
||||
Input new image
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- New generating haiku div that appears after "Yes" is clicked -->
|
||||
<div id="generating-haiku-box" class="mt-8 bg-white text-gray-900 p-6 rounded-lg shadow-lg max-w-lg w-full text-center hidden transition-opacity duration-500 ease-in-out">
|
||||
<h2 class="text-2xl font-semibold text-violet-700">Generating Haiku</h2>
|
||||
<div class="flex justify-center mt-4">
|
||||
<div class="loader animate-pulse flex space-x-4">
|
||||
<div class="w-3 h-3 bg-violet-600 rounded-full"></div>
|
||||
<div class="w-3 h-3 bg-violet-600 rounded-full"></div>
|
||||
<div class="w-3 h-3 bg-violet-600 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-lg text-gray-700 mt-4 italic">Creating a beautiful haiku based on your image...</p>
|
||||
</div>
|
||||
<div id="generated-haiku-box" class="mt-8 bg-white text-gray-900 p-6 rounded-lg shadow-lg max-w-lg w-full text-center hidden transition-opacity duration-500 ease-in-out">
|
||||
<h2 class="text-2xl font-semibold text-violet-700">Red suit, vents unseen,<br>
|
||||
Sus behavior, crew unsure,<br>
|
||||
Vote him, task complete.</h2>
|
||||
<div class="flex justify-center mt-4">
|
||||
<div class="loader animate-pulse flex space-x-4">
|
||||
<div class="w-3 h-3 bg-violet-600 rounded-full"></div>
|
||||
<div class="w-3 h-3 bg-violet-600 rounded-full"></div>
|
||||
<div class="w-3 h-3 bg-violet-600 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-lg text-gray-700 mt-4 italic">Creating a beautiful haiku based on your image...</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Get all needed elements
|
||||
const dropzoneFile = document.getElementById('dropzone-file');
|
||||
const uploadArea = document.getElementById('upload-area');
|
||||
const imagePreview = document.getElementById('image-preview');
|
||||
const previewImg = document.getElementById('preview-img');
|
||||
const removeImageBtn = document.getElementById('remove-image');
|
||||
const responseBox = document.getElementById('response-box');
|
||||
const submitButton = document.getElementById('submit-button');
|
||||
const errorMessage = document.getElementById('error-message');
|
||||
const yesButton = document.getElementById('yes-button');
|
||||
const noButton = document.getElementById('no-button');
|
||||
const generatingHaikuBox = document.getElementById('generating-haiku-box');
|
||||
const generatedHaikuBox = document.getElementById('generated-haiku-box');
|
||||
let imageUploaded = false;
|
||||
|
||||
function handleFileSelect(event) {
|
||||
const file = event.target.files[0];
|
||||
|
||||
if (file && file.type.startsWith('image/')) {
|
||||
// Create a URL for the selected image
|
||||
const imageUrl = URL.createObjectURL(file);
|
||||
|
||||
// Set the image source
|
||||
previewImg.src = imageUrl;
|
||||
|
||||
// Hide upload area and show image preview
|
||||
uploadArea.classList.add('hidden');
|
||||
imagePreview.classList.remove('hidden');
|
||||
errorMessage.classList.add('hidden');
|
||||
|
||||
// Set flag that image is uploaded
|
||||
imageUploaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
function removeImage() {
|
||||
dropzoneFile.value = '';
|
||||
|
||||
// Hide image
|
||||
imagePreview.classList.add('hidden');
|
||||
uploadArea.classList.remove('hidden');
|
||||
|
||||
URL.revokeObjectURL(previewImg.src);
|
||||
previewImg.src = '';
|
||||
|
||||
imageUploaded = false;
|
||||
responseBox.classList.add('opacity-0');
|
||||
generatingHaikuBox.classList.add('hidden');
|
||||
setTimeout(() => {
|
||||
document.getElementById('ai-response').textContent = 'Waiting for input...';
|
||||
}, 500);
|
||||
}
|
||||
|
||||
function handleSubmit() {
|
||||
if (imageUploaded) {
|
||||
// Hide error
|
||||
errorMessage.classList.add('hidden');
|
||||
|
||||
// Show response box
|
||||
responseBox.classList.remove('opacity-0');
|
||||
|
||||
// Example response
|
||||
document.getElementById('ai-response').textContent = 'Dominic Monaghan interviewing Elijah Wood if he will wear wigs';
|
||||
} else {
|
||||
|
||||
errorMessage.classList.remove('hidden');
|
||||
|
||||
uploadArea.classList.add('shake');
|
||||
setTimeout(() => {
|
||||
uploadArea.classList.remove('shake');
|
||||
}, 600);
|
||||
}
|
||||
}
|
||||
|
||||
function handleYesClick() {
|
||||
// Hide response box
|
||||
responseBox.classList.add('opacity-0');
|
||||
|
||||
// Show generating haiku box first
|
||||
setTimeout(() => {
|
||||
responseBox.classList.add('hidden');
|
||||
generatingHaikuBox.classList.remove('hidden');
|
||||
|
||||
// After a delay, hide generating box and show result
|
||||
setTimeout(() => {
|
||||
generatingHaikuBox.classList.add('hidden');
|
||||
generatedHaikuBox.classList.remove('hidden');
|
||||
}, 3000); // Show loading animation for 3 seconds before revealing the haiku
|
||||
}, 500); // Wait for response box fade out
|
||||
} function handleNoClick() {
|
||||
// Reset everything
|
||||
removeImage();
|
||||
}
|
||||
|
||||
dropzoneFile.addEventListener('change', handleFileSelect);
|
||||
removeImageBtn.addEventListener('click', removeImage);
|
||||
submitButton.addEventListener('click', handleSubmit);
|
||||
yesButton.addEventListener('click', handleYesClick);
|
||||
noButton.addEventListener('click', handleNoClick);
|
||||
|
||||
// Add some CSS animation
|
||||
document.head.insertAdjacentHTML('beforeend', `
|
||||
<style>
|
||||
@keyframes shake {
|
||||
0% { transform: translateX(0); }
|
||||
25% { transform: translateX(-5px); }
|
||||
50% { transform: translateX(5px); }
|
||||
75% { transform: translateX(-5px); }
|
||||
100% { transform: translateX(0); }
|
||||
}
|
||||
.shake {
|
||||
animation: shake 0.5s ease-in-out;
|
||||
border-color: #ef4444 !important;
|
||||
}
|
||||
</style>
|
||||
`);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
{% endblock %}
|
||||
Loading…
Add table
Add a link
Reference in a new issue