api_g / chat.html
DmitrMakeev's picture
Update chat.html
f7b3b67 verified
raw
history blame
9.75 kB
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Chat</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.chat-container {
width: 100%;
max-width: 400px;
height: 600px;
background: white;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-header {
background: #4a5568;
color: white;
padding: 15px 20px;
text-align: center;
}
.messages-container {
flex: 1;
padding: 20px;
overflow-y: auto;
background: #f7fafc;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 15px;
max-width: 80%;
word-wrap: break-word;
}
.message.own {
background: #4299e1;
color: white;
margin-left: auto;
border-bottom-right-radius: 5px;
}
.message.other {
background: #e2e8f0;
color: #2d3748;
border-bottom-left-radius: 5px;
}
.message-info {
font-size: 0.8em;
opacity: 0.7;
margin-bottom: 3px;
}
.input-container {
padding: 15px 20px;
background: white;
border-top: 1px solid #e2e8f0;
display: flex;
gap: 10px;
}
.message-input {
flex: 1;
padding: 12px 15px;
border: 2px solid #e2e8f0;
border-radius: 25px;
outline: none;
font-size: 14px;
transition: border-color 0.3s;
}
.message-input:focus {
border-color: #4299e1;
}
.send-button {
padding: 12px 25px;
background: #4299e1;
color: white;
border: none;
border-radius: 25px;
cursor: pointer;
font-weight: bold;
transition: background 0.3s;
}
.send-button:hover {
background: #3182ce;
}
.send-button:disabled {
background: #a0aec0;
cursor: not-allowed;
}
.typing-indicator {
padding: 10px 15px;
font-style: italic;
color: #718096;
font-size: 0.9em;
}
.messages-container::-webkit-scrollbar {
width: 6px;
}
.messages-container::-webkit-scrollbar-track {
background: #f1f1f1;
}
.messages-container::-webkit-scrollbar-thumb {
background: #cbd5e0;
border-radius: 3px;
}
.messages-container::-webkit-scrollbar-thumb:hover {
background: #a0aec0;
}
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h2>💬 Simple Chat</h2>
<small>Ваш ID: <span id="user-id">{{ user_id }}</span></small>
</div>
<div class="messages-container" id="messages-container">
<div class="typing-indicator" id="welcome-message">
Добро пожаловать в чат! Начните общение...
</div>
</div>
<div class="input-container">
<input type="text"
class="message-input"
id="message-input"
placeholder="Введите сообщение..."
maxlength="500">
<button class="send-button" id="send-button">Отправить</button>
</div>
</div>
<script>
class Chat {
constructor() {
this.userId = document.getElementById('user-id').textContent;
this.messagesContainer = document.getElementById('messages-container');
this.messageInput = document.getElementById('message-input');
this.sendButton = document.getElementById('send-button');
this.lastMessageId = 0;
this.init();
}
init() {
this.loadMessages();
this.sendButton.addEventListener('click', () => this.sendMessage());
this.messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
this.sendMessage();
}
});
setInterval(() => this.loadNewMessages(), 2000);
this.messageInput.focus();
}
async sendMessage() {
const message = this.messageInput.value.trim();
if (!message) return;
this.sendButton.disabled = true;
this.sendButton.textContent = 'Отправка...';
try {
const response = await fetch('/send_message', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
user_id: this.userId,
message: message
})
});
const result = await response.json();
if (result.status === 'success') {
this.messageInput.value = '';
this.loadNewMessages();
} else {
alert('Ошибка отправки: ' + result.message);
}
} catch (error) {
console.error('Ошибка:', error);
alert('Ошибка соединения с сервером');
} finally {
this.sendButton.disabled = false;
this.sendButton.textContent = 'Отправить';
}
}
async loadMessages() {
try {
const response = await fetch('/get_messages');
const data = await response.json();
this.displayMessages(data.messages);
this.scrollToBottom();
} catch (error) {
console.error('Ошибка загрузки сообщений:', error);
}
}
async loadNewMessages() {
try {
const response = await fetch(`/get_new_messages?last_id=${this.lastMessageId}`);
const data = await response.json();
if (data.messages.length > 0) {
this.displayMessages(data.messages, false);
this.scrollToBottom();
}
} catch (error) {
console.error('Ошибка загрузки новых сообщений:', error);
}
}
displayMessages(messages, clear = true) {
if (clear) {
const welcomeMsg = document.getElementById('welcome-message');
if (welcomeMsg) welcomeMsg.remove();
this.messagesContainer.innerHTML = '';
}
messages.forEach(message => {
if (message.id > this.lastMessageId) {
this.lastMessageId = message.id;
}
const messageElement = document.createElement('div');
messageElement.className = `message ${message.user_id === this.userId ? 'own' : 'other'}`;
messageElement.innerHTML = `
<div class="message-info">
${message.username}${message.timestamp}
</div>
<div class="message-text">${this.escapeHtml(message.text)}</div>
`;
this.messagesContainer.appendChild(messageElement);
});
}
scrollToBottom() {
this.messagesContainer.scrollTop = this.messagesContainer.scrollHeight;
}
escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
}
document.addEventListener('DOMContentLoaded', () => {
new Chat();
});
</script>
</body>
</html>