Spaces:
Running
Running

proč se mi odesílají zprávy které napíšu i tak že to ukáže jako druhý náhodný živatel - Follow Up Deployment
f168725
verified
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Gomegle - Chat s náhodnými ľuďmi</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
.typing-indicator::after { | |
content: "..."; | |
animation: typing 1.5s infinite; | |
display: inline-block; | |
width: 0; | |
} | |
@keyframes typing { | |
0% { content: "."; } | |
33% { content: ".."; } | |
66% { content: "..."; } | |
} | |
.chat-messages { | |
scrollbar-width: thin; | |
scrollbar-color: #4B5563 #1F2937; | |
} | |
.chat-messages::-webkit-scrollbar { | |
width: 6px; | |
} | |
.chat-messages::-webkit-scrollbar-track { | |
background: #1F2937; | |
} | |
.chat-messages::-webkit-scrollbar-thumb { | |
background-color: #4B5563; | |
border-radius: 3px; | |
} | |
.pulse-animation { | |
animation: pulse 2s infinite; | |
} | |
@keyframes pulse { | |
0% { opacity: 0.6; } | |
50% { opacity: 1; } | |
100% { opacity: 0.6; } | |
} | |
</style> | |
</head> | |
<body class="bg-gray-900 text-gray-100 min-h-screen flex flex-col"> | |
<!-- Header --> | |
<header class="bg-gray-800 py-4 px-6 shadow-lg"> | |
<div class="container mx-auto flex justify-between items-center"> | |
<div class="flex items-center space-x-2"> | |
<i class="fas fa-comments text-[#ae00eb] text-2xl"></i> | |
<h1 class="text-xl font-bold">Gomegle</h1> | |
</div> | |
<div class="flex items-center space-x-4"> | |
<button id="theme-toggle" class="text-gray-300 hover:text-white"> | |
<i class="fas fa-moon"></i> | |
</button> | |
<button id="info-btn" class="text-gray-300 hover:text-white"> | |
<i class="fas fa-info-circle"></i> | |
</button> | |
</div> | |
</div> | |
</header> | |
<!-- Main Content --> | |
<main class="flex-grow container mx-auto px-4 py-8 flex flex-col"> | |
<!-- Connection Status --> | |
<div id="status-container" class="mb-6 text-center"> | |
<div id="disconnected-view" class="bg-gray-800 rounded-lg p-6 shadow-lg"> | |
<div class="flex flex-col items-center"> | |
<i class="fas fa-user-friends text-5xl text-blue-400 mb-4"></i> | |
<h2 class="text-2xl font-bold mb-2">Chcete chatovať?</h2> | |
<p class="text-gray-400 mb-6">Kliknite na tlačidlo nižšie pre spojenie s náhodným človekom</p> | |
<button id="connect-btn" class="bg-[#ae00eb] hover:bg-[#9a00d1] text-white font-bold py-3 px-8 rounded-full transition-all transform hover:scale-105 flex items-center"> | |
<i class="fas fa-random mr-2"></i> Nájsť partnera | |
</button> | |
</div> | |
</div> | |
<div id="connecting-view" class="hidden bg-gray-800 rounded-lg p-6 shadow-lg"> | |
<div class="flex flex-col items-center"> | |
<div class="relative mb-4"> | |
<div class="w-16 h-16 rounded-full bg-blue-900 opacity-60 pulse-animation"></div> | |
<div class="w-16 h-16 rounded-full bg-blue-700 opacity-80 pulse-animation absolute top-0 left-0" style="animation-delay: 0.5s;"></div> | |
<div class="w-16 h-16 rounded-full bg-blue-500 pulse-animation absolute top-0 left-0" style="animation-delay: 1s;"></div> | |
<i class="fas fa-search absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-white text-xl"></i> | |
</div> | |
<h2 class="text-2xl font-bold mb-2">Hľadáme niekoho...</h2> | |
<p class="text-gray-400 mb-4">Čakajte kým vás spojíme s náhodným partnerom</p> | |
<button id="cancel-connect-btn" class="bg-gray-700 hover:bg-gray-600 text-white font-bold py-2 px-6 rounded-full transition-all"> | |
Zrušiť | |
</button> | |
</div> | |
</div> | |
<div id="connected-view" class="hidden bg-gray-800 rounded-lg p-6 shadow-lg"> | |
<div class="flex flex-col items-center"> | |
<div class="relative mb-4"> | |
<div class="w-16 h-16 rounded-full bg-green-900 opacity-60"></div> | |
<div class="w-16 h-16 rounded-full bg-green-700 opacity-80 absolute top-0 left-0"></div> | |
<div class="w-16 h-16 rounded-full bg-green-500 absolute top-0 left-0"></div> | |
<i class="fas fa-check absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 text-white text-xl"></i> | |
</div> | |
<h2 class="text-2xl font-bold mb-2">Pripojené!</h2> | |
<p class="text-gray-400 mb-4">Teraz chatujete s náhodným človekom</p> | |
<div class="flex space-x-4"> | |
<button id="disconnect-btn" class="bg-red-600 hover:bg-red-700 text-white font-bold py-2 px-6 rounded-full transition-all"> | |
<i class="fas fa-times mr-2"></i> Odpojiť | |
</button> | |
<button id="new-partner-btn" class="bg-[#ae00eb] hover:bg-[#9a00d1] text-white font-bold py-2 px-6 rounded-full transition-all"> | |
<i class="fas fa-sync-alt mr-2"></i> Nový partner | |
</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Chat Container --> | |
<div id="chat-container" class="hidden flex-grow flex flex-col bg-gray-800 rounded-lg shadow-lg overflow-hidden"> | |
<!-- Messages --> | |
<div id="chat-messages" class="flex-grow p-4 overflow-y-auto chat-messages max-h-96"> | |
<!-- Messages will be inserted here by JavaScript --> | |
<div id="welcome-message" class="text-center py-8 text-gray-400"> | |
<i class="fas fa-comment-dots text-4xl mb-4"></i> | |
<p class="text-lg">Pozdravte svojho nového chatovacieho partnera!</p> | |
<p class="text-sm mt-2">Správy sú end-to-end šifrované</p> | |
</div> | |
</div> | |
<!-- Typing Indicator --> | |
<div id="typing-indicator" class="hidden bg-gray-700 px-4 py-2 text-sm text-gray-400"> | |
<span class="typing-indicator">Partner píše...</span> | |
</div> | |
<!-- Message Input --> | |
<div class="bg-gray-700 p-4"> | |
<div class="flex items-center"> | |
<input type="text" id="message-input" placeholder="Napíšte svoju správu..." class="flex-grow bg-gray-600 text-white rounded-l-full py-3 px-4 focus:outline-none focus:ring-2 focus:ring-[#ae00eb]"> | |
<button id="send-btn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-6 rounded-r-full transition-all"> | |
<i class="fas fa-paper-plane"></i> | |
</button> | |
</div> | |
<div class="flex justify-between mt-2 text-xs text-gray-400"> | |
<div> | |
<button id="emoji-btn" class="hover:text-blue-400 mr-3"> | |
<i class="far fa-smile"></i> Emoji | |
</button> | |
<button id="attachment-btn" class="hover:text-[#ae00eb]"> | |
<i class="fas fa-paperclip"></i> Attach | |
</button> | |
</div> | |
<div> | |
<span id="char-count">0/500</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Interests Selection (Hidden by default) --> | |
<div id="interests-container" class="hidden mt-6 bg-gray-800 rounded-lg p-6 shadow-lg"> | |
<h3 class="text-xl font-bold mb-4">Select your interests to find better matches</h3> | |
<div class="flex flex-wrap gap-2 mb-6"> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Music | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Gaming | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Movies | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Sports | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Technology | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Travel | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Food | |
</button> | |
<button class="interest-tag bg-gray-700 hover:bg-gray-600 text-white px-4 py-2 rounded-full transition-all"> | |
Art | |
</button> | |
</div> | |
<div class="flex justify-end"> | |
<button id="save-interests-btn" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-full transition-all"> | |
Save Interests | |
</button> | |
</div> | |
</div> | |
</main> | |
<!-- Footer --> | |
<footer class="bg-gray-800 py-4 px-6"> | |
<div class="container mx-auto text-center text-gray-400 text-sm"> | |
<p>Gomegle © 2023 | <a href="#" class="hover:text-[#ae00eb]">Podmienky</a> | <a href="#" class="hover:text-[#ae00eb]">Ochrana súkromia</a> | <a href="#" class="hover:text-[#ae00eb]">Bezpečnosť</a></p> | |
<p class="mt-2">Spojte sa s náhodnými ľuďmi po celom svete</p> | |
</div> | |
</footer> | |
<!-- Info Modal --> | |
<div id="info-modal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> | |
<div class="bg-gray-800 rounded-lg p-6 max-w-md w-full mx-4 shadow-xl"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="text-xl font-bold">O Gomegle</h3> | |
<button id="close-info-modal" class="text-gray-400 hover:text-white"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="space-y-4"> | |
<p>Gomegle vás spája s náhodnými ľuďmi pre anonymné konverzácie.</p> | |
<p><strong>Ako to funguje:</strong></p> | |
<ol class="list-decimal list-inside space-y-2"> | |
<li>Kliknite na "Nájsť partnera" pre začatie vyhľadávania</li> | |
<li>Spojíme vás s náhodným používateľom</li> | |
<li>Chatujte anonymne (žiadne osobné údaje sa nezdieľajú)</li> | |
<li>Kliknite na "Odpojiť" pre ukončenie chatu</li> | |
</ol> | |
<div class="bg-gray-700 p-3 rounded-lg"> | |
<p class="text-sm"><i class="fas fa-exclamation-triangle text-yellow-400 mr-2"></i> Pamätajte byť zdvorilí a dodržiavať pravidlá komunity.</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
// DOM Elements | |
const connectBtn = document.getElementById('connect-btn'); | |
const cancelConnectBtn = document.getElementById('cancel-connect-btn'); | |
const disconnectBtn = document.getElementById('disconnect-btn'); | |
const newPartnerBtn = document.getElementById('new-partner-btn'); | |
const messageInput = document.getElementById('message-input'); | |
const sendBtn = document.getElementById('send-btn'); | |
const chatMessages = document.getElementById('chat-messages'); | |
const typingIndicator = document.getElementById('typing-indicator'); | |
const charCount = document.getElementById('char-count'); | |
const emojiBtn = document.getElementById('emoji-btn'); | |
const attachmentBtn = document.getElementById('attachment-btn'); | |
const infoBtn = document.getElementById('info-btn'); | |
const closeInfoModal = document.getElementById('close-info-modal'); | |
const infoModal = document.getElementById('info-modal'); | |
const themeToggle = document.getElementById('theme-toggle'); | |
const interestsContainer = document.getElementById('interests-container'); | |
const saveInterestsBtn = document.getElementById('save-interests-btn'); | |
// Status views | |
const disconnectedView = document.getElementById('disconnected-view'); | |
const connectingView = document.getElementById('connecting-view'); | |
const connectedView = document.getElementById('connected-view'); | |
const chatContainer = document.getElementById('chat-container'); | |
const welcomeMessage = document.getElementById('welcome-message'); | |
// State | |
let isConnected = false; | |
let isTyping = false; | |
let typingTimeout; | |
let partnerTyping = false; | |
let partnerTypingInterval; | |
// WebSocket connection | |
let socket; | |
let userId = Math.random().toString(36).substring(2, 15); | |
let partnerId = null; | |
// Initialize | |
function init() { | |
// Set up event listeners | |
connectBtn.addEventListener('click', startConnection); | |
cancelConnectBtn.addEventListener('click', cancelConnection); | |
disconnectBtn.addEventListener('click', disconnect); | |
newPartnerBtn.addEventListener('click', findNewPartner); | |
messageInput.addEventListener('input', handleTyping); | |
messageInput.addEventListener('keypress', (e) => { | |
if (e.key === 'Enter' && messageInput.value.trim() !== '') { | |
sendMessage(); | |
} | |
}); | |
sendBtn.addEventListener('click', sendMessage); | |
infoBtn.addEventListener('click', () => infoModal.classList.remove('hidden')); | |
closeInfoModal.addEventListener('click', () => infoModal.classList.add('hidden')); | |
themeToggle.addEventListener('click', toggleTheme); | |
saveInterestsBtn.addEventListener('click', saveInterests); | |
// Set up character count | |
messageInput.addEventListener('input', updateCharCount); | |
updateCharCount(); | |
// Set up interest tags | |
document.querySelectorAll('.interest-tag').forEach(tag => { | |
tag.addEventListener('click', () => { | |
tag.classList.toggle('bg-gray-700'); | |
tag.classList.toggle('bg-blue-600'); | |
}); | |
}); | |
// Check for saved theme preference | |
if (localStorage.getItem('theme') === 'dark' || | |
(!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) { | |
document.documentElement.classList.add('dark'); | |
themeToggle.innerHTML = '<i class="fas fa-sun"></i>'; | |
} else { | |
document.documentElement.classList.remove('dark'); | |
themeToggle.innerHTML = '<i class="fas fa-moon"></i>'; | |
} | |
} | |
// Theme toggle | |
function toggleTheme() { | |
if (document.documentElement.classList.contains('dark')) { | |
document.documentElement.classList.remove('dark'); | |
localStorage.setItem('theme', 'light'); | |
themeToggle.innerHTML = '<i class="fas fa-moon"></i>'; | |
} else { | |
document.documentElement.classList.add('dark'); | |
localStorage.setItem('theme', 'dark'); | |
themeToggle.innerHTML = '<i class="fas fa-sun"></i>'; | |
} | |
} | |
// Start connection | |
function startConnection() { | |
disconnectedView.classList.add('hidden'); | |
connectingView.classList.remove('hidden'); | |
// Connect to public demo WebSocket server | |
socket = new WebSocket('wss://ws.ifelse.io'); | |
socket.onopen = function(e) { | |
console.log("Connected to WebSocket server"); | |
connectingView.classList.add('hidden'); | |
connectedView.classList.remove('hidden'); | |
chatContainer.classList.remove('hidden'); | |
isConnected = true; | |
// Send connection request | |
socket.send(JSON.stringify({ | |
type: 'connect', | |
userId: userId | |
})); | |
}; | |
socket.onmessage = function(event) { | |
// This demo server just echoes messages back | |
// In a real app you'd parse JSON and handle different message types | |
if (event.data.startsWith('{')) { | |
const message = JSON.parse(event.data); | |
// Handle JSON messages | |
} else { | |
// Show echoed messages as from "Partner" | |
addMessage("Partner", event.data, false); | |
} | |
}; | |
socket.onclose = function(event) { | |
if (event.wasClean) { | |
addSystemMessage(`Connection closed cleanly, code=${event.code} reason=${event.reason}`); | |
} else { | |
addSystemMessage('Connection died'); | |
} | |
disconnect(); | |
}; | |
socket.onerror = function(error) { | |
addSystemMessage(`WebSocket error: ${error.message}`); | |
disconnect(); | |
}; | |
} | |
// Cancel connection | |
function cancelConnection() { | |
connectingView.classList.add('hidden'); | |
disconnectedView.classList.remove('hidden'); | |
} | |
// Disconnect | |
function disconnect() { | |
isConnected = false; | |
// Notify server about disconnection | |
if (socket) { | |
socket.send(JSON.stringify({ | |
type: 'disconnect', | |
partnerId: partnerId | |
})); | |
socket.close(); | |
} | |
connectedView.classList.add('hidden'); | |
chatContainer.classList.add('hidden'); | |
disconnectedView.classList.remove('hidden'); | |
// Clear chat messages | |
while (chatMessages.firstChild) { | |
chatMessages.removeChild(chatMessages.firstChild); | |
} | |
// Reset welcome message | |
welcomeMessage.classList.remove('hidden'); | |
// Clear typing indicators | |
clearTimeout(typingTimeout); | |
typingIndicator.classList.add('hidden'); | |
// Reset partner ID | |
partnerId = null; | |
} | |
// Find new partner | |
function findNewPartner() { | |
disconnect(); | |
startConnection(); | |
} | |
// Handle typing | |
function handleTyping() { | |
if (!isTyping && isConnected && socket) { | |
isTyping = true; | |
socket.send(JSON.stringify({ | |
type: 'typing', | |
isTyping: true, | |
to: partnerId | |
})); | |
} | |
// Reset the typing indicator after 3 seconds of inactivity | |
clearTimeout(typingTimeout); | |
typingTimeout = setTimeout(() => { | |
if (isTyping) { | |
isTyping = false; | |
socket.send(JSON.stringify({ | |
type: 'typing', | |
isTyping: false, | |
to: partnerId | |
})); | |
} | |
}, 3000); | |
} | |
// Simulate partner typing (for demo purposes) | |
function simulatePartnerTyping() { | |
partnerTypingInterval = setInterval(() => { | |
if (Math.random() > 0.7) { // 30% chance partner starts typing | |
partnerTyping = true; | |
typingIndicator.classList.remove('hidden'); | |
setTimeout(() => { | |
if (partnerTyping) { | |
partnerTyping = false; | |
typingIndicator.classList.add('hidden'); | |
// Add a random message from the partner | |
const messages = [ | |
"Hi there! How are you?", | |
"What brings you to RandomChat today?", | |
"Nice to meet you!", | |
"Do you come here often? 😄", | |
"What are your interests?", | |
"The weather is nice today, isn't it?", | |
"Have you tried the new chat features?" | |
]; | |
addMessage(mockUsers[Math.floor(Math.random() * mockUsers.length)].name, messages[Math.floor(Math.random() * messages.length)], false); | |
} | |
}, 1000 + Math.random() * 3000); | |
} | |
}, 8000); // Check every 8 seconds | |
} | |
// Send message | |
function sendMessage() { | |
const message = messageInput.value.trim(); | |
if (message === '' || !isConnected || !socket) return; | |
// Add message to chat | |
addMessage("You", message, true); | |
// Send message via WebSocket | |
socket.send(JSON.stringify({ | |
type: 'message', | |
text: message, | |
to: partnerId | |
})); | |
// Clear input | |
messageInput.value = ''; | |
updateCharCount(); | |
} | |
// Add message to chat | |
function addMessage(sender, text, isUser) { | |
// Hide welcome message if it's the first message | |
if (welcomeMessage && !welcomeMessage.classList.contains('hidden')) { | |
welcomeMessage.classList.add('hidden'); | |
} | |
const messageDiv = document.createElement('div'); | |
messageDiv.className = `mb-4 flex ${isUser ? 'justify-end' : 'justify-start'}`; | |
const messageContent = document.createElement('div'); | |
messageContent.className = `max-w-xs lg:max-w-md px-4 py-2 rounded-lg ${isUser ? 'bg-blue-600 rounded-tr-none' : 'bg-gray-700 rounded-tl-none'}`; | |
if (!isUser) { | |
const senderName = document.createElement('div'); | |
senderName.className = 'text-xs font-semibold text-blue-300 mb-1'; | |
senderName.textContent = sender; | |
messageContent.appendChild(senderName); | |
} | |
const messageText = document.createElement('div'); | |
messageText.className = 'text-white'; | |
messageText.textContent = text; | |
messageContent.appendChild(messageText); | |
const time = document.createElement('div'); | |
time.className = `text-xs mt-1 text-right ${isUser ? 'text-blue-200' : 'text-gray-400'}`; | |
const now = new Date(); | |
time.textContent = now.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }); | |
messageContent.appendChild(time); | |
messageDiv.appendChild(messageContent); | |
chatMessages.appendChild(messageDiv); | |
// Scroll to bottom | |
chatMessages.scrollTop = chatMessages.scrollHeight; | |
} | |
// Update character count | |
function updateCharCount() { | |
const count = messageInput.value.length; | |
charCount.textContent = `${count}/500`; | |
if (count > 450) { | |
charCount.classList.add('text-yellow-400'); | |
charCount.classList.remove('text-gray-400'); | |
} else if (count > 490) { | |
charCount.classList.add('text-red-400'); | |
charCount.classList.remove('text-yellow-400'); | |
} else { | |
charCount.classList.add('text-gray-400'); | |
charCount.classList.remove('text-yellow-400', 'text-red-400'); | |
} | |
} | |
// Save interests | |
function saveInterests() { | |
interestsContainer.classList.add('hidden'); | |
// In a real app, we'd save the selected interests to the server | |
} | |
// Initialize the app | |
init(); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=ultronek01/gomegle" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |