diff --git a/app.py b/app.py index 7fdc677..688c185 100644 --- a/app.py +++ b/app.py @@ -11,6 +11,7 @@ import io from dotenv import load_dotenv import os +from datetime import datetime from google import genai @@ -26,6 +27,7 @@ next_message = "" next_image = "" +current_file_info = None def allowed_file(filename): @@ -39,7 +41,7 @@ def upload_file(): """Takes in a file, checks if it is valid, and saves it for the next request to the API """ - global next_image + global next_image, current_file_info if "file" not in request.files: return jsonify(success=False, message="No file part") @@ -56,6 +58,15 @@ def upload_file(): file_stream.seek(0) next_image = Image.open(file_stream) + # Store file info + current_file_info = { + "filename": filename, + "size": len(file_stream.getvalue()), + "upload_time": datetime.now().strftime("%Y-%m-%d %H:%M"), + "mime_type": file.content_type, + "has_file": True + } + return jsonify( success=True, message="File uploaded successfully and added to the conversation", @@ -92,11 +103,13 @@ def stream(): def generate(): global next_message global next_image + global current_file_info assistant_response_content = "" if next_image != "": response = chat_session.send_message_stream([next_message, next_image]) next_image = "" + current_file_info = None else: response = chat_session.send_message_stream(next_message) next_message = "" @@ -107,3 +120,26 @@ def generate(): return Response(stream_with_context(generate()), mimetype="text/event-stream") + +@app.route("/get_files", methods=["GET"]) +def get_files(): + """Get current file info""" + global current_file_info, next_image + + if next_image != "" and current_file_info: # if there is a file, return the file info + return jsonify({ + "success": True, + "has_file": True, + "file": { + "filename": current_file_info["filename"], + "size": current_file_info["size"], + "upload_time": current_file_info["upload_time"], + "mime_type": current_file_info["mime_type"] + } + }) + else: # if there is no file, return None + return jsonify({ + "success": True, + "has_file": False, + "file": None + }) \ No newline at end of file diff --git a/static/event-listener.js b/static/event-listener.js index 2f28e92..e0ad0fb 100644 --- a/static/event-listener.js +++ b/static/event-listener.js @@ -1,3 +1,54 @@ +// Format file size +function formatFileSize(bytes) { + if (bytes === 0) return '0 Bytes'; + const k = 1024; + const sizes = ['Bytes', 'KB', 'MB', 'GB']; + const i = Math.floor(Math.log(bytes) / Math.log(k)); + return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; +} + +// Display file info +function populateFiles(data) { + const currentFileItem = document.querySelector('.current-file-item'); + const uploadPrompt = document.querySelector('.centered-text'); + + if (data.has_file && data.file) { + // Display current file info + const file = data.file; + + // Update file info + currentFileItem.querySelector('.file-name').textContent = file.filename; + currentFileItem.querySelector('.file-size').textContent = formatFileSize(file.size); + currentFileItem.querySelector('.file-time').textContent = file.upload_time; + + // Display file item, hide upload prompt + currentFileItem.style.display = 'flex'; + uploadPrompt.style.display = 'none'; + } else { + // Display upload prompt when no file + currentFileItem.style.display = 'none'; + uploadPrompt.style.display = 'block'; + } +} + +function refreshFileDisplay() { + fetch('/get_files') + .then(response => response.json()) + .then(data => { + if (data.success) { + populateFiles(data); + } + }) + .catch(error => { + console.error('Failed to get file info:', error); + }); +} + +// Refresh file display when page loads +document.addEventListener('DOMContentLoaded', function() { + refreshFileDisplay(); +}); + document.getElementById("file-upload").addEventListener("change", function (event) { const file = event.target.files[0]; if (!file) { @@ -23,11 +74,8 @@ document.getElementById("file-upload").addEventListener("change", function (even banner.style.display = "none"; }, 3000); - fetch("/get_files") - .then((response) => response.json()) - .then((data) => { - populateFiles(data.assistant_files); - }); + // Refresh file display + refreshFileDisplay(); } else { console.error("Upload failed:", data.message); // Update and show the banner diff --git a/static/main.css b/static/main.css index a86d2be..c3caea6 100644 --- a/static/main.css +++ b/static/main.css @@ -341,3 +341,51 @@ body::after { border-top: 1px solid #ececf1; width: 100%; } + +.current-file-container { + margin-top: 12px; +} + +.current-file-item { + border: 1px solid #e0e0e0; + border-radius: 8px; + padding: 12px; + background-color: #f8f9ff; + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 12px; +} + +.file-info { + display: flex; + align-items: center; + gap: 12px; +} + +.file-icon { + font-size: 24px; +} + +.file-details { + display: flex; + flex-direction: column; + gap: 4px; +} + +.file-name { + font-weight: 500; + color: #333; + font-size: 14px; +} + +.file-size, .file-time { + font-size: 12px; + color: #666; +} + +.status-indicator { + color: #4285f4; + font-weight: 500; + font-size: 14px; +} diff --git a/templates/index.html b/templates/index.html index 509c460..1bb7f04 100644 --- a/templates/index.html +++ b/templates/index.html @@ -17,7 +17,22 @@
Demo
- +
+ + +