365 lines
11 KiB
HTML
365 lines
11 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" dir="ltr">
|
|
<head>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" charset="utf-8" />
|
|
<title id="title"></title>
|
|
|
|
|
|
<!-- Material Icons -->
|
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
|
<!-- Material Symbols - Outlined Set -->
|
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
|
|
<!-- Material Symbols - Rounded Set -->
|
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded" rel="stylesheet" />
|
|
<!-- Material Symbols - Sharp Set -->
|
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Sharp" rel="stylesheet" />
|
|
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/uikit.min.css') }}"/>
|
|
|
|
<script src="{{ url_for('static', filename='js/uikit.min.js') }}"></script>
|
|
<script src="{{ url_for('static', filename='js/uikit-icons.min.js') }}"></script>
|
|
</head>
|
|
<style>
|
|
:root {
|
|
--body-background: #121212;
|
|
--background: #1c1c1c;
|
|
--primary-color: #f7f7f7;
|
|
--accent-color: #ffb3b3;
|
|
--secondary-text: #666666;
|
|
--highlight: #ffd700;
|
|
--font: 'Arial', sans-serif;;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--body-background);
|
|
color: var(--primary-color);
|
|
font-family: var(--font);
|
|
}
|
|
|
|
.subtitle{
|
|
font-size: 8px;
|
|
}
|
|
|
|
.my-nav-bar {
|
|
width: 100%;
|
|
height: 40px;
|
|
padding: 10px;
|
|
background-color: var(--body-background);
|
|
box-shadow: 0 2px 5px var(--background);
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 1000;
|
|
}
|
|
|
|
.my-nav-bar inline {
|
|
display: flex;
|
|
gap: 10px;
|
|
}
|
|
|
|
.nav-button{
|
|
height: 40px;
|
|
margin: 0;
|
|
box-sizing: border-box;
|
|
background-color: transparent;
|
|
color: var(--primary-color);
|
|
border: none;
|
|
padding: 10px;
|
|
border-radius: 4px;
|
|
transition: background-color 0.3s, box-shadow 0.3s;
|
|
cursor: pointer;
|
|
text-overflow: ellipsis;
|
|
font-size: 18px;
|
|
}
|
|
|
|
.nav-button span {
|
|
font-size: 18px;
|
|
width: 18px;
|
|
height: 18px;
|
|
vertical-align: middle;
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.nav-title{
|
|
margin: 0px;
|
|
font-size: x-large;
|
|
margin-left: 20px;
|
|
}
|
|
|
|
.chat-container {
|
|
background-color: var(--body-background);
|
|
min-height: calc(100vh - 120px);
|
|
margin-bottom: 60px;
|
|
margin-top: 60px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.chat-container > * {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
|
|
.floating-square {
|
|
width: 100%;
|
|
height: 50px;
|
|
padding: 10px;
|
|
background-color: var(--body-background);
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
display: flexbox;
|
|
align-items: center;
|
|
}
|
|
|
|
.full-width-input {
|
|
padding: 10px;
|
|
width: calc(100% - 70px);
|
|
height: auto; /* Allow dynamic height */
|
|
min-height: 48px; /* Starting height */
|
|
resize: vertical; /* Allow vertical resizing */
|
|
overflow: hidden;
|
|
vertical-align: bottom;
|
|
box-sizing: border-box;
|
|
border: none;
|
|
border-bottom: 2px solid var(--secondary-text);
|
|
border-radius: 0px;
|
|
transition: border-color 0.3s;
|
|
outline: none;
|
|
background-color: var(--background);
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
.full-width-input:focus {
|
|
border-bottom-color: var(--primary-color); /* Highlight upon focus */
|
|
}
|
|
|
|
.full-width-button {
|
|
width: 50px;
|
|
margin: 0;
|
|
vertical-align: bottom;
|
|
padding: 10px;
|
|
min-width: 50px;
|
|
border-radius: 4px; /* Match textarea */
|
|
border: none; /* Match textarea */
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
box-sizing: border-box;
|
|
background-color: var(--background);
|
|
color: var(--primary-color);
|
|
transition: background-color 0.3s, box-shadow 0.3s;
|
|
cursor: pointer;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.full-width-button:hover {
|
|
background-color: var(--background); /* Darker tone on hover */
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); /* Enhanced hover elevation */
|
|
}
|
|
|
|
.full-width-button:active {
|
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
}
|
|
|
|
.message-card {
|
|
padding: 10px;
|
|
margin: 0px;
|
|
background-color: var(--body-background);
|
|
color: var(--primary-color);
|
|
}
|
|
.user-info {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.avatar {
|
|
border-radius: 50%;
|
|
width: 40px;
|
|
margin-right: 10px;
|
|
}
|
|
.username {
|
|
font-weight: bold;
|
|
margin-right: 5px;
|
|
font-family: var(--font);
|
|
|
|
}
|
|
.timestamp {
|
|
font-size: 0.9em;
|
|
color: #b0b0b0;
|
|
font-family: var(--font);
|
|
}
|
|
.message-content {
|
|
margin-top: 5px;
|
|
margin-left:50px;
|
|
margin-right: 5px;
|
|
|
|
font-family: var(--font);
|
|
}
|
|
|
|
|
|
</style>
|
|
<body>
|
|
<div class="my-nav-bar">
|
|
<inline>
|
|
<a href="/logout" class="nav-button"><span class="material-icons">menu</span>Menu</a>
|
|
<p id="room-title" class="nav-title">Room Title</p>
|
|
</inline>
|
|
</div>
|
|
<div class="chat-container" >
|
|
<div id="chat" style="height: auto;">
|
|
</div>
|
|
</div>
|
|
<div id="test" class="floating-square">
|
|
<textarea id="messageInput" class="full-width-input" placeholder="Type your thoughts..."></textarea>
|
|
<button id="sendButton" onclick="sendMessage()" class="full-width-button"><span class="material-symbols-outlined">
|
|
send
|
|
</span></button>
|
|
</div>
|
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
|
|
<script type="text/javascript" charset="utf-8">
|
|
var socket = io.connect('http://192.168.1.45:5812/');
|
|
var current_room = 1;
|
|
var current_username = 'unknown';
|
|
var current_channel;
|
|
var user;
|
|
|
|
fetch('/get_session')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
user = data['user'] // Revel in the data!
|
|
current_username = user[1]
|
|
})
|
|
.catch(error => console.error('Error fetching session:', error));
|
|
|
|
socket.on('messageReceive', function(data) {
|
|
console.log('Received:', data);
|
|
let message = data.message;
|
|
// instead of adding the message do I just reload the messages? what kind of infranstructure would that require.
|
|
addMessage([data])
|
|
});
|
|
|
|
socket.on('joined', function(data) {
|
|
current_channel = data
|
|
document.getElementById('room-title').innerHTML = data['channel_name']
|
|
});
|
|
|
|
const textarea = document.getElementById('messageInput');
|
|
textarea.addEventListener('input', function() {
|
|
this.style.height = 'auto';
|
|
this.style.height = this.scrollHeight + 'px';
|
|
document.getElementById('test').style.height = this.scrollHeight + 'px'
|
|
});
|
|
textarea.addEventListener('blur', function() {
|
|
this.style.height = 'auto';
|
|
this.style.height = '40px';
|
|
document.getElementById('test').style.height = '50px'
|
|
this.blur()
|
|
});
|
|
|
|
textarea.addEventListener('keydown', function(event) {
|
|
if (event.key === 'Enter' && !event.shiftKey) { // Checks if Enter is pressed without shift
|
|
event.preventDefault();
|
|
sendMessage(); // Replace with your function
|
|
}
|
|
});
|
|
|
|
joinRoom(current_room)
|
|
|
|
function addMessage(data){
|
|
|
|
let message_card = document.createElement('div')
|
|
message_card.setAttribute('class', 'message-card')
|
|
|
|
let user_info = document.createElement('div')
|
|
user_info.setAttribute('class', 'user-info')
|
|
|
|
let image = document.createElement('img')
|
|
image.setAttribute('class', 'avatar')
|
|
image.setAttribute('src', "static/images/placeholder.webp")
|
|
|
|
let username = document.createElement('span')
|
|
username.setAttribute('class', 'username')
|
|
username.innerHTML = data[0]['user']['username']
|
|
|
|
let timestamp = document.createElement('span')
|
|
timestamp.setAttribute('class', 'timestamp')
|
|
timestamp.innerHTML = data[0]['timestamp']
|
|
|
|
user_info.append(image)
|
|
user_info.append(username)
|
|
user_info.append(timestamp)
|
|
|
|
message_card.append(user_info)
|
|
|
|
let message = document.createElement('div')
|
|
message.setAttribute('class', 'message-content')
|
|
|
|
test = `${data[0]['message_content']}`
|
|
for(let i = 1; i < data.length; i++){
|
|
test = test + `<br>${data[i]['message_content']}`
|
|
}
|
|
|
|
message.innerHTML = `${test}`
|
|
|
|
message_card.append(message)
|
|
|
|
document.getElementById('chat').append(message_card)
|
|
|
|
window.scrollTo(0, document.body.scrollHeight);
|
|
}
|
|
|
|
function sendMessage(){
|
|
let message = document.getElementById('messageInput')
|
|
|
|
let currentTime = new Date();
|
|
let timeString = currentTime.toLocaleTimeString();
|
|
let dateString = currentTime.toLocaleDateString();
|
|
let dateTimeString = `${dateString} ${timeString}`;
|
|
|
|
socket.emit('messageSend', {'message_content': message.value, 'channel_id': current_room, 'user_id': user[0], 'timestamp': currentTime})
|
|
message.value = '';
|
|
|
|
}
|
|
|
|
async function joinRoom(channel_id) {
|
|
socket.emit('join', {'channel_id': channel_id});
|
|
current_room = channel_id
|
|
|
|
const url = new URL('/get_channel_messsages', window.location.origin);
|
|
url.searchParams.append('channel_id', channel_id);
|
|
const response = await fetch(url);
|
|
data = await response.json()
|
|
messages = data.messages;
|
|
console.log(messages.length)
|
|
console.log(messages)
|
|
let combinedMessages = []
|
|
let previous_message;
|
|
let num_messages = 0
|
|
|
|
let grouped = [], tempGroup = [messages[0]];
|
|
let startTime = new Date(messages[0].timestamp);
|
|
for (let i = 1; i < messages.length; i++) {
|
|
if ((new Date(messages[i].timestamp) - startTime <= 300000) &&
|
|
(messages[i].user.id === messages[i - 1].user.id)) {
|
|
tempGroup.push(messages[i]);
|
|
} else {
|
|
grouped.push(tempGroup);
|
|
tempGroup = [messages[i]];
|
|
startTime = new Date(messages[i].timestamp);
|
|
}
|
|
}
|
|
grouped.push(tempGroup);
|
|
console.log(grouped)
|
|
|
|
for (let i = 0; i< grouped.length; i++){
|
|
addMessage(grouped[i])
|
|
}
|
|
}
|
|
|
|
// To leave a room
|
|
function leaveRoom(username, room) {
|
|
socket.emit('leave', { username, room });
|
|
}
|
|
|
|
</script>
|
|
</body>
|
|
</html> |