Hello everyone! I'm currently developing an app which users can chat with eachother on, currently it has a delete feature where you can delete comments you've created, and currently I need to add a button which can send files over, and a button which can edit chats which were made. If anyone wants to take a shot at adding these, here is the html file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chat</title>
<style>
body {
font-family: 'Arial', sans-serif;
background-color: #e8eff1;
margin: 0;
padding: 0;
color: #333;
}
.header {
color: #022c22;
font-size: 14px;
text-align: center;
}
.container {
max-width: 60%;
margin: auto;
}
.messages {
background: #ffffff;
border-radius: 8px;
padding: 20px;
margin-bottom: 30px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
font-size: 16px;
height: 50vh;
overflow-y: scroll;
}
.message {
border-bottom: 1px solid #ced6e0;
padding: 15px 0;
}
.message:last-child {
border-bottom: none;
}
form {
display: flex;
flex-direction: column;
}
textarea, input, button {
margin-bottom: 15px;
padding: 15px;
border: 1px solid #ced6e0;
border-radius: 6px;
font-size: 16px;
}
.button {
background-color: #2ecc71;
color: white;
border: none;
cursor: pointer;
transition: background-color 0.3s;
}
.button:hover {
background-color: #27ae60;
}
.message-box {
background: rgba(247, 248, 245, 0.42);
border-left: 4px solid rgba(51, 177, 104, 0.42);
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 6px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
position: relative;
}
.message-author {
font-weight: bold;
margin-bottom: 5px;
}
.message-content {
font-size: 16px;
line-height: 1.4;
display: flex;
justify-content: space-between;
align-items: center;
}
.message-time {
font-size: 12px;
color: #888;
}
textarea {
background: #f8f9fa;
border: 1px solid #ced4da;
box-sizing: border-box;
width: 100%;
padding: 12px 20px;
border-radius: 6px;
min-height: 100px;
font-size: 16px;
line-height: 1.5;
resize: none;
outline: none;
}
.delete-button {
background-color: #FF9AA2;
color: white;
border: none;
cursor: pointer;
transition: background-color 0.3s;
padding: 5px 10px;
font-size: 14px;
border-radius: 4px;
position: absolute;
right: 10px;
top: 10px;
}
.delete-button:hover {
background-color: #FF6F61;
}
</style>
<style>
[x-cloak] {
display: none !important;
}
</style>
</head>
<body>
<div class="header">
<h1>Welcome {{ request.session.username }}</h1>
</div>
<div class="container">
<div class="messages">
<div id="sse-data">
{% regroup messages by created_at.date as dated_messages %}
{% for date_group in dated_messages %}
{% for message in date_group.list %}
<div class="message-box" data-message-id="{{ message.id }}"> <div class="message-content">
{{ message.content }}
<span class="message-time">{{ message.created_at|date:"Y-m-d H:i" }}</span>
</div>
<form action="{% url 'delete_message' message.id %}" method="post" style="display:inline;"> {% csrf_token %}
<button type="submit" class="delete-button">Delete</button>
</form>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
<form x-cloak @submit.prevent="submit" x-data="{state: 'composing', errors: {}}">
<div>
<textarea name="content" @input="state = 'composing'" autofocus placeholder="Your next message..."></textarea>
<button class="button">Send</button>
</div>
<div x-show="state === 'error'">
<p>Error sending your message ❌</p>
</div>
</form>
<form x-cloak @submit.prevent="submit" x-data="{state: 'composing', errors: {}}">
<div>
<textarea name="content" @input="state = 'composing'" autofocus placeholder="Your next message..."></textarea>
<input type="file" name="file" id="file-input" style="display:none;">
<button type="button" class="upload-button" onclick="document.getElementById('file-input').click();">Upload</button>
<button class="send-button" type="submit">Send</button>
</div>
<div x-show="state === 'error'">
<p>Error sending your message ❌</p>
</div>
</form>
<form action="/lobby/" method="get">
<button type="submit">Return to Lobby</button>
</form>
</div>
<script>
let eventSource;
const sseData = document.getElementById('sse-data');
function startSSE() {
eventSource = new EventSource('/stream-chat-messages/');
eventSource.onmessage = event => {
const data = JSON.parse(event.data);
// Check if the message already exists to prevent duplicates
if (!document.querySelector(`[data-message-id="${data.id}"]`)) {
// Format date and time
const createdAt = new Date(data.created_at);
const timeString = createdAt.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const dateString = createdAt.toLocaleDateString([], { year: 'numeric', month: '2-digit', day: '2-digit' });
// Create the message HTML
const messageHTML = `
<div class="message-box" data-message-id="${data.id}">
<div class="message-author">${data.author__name}</div>
<div class="message-content">
${data.content}
<span class="message-time">${dateString} ${timeString}</span>
</div>
<form action="/delete_message/${data.id}/" method="post" style="display:inline;">
{% csrf_token %}
<button type="submit" class="delete-button">Delete</button>
</form>
</div>`;
// Append the message
sseData.innerHTML += messageHTML;
}
};
}
// On load, start SSE if the browser supports it.
if (typeof(EventSource) !== 'undefined') {
startSSE();
} else {
sseData.innerHTML = 'Whoops! Your browser doesn\'t receive server-sent events.';
}
</script>
<script>
function submit(event) {
event.preventDefault();
const formData = new FormData(event.target);
const endpointUrl = "/create-message/";
fetch(endpointUrl, {
method: "post",
body: formData,
headers: {
'X-CSRFToken': '{{ csrf_token }}',
},
})
.then(response => response.json())
.then(data => {
// Handle the response data
if (data.errors) {
this.state = 'error';
this.errors = data.errors;
} else {
this.state = 'success';
this.errors = {};
// Format date and time
const createdAt = new Date(data.created_at);
const timeString = createdAt.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const dateString = createdAt.toLocaleDateString([], { year: 'numeric', month: '2-digit', day: '2-digit' });
// Create the message HTML
const messageHTML = `
<div class="message-box" data-message-id="${data.id}">
<div class="message-author">${data.author__name}</div>
<div class="message-content">
${data.content}
<span class="message-time">${dateString} ${timeString}</span>
</div>
<form action="/delete_message/${data.id}/" method="post" style="display:inline;">
{% csrf_token %}
<button type="submit" class="delete-button">Delete</button>
</form>
</div>`;
// Append the message
sseData.innerHTML += messageHTML;
}
});
}
</script>
</body>
</html>