api_g / chat.html
DmitrMakeev's picture
Update chat.html
4c5689c verified
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Chat 🌿</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #38b2ac 0%, #48bb78 100%);
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.chat-container {
width: 100%;
max-width: 480px;
height: 700px;
background: #f0fff4;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
display: flex;
flex-direction: column;
overflow: hidden;
}
.chat-header {
background: #2f855a;
color: white;
padding: 15px 20px;
text-align: center;
position: relative;
}
.security-badge {
position: absolute;
top: 10px;
right: 15px;
background: #68d391;
padding: 4px 8px;
border-radius: 12px;
font-size: 0.7em;
font-weight: bold;
}
.encryption-notice {
text-align: center;
padding: 8px;
background: #c6f6d5;
color: #22543d;
font-size: 0.8em;
border-bottom: 1px solid #9ae6b4;
}
.key-input {
width: 90%;
margin: 10px auto;
display: block;
padding: 10px 12px;
border: 2px solid #9ae6b4;
border-radius: 10px;
font-size: 14px;
text-align: center;
background: #fafffa;
transition: border-color 0.3s;
}
.key-input:focus {
border-color: #48bb78;
outline: none;
}
.messages-container {
flex: 1;
padding: 20px;
overflow-y: auto;
background: #f7faf7;
}
.message {
margin-bottom: 15px;
padding: 10px 15px;
border-radius: 15px;
max-width: 80%;
word-wrap: break-word;
}
.message.own {
background: #68d391;
color: #1a202c;
margin-left: auto;
border-bottom-right-radius: 5px;
}
.message.other {
background: #e6fffa;
color: #2f855a;
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 #c6f6d5;
display: flex;
flex-direction: column;
gap: 10px;
}
.message-input {
width: 100%;
height: 70px;
resize: none;
padding: 12px 15px;
border: 2px solid #c6f6d5;
border-radius: 12px;
outline: none;
font-size: 15px;
line-height: 1.4;
transition: border-color 0.3s;
background: #fafffa;
}
.message-input:focus {
border-color: #48bb78;
}
.button-row {
display: flex;
justify-content: space-between;
align-items: center;
}
.send-button, .clear-button {
padding: 10px 20px;
border: none;
border-radius: 25px;
font-weight: bold;
cursor: pointer;
transition: background 0.3s;
}
.send-button {
background: #48bb78;
color: white;
}
.send-button:hover { background: #38a169; }
.clear-button {
background: #e53e3e;
color: white;
}
.clear-button:hover { background: #c53030; }
.messages-container::-webkit-scrollbar { width: 6px; }
.messages-container::-webkit-scrollbar-thumb { background: #a0aec0; border-radius: 3px; }
.messages-container::-webkit-scrollbar-thumb:hover { background: #718096; }
</style>
</head>
<body>
<div class="chat-container">
<div class="chat-header">
<h2>🌿 Secure Chat</h2>
<div class="security-badge">AES ШИФРОВАНИЕ</div>
</div>
<div class="encryption-notice">Введите общий ключ шифрования ниже</div>
<input type="password" id="key-input" class="key-input" placeholder="🔑 Ключ шифрования (один и тот же у обоих)" />
<div class="messages-container" id="messages"></div>
<div class="input-container">
<textarea class="message-input" id="message-input" placeholder="Введите сообщение..."></textarea>
<div class="button-row">
<button class="send-button" id="send-btn">Отправить</button>
<button class="clear-button" id="clear-btn">🗑 Очистить</button>
</div>
</div>
</div>
<script>
const userId = "{{ user_id }}";
let lastId = 0;
let encryptionKey = '';
const keyInput = document.getElementById('key-input');
const msgInput = document.getElementById('message-input');
const messagesDiv = document.getElementById('messages');
document.getElementById('send-btn').onclick = sendMessage;
document.getElementById('clear-btn').onclick = clearChat;
keyInput.oninput = () => encryptionKey = keyInput.value.trim();
async function sendMessage() {
const text = msgInput.value.trim();
if (!text || !encryptionKey) return alert('Введите сообщение и ключ');
const encrypted = CryptoJS.AES.encrypt(text, encryptionKey).toString();
await fetch('/send_message', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: userId, encrypted_text: encrypted })
});
msgInput.value = '';
loadNewMessages();
}
async function loadMessages() {
const res = await fetch('/get_messages');
const data = await res.json();
renderMessages(data.messages);
}
async function loadNewMessages() {
const res = await fetch(`/get_new_messages?last_id=${lastId}`);
const data = await res.json();
if (data.messages.length) renderMessages(data.messages, false);
}
async function clearChat() {
if (!confirm('Очистить чат?')) return;
await fetch('/clear_chat', { method: 'POST' });
messagesDiv.innerHTML = '';
lastId = 0;
}
function renderMessages(msgs, clear = true) {
if (clear) messagesDiv.innerHTML = '';
msgs.forEach(m => {
// если это уже было добавлено — пропускаем
if (document.getElementById('msg-' + m.id)) return;
lastId = Math.max(lastId, m.id);
let decrypted = '[🔒 Сообщение зашифровано]';
if (encryptionKey) {
try {
decrypted = CryptoJS.AES.decrypt(m.encrypted_text, encryptionKey).toString(CryptoJS.enc.Utf8) || decrypted;
} catch {}
}
const div = document.createElement('div');
div.id = 'msg-' + m.id; // уникальный ID для проверки
div.className = 'message ' + (m.user_id === userId ? 'own' : 'other');
div.innerHTML = `<div><b>${m.username}</b> • ${m.timestamp}</div><div>${decrypted}</div>`;
messagesDiv.appendChild(div);
});
messagesDiv.scrollTop = messagesDiv.scrollHeight;
}
setInterval(loadNewMessages, 2000);
loadMessages();
</script>
</body>
</html>