templates/index.html.twig line 1
{# templates/chat/index.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<title>Poll</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<script>
var sessionId = 1;
$(document).ready(function() {
var lastMessageId = -1;
var pollSelector = document.getElementById('poll-selector');
var getSessionUrl = '{{ path('api_get_session',{'pollId': 1}) }}';
var getQuestionUrl = '{{ path('api_get_question',{'pollId': 1}) }}';
var postMessageUrl = '{{ path('api_post_message',{'pollId': 1}) }}';
var initialPollId = 1;
getSessionUrl = getSessionUrl.replace('initialPollId', initialPollId);
pollSelector.addEventListener('change', function() {
var selectedPollId = pollSelector.value;
getSessionUrl = getSessionUrl.replace(initialPollId, selectedPollId);
getQuestionUrl = getQuestionUrl.replace(initialPollId, selectedPollId);
postMessageUrl = postMessageUrl.replace(initialPollId, selectedPollId);
initialPollId = selectedPollId;
getSession();
loadFirstQuestion();
$('#chat-messages').html('');
});
function getSession() {
$.ajax({
url: getSessionUrl,
type: 'GET',
dataType: 'json',
success: function(data) {
sessionId = data.session_id;
loadFirstQuestion();
// Load messages initially
loadMessages();
},
});
}
function loadFirstQuestion() {
$.ajax({
url: getQuestionUrl,
type: 'GET',
dataType: 'json',
headers: {
'x-session-id': sessionId,
},
success: function(data) {
console.log(data);
},
});
}
// Function to load messages via AJAX
function loadMessages() {
$.ajax({
url: '{{ path('chat_messages')}}',
type: 'GET',
dataType: 'json',
headers: {
'x-session-id': sessionId
},
beforeSend: function(xhr) {
// Display loading icon3
$('#loading-icon').show();
},
success: function(data) {
// Process the JSON response
var chatMessages = '';
var isNewMessage = false;
for (var i = 0; i < data.length; i++) {
var message = data[i];
var createdAt = new Date(message.createdAt).toLocaleTimeString();
if (message.id > lastMessageId) {
css = (message.user == 'user') ? 'userMessage' : 'assitantMessage';
chatMessages += '<div class="message '+css+' new">';
chatMessages += '<p class="content">' + message.content + '</p>';
chatMessages += '<span class="timestamp">' + createdAt + '</span>';
chatMessages += '</div>';
isNewMessage = true;
}
}
if (isNewMessage) {
$('#chat-messages').append(chatMessages);
// Scroll to the bottom of the chat window if there is a new message
var chatWindow = $('#chat-window');
chatWindow.scrollTop(chatWindow[0].scrollHeight);
// Update the last message ID
lastMessageId = data[data.length - 1].id;
}
$('#loading-icon').hide();
}
});
}
getSession();
// Function to handle form submission
$('#message-form').submit(function(event) {
event.preventDefault();
var formData = $(this).serialize();
$.ajax({
url: postMessageUrl,
type: 'POST',
data: formData,
headers: {
'x-session-id': sessionId,
},
beforeSend: function() {
// Display loading icon
$('#loading-icon').show();
},
success: function() {
$('#message-content').val('');
loadMessages();
},
complete: function() {
// Hide loading icon
$('#loading-icon').hide();
}
});
});
// Function to periodically load messages
setInterval(loadMessages, 3000);
});
</script>
<style>
body, html {
height: 90%;
}
.message {
background-color: #f1f1f1;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
}
.message.userMessage {
background-color: #6388b1;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
}
.content {
font-weight: bold;
margin-bottom: 5px;
}
.timestamp {
font-size: 0.8rem;
color: #999;
}
.loading {
height: 32px;
}
.message-form {
margin-bottom: 30px;
}
</style>
</head>
<body>
<div class="container">
<div style="display: flex; justify-content: space-between;">
<h1>Poll Chat <span style="font-size: 10px;"> v0.2</span></h1>
<select id="poll-selector" style="padding: 5px; margin: 5px; margin-right: 0px; width: 200px; border-radius: 5px; border: 1px solid #ccc;">
{% for poll in polls %}
<option value="{{ poll.id }}">{{ poll.title }}</option>
{% endfor %}
</select>
</div>
<div id="chat-window" style="height: 80vh; overflow-y: scroll;">
<div id="chat-messages"></div>
</div>
<div class="loading">
<div id="loading-icon" style="display: none;">
<img src="images/Loading_icon.gif" alt="Loading" width="32" height="32">
</div>
</div>
</div>
<form autocomplete="off" id="message-form" method="post" class="fixed-bottom bg-light p-3 message-form">
<div class="container">
<div class="form-row">
<div class="col">
<input autocomplete="off" type="text" name="content" id="message-content" class="form-control" placeholder="Type your message" required>
</div>
<div class="col-auto">
<button type="submit" class="btn btn-primary">Send</button>
</div>
</div>
</div>
</form>
</body>
</html>